mirror of
https://github.com/david942j/one_gadget.git
synced 2026-10-11 22:09:54 +00:00
@@ -44,14 +44,14 @@ The article introducing how I develop this tool can be found [on my blog](https:
|
||||
|
||||
```bash
|
||||
$ one_gadget
|
||||
# Usage: one_gadget [file] [options]
|
||||
# Usage: one_gadget <FILE|-b BuildID> [options]
|
||||
# -b, --build-id BuildID BuildID[sha1] of libc.
|
||||
# -f, --[no-]force-file Force search gadgets in file instead of build id first.
|
||||
# -n, --near FUNCTIONS/FILE Order gadgets by their distance to the given functions or to the GOT functions of the given file.
|
||||
# -l, --level OUTPUT_LEVEL The output level.
|
||||
# OneGadget automatically selects gadgets with higher successful probability.
|
||||
# Increase this level to ask OneGadget show more gadgets it found.
|
||||
# Default: 0
|
||||
# -n, --near FUNCTIONS/FILE Order gadgets by their distance to the given functions or to the GOT functions of the given file.
|
||||
# -r, --[no-]raw Output gadgets offset only, split with one space.
|
||||
# -s, --script exploit-script Run exploit script with all possible gadgets.
|
||||
# The script will be run as 'exploit-script $offset'.
|
||||
|
||||
+2
-110
@@ -1,114 +1,6 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'optparse'
|
||||
require 'one_gadget/cli'
|
||||
|
||||
require 'one_gadget'
|
||||
|
||||
options = { raw: false }
|
||||
usage = 'Usage: one_gadget [file] [options]'
|
||||
parser = OptionParser.new do |opts|
|
||||
opts.banner = usage
|
||||
|
||||
opts.on('-b', '--build-id BuildID', 'BuildID[sha1] of libc.') do |b|
|
||||
options[:build_id] = b
|
||||
end
|
||||
|
||||
opts.on('-f', '--[no-]force-file', 'Force search gadgets in file instead of build id first.') do |b|
|
||||
options[:force_file] = b
|
||||
end
|
||||
|
||||
opts.on('-n', '--near FUNCTIONS/FILE', 'Order gadgets by their distance to the given functions'\
|
||||
' or to the GOT functions of the given file.') do |n|
|
||||
options[:near] = n
|
||||
end
|
||||
|
||||
opts.on('-l', '--level OUTPUT_LEVEL', Integer, 'The output level.',
|
||||
'OneGadget automatically selects gadgets with higher successful probability.',
|
||||
'Increase this level to ask OneGadget show more gadgets it found.',
|
||||
'Default: 0') do |l|
|
||||
options[:level] = l
|
||||
end
|
||||
|
||||
opts.on('-r', '--[no-]raw', 'Output gadgets offset only, split with one space.') do |v|
|
||||
options[:raw] = v
|
||||
end
|
||||
|
||||
opts.on('-s', '--script exploit-script', 'Run exploit script with all possible gadgets.',
|
||||
'The script will be run as \'exploit-script $offset\'.') do |script|
|
||||
options[:script] = script
|
||||
end
|
||||
|
||||
opts.on('--info BuildID', 'Show version information given BuildID.') do |b|
|
||||
options[:info] = b
|
||||
end
|
||||
|
||||
opts.on('--version', 'Current gem version.') do |v|
|
||||
options[:version] = v
|
||||
end
|
||||
end
|
||||
parser.parse!
|
||||
|
||||
if options[:version]
|
||||
puts "OneGadget Version #{OneGadget::VERSION}"
|
||||
exit(0)
|
||||
end
|
||||
|
||||
def execute(script, offset)
|
||||
pid = fork do
|
||||
exec([script, offset.to_s].join(' '))
|
||||
end
|
||||
Process.wait pid
|
||||
end
|
||||
|
||||
if options[:info]
|
||||
result = OneGadget::Gadget.builds_info(options[:info])
|
||||
exit(1) if result.nil? # error happend
|
||||
OneGadget::Logger.info("Information of #{options[:info]}:\n#{result.join("\n")}\n")
|
||||
exit(0)
|
||||
end
|
||||
|
||||
level = options[:level] || 0
|
||||
if options[:build_id]
|
||||
gadgets = OneGadget.gadgets(build_id: options[:build_id], details: true, level: level)
|
||||
elsif ARGV[0]
|
||||
gadgets = OneGadget.gadgets(file: ARGV[0], details: true, force_file: options[:force_file], level: level)
|
||||
else
|
||||
puts parser.help
|
||||
exit(1)
|
||||
end
|
||||
|
||||
if options[:script]
|
||||
gadgets.map(&:offset).each do |offset|
|
||||
OneGadget::Logger.info("Trying #{OneGadget::Helper.colored_hex(offset)}...\n")
|
||||
execute(options[:script], offset)
|
||||
end
|
||||
exit(0)
|
||||
end
|
||||
|
||||
if !options[:build_id] && ARGV[0] && options[:near]
|
||||
functions = if File.file?(options[:near]) && OneGadget::Helper.valid_elf_file?(options[:near])
|
||||
OneGadget::Helper.got_functions(options[:near])
|
||||
else
|
||||
options[:near].split(',').map(&:strip)
|
||||
end
|
||||
function_offsets = OneGadget::Helper.function_offsets(ARGV[0], functions)
|
||||
function_offsets.each do |function, offset|
|
||||
colored_offset = OneGadget::Helper.colored_hex(offset)
|
||||
OneGadget::Logger.warn("Gadgets near #{OneGadget::Helper.colorize(function)}(#{colored_offset}):\n")
|
||||
gadgets.sort_by! { |gadget| (gadget.offset - offset).abs }
|
||||
if options[:raw]
|
||||
puts gadgets.map(&:offset).join(' ')
|
||||
else
|
||||
puts gadgets.map(&:inspect).join("\n")
|
||||
end
|
||||
puts "\n"
|
||||
end
|
||||
exit(0)
|
||||
end
|
||||
|
||||
if options[:raw]
|
||||
puts gadgets.map(&:offset).join(' ')
|
||||
else
|
||||
puts gadgets.map(&:inspect).join("\n")
|
||||
end
|
||||
exit OneGadget::CLI.work(ARGV.dup)
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'optparse'
|
||||
|
||||
require 'one_gadget/logger'
|
||||
require 'one_gadget/one_gadget'
|
||||
require 'one_gadget/version'
|
||||
|
||||
module OneGadget
|
||||
# Methods for command line interface.
|
||||
module CLI
|
||||
# Help message.
|
||||
USAGE = 'Usage: one_gadget <FILE|-b BuildID> [options]'
|
||||
# Default options.
|
||||
DEFAULT_OPTIONS = { raw: false, level: 0 }.freeze
|
||||
|
||||
module_function
|
||||
|
||||
# Main method of CLI.
|
||||
# @param [Array<String>] argv
|
||||
# Command line arguments.
|
||||
# @return [Boolean]
|
||||
# Whether the command execute successfully.
|
||||
# @example
|
||||
# CLI.work(%w[--help])
|
||||
# # usage message
|
||||
# #=> true
|
||||
# CLI.work(%w[--version])
|
||||
# # version message
|
||||
# #=> true
|
||||
# @example
|
||||
# CLI.work([])
|
||||
# # usage message
|
||||
# #=> false
|
||||
# @example
|
||||
# CLI.work(%w[-b b417c0ba7cc5cf06d1d1bed6652cedb9253c60d0 -r])
|
||||
# # 324293 324386 1090444
|
||||
# #=> true
|
||||
def work(argv)
|
||||
@options = DEFAULT_OPTIONS.dup
|
||||
parser.parse!(argv)
|
||||
return show("OneGadget Version #{OneGadget::VERSION}") if @options[:version]
|
||||
return info_build_id(@options[:info]) if @options[:info]
|
||||
|
||||
libc_file = argv.pop
|
||||
build_id = @options[:build_id]
|
||||
level = @options[:level]
|
||||
return error("Either FILE or BuildID can be passed\n") if libc_file && @options[:build_id]
|
||||
return show(parser.help) && false unless build_id || libc_file
|
||||
|
||||
gadgets = if build_id
|
||||
OneGadget.gadgets(build_id: build_id, details: true, level: level)
|
||||
else # libc_file
|
||||
OneGadget.gadgets(file: libc_file, details: true, force_file: @options[:force_file], level: level)
|
||||
end
|
||||
handle_gadgets(gadgets, libc_file)
|
||||
end
|
||||
|
||||
# Gadgets fetched, decides how to display them.
|
||||
# @param [Array<OneGadget::Gadget::Gadget>] gadgets
|
||||
# @param [String] libc_file
|
||||
# @return [Boolean]
|
||||
def handle_gadgets(gadgets, libc_file)
|
||||
return handle_script(gadgets, @options[:script]) if @options[:script]
|
||||
return handle_near(libc_file, gadgets, @options[:near]) if libc_file && @options[:near]
|
||||
|
||||
display_gadgets(gadgets, @options[:raw])
|
||||
true
|
||||
end
|
||||
|
||||
# Display libc information given BuildID.
|
||||
# @param [String] id
|
||||
# @return [Boolean]
|
||||
# @example
|
||||
# CLI.info_build_id('b417c')
|
||||
# # [OneGadget] Information of b417c:
|
||||
# # spec/data/libc-2.27-b417c0ba7cc5cf06d1d1bed6652cedb9253c60d0.so
|
||||
# #
|
||||
# # Advanced Micro Devices X86-64
|
||||
# #
|
||||
# # GNU C Library (Ubuntu GLIBC 2.27-3ubuntu1) stable release version 2.27.
|
||||
# # Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
# # This is free software; see the source for copying conditions.
|
||||
# # There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
||||
# # PARTICULAR PURPOSE.
|
||||
# # Compiled by GNU CC version 7.3.0.
|
||||
# # libc ABIs: UNIQUE IFUNC
|
||||
# # For bug reporting instructions, please see:
|
||||
# # <https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
|
||||
# #=> true
|
||||
def info_build_id(id)
|
||||
result = OneGadget::Gadget.builds_info(id)
|
||||
return false if result.nil? # invalid form or BuildID not found
|
||||
|
||||
OneGadget::Logger.info("Information of #{id}:\n#{result.join("\n")}\n")
|
||||
true
|
||||
end
|
||||
|
||||
# The option parser.
|
||||
# @return [OptionParser]
|
||||
def parser
|
||||
@parser ||= OptionParser.new do |opts|
|
||||
opts.banner = USAGE
|
||||
|
||||
opts.on('-b', '--build-id BuildID', 'BuildID[sha1] of libc.') do |b|
|
||||
@options[:build_id] = b
|
||||
end
|
||||
|
||||
opts.on('-f', '--[no-]force-file', 'Force search gadgets in file instead of build id first.') do |b|
|
||||
@options[:force_file] = b
|
||||
end
|
||||
|
||||
opts.on('-l', '--level OUTPUT_LEVEL', Integer, 'The output level.',
|
||||
'OneGadget automatically selects gadgets with higher successful probability.',
|
||||
'Increase this level to ask OneGadget show more gadgets it found.',
|
||||
'Default: 0') do |l|
|
||||
@options[:level] = l
|
||||
end
|
||||
|
||||
opts.on('-n', '--near FUNCTIONS/FILE', 'Order gadgets by their distance to the given functions'\
|
||||
' or to the GOT functions of the given file.') do |n|
|
||||
@options[:near] = n
|
||||
end
|
||||
|
||||
opts.on('-r', '--[no-]raw', 'Output gadgets offset only, split with one space.') do |v|
|
||||
@options[:raw] = v
|
||||
end
|
||||
|
||||
opts.on('-s', '--script exploit-script', 'Run exploit script with all possible gadgets.',
|
||||
'The script will be run as \'exploit-script $offset\'.') do |script|
|
||||
@options[:script] = script
|
||||
end
|
||||
|
||||
opts.on('--info BuildID', 'Show version information given BuildID.') do |b|
|
||||
@options[:info] = b
|
||||
end
|
||||
|
||||
opts.on('--version', 'Current gem version.') do |v|
|
||||
@options[:version] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Writes +msg+ to stdout and returns +true+.
|
||||
# @param [String] msg
|
||||
# @return [true]
|
||||
def show(msg)
|
||||
puts msg
|
||||
true
|
||||
end
|
||||
|
||||
# Forks and executes the command.
|
||||
# @param [String] cmd
|
||||
# @return [void]
|
||||
def execute(cmd)
|
||||
Process.wait(spawn(cmd))
|
||||
end
|
||||
|
||||
# Handle the --script feature.
|
||||
# @param [Array<OneGadget::Gadget::Gadget>] gadgets
|
||||
# @param [String] script
|
||||
# @return [true]
|
||||
def handle_script(gadgets, script)
|
||||
gadgets.map(&:offset).each do |offset|
|
||||
OneGadget::Logger.info("Trying #{OneGadget::Helper.colored_hex(offset)}...\n")
|
||||
execute("#{script} #{offset}")
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
# Write gadgets to stdout.
|
||||
# @param [Array<OneGadget::Gadget::Gadget>] gadgets
|
||||
# @param [Boolean] raw
|
||||
# In raw mode, only the offset of gadgets are printed.
|
||||
# @return [void]
|
||||
def display_gadgets(gadgets, raw)
|
||||
if raw
|
||||
puts gadgets.map(&:offset).join(' ')
|
||||
else
|
||||
puts gadgets.map(&:inspect).join("\n")
|
||||
end
|
||||
end
|
||||
|
||||
# Log error.
|
||||
# @param [String] msg
|
||||
# @return [false]
|
||||
def error(msg)
|
||||
OneGadget::Logger.error(msg)
|
||||
false
|
||||
end
|
||||
|
||||
# Implements the --near feature.
|
||||
# @param [String] libc_file
|
||||
# @param [Array<OneGadget::Gadget::Gadget>] gadgets
|
||||
# @param [String] near
|
||||
# This can be name of functions or an ELF file.
|
||||
# - Use one comma without spaces to specify a list of functions: +printf,scanf,free+.
|
||||
# - Path to an ELF file and take its GOT functions to process: +/bin/ls+
|
||||
def handle_near(libc_file, gadgets, near)
|
||||
# TODO: show proper message for invalid +near+
|
||||
functions = if File.file?(near) && OneGadget::Helper.valid_elf_file?(near)
|
||||
OneGadget::Helper.got_functions(near)
|
||||
else
|
||||
near.split(',').map(&:strip)
|
||||
end
|
||||
function_offsets = OneGadget::Helper.function_offsets(libc_file, functions)
|
||||
function_offsets.each do |function, offset|
|
||||
colored_offset = OneGadget::Helper.colored_hex(offset)
|
||||
OneGadget::Logger.warn("Gadgets near #{OneGadget::Helper.colorize(function)}(#{colored_offset}):\n")
|
||||
display_gadgets(gadgets.sort_by { |gadget| (gadget.offset - offset).abs }, @options[:raw])
|
||||
puts "\n"
|
||||
end
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
+2
-74
@@ -8,14 +8,14 @@ describe 'Binary' do
|
||||
|
||||
it 'help' do
|
||||
expect(`env ruby -I#{@lib} #{@bin}`).to eq <<-EOS
|
||||
Usage: one_gadget [file] [options]
|
||||
Usage: one_gadget <FILE|-b BuildID> [options]
|
||||
-b, --build-id BuildID BuildID[sha1] of libc.
|
||||
-f, --[no-]force-file Force search gadgets in file instead of build id first.
|
||||
-n, --near FUNCTIONS/FILE Order gadgets by their distance to the given functions or to the GOT functions of the given file.
|
||||
-l, --level OUTPUT_LEVEL The output level.
|
||||
OneGadget automatically selects gadgets with higher successful probability.
|
||||
Increase this level to ask OneGadget show more gadgets it found.
|
||||
Default: 0
|
||||
-n, --near FUNCTIONS/FILE Order gadgets by their distance to the given functions or to the GOT functions of the given file.
|
||||
-r, --[no-]raw Output gadgets offset only, split with one space.
|
||||
-s, --script exploit-script Run exploit script with all possible gadgets.
|
||||
The script will be run as 'exploit-script $offset'.
|
||||
@@ -23,76 +23,4 @@ Usage: one_gadget [file] [options]
|
||||
--version Current gem version.
|
||||
EOS
|
||||
end
|
||||
|
||||
context 'near' do
|
||||
before do
|
||||
skip_unless_objdump
|
||||
end
|
||||
|
||||
it 'functions' do
|
||||
file = data_path('libc-2.24-8cba3297f538691eb1875be62986993c004f3f4d.so')
|
||||
expect(`env ruby -I#{@lib} #{@bin} -n system -l 1 #{file}`).to eq <<-EOS
|
||||
[OneGadget] Gadgets near system(0x3f4d0):
|
||||
0x3f3aa execve("/bin/sh", rsp+0x30, environ)
|
||||
constraints:
|
||||
[rsp+0x30] == NULL
|
||||
|
||||
0x3f356 execve("/bin/sh", rsp+0x30, environ)
|
||||
constraints:
|
||||
rax == NULL
|
||||
|
||||
0xb8a38 execve("/bin/sh", r13, r12)
|
||||
constraints:
|
||||
[r13] == NULL || r13 == NULL
|
||||
[r12] == NULL || r12 == NULL
|
||||
|
||||
0xd67e5 execve("/bin/sh", rsp+0x70, environ)
|
||||
constraints:
|
||||
[rsp+0x70] == NULL
|
||||
|
||||
0xd67f1 execve("/bin/sh", rsi, [rax])
|
||||
constraints:
|
||||
[rsi] == NULL || rsi == NULL
|
||||
[[rax]] == NULL || [rax] == NULL
|
||||
|
||||
EOS
|
||||
end
|
||||
|
||||
it 'functions' do
|
||||
file = data_path('libc-2.24-8cba3297f538691eb1875be62986993c004f3f4d.so')
|
||||
expect(`env ruby -I#{@lib} #{@bin} -n wscanf,pwrite -l 1 -r #{file}`).to eq <<-EOS
|
||||
[OneGadget] Gadgets near pwrite(0xd9b70):
|
||||
878577 878565 756280 258986 258902
|
||||
|
||||
[OneGadget] Gadgets near wscanf(0x6afe0):
|
||||
258986 258902 756280 878565 878577
|
||||
|
||||
EOS
|
||||
end
|
||||
|
||||
it 'file' do
|
||||
bin_file = data_path('test_near_file.elf')
|
||||
lib_file = data_path('libc-2.24-8cba3297f538691eb1875be62986993c004f3f4d.so')
|
||||
expect(`env ruby -I#{@lib} #{@bin} -n #{bin_file} -l 1 -r #{lib_file}`).to eq <<-EOS
|
||||
[OneGadget] Gadgets near exit(0x359d0):
|
||||
258902 258986 756280 878565 878577
|
||||
|
||||
[OneGadget] Gadgets near puts(0x68fe0):
|
||||
258986 258902 756280 878565 878577
|
||||
|
||||
[OneGadget] Gadgets near printf(0x4f1e0):
|
||||
258986 258902 756280 878565 878577
|
||||
|
||||
[OneGadget] Gadgets near strlen(0x80420):
|
||||
756280 258986 258902 878565 878577
|
||||
|
||||
[OneGadget] Gadgets near __cxa_finalize(0x35c70):
|
||||
258902 258986 756280 878565 878577
|
||||
|
||||
[OneGadget] Gadgets near __libc_start_main(0x201a0):
|
||||
258902 258986 756280 878565 878577
|
||||
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'one_gadget/cli'
|
||||
require 'one_gadget/version'
|
||||
|
||||
describe OneGadget::CLI do
|
||||
let(:b_param) { %w[-b b417c0ba7cc5cf06d1d1bed6652cedb9253c60d0] }
|
||||
let(:libc_file) { data_path('libc-2.27-b417c0ba7cc5cf06d1d1bed6652cedb9253c60d0.so') }
|
||||
|
||||
it 'version' do
|
||||
expect { described_class.work(['--version']) }.to output("OneGadget Version #{OneGadget::VERSION}\n").to_stdout
|
||||
end
|
||||
|
||||
it 'error' do
|
||||
expect { hook_logger { described_class.work(b_param + ['file']) } }.to output(<<-EOS).to_stdout
|
||||
[OneGadget] Either FILE or BuildID can be passed
|
||||
EOS
|
||||
end
|
||||
|
||||
it 'info' do
|
||||
expect { hook_logger { described_class.work(%w[--info b417c]) } }.to output(<<-EOS).to_stdout
|
||||
[OneGadget] Information of b417c:
|
||||
spec/data/libc-2.27-b417c0ba7cc5cf06d1d1bed6652cedb9253c60d0.so
|
||||
|
||||
Advanced Micro Devices X86-64
|
||||
|
||||
GNU C Library (Ubuntu GLIBC 2.27-3ubuntu1) stable release version 2.27.
|
||||
Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
This is free software; see the source for copying conditions.
|
||||
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE.
|
||||
Compiled by GNU CC version 7.3.0.
|
||||
libc ABIs: UNIQUE IFUNC
|
||||
For bug reporting instructions, please see:
|
||||
<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
|
||||
EOS
|
||||
end
|
||||
|
||||
it 'build id' do
|
||||
expect { described_class.work(b_param) }.to output(<<-EOS).to_stdout
|
||||
0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
|
||||
constraints:
|
||||
rcx == NULL
|
||||
|
||||
0x4f322 execve("/bin/sh", rsp+0x40, environ)
|
||||
constraints:
|
||||
[rsp+0x40] == NULL
|
||||
|
||||
0x10a38c execve("/bin/sh", rsp+0x70, environ)
|
||||
constraints:
|
||||
[rsp+0x70] == NULL
|
||||
EOS
|
||||
end
|
||||
|
||||
it 'build id with raw' do
|
||||
expect { described_class.work(b_param + %w[--raw --level 1]) }.to output(<<-EOS).to_stdout
|
||||
324293 324386 939679 940120 940127 940131 1090444 1090456
|
||||
EOS
|
||||
end
|
||||
|
||||
it 'file with raw' do
|
||||
skip_unless_objdump
|
||||
|
||||
expect { described_class.work(%w[--force --raw --level 1] + [libc_file]) }.to output(<<-EOS).to_stdout
|
||||
324293 324386 939679 940120 940127 940131 1090444 1090456
|
||||
EOS
|
||||
end
|
||||
|
||||
it 'script' do
|
||||
skip_on_windows
|
||||
|
||||
expect { hook_logger { described_class.work(b_param + %w[-s true]) } }.to output(<<-EOS).to_stdout
|
||||
[OneGadget] Trying 0x4f2c5...
|
||||
[OneGadget] Trying 0x4f322...
|
||||
[OneGadget] Trying 0x10a38c...
|
||||
EOS
|
||||
end
|
||||
|
||||
context 'near' do
|
||||
before do
|
||||
skip_unless_objdump
|
||||
end
|
||||
|
||||
it 'function' do
|
||||
file = data_path('libc-2.24-8cba3297f538691eb1875be62986993c004f3f4d.so')
|
||||
expect { hook_logger { described_class.work(%w[-n system -l 1] + [file]) } }.to output(<<-EOS).to_stdout
|
||||
[OneGadget] Gadgets near system(0x3f4d0):
|
||||
0x3f3aa execve("/bin/sh", rsp+0x30, environ)
|
||||
constraints:
|
||||
[rsp+0x30] == NULL
|
||||
|
||||
0x3f356 execve("/bin/sh", rsp+0x30, environ)
|
||||
constraints:
|
||||
rax == NULL
|
||||
|
||||
0xb8a38 execve("/bin/sh", r13, r12)
|
||||
constraints:
|
||||
[r13] == NULL || r13 == NULL
|
||||
[r12] == NULL || r12 == NULL
|
||||
|
||||
0xd67e5 execve("/bin/sh", rsp+0x70, environ)
|
||||
constraints:
|
||||
[rsp+0x70] == NULL
|
||||
|
||||
0xd67f1 execve("/bin/sh", rsi, [rax])
|
||||
constraints:
|
||||
[rsi] == NULL || rsi == NULL
|
||||
[[rax]] == NULL || [rax] == NULL
|
||||
|
||||
EOS
|
||||
end
|
||||
|
||||
it 'functions' do
|
||||
file = data_path('libc-2.24-8cba3297f538691eb1875be62986993c004f3f4d.so')
|
||||
expect { hook_logger { described_class.work(%w[-n wscanf,pwrite -l 1 -r] + [file]) } }.to output(<<-EOS).to_stdout
|
||||
[OneGadget] Gadgets near pwrite(0xd9b70):
|
||||
878577 878565 756280 258986 258902
|
||||
|
||||
[OneGadget] Gadgets near wscanf(0x6afe0):
|
||||
258986 258902 756280 878565 878577
|
||||
|
||||
EOS
|
||||
end
|
||||
|
||||
it 'file' do
|
||||
bin_file = data_path('test_near_file.elf')
|
||||
lib_file = data_path('libc-2.24-8cba3297f538691eb1875be62986993c004f3f4d.so')
|
||||
argv = ['-n', bin_file, '-l1', '-r', lib_file]
|
||||
expect { hook_logger { described_class.work(argv) } }.to output(<<-EOS).to_stdout
|
||||
[OneGadget] Gadgets near exit(0x359d0):
|
||||
258902 258986 756280 878565 878577
|
||||
|
||||
[OneGadget] Gadgets near puts(0x68fe0):
|
||||
258986 258902 756280 878565 878577
|
||||
|
||||
[OneGadget] Gadgets near printf(0x4f1e0):
|
||||
258986 258902 756280 878565 878577
|
||||
|
||||
[OneGadget] Gadgets near strlen(0x80420):
|
||||
756280 258986 258902 878565 878577
|
||||
|
||||
[OneGadget] Gadgets near __cxa_finalize(0x35c70):
|
||||
258902 258986 756280 878565 878577
|
||||
|
||||
[OneGadget] Gadgets near __libc_start_main(0x201a0):
|
||||
258902 258986 756280 878565 878577
|
||||
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -21,6 +21,10 @@ module Helpers
|
||||
yield
|
||||
end
|
||||
|
||||
def skip_on_windows
|
||||
skip 'Cannot run on Windows' if /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
|
||||
end
|
||||
|
||||
def skip_unless_objdump
|
||||
skip 'binutils not installed' if OneGadget::Helper.which('objdump').nil?
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user