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 +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
|