class OneGadget::Fetcher::Amd64

Fetcher for amd64.

Private Instance Methods

bin_sh_hex() click to toggle source
# File lib/one_gadget/fetchers/amd64.rb, line 52
def bin_sh_hex
  @bin_sh_hex ||= str_offset('/bin/sh').to_s(16)
end
candidates() click to toggle source
Calls superclass method OneGadget::Fetcher::Base#candidates
# File lib/one_gadget/fetchers/amd64.rb, line 16
def candidates
  # one basic block case
  cands = super do |candidate|
    next true if candidate.include?('posix_spawn@')
    next false unless candidate.include?(bin_sh_hex) # works in x86-64
    next false unless candidate.lines.last.include?('execve') # only care execve

    true
  end
  cands + jmp_case_candidates
end
emulator() click to toggle source
# File lib/one_gadget/fetchers/amd64.rb, line 12
def emulator
  OneGadget::Emulators::Amd64.new
end
global_var?(str) click to toggle source
# File lib/one_gadget/fetchers/amd64.rb, line 60
def global_var?(str)
  str.include?('rip')
end
jmp_case_candidates() click to toggle source

find gadgets in form:

lea rdi, '/bin/sh'
...
jmp xxx

xxx:

...
call execve
# File lib/one_gadget/fetchers/amd64.rb, line 35
def jmp_case_candidates
  `#{@objdump.command}|egrep '# #{bin_sh_hex}' -A 8`.split('--').map do |cand|
    cand = cand.lines.map(&:strip).reject(&:empty?)
    jmp_at = cand.index { |c| c.include?('jmp') }
    next nil if jmp_at.nil?

    cand = cand[0..jmp_at]
    next if cand.any? { |c| c.include?(call_str) }

    jmp_addr = cand.last.scan(/jmp\s+([\da-f]+)\s/)[0][0].to_i(16)
    dump = `#{@objdump.command(start: jmp_addr, stop: jmp_addr + 100)}|egrep '[0-9a-f]+:'`
    remain = dump.lines.map(&:strip).reject(&:empty?)
    remain = remain[0..remain.index { |r| r.match(/call.*<execve[^+]*>/) }]
    [cand + remain].join("\n")
  end.compact
end
str_bin_sh?(str) click to toggle source
# File lib/one_gadget/fetchers/amd64.rb, line 56
def str_bin_sh?(str)
  str.include?('rip+0x') # && str.include?(bin_sh_hex)
end