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 +4 -4
- data/README.md +7 -1
- data/lib/one_gadget/builds/libc-2.23-b5381a457906d279073822a5ceb24c4bfef94ddb.rb +10 -1
- data/lib/one_gadget/builds/libc-2.23-dd5192a769e33ed6ca68a6ab5740ff9e8ec678a7.rb +1 -1
- data/lib/one_gadget/builds/libc-2.24-0f523a27b7460f50befd3d281238c6f189c92d84.rb +1 -1
- data/lib/one_gadget/builds/libc-2.24-aad7dbe330f23ea00ca63daf793b766b51aceb5d.rb +1 -1
- data/lib/one_gadget/builds/libc-2.24-fd0655c4d2073eda4235084e1d0e558f0251be8a.rb +1 -1
- data/lib/one_gadget/builds/libc-2.26-ddcc13122ddbfe5e5ef77d4ebe66d124ae5762c2.rb +1 -1
- data/lib/one_gadget/builds/libc-2.26-f65648a832414f2144ce795d75b6045a1ec2e252.rb +1 -1
- data/lib/one_gadget/builds/libc-2.27-63b3d43ad45e1b0f601848c65b067f9e9b40528b.rb +1 -1
- data/lib/one_gadget/builds/libc-2.27-b417c0ba7cc5cf06d1d1bed6652cedb9253c60d0.rb +2 -2
- data/lib/one_gadget/builds/libc-2.28-5b157f49586a3ca84d55837f97ff466767dd3445.rb +1 -1
- data/lib/one_gadget/cli.rb +7 -2
- data/lib/one_gadget/emulators/lambda.rb +4 -4
- data/lib/one_gadget/emulators/processor.rb +9 -3
- data/lib/one_gadget/emulators/x86.rb +2 -2
- data/lib/one_gadget/error.rb +1 -1
- data/lib/one_gadget/fetchers/i386.rb +1 -1
- data/lib/one_gadget/gadget.rb +20 -6
- data/lib/one_gadget/helper.rb +1 -1
- data/lib/one_gadget/one_gadget.rb +1 -1
- data/lib/one_gadget/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e18cc48cf48847c6303e01416f9c36fb7284bc926d30f63fb716ce993a569ad
|
4
|
+
data.tar.gz: 17288573c3302ee9a1e9773b1dfc71ec36a433694ae9742f56999e5e719396e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
|
-
#
|
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
|
-
#
|
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"],
|
data/lib/one_gadget/cli.rb
CHANGED
@@ -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(&:
|
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
|
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
|
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
|
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
|
-
#
|
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
|
-
#
|
87
|
-
|
88
|
-
|
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
|
-
#
|
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) }
|
data/lib/one_gadget/error.rb
CHANGED
data/lib/one_gadget/gadget.rb
CHANGED
@@ -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(
|
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
|
-
|
68
|
-
|
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
|
-
|
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)
|
data/lib/one_gadget/helper.rb
CHANGED
@@ -187,7 +187,7 @@ module OneGadget
|
|
187
187
|
nil
|
188
188
|
end
|
189
189
|
|
190
|
-
# Fetch the ELF
|
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-
|
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
|
data/lib/one_gadget/version.rb
CHANGED
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.
|
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-
|
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: '
|
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: '
|
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.
|
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.
|
88
|
+
version: 0.17.0
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
90
|
name: yard
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|