one_gadget 1.7.2 → 1.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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