/*
The Lord of the BOF : The Fellowship of the BOF
- orge
- check argv[0]
*/
#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);
}
// here is changed!
if(strlen(argv[0]) != 77){
printf("argv[0] 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[0] 길이 검사하는 부분이 추가되었다.
argv[0]은 ./orge AA BB 에서 ./orge가 해당된다.
따라서 argv[0]의 길이가 77이 되야하니까 ./(2글자)를 제외한 파일면 75글자로 만들면된다.
-> ./ 도 포함된다는 걸 몰라서 파일명 77글자로 하다가 삽질함..
python을 이용해 파일명 변경 ㄱㄱ
[그림 1-2] 보면 argv[0] 조건문을 통관하는걸 알 수 있다.
그 후로는 이전 문제랑 동일하다.
1. argv로 입력
2. argv[0] == 77
3. 환경변수 x
4. argv[1] 48번째 글자 \xbf
5. argv[1] 길이 48 이하
[그림 1-3] 과 위 조건들을 생각해서 payload를 짜면 payload = nop(19) + shellcode(25) + argv[1] 위치(4) 된다.
argv[1] 위치를 찾자!
r "`python -c 'print("B"*44+"\xbf\xbf\xbf\xbf")'`" 입력해 B 위치를 찾아보면 0xbffffbf1 위치에 들어간다. -> argv[1] 추측됨
payload를 완성하고 exploit 하니 segmentation 뜸..
스택 주소를 구할 때 gdb를 통해 실행(r) 시켰을 때와 실제 프로그램의 스텍 주소는 차이가 있어서 core 파일을 분석해서 payload가 어디로 들어갔는지 확인을 해야한다. -> core 파일을 분석해보면 실제 프로그램의 적제된 스텍 주소를 알 수 있다!
-c 옵션은 필요하다.
x/100x $esp-1000 입력해서 눈 빠지게 찾다보면 0xbffffb9e 주소에 argv[1] 값이 들어가 있다. 따라서 payload에서 ret 값을 0xbffffb9e 주소로 바꿔준다.
성공! -> 파일명을 안바꾸고 심볼릭 링크를 걸어서 풀 수 도 있다..!
참고 블로그