포너블 공부 2일차. 여전히 카나리 릭, 파이썬과 싸우고 있다.
파이썬 문법, pwntools 모듈 등이 나에겐 너무 생소한지라 아직까진 어려운데 어쩌겠습니까... 해야죠 네 ...
이번 문제도 역시 Canary Leak을 이용해 풀어야 하는 문제이다. 문제를 한번 자세히 보도록 하자.
(문제 출처 : https://dreamhack.io/wargame/challenges/33 )
이 문제는 작동하고 있는 서비스(ssp_001)의 바이너리와 소스코드가 주어집니다.
프로그램의 취약점을 찾고 SSP 방어 기법을 우회하여 익스플로잇해 셸을 획득한 후, “flag” 파일을 읽으세요.
“flag” 파일의 내용을 워게임 사이트에 인증하면 점수를 획득할 수 있습니다.
플래그의 형식은 DH{…} 입니다.
라고 한다. 저기서 등장하는 SSP는 stack smashing protocol이다.
문제를 보면
get_shell()함수를 실행시키는 것을 목적으로 하면 될 것 같다.
main()함수를 보면,
box[0x40], name[0x40], selset[2], idx, name_len이라는 변수를 선언해주고,
while(1) 안에서 switch_case 문을 실행해준다.
switch안에 들어가는 인자는 read함수에서 받아오니 이건 p.send를 써야하겠다... 라는 생각을 하며 진행해보도록 하자.
총 세 가지 기능이 구현되어있는데,
F : fill the box
P : print box value
E : fill name buffer and return.
이렇게 되어있다. 이제 checksec을 해보자.
Canary가 적용되어있으니 어쨋든 Leak을 해주어야할 것 같다. Canary Leak을 하기 위해서는(다른 방법은 아직 모른다..) 스택의 데이터를 출력해주는 함수가 필요한데, 딱 적당하게 P 기능에서 이를 수행해준다.
P 기능 내의 print_box를 살펴보자.
box[idx]는 사실 *(box + idx) 라고 볼 수 있는거니까, box 배열의 base address에서부터 idx만큼 떨어져있는 곳의 데이터를 말하는 것이다. 따라서 이를 이용하면 Canary 값을 읽을 수 있다.
그럼 한번 스택 상황을 보러 가볼까?
일단 처음에, 공간을 0x94만큼 잡아주는 것을 볼 수 있다.
pwndbg를 이용해 까보았더니 cmp eax, 0x50 즉, 'P'에 해당하면, <main + 192>로 jmp 해준다. <main+192>부터 보면, [ebp-0x88]의 주소를 PUSH해서 print_box로 넘겨주는 것을 볼수 있다. 그렇다면, box의 주소는 0x88일테니까,
그림을 그려봐야겠다.
이런 느낌일 것이다.
그렇다면, P기능에서 81개의 아무 데이터나 넣고, 그 다음 3바이트의 canary 값을 받아오면 canary leak을 할 수 있겠다.
그리고, 일단 get_shell의 주소를 받아와야한다.
이렇게 했으면, canary 값도 받아왔고, get_shell의 주소도 구했으니 RET 주소에 get_shell의 주소만 넣으면 되겠다.
이렇게 구성하면 될 것 같다.
이제 실행을 해볼까?
히히 야호~ 성공했다. 끗.