one_gadget 1.7.2 → 1.7.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8408e8896c26b1f1841de6d054d3535f557e9460d0cf888b11d9bf0e84794b92
4
- data.tar.gz: 61f4578f7bc943a7bf2914807769285832870af127c615e45635b89dc1a66a19
3
+ metadata.gz: 8e18cc48cf48847c6303e01416f9c36fb7284bc926d30f63fb716ce993a569ad
4
+ data.tar.gz: 17288573c3302ee9a1e9773b1dfc71ec36a433694ae9742f56999e5e719396e4
5
5
  SHA512:
6
- metadata.gz: 8e8462690bcbdfa1424cc9374f71a027423f544b956153507b9cb6bf0ee4d829656eb559d90016ec399595a4de32dc6475155347cb417b806d10e6b9bf78f010
7
- data.tar.gz: 4180279e347d9f1623ece4cd1829da966c9f759062ac787d5910019e10b7eae0f7b46e75b419997e9d8cbf1df8fc4a1aa9f7e4e02ca0557d2fb8973e5a10f2b1
6
+ metadata.gz: 113e516e80c9ac3baf01505d8ddceb12c4c47db1c70e5b472baffa35b271f00ac38f46d9d4d0b5c81abfb91c23af7ab732ef89c873c50f512e35c166cb56b0aa
7
+ data.tar.gz: 650ca490c96910e5a12b2da59e707a7f23c2346b1beaeb5df7ef977d764e764e08f9615f6ac006d1525a04cbbe173b6d7a8cf2bc765f6c2dc38ea9eafd3457f8
data/README.md CHANGED
@@ -56,6 +56,8 @@ $ one_gadget
56
56
  # -s, --script exploit-script Run exploit script with all possible gadgets.
57
57
  # The script will be run as 'exploit-script $offset'.
58
58
  # --info BuildID Show version information given BuildID.
59
+ # --base BASE_ADDRESS The base address of libc.
60
+ # Default: 0
59
61
  # --version Current gem version.
60
62
 
61
63
  ```
@@ -64,6 +66,7 @@ $ one_gadget
64
66
  $ one_gadget /lib/x86_64-linux-gnu/libc.so.6
65
67
  # 0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
66
68
  # constraints:
69
+ # rsp & 0xf == 0
67
70
  # rcx == NULL
68
71
  #
69
72
  # 0x4f322 execve("/bin/sh", rsp+0x40, environ)
@@ -105,7 +108,7 @@ $ one_gadget -b aad7dbe330f23ea00ca63daf793b766b51aceb5d
105
108
 
106
109
  Consider this scenario when exploiting:
107
110
  1. Able to write on GOT (Global Offset Table)
108
- 2. Libc base address is unknown
111
+ 2. Base address of libc is *unknown*
109
112
 
110
113
  In this scenario you can choose to write two low-byte on a GOT entry with one-gadget's two low-byte.
111
114
  If the function offset on GOT is close enough with the one-gadget,
@@ -120,6 +123,7 @@ $ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near exit,mkdir
120
123
  # [OneGadget] Gadgets near exit(0x43120):
121
124
  # 0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
122
125
  # constraints:
126
+ # rsp & 0xf == 0
123
127
  # rcx == NULL
124
128
  #
125
129
  # 0x4f322 execve("/bin/sh", rsp+0x40, environ)
@@ -141,6 +145,7 @@ $ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near exit,mkdir
141
145
  #
142
146
  # 0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
143
147
  # constraints:
148
+ # rsp & 0xf == 0
144
149
  # rcx == NULL
145
150
  #
146
151
 
@@ -194,6 +199,7 @@ Use option `--level 1` to show all gadgets found instead of only those with high
194
199
  $ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --level 1
195
200
  # 0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
196
201
  # constraints:
202
+ # rsp & 0xf == 0
197
203
  # rcx == NULL
198
204
  #
199
205
  # 0x4f322 execve("/bin/sh", rsp+0x40, environ)
@@ -1,5 +1,5 @@
1
1
  require 'one_gadget/gadget'
2
- # Ubuntu 16.04
2
+ # https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6_2.23-0ubuntu10_amd64/lib/x86_64-linux-gnu/libc-2.23.so
3
3
  #
4
4
  # Advanced Micro Devices X86-64
5
5
  #
@@ -25,6 +25,12 @@ OneGadget::Gadget.add(build_id, 283158,
25
25
  OneGadget::Gadget.add(build_id, 283242,
26
26
  constraints: ["[rsp+0x30] == NULL"],
27
27
  effect: "execve(\"/bin/sh\", rsp+0x30, environ)")
28
+ OneGadget::Gadget.add(build_id, 839923,
29
+ constraints: ["[rcx] == NULL || rcx == NULL", "[r12] == NULL || r12 == NULL"],
30
+ effect: "execve(\"/bin/sh\", rcx, r12)")
31
+ OneGadget::Gadget.add(build_id, 840136,
32
+ constraints: ["[rax] == NULL || rax == NULL", "[r12] == NULL || r12 == NULL"],
33
+ effect: "execve(\"/bin/sh\", rax, r12)")
28
34
  OneGadget::Gadget.add(build_id, 983716,
29
35
  constraints: ["[rsp+0x50] == NULL"],
30
36
  effect: "execve(\"/bin/sh\", rsp+0x50, environ)")
@@ -34,4 +40,7 @@ OneGadget::Gadget.add(build_id, 983728,
34
40
  OneGadget::Gadget.add(build_id, 987463,
35
41
  constraints: ["[rsp+0x70] == NULL"],
36
42
  effect: "execve(\"/bin/sh\", rsp+0x70, environ)")
43
+ OneGadget::Gadget.add(build_id, 1009392,
44
+ constraints: ["[rcx] == NULL || rcx == NULL", "[[rbp-0xf8]] == NULL || [rbp-0xf8] == NULL"],
45
+ effect: "execve(\"/bin/sh\", rcx, [rbp-0xf8])")
37
46
 
@@ -1,5 +1,5 @@
1
1
  require 'one_gadget/gadget'
2
- # Ubuntu 16.04
2
+ # https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6_2.23-0ubuntu10_i386/lib/i386-linux-gnu/libc-2.23.so
3
3
  #
4
4
  # Intel 80386
5
5
  #
@@ -1,5 +1,5 @@
1
1
  require 'one_gadget/gadget'
2
- # ubuntu17.04-lib32-libc-2.24.so
2
+ # https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6-i386_2.24-9ubuntu2.2_amd64/lib32/libc-2.24.so
3
3
  #
4
4
  # Intel 80386
5
5
  #
@@ -1,5 +1,5 @@
1
1
  require 'one_gadget/gadget'
2
- # ubuntu17.04-lib-x86_64-linux-gnu-libc-2.24.so
2
+ # https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6_2.24-9ubuntu2.2_amd64/lib/x86_64-linux-gnu/libc-2.24.so
3
3
  #
4
4
  # Advanced Micro Devices X86-64
5
5
  #
@@ -1,5 +1,5 @@
1
1
  require 'one_gadget/gadget'
2
- # spec/data/aarch64-libc-2.24.so
2
+ # https://gitlab.com/libcdb/libcdb/blob/master/libc/aarch64-linux-gnu-glibc-2.24-1-any.pkg.tar/usr/aarch64-linux-gnu/lib/libc-2.24.so
3
3
  #
4
4
  # AArch64
5
5
  #
@@ -1,5 +1,5 @@
1
1
  require 'one_gadget/gadget'
2
- # ubuntu17.10-libc-2.26.so
2
+ # https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6_2.26-0ubuntu2.1_amd64/lib/x86_64-linux-gnu/libc-2.26.so
3
3
  #
4
4
  # Advanced Micro Devices X86-64
5
5
  #
@@ -1,5 +1,5 @@
1
1
  require 'one_gadget/gadget'
2
- # ubuntu17.10-libc-2.26.so
2
+ # https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6-i386_2.26-0ubuntu2.1_amd64/lib32/libc-2.26.so
3
3
  #
4
4
  # Intel 80386
5
5
  #
@@ -1,5 +1,5 @@
1
1
  require 'one_gadget/gadget'
2
- # spec/data/libc-2.27-63b3d43ad45e1b0f601848c65b067f9e9b40528b.so
2
+ # https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6-i386_2.27-3ubuntu1_amd64/lib32/libc-2.27.so
3
3
  #
4
4
  # Intel 80386
5
5
  #
@@ -1,5 +1,5 @@
1
1
  require 'one_gadget/gadget'
2
- # spec/data/libc-2.27-b417c0ba7cc5cf06d1d1bed6652cedb9253c60d0.so
2
+ # https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6_2.27-3ubuntu1_amd64/lib/x86_64-linux-gnu/libc-2.27.so
3
3
  #
4
4
  # Advanced Micro Devices X86-64
5
5
  #
@@ -15,7 +15,7 @@ require 'one_gadget/gadget'
15
15
 
16
16
  build_id = File.basename(__FILE__, '.rb').split('-').last
17
17
  OneGadget::Gadget.add(build_id, 324293,
18
- constraints: ["rcx == NULL"],
18
+ constraints: ["rsp & 0xf == 0", "rcx == NULL"],
19
19
  effect: "execve(\"/bin/sh\", rsp+0x40, environ)")
20
20
  OneGadget::Gadget.add(build_id, 324386,
21
21
  constraints: ["[rsp+0x40] == NULL"],
@@ -15,7 +15,7 @@ require 'one_gadget/gadget'
15
15
 
16
16
  build_id = File.basename(__FILE__, '.rb').split('-').last
17
17
  OneGadget::Gadget.add(build_id, 328070,
18
- constraints: ["rcx == NULL"],
18
+ constraints: ["rsp & 0xf == 0", "rcx == NULL"],
19
19
  effect: "execve(\"/bin/sh\", rsp+0x40, environ)")
20
20
  OneGadget::Gadget.add(build_id, 328163,
21
21
  constraints: ["[rsp+0x40] == NULL"],
@@ -12,7 +12,7 @@ module OneGadget
12
12
  # Help message.
13
13
  USAGE = 'Usage: one_gadget <FILE|-b BuildID> [options]'
14
14
  # Default options.
15
- DEFAULT_OPTIONS = { raw: false, force_file: false, level: 0 }.freeze
15
+ DEFAULT_OPTIONS = { raw: false, force_file: false, level: 0, base: 0 }.freeze
16
16
 
17
17
  module_function
18
18
 
@@ -53,6 +53,7 @@ module OneGadget
53
53
  else # libc_file
54
54
  OneGadget.gadgets(file: libc_file, details: true, force_file: @options[:force_file], level: level)
55
55
  end
56
+ gadgets.each { |g| g.base = @options[:base] }
56
57
  handle_gadgets(gadgets, libc_file)
57
58
  end
58
59
 
@@ -136,6 +137,10 @@ module OneGadget
136
137
  @options[:info] = b
137
138
  end
138
139
 
140
+ opts.on('--base BASE_ADDRESS', Integer, 'The base address of libc.', 'Default: 0') do |b|
141
+ @options[:base] = b
142
+ end
143
+
139
144
  opts.on('--version', 'Current gem version.') do |v|
140
145
  @options[:version] = v
141
146
  end
@@ -176,7 +181,7 @@ module OneGadget
176
181
  # @return [true]
177
182
  def display_gadgets(gadgets, raw)
178
183
  if raw
179
- show(gadgets.map(&:offset).join(' '))
184
+ show(gadgets.map(&:value).join(' '))
180
185
  else
181
186
  show(gadgets.map(&:inspect).join("\n"))
182
187
  end
@@ -38,20 +38,20 @@ module OneGadget
38
38
  ret
39
39
  end
40
40
 
41
- # Implement substract with +Numeric+.
41
+ # Implement subtract with +Numeric+.
42
42
  # @param [Numeric] other Value to substract.
43
43
  # @return [Lambda] The result.
44
44
  def -(other)
45
45
  self.+(-other)
46
46
  end
47
47
 
48
- # Increase dreference count with 1.
48
+ # Increase dereference count with 1.
49
49
  # @return [void]
50
50
  def deref!
51
51
  @deref_count += 1
52
52
  end
53
53
 
54
- # Decrease dreference count with 1.
54
+ # Decrease dereference count with 1.
55
55
  # @return [self]
56
56
  # @raise [Error::InstrutionArgumentError] When this object cannot be referenced anymore.
57
57
  def ref!
@@ -102,7 +102,7 @@ module OneGadget
102
102
  # Target: parse string like <tt>[rsp+0x50]</tt> into a {Lambda} object.
103
103
  # @param [String] argument
104
104
  # @param [Hash{String => Lambda}] predefined
105
- # Predfined values.
105
+ # Predefined values.
106
106
  # @return [OneGadget::Emulators::Lambda, Integer]
107
107
  # If +argument+ contains number only, returns the value.
108
108
  # Otherwise, returns a {Lambda} object.
@@ -83,9 +83,15 @@ module OneGadget
83
83
  def constraints
84
84
  return [] if @constraints.empty?
85
85
 
86
- # currently only ':writable' type
87
- cons = @constraints.uniq { |_type, obj| obj.deref_count.zero? ? obj.obj.to_s : obj.to_s }
88
- cons.map { |_type, obj| "writable: #{obj}" }.sort
86
+ # we have these types:
87
+ # * :writable
88
+ # * :raw
89
+ cons = @constraints.uniq do |type, obj|
90
+ next obj unless type == :writable
91
+
92
+ obj.deref_count.zero? ? obj.obj.to_s : obj.to_s
93
+ end
94
+ cons.map { |type, obj| type == :writable ? "writable: #{obj}" : obj }.sort
89
95
  end
90
96
 
91
97
  private
@@ -70,15 +70,15 @@ module OneGadget
70
70
  # This instruction moves 128bits.
71
71
  def inst_movaps(dst, src)
72
72
  # XXX: here we only support `movaps [sp+*], xmm*`
73
- # TODO: This need an extra constraint: sp & 0xf == 0
74
73
  src, dst = check_xmm_sp(src, dst) { raise_unsupported('movaps', dst, src) }
75
74
  off = dst.evaluate(eval_dict)
75
+ @constraints << [:raw, "#{sp} & 0xf == #{0x10 - off & 0xf}"]
76
76
  (128 / self.class.bits).times do |i|
77
77
  stack[off + i * size_t] = src[i]
78
78
  end
79
79
  end
80
80
 
81
- # Mov *src to dst[:64]
81
+ # Move *src to dst[:64]
82
82
  def inst_movq(dst, src)
83
83
  # XXX: here we only support `movq xmm*, [sp+*]`
84
84
  dst, src = check_xmm_sp(dst, src) { raise_unsupported('movq', dst, src) }
@@ -15,7 +15,7 @@ module OneGadget
15
15
  class UnsupportedInstructionError < UnsupportedError
16
16
  end
17
17
 
18
- # Raises when arguments form of an instrution is invalid.
18
+ # Raises when arguments form of an instruction is invalid.
19
19
  class InstructionArgumentError < Error
20
20
  end
21
21
 
@@ -35,7 +35,7 @@ module OneGadget
35
35
  res = super
36
36
  return if res.nil?
37
37
 
38
- # unshift got constraint into cons
38
+ # unshift GOT constraint into cons
39
39
  res[:constraints].unshift("#{@base_reg} is the GOT address of libc")
40
40
  res
41
41
  end
@@ -9,6 +9,8 @@ module OneGadget
9
9
  module Gadget
10
10
  # Information of a gadget.
11
11
  class Gadget
12
+ # @return [Integer] Base address of libc. Default: 0.
13
+ attr_accessor :base
12
14
  # @return [Integer] The gadget's address offset.
13
15
  attr_reader :offset
14
16
  # @return [Array<String>] The constraints need for this gadget.
@@ -23,6 +25,7 @@ module OneGadget
23
25
  # @example
24
26
  # OneGadget::Gadget::Gadget.new(0x12345, constraints: ['rax == 0'])
25
27
  def initialize(offset, **options)
28
+ @base = 0
26
29
  @offset = offset
27
30
  @constraints = options[:constraints] || []
28
31
  @effect = options[:effect]
@@ -30,7 +33,7 @@ module OneGadget
30
33
 
31
34
  # Show gadget in a pretty way.
32
35
  def inspect
33
- str = OneGadget::Helper.hex(offset)
36
+ str = OneGadget::Helper.hex(value)
34
37
  str += effect ? " #{effect}\n" : "\n"
35
38
  unless constraints.empty?
36
39
  str += "#{OneGadget::Helper.colorize('constraints')}:\n "
@@ -43,6 +46,12 @@ module OneGadget
43
46
  str + "\n"
44
47
  end
45
48
 
49
+ # @return [Integer]
50
+ # Returns +base+ plus +offset+.
51
+ def value
52
+ base + offset
53
+ end
54
+
46
55
  # @return [Float]
47
56
  # The success probability of the constraints.
48
57
  def score
@@ -58,16 +67,21 @@ module OneGadget
58
67
  # Expr: <REG> is the GOT address of libc
59
68
  # Expr: writable: <Identity>
60
69
  # Expr: <Identity> == NULL
70
+ # Expr: <REG> & 0xf == <IMM>
61
71
  # Expr: <Expr> || <Expr>
62
72
  def calculate_score(cons)
63
73
  return cons.split(' || ').map(&method(:calculate_score)).max if cons.include?(' || ')
64
- return 0.9 if cons.include?('GOT address')
65
- return 0.81 if cons.include?('writable')
66
74
 
67
- expr = cons.gsub(' == NULL', ' == 0')
68
- # raise Error::ArgumentError, cons unless expr.end_with?(' == 0')
75
+ case cons
76
+ when / & 0xf/ then 0.95
77
+ when /GOT address/ then 0.9
78
+ when /^writable/ then 0.81
79
+ when / == NULL$/ then calculate_null_score(cons)
80
+ end
81
+ end
69
82
 
70
- identity = expr.slice(0...expr.rindex(' == 0'))
83
+ def calculate_null_score(cons)
84
+ identity = cons.slice(0...cons.rindex(' == NULL'))
71
85
  # Thank God we are already able to parse this
72
86
  lmda = OneGadget::Emulators::Lambda.parse(identity)
73
87
  # raise Error::ArgumentError, cons unless OneGadget::ABI.all.include?(lmda.obj)
@@ -187,7 +187,7 @@ module OneGadget
187
187
  nil
188
188
  end
189
189
 
190
- # Fetch the ELF archiecture of +file+.
190
+ # Fetch the ELF architecture of +file+.
191
191
  # @param [String] file The target ELF filename.
192
192
  # @return [Symbol]
193
193
  # Currently supports amd64, i386, arm, aarch64, and mips.
@@ -59,7 +59,7 @@ module OneGadget
59
59
  OneGadget::Fetcher.from_build_id(build_id, remote: false)
60
60
  end
61
61
 
62
- # Remove hard-to-reach-constrains gadgets according to level
62
+ # Remove hard-to-reach-constraints gadgets according to level
63
63
  def refine_gadgets(gadgets, level)
64
64
  return [] if gadgets.empty?
65
65
  return gadgets if level.positive? # currently only supports level > 0 or not
@@ -2,5 +2,5 @@
2
2
 
3
3
  module OneGadget
4
4
  # Current gem version.
5
- VERSION = '1.7.2'
5
+ VERSION = '1.7.3'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: one_gadget
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.2
4
+ version: 1.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - david942j
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-05 00:00:00.000000000 Z
11
+ date: 2019-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: elftools
@@ -36,14 +36,14 @@ dependencies:
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '12.3'
39
+ version: '13.0'
40
40
  type: :development
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '12.3'
46
+ version: '13.0'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -78,14 +78,14 @@ dependencies:
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: 0.16.1
81
+ version: 0.17.0
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: 0.16.1
88
+ version: 0.17.0
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: yard
91
91
  requirement: !ruby/object:Gem::Requirement