one_gadget 1.0.0 → 1.1.0
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 +34 -6
- data/bin/one_gadget +8 -4
- data/lib/one_gadget.rb +12 -4
- data/lib/one_gadget/builds/libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9.rb +8 -0
- data/lib/one_gadget/fetcher.rb +7 -34
- data/lib/one_gadget/fetchers/amd64.rb +21 -0
- data/lib/one_gadget/fetchers/base.rb +64 -0
- data/lib/one_gadget/fetchers/i386.rb +54 -0
- data/lib/one_gadget/helper.rb +13 -1
- data/lib/one_gadget/logger.rb +21 -0
- data/lib/one_gadget/version.rb +1 -1
- data/spec/data/{libc-2.19.so → libc-2.19-cf699a15caae64f50311fc4655b86dc39a479789.so} +0 -0
- data/spec/data/libc-2.19-fd51b20e670e9a9f60dc3b06dc9761fb08c9358b.so +0 -0
- data/spec/data/{libc-2.23.so → libc-2.23-60131540dadc6796cab33388349e6e4e68692053.so} +0 -0
- data/spec/data/libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9.so +0 -0
- data/spec/helper_spec.rb +8 -2
- data/spec/{one_gadget_spec.rb → one_gadget_amd64_spec.rb} +1 -1
- data/spec/one_gadget_i386_spec.rb +24 -0
- metadata +24 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc34f437cb6bb8562f408c558c9d58f9c6b88658
|
4
|
+
data.tar.gz: 0604cd9f82c3c66500ce54b529255fa3fc323af3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ff369c093af7bffab44931cf6cac32e8f961f91576e435a48245d5cc7b3c6bec17b3ca5d450f337d86852c5339b010d56dc39e1ddc8e4828894ab12ab317f1e
|
7
|
+
data.tar.gz: 78d0f190661d5275ab4bb29d3063f8dd883fbe8a37422dead64c2b9fc0ad32bfe006dc13a2e52a3130deda3fba3488410bb58b85f4b0853c5d0a7aa0e4aafc45
|
data/README.md
CHANGED
@@ -13,11 +13,16 @@ This gem provides such gadget finder, no need to use IDA-pro every time like a f
|
|
13
13
|
|
14
14
|
Also provides the command-line tool `one_gadget` for easy usage.
|
15
15
|
|
16
|
-
Note:
|
16
|
+
Note: Supports amd64 and i386!
|
17
|
+
|
18
|
+
Note2: still work in progress, the gem version might update frequently :p.
|
17
19
|
|
18
20
|
## Install
|
19
21
|
|
20
|
-
|
22
|
+
Available on RubyGems.org!
|
23
|
+
```bash
|
24
|
+
gem install one_gadget
|
25
|
+
```
|
21
26
|
|
22
27
|
## Usage
|
23
28
|
|
@@ -26,9 +31,10 @@ I'll push to rubygems.org..
|
|
26
31
|
```bash
|
27
32
|
one_gadget
|
28
33
|
# Usage: one_gadget [file] [options]
|
29
|
-
# -b, --build-id BuildID BuildID[sha1] of libc
|
30
|
-
# -
|
31
|
-
# -
|
34
|
+
# -b, --build-id BuildID BuildID[sha1] of libc.
|
35
|
+
# -f, --[no-]force-file Force search gadgets in file instead of build id first.
|
36
|
+
# -r, --[no-]raw Output gadgets offset only, split with one space.
|
37
|
+
# -s, --script exploit-script Run exploit script with all possible gadgets.
|
32
38
|
# The script will be run as 'exploit-script $offset'.
|
33
39
|
|
34
40
|
one_gadget -b 60131540dadc6796cab33388349e6e4e68692053
|
@@ -43,6 +49,28 @@ one_gadget -b 60131540dadc6796cab33388349e6e4e68692053
|
|
43
49
|
# offset: 0xf0567
|
44
50
|
# constraints:
|
45
51
|
# [rsp+0x70] == NULL
|
52
|
+
#
|
53
|
+
# offset: 0xf5b10
|
54
|
+
# constraints:
|
55
|
+
# [rbp-0xf8] == NULL
|
56
|
+
# rcx == NULL
|
57
|
+
|
58
|
+
one_gadget /lib/i386-linux-gnu/libc.so.6
|
59
|
+
# offset: 0x3ac69
|
60
|
+
# constraints:
|
61
|
+
# esi is the address of `rw-p` area of libc
|
62
|
+
# [esp+0x34] == NULL
|
63
|
+
#
|
64
|
+
# offset: 0x5fbbe
|
65
|
+
# constraints:
|
66
|
+
# esi is the address of `rw-p` area of libc
|
67
|
+
# eax == NULL
|
68
|
+
#
|
69
|
+
# offset: 0x12036c
|
70
|
+
# constraints:
|
71
|
+
# esi is the address of `rw-p` area of libc
|
72
|
+
# eax == NULL
|
73
|
+
|
46
74
|
```
|
47
75
|
|
48
76
|
#### Combine with exploit script
|
@@ -59,7 +87,7 @@ one_gadget ./spec/data/libc-2.19.so -s 'echo "offset ->"'
|
|
59
87
|
```ruby
|
60
88
|
require 'one_gadget'
|
61
89
|
OneGadget.gadgets(file: '/lib/x86_64-linux-gnu/libc.so.6')
|
62
|
-
# => [283242, 980676, 984423]
|
90
|
+
# => [283242, 980676, 984423, 1006352]
|
63
91
|
```
|
64
92
|
|
65
93
|
## Screenshots
|
data/bin/one_gadget
CHANGED
@@ -7,11 +7,15 @@ usage = 'Usage: one_gadget [file] [options]'
|
|
7
7
|
parser = OptionParser.new do |opts|
|
8
8
|
opts.banner = usage
|
9
9
|
|
10
|
-
opts.on('-b', '--build-id BuildID', 'BuildID[sha1] of libc') do |b|
|
10
|
+
opts.on('-b', '--build-id BuildID', 'BuildID[sha1] of libc.') do |b|
|
11
11
|
options[:build_id] = b
|
12
12
|
end
|
13
13
|
|
14
|
-
opts.on('-
|
14
|
+
opts.on('-f', '--[no-]force-file', 'Force search gadgets in file instead of build id first.') do |b|
|
15
|
+
options[:force_file] = b
|
16
|
+
end
|
17
|
+
|
18
|
+
opts.on('-r', '--[no-]raw', 'Output gadgets offset only, split with one space.') do |v|
|
15
19
|
options[:raw] = v
|
16
20
|
end
|
17
21
|
|
@@ -32,7 +36,7 @@ end
|
|
32
36
|
if options[:build_id]
|
33
37
|
gadgets = OneGadget.gadgets(build_id: options[:build_id], details: true)
|
34
38
|
elsif ARGV[0]
|
35
|
-
gadgets = OneGadget.gadgets(file: ARGV[0], details: true)
|
39
|
+
gadgets = OneGadget.gadgets(file: ARGV[0], details: true, force_file: options[:force_file])
|
36
40
|
else
|
37
41
|
puts parser.help
|
38
42
|
exit(1)
|
@@ -41,7 +45,7 @@ end
|
|
41
45
|
extend OneGadget::Helper::ClassMethods
|
42
46
|
if options[:script]
|
43
47
|
gadgets.map(&:offset).each do |offset|
|
44
|
-
|
48
|
+
OneGadget::Logger.info("Trying #{colorize(format('0x%x', offset), sev: :integer)}...\n")
|
45
49
|
execute(options[:script], offset)
|
46
50
|
end
|
47
51
|
exit(0)
|
data/lib/one_gadget.rb
CHANGED
@@ -11,19 +11,26 @@ module OneGadget
|
|
11
11
|
# The relative path of libc.so.6.
|
12
12
|
# @param [String] build_id
|
13
13
|
# The BuildID of target libc.so.6.
|
14
|
+
# @param [Boolean] details
|
15
|
+
# Return gadget objects or offset only.
|
16
|
+
# @param [Boolean] force_file
|
17
|
+
# When +file+ is given, {OneGadget} will search gadgets according its
|
18
|
+
# build id first. +force_file = true+ to disable this feature.
|
14
19
|
# @return [Array<OneGadget::Gadget::Gadget>, Array<Integer>]
|
15
20
|
# The gadgets found.
|
16
21
|
# @example
|
17
22
|
# OneGadget.gadgets(file: './libc.so.6')
|
18
23
|
# OneGadget.gadgets(build_id: '60131540dadc6796cab33388349e6e4e68692053')
|
19
|
-
def gadgets(file: nil, build_id: nil, details: false)
|
24
|
+
def gadgets(file: nil, build_id: nil, details: false, force_file: false)
|
20
25
|
if build_id
|
21
26
|
OneGadget::Fetcher.from_build_id(build_id, details: details)
|
22
27
|
elsif file
|
23
28
|
file = OneGadget::Helper.abspath(file)
|
24
|
-
|
25
|
-
|
26
|
-
|
29
|
+
unless force_file
|
30
|
+
build_id = OneGadget::Helper.build_id_of(file)
|
31
|
+
gadgets = OneGadget::Fetcher.from_build_id(build_id, details: details)
|
32
|
+
return gadgets unless gadgets.empty?
|
33
|
+
end
|
27
34
|
OneGadget::Fetcher.from_file(file, details: details)
|
28
35
|
end
|
29
36
|
end
|
@@ -32,4 +39,5 @@ end
|
|
32
39
|
|
33
40
|
require 'one_gadget/fetcher'
|
34
41
|
require 'one_gadget/helper'
|
42
|
+
require 'one_gadget/logger'
|
35
43
|
require 'one_gadget/version'
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'one_gadget/gadget'
|
2
|
+
# Ubuntu GLIBC 2.23-0ubuntu5
|
3
|
+
# ELF 32-bit LSB shared object, Intel 80386
|
4
|
+
build_id = File.basename(__FILE__, '.rb').split('-').last + 'a'
|
5
|
+
rw_area_constraint = 'esi is the address of `rw-p` area of libc'
|
6
|
+
OneGadget::Gadget.add(build_id, 0x3ac69, constraints: [rw_area_constraint, '[esp+0x34] == NULL'])
|
7
|
+
OneGadget::Gadget.add(build_id, 0x5fbbe, constraints: [rw_area_constraint, 'eax == NULL'])
|
8
|
+
OneGadget::Gadget.add(build_id, 0x12036c, constraints: [rw_area_constraint, 'eax == NULL'])
|
data/lib/one_gadget/fetcher.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'one_gadget/helper'
|
2
|
+
require 'one_gadget/fetchers/amd64'
|
3
|
+
require 'one_gadget/fetchers/i386'
|
2
4
|
require 'one_gadget/gadget'
|
3
5
|
|
4
6
|
module OneGadget
|
@@ -32,43 +34,14 @@ module OneGadget
|
|
32
34
|
# contains offset only.
|
33
35
|
# Otherwise, array of gadgets is returned.
|
34
36
|
def from_file(file, details: false)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
41
|
-
candidates.map! do |candidate|
|
42
|
-
# remove other calls
|
43
|
-
lines = candidate.lines
|
44
|
-
to_rm = lines[0...-1].rindex { |c| c.include?('call') }
|
45
|
-
lines = lines[to_rm + 1..-1] unless to_rm.nil?
|
46
|
-
lines.map! { |s| s.gsub(/#\s+#{bin_sh_hex}\s+<.*>$/, "# #{bin_sh_hex} \"/bin/sh\"") }
|
47
|
-
lines.join
|
48
|
-
end
|
49
|
-
gadgets = candidates.map { |c| convert_to_gadget(c) }
|
37
|
+
gadgets = {
|
38
|
+
amd64: OneGadget::Fetcher::Amd64,
|
39
|
+
i386: OneGadget::Fetcher::I386,
|
40
|
+
unknown: OneGadget::Fetcher::Base
|
41
|
+
}[OneGadget::Helper.architecture(file)].new(file).find
|
50
42
|
return gadgets if details
|
51
43
|
gadgets.map(&:offset)
|
52
44
|
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
def str_offset(file, str)
|
57
|
-
match = `strings -tx #{file} | grep '#{str}'`.lines.map(&:strip).first
|
58
|
-
return nil if match.nil?
|
59
|
-
# 17c8c3 /bin/sh
|
60
|
-
match.split.first.to_i(16)
|
61
|
-
end
|
62
|
-
|
63
|
-
def convert_to_gadget(assembly)
|
64
|
-
lines = assembly.lines.map(&:strip)
|
65
|
-
offset = lines.first.scan(/^([\da-f]+):/)[0][0].to_i(16)
|
66
|
-
# fetch those might be constraints lines.
|
67
|
-
important_lines = lines.select { |line| ['rsi'].any? { |r| line.include?(r) } }.map do |line|
|
68
|
-
line.split("\t").last.gsub(/\s+/, ' ')
|
69
|
-
end
|
70
|
-
OneGadget::Gadget::Gadget.new(offset, constraints: important_lines)
|
71
|
-
end
|
72
45
|
end
|
73
46
|
extend ClassMethods
|
74
47
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'one_gadget/fetchers/base'
|
2
|
+
module OneGadget
|
3
|
+
module Fetcher
|
4
|
+
# Fetcher for amd64.
|
5
|
+
class Amd64 < OneGadget::Fetcher::Base
|
6
|
+
def find
|
7
|
+
bin_sh_hex = str_offset('/bin/sh').to_s(16)
|
8
|
+
cands = candidates do |candidate|
|
9
|
+
next false unless candidate.include?(bin_sh_hex) # works in x86-64
|
10
|
+
next false unless candidate.lines.last.include?('execve') # only care execve
|
11
|
+
true
|
12
|
+
end
|
13
|
+
cands.map do |candidate|
|
14
|
+
convert_to_gadget(candidate) do |line|
|
15
|
+
['rsi'].any? { |r| line.include?(r) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
|
3
|
+
module OneGadget
|
4
|
+
module Fetcher
|
5
|
+
# define common methods for gadget fetchers.
|
6
|
+
class Base
|
7
|
+
attr_reader :file
|
8
|
+
# @param [String] file Absolute path of target libc.
|
9
|
+
def initialize(file)
|
10
|
+
@file = ::Shellwords.escape(file)
|
11
|
+
end
|
12
|
+
|
13
|
+
def find; raise NotImplementedError
|
14
|
+
end
|
15
|
+
|
16
|
+
# Fetch candidates that end with call exec*.
|
17
|
+
# @return [Array<String>]
|
18
|
+
# Each +String+ returned is multi-lines of assembly code.
|
19
|
+
def candidates(&block)
|
20
|
+
cands = `objdump -w -d -M intel #{file}|egrep 'call.*<exec[^+]*>$' -B 20`.split('--').map do |cand|
|
21
|
+
cand.lines.map(&:strip).reject(&:empty?).join("\n")
|
22
|
+
end
|
23
|
+
# remove all calls, jmps
|
24
|
+
cands = slice_prefix(cands, &method(:branch?))
|
25
|
+
cands.select!(&block) if block_given?
|
26
|
+
cands
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def slice_prefix(cands)
|
32
|
+
cands.map do |cand|
|
33
|
+
lines = cand.lines
|
34
|
+
to_rm = lines[0...-1].rindex { |c| yield(c) }
|
35
|
+
lines = lines[to_rm + 1..-1] unless to_rm.nil?
|
36
|
+
lines.join
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# If str contains a branch instruction.
|
41
|
+
def branch?(str)
|
42
|
+
%w(call jmp je jne jl jb ja jg).any? { |f| str.include?(f) }
|
43
|
+
end
|
44
|
+
|
45
|
+
def str_offset(str)
|
46
|
+
match = `strings -tx #{file} -n #{str.size} | grep " #{::Shellwords.escape(str)}"`.lines.map(&:strip).first
|
47
|
+
return nil if match.nil?
|
48
|
+
# 17c8c3 /bin/sh
|
49
|
+
match.split.first.to_i(16)
|
50
|
+
end
|
51
|
+
|
52
|
+
def convert_to_gadget(assembly, &block)
|
53
|
+
lines = assembly.lines
|
54
|
+
offset = lines.first.scan(/^([\da-f]+):/)[0][0].to_i(16)
|
55
|
+
# fetch those might be constraints lines.
|
56
|
+
important_lines = lines.select(&block).map do |line|
|
57
|
+
ar = line.split("\t")
|
58
|
+
"#{ar.first} #{ar.last.gsub(/\s+/, ' ')}"
|
59
|
+
end
|
60
|
+
OneGadget::Gadget::Gadget.new(offset, constraints: important_lines)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'one_gadget/fetchers/base'
|
2
|
+
module OneGadget
|
3
|
+
module Fetcher
|
4
|
+
# Fetcher for i386.
|
5
|
+
class I386 < OneGadget::Fetcher::Base
|
6
|
+
def find
|
7
|
+
rw_off = rw_offset
|
8
|
+
bin_sh = str_offset('/bin/sh')
|
9
|
+
minus_c = str_offset('-c')
|
10
|
+
rel_sh_hex = (rw_off - bin_sh).to_s(16)
|
11
|
+
rel_minus_c = (rw_off - minus_c).to_s(16)
|
12
|
+
cands = candidates do |candidate|
|
13
|
+
next false unless candidate.include?(rel_sh_hex)
|
14
|
+
true
|
15
|
+
end
|
16
|
+
# remove lines before and with -c appears
|
17
|
+
cands = slice_prefix(cands) do |line|
|
18
|
+
line.include?(rel_minus_c)
|
19
|
+
end
|
20
|
+
# special handle for execl call
|
21
|
+
cands.map! do |cand|
|
22
|
+
lines = cand.lines
|
23
|
+
next cand unless lines.last.include?('execl')
|
24
|
+
# Find the last three +push+, or mov [esp+0x8], .*
|
25
|
+
# Make it call +execl("/bin/sh", "sh", NULL)+.
|
26
|
+
if cand.include?('esp+0x8')
|
27
|
+
to_rm = lines.index { |c| c.include?('esp+0x8') }
|
28
|
+
else
|
29
|
+
push_cnt = 0
|
30
|
+
to_rm = lines.rindex do |c|
|
31
|
+
push_cnt += 1 if c.include?('push')
|
32
|
+
push_cnt >= 3
|
33
|
+
end
|
34
|
+
end
|
35
|
+
lines = lines[to_rm..-1] unless to_rm.nil?
|
36
|
+
lines.join
|
37
|
+
end
|
38
|
+
cands.map do |candidate|
|
39
|
+
convert_to_gadget(candidate) do |_|
|
40
|
+
true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def rw_offset
|
48
|
+
# How to find this offset correctly..?
|
49
|
+
line = `readelf -d #{file}|grep PLTGOT`
|
50
|
+
line.scan(/0x[\da-f]+/).last.to_i(16) & -0x1000
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/one_gadget/helper.rb
CHANGED
@@ -3,6 +3,7 @@ require 'shellwords'
|
|
3
3
|
require 'net/http'
|
4
4
|
require 'openssl'
|
5
5
|
require 'tempfile'
|
6
|
+
require 'one_gadget/logger'
|
6
7
|
|
7
8
|
module OneGadget
|
8
9
|
# Define some helpful methods here.
|
@@ -120,7 +121,18 @@ module OneGadget
|
|
120
121
|
def ask_update(msg: '')
|
121
122
|
name = 'one_gadget'
|
122
123
|
cmd = colorize("gem update #{name}")
|
123
|
-
|
124
|
+
OneGadget::Logger.info(msg + "\n" + "Update with: $ #{cmd}" + "\n")
|
125
|
+
end
|
126
|
+
|
127
|
+
# Fetch the file archiecture of +file+.
|
128
|
+
# @param [String] The target ELF filename.
|
129
|
+
# @return [String]
|
130
|
+
# Only supports :amd64, :i386 now.
|
131
|
+
def architecture(file)
|
132
|
+
str = `file #{::Shellwords.escape(file)}`
|
133
|
+
return :amd64 if str.include?('x86-64')
|
134
|
+
return :i386 if str.include?('Intel 80386')
|
135
|
+
:unknown
|
124
136
|
end
|
125
137
|
end
|
126
138
|
extend ClassMethods
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'one_gadget/helper'
|
3
|
+
|
4
|
+
module OneGadget
|
5
|
+
# A logger for internal usage.
|
6
|
+
module Logger
|
7
|
+
@logger = ::Logger.new(STDOUT)
|
8
|
+
@logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
9
|
+
prep = ' ' * 12
|
10
|
+
message = msg.lines.map.with_index do |str, i|
|
11
|
+
next str if i.zero?
|
12
|
+
prep + str
|
13
|
+
end
|
14
|
+
"[#{OneGadget::Helper.colorize('OneGadget', sev: :reg)}] #{message.join}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.info(msg)
|
18
|
+
@logger.info(msg)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/one_gadget/version.rb
CHANGED
File without changes
|
Binary file
|
File without changes
|
Binary file
|
data/spec/helper_spec.rb
CHANGED
@@ -3,10 +3,11 @@ require 'one_gadget/helper'
|
|
3
3
|
describe OneGadget::Helper do
|
4
4
|
before(:all) do
|
5
5
|
OneGadget::Helper.color_on!
|
6
|
-
@libcpath = File.join(File.dirname(__FILE__), 'data', 'libc-2.23.so')
|
6
|
+
@libcpath = File.join(File.dirname(__FILE__), 'data', 'libc-2.23-60131540dadc6796cab33388349e6e4e68692053.so')
|
7
7
|
end
|
8
8
|
it 'abspath' do
|
9
|
-
expect(OneGadget::Helper.abspath('./spec/data/libc-2.23.so'))
|
9
|
+
expect(OneGadget::Helper.abspath('./spec/data/libc-2.23-60131540dadc6796cab33388349e6e4e68692053.so'))
|
10
|
+
.to eq @libcpath
|
10
11
|
end
|
11
12
|
|
12
13
|
it 'build_id_of' do
|
@@ -16,4 +17,9 @@ describe OneGadget::Helper do
|
|
16
17
|
it 'colorize' do
|
17
18
|
expect(OneGadget::Helper.colorize('123', sev: :integer)).to eq "\e[38;5;12m123\e[0m"
|
18
19
|
end
|
20
|
+
|
21
|
+
it 'architecture' do
|
22
|
+
expect(OneGadget::Helper.architecture(@libcpath)).to be :amd64
|
23
|
+
expect(OneGadget::Helper.architecture(__FILE__)).to be :unknown
|
24
|
+
end
|
19
25
|
end
|
@@ -3,7 +3,7 @@ require 'one_gadget'
|
|
3
3
|
describe 'one_gadget' do
|
4
4
|
before(:each) do
|
5
5
|
@build_id = '60131540dadc6796cab33388349e6e4e68692053'
|
6
|
-
@libcpath = File.join(File.dirname(__FILE__), 'data', 'libc-2.19.so')
|
6
|
+
@libcpath = File.join(File.dirname(__FILE__), 'data', 'libc-2.19-cf699a15caae64f50311fc4655b86dc39a479789.so')
|
7
7
|
end
|
8
8
|
|
9
9
|
it 'from file' do
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'one_gadget'
|
2
|
+
|
3
|
+
describe 'one_gadget' do
|
4
|
+
before(:each) do
|
5
|
+
@build_id = '926eb99d49cab2e5622af38ab07395f5b32035e9'
|
6
|
+
@libcpath19 = File.join(File.dirname(__FILE__), 'data', 'libc-2.19-fd51b20e670e9a9f60dc3b06dc9761fb08c9358b.so')
|
7
|
+
@libcpath23 = File.join(File.dirname(__FILE__), 'data', 'libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9.so')
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'from file libc-2.19' do
|
11
|
+
expect(OneGadget.gadgets(file: @libcpath19, force_file: true)).to eq [0x3fd27, 0x64c60, 0x1244a6]
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'from file libc-2.23' do
|
15
|
+
expect(OneGadget.gadgets(file: @libcpath23, force_file: true)).to eq [0x3ac69, 0x5fbbe, 0x12036c]
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'from build id' do
|
19
|
+
it 'normal' do
|
20
|
+
# only check not empty because the gadgets might add frequently.
|
21
|
+
expect(OneGadget.gadgets(build_id: @build_id)).not_to be_empty
|
22
|
+
end
|
23
|
+
end
|
24
|
+
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.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- david942j
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-02-
|
11
|
+
date: 2017-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -81,9 +81,11 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0.6'
|
83
83
|
description: |2
|
84
|
-
When playing ctf pwn challenges we usually needs the one-gadget of
|
85
|
-
|
86
|
-
|
84
|
+
When playing ctf pwn challenges we usually needs the one-gadget of execve('/bin/sh', NULL, NULL).
|
85
|
+
|
86
|
+
This gem provides such gadget finder, no need to use IDA-pro every time like a fool :p.
|
87
|
+
|
88
|
+
Also provides the command-line tool +one_gadget+ for easy usage.
|
87
89
|
email:
|
88
90
|
- david942j@gmail.com
|
89
91
|
executables:
|
@@ -96,15 +98,23 @@ files:
|
|
96
98
|
- lib/one_gadget.rb
|
97
99
|
- lib/one_gadget/abi.rb
|
98
100
|
- lib/one_gadget/builds/libc-2.23-60131540dadc6796cab33388349e6e4e68692053.rb
|
101
|
+
- lib/one_gadget/builds/libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9.rb
|
99
102
|
- lib/one_gadget/fetcher.rb
|
103
|
+
- lib/one_gadget/fetchers/amd64.rb
|
104
|
+
- lib/one_gadget/fetchers/base.rb
|
105
|
+
- lib/one_gadget/fetchers/i386.rb
|
100
106
|
- lib/one_gadget/gadget.rb
|
101
107
|
- lib/one_gadget/helper.rb
|
108
|
+
- lib/one_gadget/logger.rb
|
102
109
|
- lib/one_gadget/version.rb
|
103
|
-
- spec/data/libc-2.19.so
|
104
|
-
- spec/data/libc-2.
|
110
|
+
- spec/data/libc-2.19-cf699a15caae64f50311fc4655b86dc39a479789.so
|
111
|
+
- spec/data/libc-2.19-fd51b20e670e9a9f60dc3b06dc9761fb08c9358b.so
|
112
|
+
- spec/data/libc-2.23-60131540dadc6796cab33388349e6e4e68692053.so
|
113
|
+
- spec/data/libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9.so
|
105
114
|
- spec/gadget_spec.rb
|
106
115
|
- spec/helper_spec.rb
|
107
|
-
- spec/
|
116
|
+
- spec/one_gadget_amd64_spec.rb
|
117
|
+
- spec/one_gadget_i386_spec.rb
|
108
118
|
- spec/spec_helper.rb
|
109
119
|
homepage: https://github.com/david942j/one_gadget
|
110
120
|
licenses:
|
@@ -131,9 +141,12 @@ signing_key:
|
|
131
141
|
specification_version: 4
|
132
142
|
summary: one_gadget
|
133
143
|
test_files:
|
134
|
-
- spec/
|
135
|
-
- spec/
|
144
|
+
- spec/one_gadget_i386_spec.rb
|
145
|
+
- spec/one_gadget_amd64_spec.rb
|
146
|
+
- spec/data/libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9.so
|
147
|
+
- spec/data/libc-2.19-cf699a15caae64f50311fc4655b86dc39a479789.so
|
148
|
+
- spec/data/libc-2.23-60131540dadc6796cab33388349e6e4e68692053.so
|
149
|
+
- spec/data/libc-2.19-fd51b20e670e9a9f60dc3b06dc9761fb08c9358b.so
|
136
150
|
- spec/spec_helper.rb
|
137
151
|
- spec/helper_spec.rb
|
138
|
-
- spec/one_gadget_spec.rb
|
139
152
|
- spec/gadget_spec.rb
|