이번 해킹캠프 포너블 출제를 맡은 김서우 입니다.
해당 Write-up은 2018년도 겨울 해킹캠프 포너블 Echo문제에 해당하는 write-up입니다.
간단한 FSB(format string bug)문제입니다.
-----------2018-04-02------12.49.23
메뉴를보면 1.로그인 2.에코 메뉴가 있습니다.

-----------2018-04-02------12.47.42
로그인 메뉴를 살펴보면, id를 최대 20글자 입력받아 앞 5글자가 "HCAMP"를 만족하면 되고,한번이상 입력받으면 전역변수하나를 1로 만들어 더이상 로그인 할 수 없게합니다.

-----------2018-04-02------12.54.29
echo 함수를 살펴보면, 로그인 메뉴에서 입력했던 아이디를 매개변수로 전달받아 printf(a1); 으로 그냥 출력해주는걸 확인할 수 있습니다.
여기서 FSB가 일어날 수 있고, 원하는곳(이미 알고있는 주소)에 원하는 값을 덮어씌울 수 있다고 생각할 수 있습니다.

-----------2018-04-02------12.59.27
또한 system("/bin/cat flag")를 진행해주는 함수가 미리 만들어져 있으므로, 트리거할때 이 함수를 이용하면 되겠습니다.
트리거 방식은 fsb로 exit의 got를 0x400876(system() 콜 하는 함수)으로 변경해주면 쉽게 트리거 가능합니다.

먼저,exit을 바꾸는 이유는, FSB를 진행하려고 봣을때, 페이로드의 길이가 매우 제한적 입니다.id 부분에 페이로드를 넣어야 할 텐데,20글자를 입력받고 그중 앞 5글자는 HCAMP여야 하므로 실질적으로 우리가 쓸 수 있는 페이로드는 15글자 밖에 안됩니다.
GOT 특성상, 한번도 호출되지 않은 함수의 GOT영역에는 해당 함수의 PLT주소+6(_dl_runtime_resolve로 libc내의 함수 주소를 가져오기 위해) 가 들어가 있습니다. 따라서,exit 의 GOT에는 exit의 PLT주소+6 인 0x400766이 들어가 있을 것이고,우리가 호출하기원하는 함수 0x400876과 주소가 다른 부분이 2바이트밖에 없습니다. 그래서 exit을 트리거 함수로 선택할 시,%???$hn과 같은 페이로드로 2바이트만 덮을수 있기 때문에, exit을 트리거로 설정 해야만 풀릴 수 있게 낸것이 원래 의도된 풀이입니다.

앞에 "HCAMP"가 들어가야만 로그인이 되므로, 페이로드 작성시 앞에 꼭 넣고, 0x0876 넣을때 앞에 이미 5바이트가 나왓으므로 5를 뺀 값을 이용해야합니다.
해당 페이로드 파이썬 코드는 다음과 같습니다.
payload = 'HCAMP'
payload += '%2161c%33$hn'
payload += 'A'*7
payload += p64(0x601068)

%2161c는 0x0876을 넣을때 앞에 HCAMP로 이미 5바이트가 나왓으니 0x876-5 = 0x871 = 2161 을 이용한 것이고, 스택에서 8바이트 정렬을 맞추어 오프셋이 딱 떨어지게 사용하기위해 'A'를 임의로 7글자 넣어주고, 그 이후에 exit의 GOT주소인 0x601068을 넣어주면 됩니다. 그럴때 0x601068이 들어가는 해당 위치가 33번째 offset에 해당되고,따라서 페이로드가 %2161c%33$hn 가 됩니다.

-----------2018-04-02------1.13.57

-----------2018-04-02------1.16.39