티스토리 뷰
카테고리
PWNABLE
문제
32 bit elf 바이너리인 echo_system 파일이 주어졌다.
IDA로 열어보자.
buf 변수는 ebp-0x88 에 위치하고 있지만 read 함수를 통해 최대 0xC8 바이트의 입력 값을 넣을 수 있다.
buf 변수를 그대로 출력하고 있으므로 FSB!! 가 일어날 것 같았지만 자세히 보니 printf함수가 아니라 print라는 사용자 정의 함수였고, 내부적으로 write 함수를 통해 출력하고 있어 FSB는 일어나지 않는다.
또한 친절하게도 프로그램의 내부에 cat_flag라는, flag를 출력시켜주는 함수가 존재한다!
너무 쉬운 거 아닌가…
BOF가 발생하므로 이를 이용해 RET를 cat_flag 함수의 주소로 변조하면 된다!!
라고 생각했지만 그렇게 간단한 문제는 아니었다.
main함수의 초반부를 보면 우리의 exploit을 방해할 ecx 레지스터가 등장한다.
[esp+4]라는 스택 주소를 ecx 레지스가 가리키고 ebp 레지스터를 push한 후, 곧 바로 ecx 레지스터가 push 된다.
끝날 때도 leave, ret이 아니다.
[ebp-4]의 값(초반에 push한 ecx 레지스터 값)을 다시 ecx 레지스터로 불러오고, [ecx-4]가 가리키는 주소로 esp 레지스터를 이동시킨다.
[ebp-4]에 위치한 ecx의 값이 변조되면 esp의 값이 달라지고, 이는 RET의 위치가 변조됨을 의미한다.
즉, 단순한 Overflow로는 RET를 변조하지 못 한다.
ecx의 값에 무엇을 넣을지 계산해야 한다.
여기서 ecx 레지스터의 값이 갖는 의미는 [RET가 담겨있는 스택 + 4] 의 주소이다.
입력 데이터를 받는 buf 변수에 뛰고 싶은 주소인 cat_flag 함수의 주소(0x080484A2)를 적고,
BOF를 이용하여 ecx 레지스터에는 [buf 변수의 주소 + 4]의 값을 써주면 된다.
잠깐, buf 변수는 지역 변수이기 때문에 데이터 영역이 아닌 스택 영역에 존재한다.
스택의 주소는 어떻게 알지?
위는 print 함수의 내부 구현 모습이다.
*(buf + n)의 값이 널(0x00)일 때까지 계속 출력한다.
ecx의 원래 값은 스택의 어딘가를 가리키고 있을 테니, ecx 직전까지 데이터를 입력하여 ecx의 값을 leak 시키자!
buf 변수는 ebp-0x88, ecx의 원래 값은 ebp-0x4 에 위치하고 있으니 입력 데이터를 0x84 만큼 넣어주면 print 함수가 실행될 때 스택의 주소를 leak 시킬 수 있다.
음?
스택의 주소가 계속 바뀐다.
한 번에 공격하긴 어려울 것 같다.
스택의 주소를 정확히 알 수 없으니 buf 변수에 cat_flag 함수의 주소를 33번(총 0x84 바이트) 스프레이 한 후,
ecx 레지스터 위치에는 알아낸 스택의 주소 중 임의의 하나를 넣어 Brute-Force 공격을 한다.
exploit
'해킹 > CTF' 카테고리의 다른 글
[WhiteHat Contest 12] Pwn001 write-up (2) | 2016.09.11 |
---|---|
[WhiteHat Contest 12] Misc002 write-up (1) | 2016.09.11 |
[2016 Layer7 CTF] EASY UAF write-up (3) | 2016.09.06 |
[2016 Layer7 CTF] EASY FSB write-up (0) | 2016.09.06 |
[2016 Layer7 CTF] SANITY CHECK write-up (0) | 2016.09.06 |