one_gadget 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|