level 10에서 얻은 패스워드로 로그인한다면 setuid가 걸려있는 attackme 파일과 hint 파일을 볼 수 있다.
hint 파일을 확인해보면 bof에 취약한 strcpy를 통해 인자 값을 str 변수에 복사하는데, 이 str 변수는 256 크기다.
strcpy 함수를 사용하기 때문에 bof 공격을 하면 될 것 같고, 쉘을 얻게 해주는 함수가 따로 없으므로 shellcode를 이용하면 되겠다.
일단 bof 공격이 통하는지를 확인하기 위해 인자로 더미 값을 256byte 넘게 주었다. 그러니 Segmentation fault가 발생한 것을 알 수 있다. bof 공격이 맞는 것 같다.
권한 문제 때문에 attackme 파일은 gdb로 디버깅 할 수 없으므로 tmp 폴더에 소스 코드를 이용해 똑같은 파일을 하나 만들어줬다.
ret의 스택 위치, str의 위치를 확인하기 위해서 gdb로 열고 bp를 걸어줬다.
ret는 0xbffff4ec, str은 0xbffff3e0인 것을 알 수 있다. 즉 ret, str의 사이가 268byte니 쉘 코드와 더미 값으로 채운 다음 ret를 쉘 코드의 위치로 변조하는 방법으로 해도 될 것 같다.
하지만 문제가 있다. attackme 파일은 실행할 때마다 스택 주소가 조금씩 변하는데, 이 때문에 쉘 코드의 위치(str의 주소)로 ret를 변조하기 힘들어진다. 이를 해결하는 방법으로 nop(0x90)을 삽입하는 nop sled 공격도 있지만, 더 간단하게 환경변수에 쉘 코드를 넣은 다음 ret를 해당 환경변수의 주소로 변조하면 된다.
환경변수는 export <환경변수 명> = <내용>을 통해 생성할 수 있다. 삭제는 unset <환경변수 명>을 해주면 된다.
tmp라는 환경변수 안에 쉘 코드를 삽입했다. 그냥 쉘 코드만 넣었을 때는 제대로 exploit이 되지 않아 앞에 \x90을 조금 넣어줬다.
환경변수의 주소는 위와 같은 코드의 프로그램을 컴파일해 구했다. getenv("<환경변수>");를 해주면 해당 환경변수의 주소를 구할 수 있는데, 이 주소를 address에 저장하고 %p 서식 지정자로 출력했다.
위 프로그램을 통해 환경변수의 주소가 0xbffffe0f인 것을 알아냈으니 ret를 이 주소로 변조한다면 쉘을 얻을 수 있을 것이다.
python으로 더미 값 'A'를 268byte만큼 삽입하고 ret를 0xbffffe0f로 overwrite하니 쉘을 얻은 것을 볼 수 있다.
'Wargame > FTZ' 카테고리의 다른 글
[FTZ] level 13 (0) | 2021.06.04 |
---|---|
[FTZ] Level 12 (0) | 2021.05.29 |
[FTZ] Level 10 (0) | 2021.05.28 |
[FTZ] Level 9 (0) | 2021.05.10 |
[FTZ] Level 6 ~ Level 8 (0) | 2021.03.28 |