스터디 그룹/ProjectH4C

ProjectH4C 3개월 3주차 과제 (pwnable.kr - bof)

 

 


📖 1) 문제 파악

무난하게 BOF 슈슉 해주면 풀릴 것 같다.

 

소스코드를 바로 다운 받을 수 있지만, 공부하는 차원에서 직접 IDA나 GDB로 보도록 하자. 

main 함수에서는 우선 func(3735928559); 를 실행한다. 이제 func 함수를 알아보자.

여기서 3735928559 16진수로 바꾸면 0xdeadbeef가 된다.

a1에는 0xdeadebeef가 들어가 있는 상황이다. 뭐 그런 상태에서 s배열, v3를 선언한다.

근데 아직 저 __readgsdword(0x14u)의 역할이 무엇인지 모르겠다. 아마도 canary인 것으로 생각된다.

 


📖 2) 문제 분석

우선 func 함수 내에서 return __readgsdword(0x14u) ^ v3 라는 코드가 있다.

v3라는 변수도 마찬가지이고, 보면 볼 수록 canary 같다. 아직 잘은 모르지만, 좀 알아보자.

return __readgsdword(0x14u) ^ v3; 라는 코드가 존재한다.

지금 내가 그린 버퍼오버플로우를 확인해 보면 v3라는 값을 덮게되므로 오버플로우 공격이 감지된다.

 

그럼 공격에 실패하는 것인가 ? 그것은 또 아니다. 어차피 system 함수는 return을 만나기 전에 실행되기 때문이다.

 

그럼 이제 a1을 덮기 위해 몇 바이트가 필요할 지 계산해보자.

 

char s + int v3 + SFP + RET = 32 + 4 + 4 + 4 이다. 즉 44바이트를 덮어주어야 한다.

 

44바이트를 덮어주고 0xCAFEBABE 를 또 덮어주어야 한다.


📖 3) 문제 풀이

우선 44바이트를 덮었더니, 성공하지 못하였다. 그 이유는 무엇일까 ?

IDA PRO를 통해 func의 stack을 확인해보자.

 

우선 가장 위의 s는 문자열 s를 의미한다. 밑의 var_C는 위에서 나온 v4인 canary때문에 만들어진 변수같다.

그리고 밑의 s는 SFP, r은 RET을 의미하고, 그 밑에 arg_0 (a1)이 출현한다.

 

즉 우리가 덮어야 하는 바이트는 2C + 8 인 52가 나오게 된다.

컴파일러마다 최적화 또는 기타 등등의 사유로 인해 스택에서 볼 수 있듯이 dummy를 집어넣게 된다.

앞으로 문제를 풀 때 조심하도록 하자.

문제를 풀었다.

 

from pwn import *
p = remote("pwnable.kr", 9000);

addr = p32(0xCAFEBABE)
payload = 'A'*52 + addr

p.sendline(payload)
p.interactive()