0. 후기
그닥 어렵지 않았다. level11과 level12를 풀어서 level13도 어렵지 않게 풀이를 생각해 냈다. 어느 정도 풀어놓고 level11부터 풀이를 쓰느라 잊고 있었는데 level13을 풀면서 main함수가 끝나고 복귀하는 부분을 조작하는걸 이 때 이해했다.
1. 문제 파악하기
바로 힌트부터 봤다.
2. 코드 해석
#include<stdlib.h>
main(int argc, char *argv[])
{
long i=0x1234567;
char buf[1024];
setreuid(3094,3094);
// 프로그램을 실행할 떄 넣어준 인자의 수가 2개 이상이면 buf에 첫번째 인자를 넣어준다.
if(argc>1)
strcpy(buf,argv[1]);
// 오버플로우가 발생하면 프로그램을 바로 죽임
if(i != 0x1234567) {
printf("Warnning: Buffer OverFlow !!! \n");
kill(0,11);
}
}
level11과 같은 함수를 이용해서 프로그램의 인자를 복사하는건 같지만 오버플로우 발생 여부를 검증하는 코드가 추가됐다. 그러면 추가로 0x1234567까지 신경쓰면서 값을 덮어 써주면 된다.
3. gdb 확인
1048바이트 만큼 스택을 확보한 모습을 볼 수 있고, ebp-12가 i인 것도 확인할 수 있다. 변수 별 스택 크기를 예상해 보면
buf : 1024 + 12(dummy)
i : 4 + 8(dummy)
이렇게 예상할 수 있다.
확인을 위해 프로그램 인자를 복사하고 오버플로우를 확인하는 부분(main+69)에 bp를 걸고 인자로 A문자 1024개 넣고 실행을 하면
내가 예상한 것과 같이 쓸데없는 값이 들어가 있는 것을 확인 할 수 있다. 그리고 빨간거 두개가 앞에는 ebp이고 뒤에가 main 함수의 복귀 주소이다.
스택 상황을 정리해 보면 이렇다.
4. 귀환할 주소 찾기
level11에서 했던 것처럼 argv에서 쉘코드를 실행할 거기 때문에 argv위치를 찾아봤다. 찾기 위해서 내가 입력할 페이로드만큼 A를 넣어야 한다.
그래서 1056(1048 + 4 + 4)만큼 A 문자를 넣어줬다. 그리고 중간에 0x1234567이 잘 들어가는지도 확인해 보기 위해 넣어 봤다.
잘 들어간다.
5. 페이로드 작성
위에 귀환할 주소를 토대로 페이로드를 작성했다.
"\X90"을 1011개 넣은 이유는 1036바이크 만큼의 크기에서 25바이트는 쉘코드를 넣어야 하기 때문이다.
그 뒤에 쉴코드를 넣고, 바로 0x1234567도 넣어준다.
그리고 아무 문자 12개 넣어주고 복귀할 주소를 넣어줬다.
6. 정답
'문제 풀이 > Hackerschool FTZ' 카테고리의 다른 글
FTZ - level12 (1) | 2024.09.25 |
---|---|
FTZ - level10 (0) | 2024.08.03 |
FTZ - level9 (0) | 2024.08.02 |
FTZ - level8 (0) | 2024.08.02 |
FTZ - level7 (0) | 2024.07.31 |