어제부터 힙에 관한 기본 지식과 메모리 구조에 대해 공부해 봤는데, 이를 바탕으로 Beginner_Heap 문제를 풀어보겠다.
우선은 heap 문제이든 stack 문제이든 checksec이 국룰이다.
보니까 Partial RELRO와 NX bit가 적용되어 있다. 즉, GOT overwriting은 가능하나 쉘 코드 사용이 불가능하다.
우선 어떤 코드인지 IDA로 보자.
오.... 역시 heap 문제답게 동적 할당이 나온다...
무섭지만ㅜㅜ 한번 분석해보자.
그런데, 너무 main이 더럽다. 깔끔하게 볼 수 없을까?
당연히 방법은 존재한다. 키보드의 '|'와 '\'가 있는 버튼을 누르면!
자료형이 보이지 않게 된다!
아무튼... 분석 시작해보자.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
첫 번째로 v3에 malloc(16)을 한 다음, user data 영역에 1을 대입한다.
그다음 v3+1 위치에 malloc(8)하고 난 후 해당하는 user data의 첫 주소를 대입한다.
v4도 마찬가지로 같은 방법으로 동적 할당과 값 대입을 한다.
중요한 부분인데, fgets로 s에 0x1000, 즉 4096byte만큼을 입력받을 수 있다. 즉, heap overflow가 가능하다는 말이다.
입력 후, strcpy로 (v3+1) 위치에 저장되어 있는 값을 주소로 생각해 그 주소에 문자열 s를 복사한다.
이 과정을 (v4+1) 위치에도 수행한다.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
아까 checksec 결과를 보고 GOT overwriting을 할 수 있다고 했는데, 마지막 입력받는 부분에서 기법을 사용할 수 있을 것 같다.
우선, exploit 과정은 다음과 같다.
1. 마지막의 strcpy(*(v4+1), &s); 부분에서 *(v4+1), 즉 v4+1 위치에 내가 원하는 주소를 대입하고 싶다.
2. 첫 번째 fgets에서 s에 v4+1 위치 직전까지 dummy를 채운 다음 원하는 주소를 넣는다.
3. 두 번째 fgets에서 그 주소에 넣고 싶은 또 다른 주소를 넣는다.
다시 말하자면, 어떤 함수의 got를 쉘을 실행시키는 특정 함수의 주소로 바꾼 다음 원래 함수를 실행시키는 것이다.
여기서는 main에 exit 함수가 실행되길래 exit가 실행되게 하지 않고 쉘 실행 함수를 호출하게 만들면 될 것 같다.
보니까 사용자가 만든 함수인 sub_400826() 함수를 호출하면 flag를 획득할 수 있을 것 같다.
그림으로 설명하면 다음과 같다.
exit의 got는 IDA에서 찾았다.
자, 이제 exploit code를 작성해보자.
v3에서 v3+1, v4까지 전부 40byte가 동적 할당되었으므로 40byte를 dummy로 주고, exit_got를 첫 번째 sendline한다음, flag 출력 함수 주소를 2번째 sendline 하면 된다.
exploit code는 다음과 같다.
짧은 payload라도, 많은 지식과 연구를 함으로써 나오는 결과물이므로 지금까지 설명을 길게 하였다. 모든 힙 스터디원들이 이해할 수 있길 바라는 마음에서이다.
flag가 출력되었다!!!!
이제... 정말 Heap 공부 시작이다!!!
'Hacking > HackCTF' 카테고리의 다른 글
HackCTF ROP Write-up (0) | 2020.01.14 |
---|---|
HackCTF pwning Write-up (0) | 2020.01.14 |
HackCTF gift Write-up (0) | 2020.01.08 |
HackCTF Look at me Write-up (0) | 2020.01.08 |
HackCTF RTL_Core Write-up (0) | 2020.01.07 |