level11과 비슷하게 로그인 후 ls 명령어를 통해 파일 들을 확인해보면 setuid가 걸린 파일 attackme와 hint가 존재하는 것을 알 수 있다. hint에는 attackme의 소스코드가 들어있다.
딱 봐도 알 수 있듯이 bof에 취약한 함수 gets를 쓴다. 입력을 받는 변수는 256byte 크기의 char형 배열 str이지만 gets 함수는 입력 값의 길이를 제한해주지 않기 때문에 256byte 넘는 입력 값을 준다면 stack bufferoverflow가 발생할 것이다.
마찬가지로 쉘을 얻게 해주는 함수가 없으므로 환경 변수에 쉘 코드를 넣고 ret를 해당 환경 변수로 overwrite하는 방법으로 exploit하면 될 것 같다.
ret와 str 배열의 거리를 확인하기 위해 hint에 나온 소스코드를 이용해 tmp 폴더에 attackme와 똑같은 프로그램을 빌드하고 gdb로 열어봤다.(attackme 문제 파일은 권한 문제 때문에 디버깅을 할 수 없다.)
main 함수의 시작 위치, gets 함수 호출 전에 각각 bp를 걸고 실행한다면 각각의 스택 주소를 알 수 있다.
ret : 0xbfffe2dc
str : 0xbfffe1d0
따라서 둘의 거리는 268byte다.
그렇다면 268byte만큼 더미 값으로 채워주고 ret를 쉘 코드가 들어있는 환경 변수로 바꿔준다면 level13 shell을 얻을 수 있을 것이다.
"\x31\xc0\x31\xdb\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\xb0\x01\xcd\x80"
python을 이용해 환경변수 lev12에 쉘 코드를 넣었다.
환경변수의 주소를 알아내야하므로 getenv를 이용해 lev12 환경변수의 주소를 구해주는 코드를 작성하고 빌드했다.
위의 소스코드로 빌드된 프로그램을 실행해보면 lev12 환경변수의 주소가 0xbffffe5d인 것을 알 수 있다.
그렇다면 payload는 (더미 값)*268 + (0xbffffe5d)로 구성된다.
단 주의할 점은 이번 문제는 lev11과 달리 인자로 입력 값을 받는게 아닌, gets 함수를 통해 입력을 받으므로 |를 이용해서 입력 값을 전달해줘야한다.
exploit 코드의 마지막에 ; cat을 써준 이유는 쉘을 얻자마자 프로그램이 종료되는 것을 방지하고 사용자가 입력한 쉘 명령어를 전달하기 위해서다.
'Wargame > FTZ' 카테고리의 다른 글
[FTZ] level 14 (0) | 2021.06.04 |
---|---|
[FTZ] level 13 (0) | 2021.06.04 |
[FTZ] Level 11 (0) | 2021.05.28 |
[FTZ] Level 10 (0) | 2021.05.28 |
[FTZ] Level 9 (0) | 2021.05.10 |