Skip to content

Instantly share code, notes, and snippets.

@xpn
Created December 7, 2016 16:54
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save xpn/9dbc8aea2ea53d92f9fca08f0a1e4fa7 to your computer and use it in GitHub Desktop.
Save xpn/9dbc8aea2ea53d92f9fca08f0a1e4fa7 to your computer and use it in GitHub Desktop.
Radare2 r2pipe script to decode Meterpreters Single Byte XOR Countdown Encoder
# Radare2 r2pipe script to decode Meterpreters Single Byte XOR Countdown Encoder
# https://github.com/rapid7/metasploit-framework/blob/master/modules/encoders/x86/countdown.rb
import r2pipe
import sys
def dump(addr):
pass
def startEsil():
r.cmd('e io.cache=true') # We aren't writing to disk, we will be dumping from memory
r.cmd('e asm.bits=32') # This is used for the 32 bit payload
r.cmd('e asm.arch=x86')
r.cmd('aei') # Initialise the ESIL VM
r.cmd('aeim 0xffffd000 0x2000 stack') # Create our stack
def emulate():
# First we need to find our current address
cmd = r.cmdj('pdj 1')
base = cmd[0]['offset']
print "Base address: %x" % (base)
cmd = r.cmdj('oj')
end = cmd[0]['size']
print "Size of payload: %x" % (end)
# Next we need to find the LOOP opcode
cmd = r.cmdj('pdj 100')
for c in cmd:
if c['opcode'].startswith('loop'):
decoded = c['offset'] + 2
break
print "Length of Decoder: %d bytes" % (decoded - base)
# Now we emulate until we are beyond the loop and the orig payload has been decoded
r.cmd('aecu %d' % (base + (decoded - base)))
print r.cmd('pD %d @ %d' % (end - (decoded - base), base + (decoded - base)))
raw = r.cmdj('p8j %d @ %d' % (end - (decoded - base), decoded))
with open('out.bin', 'w') as f:
f.write(''.join(map(chr, raw)))
print "Raw code is now in ./out.bin"
r = r2pipe.open(sys.argv[1])
r.cmd('e asm.comments=false');
r.cmd('e asm.lines=false');
r.cmd('e asm.flags=false');
startEsil()
emulate()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment