one_gadget 1.6.1 → 1.6.2
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/lib/one_gadget.rb +4 -68
- data/lib/one_gadget/emulators/x86.rb +9 -2
- data/lib/one_gadget/error.rb +5 -0
- data/lib/one_gadget/fetchers/amd64.rb +1 -2
- data/lib/one_gadget/gadget.rb +1 -1
- data/lib/one_gadget/helper.rb +1 -10
- data/lib/one_gadget/logger.rb +8 -0
- data/lib/one_gadget/one_gadget.rb +70 -0
- data/lib/one_gadget/update.rb +1 -1
- data/lib/one_gadget/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e26da79b62658e7dd1ce9efcaeda04fbe805b98eb1fecf234948311d70553e3
|
4
|
+
data.tar.gz: 2ed832df9cffecaba987753e1ed9c9ebe8068e410c00da108c1348e80efe6637
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47732f230a683edcb699a21f3891812326b1a7d9b966c13fb3a50c8d07b7ffbb3ce4244d324c0f13907f8b5d64e6a16a824d44946d97f6f131df7cf0b1380b8e
|
7
|
+
data.tar.gz: 0a90f8f323ee47f78314eeb420eec22a36f8954b12806a47d493d8996128abb4ac40c2cb4ec25b236b3723a390391903e5082f1af6751a061645e4dfc442e8e0
|
data/lib/one_gadget.rb
CHANGED
@@ -4,70 +4,12 @@
|
|
4
4
|
|
5
5
|
# Main module.
|
6
6
|
module OneGadget
|
7
|
-
class << self
|
8
|
-
# The man entry of gem +one_gadget+.
|
9
|
-
# If want to find gadgets from file, it will search gadgets by its
|
10
|
-
# build id first.
|
11
|
-
#
|
12
|
-
# @param [String] file
|
13
|
-
# The relative path of libc.so.6.
|
14
|
-
# @param [String] build_id
|
15
|
-
# The BuildID of target libc.so.6.
|
16
|
-
# @param [Boolean] details
|
17
|
-
# Return gadget objects or offset only.
|
18
|
-
# @param [Boolean] force_file
|
19
|
-
# When +file+ is given, {OneGadget} will search gadgets according its
|
20
|
-
# build id first. +force_file = true+ to disable this feature.
|
21
|
-
# @param [Integer] level
|
22
|
-
# Output level.
|
23
|
-
# If +level+ equals to zero, only gadgets with highest successful probability would be output.
|
24
|
-
# @return [Array<OneGadget::Gadget::Gadget>, Array<Integer>]
|
25
|
-
# The gadgets found.
|
26
|
-
# @example
|
27
|
-
# OneGadget.gadgets(file: './libc.so.6')
|
28
|
-
# OneGadget.gadgets(build_id: '60131540dadc6796cab33388349e6e4e68692053')
|
29
|
-
def gadgets(file: nil, build_id: nil, details: false, force_file: false, level: 0)
|
30
|
-
ret = if build_id
|
31
|
-
OneGadget::Fetcher.from_build_id(build_id) || OneGadget::Logger.not_found(build_id)
|
32
|
-
else
|
33
|
-
from_file(OneGadget::Helper.abspath(file), force: force_file)
|
34
|
-
end
|
35
|
-
ret = refine_gadgets(ret, level)
|
36
|
-
ret.map!(&:offset) unless details
|
37
|
-
ret
|
38
|
-
rescue OneGadget::Error::Error => e
|
39
|
-
OneGadget::Logger.error("#{e.class.name.split('::').last}: #{e.message}")
|
40
|
-
[]
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
# Try from build id first, then file
|
46
|
-
def from_file(path, force: false)
|
47
|
-
OneGadget::Helper.verify_elf_file!(path)
|
48
|
-
gadgets = try_from_build(path) unless force
|
49
|
-
gadgets || OneGadget::Fetcher.from_file(path)
|
50
|
-
end
|
51
|
-
|
52
|
-
def try_from_build(file)
|
53
|
-
build_id = OneGadget::Helper.build_id_of(file)
|
54
|
-
return unless build_id
|
55
|
-
|
56
|
-
OneGadget::Fetcher.from_build_id(build_id, remote: false)
|
57
|
-
end
|
58
|
-
|
59
|
-
# Remove hard-to-reach-constrains gadgets according to level
|
60
|
-
def refine_gadgets(gadgets, level)
|
61
|
-
return [] if gadgets.empty?
|
62
|
-
return gadgets if level > 0 # currently only supports level > 0 or not
|
63
|
-
|
64
|
-
# remain gadgets with the fewest constraints
|
65
|
-
best = gadgets.map { |g| g.constraints.size }.min
|
66
|
-
gadgets.select { |g| g.constraints.size == best }
|
67
|
-
end
|
68
|
-
end
|
69
7
|
end
|
70
8
|
|
9
|
+
require 'one_gadget/helper'
|
10
|
+
require 'one_gadget/one_gadget'
|
11
|
+
require 'one_gadget/version'
|
12
|
+
|
71
13
|
# Shorter way to use one gadget.
|
72
14
|
# @param [String?] arg
|
73
15
|
# Can be either +build_id+ or path to libc.
|
@@ -92,9 +34,3 @@ end
|
|
92
34
|
|
93
35
|
require 'one_gadget/update'
|
94
36
|
OneGadget::Update.check!
|
95
|
-
|
96
|
-
require 'one_gadget/error'
|
97
|
-
require 'one_gadget/fetcher'
|
98
|
-
require 'one_gadget/helper'
|
99
|
-
require 'one_gadget/logger'
|
100
|
-
require 'one_gadget/version'
|
@@ -46,8 +46,8 @@ module OneGadget
|
|
46
46
|
false
|
47
47
|
end
|
48
48
|
|
49
|
-
#
|
50
|
-
# @return [Array<Instruction>] The
|
49
|
+
# Supported instruction set.
|
50
|
+
# @return [Array<Instruction>] The supported instructions.
|
51
51
|
def instructions
|
52
52
|
[
|
53
53
|
Instruction.new('add', 2),
|
@@ -72,6 +72,13 @@ module OneGadget
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
+
# To be inherited.
|
76
|
+
#
|
77
|
+
# @param [Integer] _idx
|
78
|
+
# The idx-th argument.
|
79
|
+
#
|
80
|
+
# @return [Lambda, Integer]
|
81
|
+
# Return value can be a {Lambda} or an +Integer+.
|
75
82
|
def argument(_idx); raise NotImplementedError
|
76
83
|
end
|
77
84
|
|
data/lib/one_gadget/error.rb
CHANGED
@@ -1,14 +1,19 @@
|
|
1
1
|
module OneGadget
|
2
|
+
# OneGadget errors.
|
2
3
|
module Error
|
4
|
+
# Generic error class.
|
3
5
|
class Error < StandardError
|
4
6
|
end
|
5
7
|
|
8
|
+
# Unsupported arguments of intructions.
|
6
9
|
class UnsupportedInstructionArgumentsError < Error
|
7
10
|
end
|
8
11
|
|
12
|
+
# Unsupported architecture.
|
9
13
|
class UnsupportedArchitectureError < Error
|
10
14
|
end
|
11
15
|
|
16
|
+
# Argument error of ruby methods.
|
12
17
|
class ArgumentError < Error
|
13
18
|
end
|
14
19
|
end
|
@@ -19,7 +19,7 @@ module OneGadget
|
|
19
19
|
|
20
20
|
true
|
21
21
|
end
|
22
|
-
cands + jmp_case_candidates
|
22
|
+
cands + jmp_case_candidates
|
23
23
|
end
|
24
24
|
|
25
25
|
# find gadgets in form:
|
@@ -30,7 +30,6 @@ module OneGadget
|
|
30
30
|
# ...
|
31
31
|
# call execve
|
32
32
|
def jmp_case_candidates
|
33
|
-
bin_sh_hex = str_offset('/bin/sh').to_s(16)
|
34
33
|
`#{objdump_cmd}|egrep 'rdi.*# #{bin_sh_hex}' -A 3`.split('--').map do |cand|
|
35
34
|
cand = cand.lines.map(&:strip).reject(&:empty?)
|
36
35
|
jmp_at = cand.index { |c| c.include?('jmp') }
|
data/lib/one_gadget/gadget.rb
CHANGED
@@ -60,7 +60,7 @@ module OneGadget
|
|
60
60
|
return build_not_found if table.nil? # remote doesn't have this one either.
|
61
61
|
|
62
62
|
# builds found in remote! Ask update gem and download remote gadgets.
|
63
|
-
OneGadget::
|
63
|
+
OneGadget::Logger.ask_update(msg: 'The desired one-gadget can be found in lastest version!')
|
64
64
|
tmp_file = OneGadget::Helper.download_build(table)
|
65
65
|
require tmp_file.path
|
66
66
|
tmp_file.unlink
|
data/lib/one_gadget/helper.rb
CHANGED
@@ -6,7 +6,6 @@ require 'tempfile'
|
|
6
6
|
require 'elftools'
|
7
7
|
|
8
8
|
require 'one_gadget/error'
|
9
|
-
require 'one_gadget/logger'
|
10
9
|
|
11
10
|
module OneGadget
|
12
11
|
# Define some helpful methods here.
|
@@ -103,7 +102,7 @@ module OneGadget
|
|
103
102
|
# True or false.
|
104
103
|
def color_enabled?
|
105
104
|
# if not set, use tty to check
|
106
|
-
return $stdout.tty?
|
105
|
+
return $stdout.tty? unless instance_variable_defined?(:@disable_color)
|
107
106
|
|
108
107
|
!@disable_color
|
109
108
|
end
|
@@ -184,14 +183,6 @@ module OneGadget
|
|
184
183
|
nil
|
185
184
|
end
|
186
185
|
|
187
|
-
# Show the message of ask user to update gem.
|
188
|
-
# @return [void]
|
189
|
-
def ask_update(msg: '')
|
190
|
-
name = 'one_gadget'
|
191
|
-
cmd = colorize("gem update #{name} && gem cleanup #{name}")
|
192
|
-
OneGadget::Logger.info(msg + "\n" + "Update with: $ #{cmd}" + "\n")
|
193
|
-
end
|
194
|
-
|
195
186
|
# Fetch the file archiecture of +file+.
|
196
187
|
# @param [String] file The target ELF filename.
|
197
188
|
# @return [Symbol]
|
data/lib/one_gadget/logger.rb
CHANGED
@@ -31,6 +31,14 @@ module OneGadget
|
|
31
31
|
[]
|
32
32
|
end
|
33
33
|
|
34
|
+
# Show the message of ask user to update gem.
|
35
|
+
# @return [void]
|
36
|
+
def ask_update(msg: '')
|
37
|
+
name = 'one_gadget'
|
38
|
+
cmd = OneGadget::Helper.colorize("gem update #{name} && gem cleanup #{name}")
|
39
|
+
OneGadget::Logger.info(msg + "\n" + "Update with: $ #{cmd}" + "\n")
|
40
|
+
end
|
41
|
+
|
34
42
|
%i[info warn error].each do |sym|
|
35
43
|
define_method(sym) do |msg|
|
36
44
|
@logger.__send__(sym, msg)
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'one_gadget/error'
|
2
|
+
require 'one_gadget/fetcher'
|
3
|
+
require 'one_gadget/helper'
|
4
|
+
require 'one_gadget/logger'
|
5
|
+
|
6
|
+
# Main module.
|
7
|
+
module OneGadget
|
8
|
+
class << self
|
9
|
+
# The man entry of gem +one_gadget+.
|
10
|
+
# If want to find gadgets from file, it will search gadgets by its
|
11
|
+
# build id first.
|
12
|
+
#
|
13
|
+
# @param [String] file
|
14
|
+
# The relative path of libc.so.6.
|
15
|
+
# @param [String] build_id
|
16
|
+
# The BuildID of target libc.so.6.
|
17
|
+
# @param [Boolean] details
|
18
|
+
# Return gadget objects or offset only.
|
19
|
+
# @param [Boolean] force_file
|
20
|
+
# When +file+ is given, {OneGadget} will search gadgets according its
|
21
|
+
# build id first. +force_file = true+ to disable this feature.
|
22
|
+
# @param [Integer] level
|
23
|
+
# Output level.
|
24
|
+
# If +level+ equals to zero, only gadgets with highest successful probability would be output.
|
25
|
+
# @return [Array<OneGadget::Gadget::Gadget>, Array<Integer>]
|
26
|
+
# The gadgets found.
|
27
|
+
# @example
|
28
|
+
# OneGadget.gadgets(file: './libc.so.6')
|
29
|
+
# OneGadget.gadgets(build_id: '60131540dadc6796cab33388349e6e4e68692053')
|
30
|
+
def gadgets(file: nil, build_id: nil, details: false, force_file: false, level: 0)
|
31
|
+
ret = if build_id
|
32
|
+
OneGadget::Fetcher.from_build_id(build_id) || OneGadget::Logger.not_found(build_id)
|
33
|
+
else
|
34
|
+
from_file(OneGadget::Helper.abspath(file), force: force_file)
|
35
|
+
end
|
36
|
+
ret = refine_gadgets(ret, level)
|
37
|
+
ret.map!(&:offset) unless details
|
38
|
+
ret
|
39
|
+
rescue OneGadget::Error::Error => e
|
40
|
+
OneGadget::Logger.error("#{e.class.name.split('::').last}: #{e.message}")
|
41
|
+
[]
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# Try from build id first, then file
|
47
|
+
def from_file(path, force: false)
|
48
|
+
OneGadget::Helper.verify_elf_file!(path)
|
49
|
+
gadgets = try_from_build(path) unless force
|
50
|
+
gadgets || OneGadget::Fetcher.from_file(path)
|
51
|
+
end
|
52
|
+
|
53
|
+
def try_from_build(file)
|
54
|
+
build_id = OneGadget::Helper.build_id_of(file)
|
55
|
+
return unless build_id
|
56
|
+
|
57
|
+
OneGadget::Fetcher.from_build_id(build_id, remote: false)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Remove hard-to-reach-constrains gadgets according to level
|
61
|
+
def refine_gadgets(gadgets, level)
|
62
|
+
return [] if gadgets.empty?
|
63
|
+
return gadgets if level > 0 # currently only supports level > 0 or not
|
64
|
+
|
65
|
+
# remain gadgets with the fewest constraints
|
66
|
+
best = gadgets.map { |g| g.constraints.size }.min
|
67
|
+
gadgets.select { |g| g.constraints.size == best }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/one_gadget/update.rb
CHANGED
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.6.
|
4
|
+
version: 1.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- david942j
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-10-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: elftools
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.0.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.0.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -796,6 +796,7 @@ files:
|
|
796
796
|
- lib/one_gadget/gadget.rb
|
797
797
|
- lib/one_gadget/helper.rb
|
798
798
|
- lib/one_gadget/logger.rb
|
799
|
+
- lib/one_gadget/one_gadget.rb
|
799
800
|
- lib/one_gadget/update.rb
|
800
801
|
- lib/one_gadget/version.rb
|
801
802
|
homepage: https://github.com/david942j/one_gadget
|