one_gadget 1.3.4.1 → 1.3.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c69447e16b79866cfd608d5b714e65cfa16d2492
4
- data.tar.gz: 2a4ce21e7fb1070845a8fde268e8477b23f2e8da
3
+ metadata.gz: 769666a5afd3ce890eea834682b010137958e50a
4
+ data.tar.gz: 303399584d0b4163058ad74c0e9f80a8fea13694
5
5
  SHA512:
6
- metadata.gz: 3768aa0cd2c00128fe75e232a115ed81b9783efed4de71cdbc28322843c534b25d7da93b731b85f0c22d6b1b5cd592984cd002dce099c05c6ff020060e503f66
7
- data.tar.gz: 72a5b04cc4cfa3dfcaa99c248260bb3e0040a45166fe566405158917ad11a3ed65c943902099a3471fb224a18dd726404650892ca7b239d6699a0dcfd2775cb1
6
+ metadata.gz: bb098f44596a0bd6f9a51ae533fbb2456c66c65a64a11bd7c8bc031bdd08684ccee0a549a7d833d26cfe3314a1caf34bfbd294ed67960d9843ea21b72927c931
7
+ data.tar.gz: 743e95a1efac018fc6e887348b234bd08da77776494bfcd8f793a2b8612e2ccd69fecab26d948ae55525de15fc298179d04c4ff772b7c6c02b3e19120c98d03b
data/README.md CHANGED
@@ -8,9 +8,10 @@
8
8
 
9
9
  ## One Gadget
10
10
 
11
- When playing ctf pwn challenges we usually need the one-gadget of `execve('/bin/sh', NULL, NULL)`.
11
+ When playing ctf pwn challenges we usually need the one-gadget RCE (remote code execution),
12
+ which leads to call `execve('/bin/sh', NULL, NULL)`.
12
13
 
13
- This gem provides such gadget finder, no need to use IDA-pro every time like a fool.
14
+ This gem provides such gadgets finder, no need to use IDA-pro every time like a fool.
14
15
 
15
16
  This work provides the command-line tool `one_gadget` for easy usage.
16
17
 
data/lib/one_gadget.rb CHANGED
@@ -26,8 +26,8 @@ module OneGadget
26
26
  OneGadget::Fetcher.from_build_id(build_id, details: details)
27
27
  elsif file
28
28
  file = OneGadget::Helper.abspath(file)
29
- unless force_file
30
- build_id = OneGadget::Helper.build_id_of(file)
29
+ build_id = OneGadget::Helper.build_id_of(file)
30
+ if !force_file && build_id
31
31
  gadgets = OneGadget::Fetcher.from_build_id(build_id, details: details)
32
32
  return gadgets unless gadgets.empty?
33
33
  end
@@ -3,7 +3,9 @@ module OneGadget
3
3
  module ABI
4
4
  # Define class methods here.
5
5
  module ClassMethods
6
+ # Registers in i386.
6
7
  LINUX_X86_32 = %w(eax ebx ecx edx edi esi ebp esp).freeze
8
+ # Registers in x86_64/
7
9
  LINUX_X86_64 = LINUX_X86_32 + %w(rax rbx rcx rdx rdi rsi rbp rsp) + 7.upto(15).map { |i| "r#{i}" }
8
10
  # Registers' name in amd64.
9
11
  # @return [Array<String>] List of registers.
@@ -6,6 +6,7 @@ module OneGadget
6
6
  # Emulator of amd64 instruction set.
7
7
  class I386 < X86
8
8
  class << self
9
+ # Yap, bits.
9
10
  def bits
10
11
  32
11
12
  end
@@ -3,10 +3,10 @@ require 'one_gadget/helper'
3
3
  module OneGadget
4
4
  module Emulators
5
5
  # A {Lambda} object can be:
6
- # 1. {String} # variable name
7
- # 2. {Numeric}
8
- # 3. {Lambda} + {Numeric}
9
- # 4. dereference {Lambda}
6
+ # 1. +String+ (variable name)
7
+ # 2. +Numeric+
8
+ # 3. {Lambda} + +Numeric+
9
+ # 4. dereferenced {Lambda}
10
10
  class Lambda
11
11
  attr_accessor :obj # @return [String, Lambda] The object currently related to.
12
12
  attr_accessor :immi # @return [Integer] The immidiate value currently added.
@@ -49,6 +49,7 @@ module OneGadget
49
49
 
50
50
  # Decrease dreference count with 1.
51
51
  # @return [void]
52
+ # @raise [ArgumentError] When this object cannot be referenced anymore.
52
53
  def ref!
53
54
  raise ArgumentError, 'Cannot reference anymore!' if @deref_count <= 0
54
55
  @deref_count -= 1
@@ -86,14 +87,18 @@ module OneGadget
86
87
  end
87
88
 
88
89
  class << self
89
- # Target: parse something like +[rsp+0x50]+ into a {Lambda} object.
90
+ # Target: parse things like <tt>[rsp+0x50]</tt> into a {Lambda} object.
90
91
  # @param [String] arg
91
92
  # @param [Hash{String => Lambda}] predefined
93
+ # Predfined values.
92
94
  # @return [OneGadget::Emulators::Lambda, Integer]
93
95
  # If +arg+ contains number only, return it.
94
96
  # Otherwise, return a {Lambda} object.
95
97
  # @example
96
- # parse('[rsp+0x50]') #=> #<Lambda @obj='rsp', @immi=80, @deref_count=1>
98
+ # obj = parse('[rsp+0x50]')
99
+ # #=> #<Lambda @obj='rsp', @immi=80, @deref_count=1>
100
+ # parse('obj+0x30', predefined: { 'obj' => obj }).to_s
101
+ # #=> '[rsp+0x50]+0x30'
97
102
  def parse(arg, predefined: {})
98
103
  deref_count = 0
99
104
  if arg[0] == '[' # a little hack because there should nerver something like +[[rsp+1]+2]+ to parse.
@@ -34,12 +34,12 @@ module OneGadget
34
34
  # contains offset only.
35
35
  # Otherwise, array of gadgets is returned.
36
36
  def from_file(file, details: false)
37
- gadgets = {
37
+ klass = {
38
38
  amd64: OneGadget::Fetcher::Amd64,
39
- i386: OneGadget::Fetcher::I386,
40
- unknown: OneGadget::Fetcher::Base
41
- }[OneGadget::Helper.architecture(file)].new(file).find
42
- gadgets = trim_gadgets(gadgets)
39
+ i386: OneGadget::Fetcher::I386
40
+ }[OneGadget::Helper.architecture(file)]
41
+ raise ArgumentError, 'Unsupported architecture!' if klass.nil?
42
+ gadgets = trim_gadgets(klass.new(file).find)
43
43
  return gadgets if details
44
44
  gadgets.map(&:offset)
45
45
  end
@@ -2,7 +2,7 @@ require 'shellwords'
2
2
 
3
3
  module OneGadget
4
4
  module Fetcher
5
- # define common methods for gadget fetchers.
5
+ # Define common methods for gadget fetchers.
6
6
  class Base
7
7
  # The absolute path of glibc.
8
8
  # @return [String] The filename.
@@ -10,7 +10,7 @@ module OneGadget
10
10
  # Instantiate a fetcher object.
11
11
  # @param [String] file Absolute path of target libc.
12
12
  def initialize(file)
13
- @file = ::Shellwords.escape(file)
13
+ @file = file
14
14
  end
15
15
 
16
16
  # Method need to be implemented in inheritors.
@@ -19,6 +19,12 @@ module OneGadget
19
19
  end
20
20
 
21
21
  # Fetch candidates that end with call exec*.
22
+ #
23
+ # Give a block to filter gadget candidates.
24
+ # @yieldparam [String] cand
25
+ # Is this candidate valid?
26
+ # @yieldreturn [Boolean]
27
+ # True for valid.
22
28
  # @return [Array<String>]
23
29
  # Each +String+ returned is multi-lines of assembly code.
24
30
  def candidates(&block)
@@ -34,7 +40,7 @@ module OneGadget
34
40
  private
35
41
 
36
42
  def objdump_cmd(start: nil, stop: nil)
37
- cmd = %(objdump -w -d -M intel "#{file}")
43
+ cmd = %(objdump -w -d -M intel #{::Shellwords.escape(file)})
38
44
  cmd.concat(" --start-address #{start}") if start
39
45
  cmd.concat(" --stop-address #{stop}") if stop
40
46
  cmd
@@ -55,7 +61,8 @@ module OneGadget
55
61
  end
56
62
 
57
63
  def str_offset(str)
58
- match = `strings -tx #{file} -n #{str.size} | grep " #{::Shellwords.escape(str)}"`.lines.map(&:strip).first
64
+ match = `strings -tx #{::Shellwords.escape(file)} -n #{str.size} | grep #{::Shellwords.escape(' ' + str)}`
65
+ match = match.lines.map(&:strip).first
59
66
  return nil if match.nil?
60
67
  # 17c8c3 /bin/sh
61
68
  match.split.first.to_i(16)
@@ -40,7 +40,9 @@ module OneGadget
40
40
 
41
41
  # Define class methods here.
42
42
  module ClassMethods
43
- BUILDS_PATH = File.join(File.dirname(__FILE__), 'builds').freeze
43
+ # Path to the pre-build files.
44
+ BUILDS_PATH = File.join(__dir__, 'builds').freeze
45
+ # Cache.
44
46
  BUILDS = Hash.new { |h, k| h[k] = [] }
45
47
  # Get gadgets from pre-defined corpus.
46
48
  # @param [String] build_id Desired build id.
@@ -9,6 +9,7 @@ require 'one_gadget/logger'
9
9
  module OneGadget
10
10
  # Define some helpful methods here.
11
11
  module Helper
12
+ # Format of build-id, 40 hex numbers.
12
13
  BUILD_ID_FORMAT = /[0-9a-f]{40}/
13
14
  # Define class methods here.
14
15
  module ClassMethods
@@ -125,15 +126,16 @@ module OneGadget
125
126
  end
126
127
 
127
128
  # Fetch the file archiecture of +file+.
128
- # @param [String] The target ELF filename.
129
+ # @param [String] file The target ELF filename.
129
130
  # @return [String]
130
131
  # Only supports :amd64, :i386 now.
131
132
  def architecture(file)
132
133
  str = ELFTools::ELFFile.new(File.open(file)).machine
133
134
  return :amd64 if str.include?('X86-64')
134
135
  return :i386 if str.include?('Intel 80386')
135
- rescue ELFTools::ELFError # not a valid ELF
136
136
  :unknown
137
+ rescue ELFTools::ELFError # not a valid ELF
138
+ :invalid
137
139
  end
138
140
 
139
141
  # Present number in hex format.
@@ -1,3 +1,4 @@
1
1
  module OneGadget
2
- VERSION = '1.3.4.1'.freeze
2
+ # Current gem version.
3
+ VERSION = '1.3.5'.freeze
3
4
  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.3.4.1
4
+ version: 1.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - david942j
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-22 00:00:00.000000000 Z
11
+ date: 2017-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: elftools
@@ -99,7 +99,7 @@ description: |2
99
99
 
100
100
  This gem provides such gadget finder, no need to use IDA-pro every time like a fool :p.
101
101
 
102
- Also provides the command-line tool +one_gadget+ for easy usage.
102
+ Typing `one_gadget /path/to/libc` in terminal and having fun!
103
103
  email:
104
104
  - david942j@gmail.com
105
105
  executables: