
๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฝ๋๋ฅผ ๋ถ์ํ๋ฉด์ ์ด๋ค ๋ฐฉ์์ผ๋ก ํ๋ก์ธ์ค๋ฅผ ์ข ๋ฃํ๋์ง ์์๋ณด์.
_rtld_global ์ค์ต ์์
// Name: rtld.c
// Compile: gcc -o rtld rtld.c
int main() {
return 0;
}
๋ค์์ ์ฝ๋๋ ์ข ๋ฃํ๋ ๊ณผ์ ์ ์์๋ณด๊ธฐ ์ํ ์์ ์ฝ๋์ด๋ค.
_rtld_global
__Gl_exit
์์ ์ปดํ์ผ ํ ์์ ์ฝ๋๋ ๋ณ๋ค๋ฅธ ์ฝ๋๋ฅผ ์คํํ์ง ์๊ณ ํ๋ก๊ทธ๋จ์ ์ข ๋ฃํ๋ค.
๋๋ฒ๊น ์ ํตํด ๋ ์์ธํ ์์๋ณด์.
main ํจ์ ๋ด์ ๋ฆฌํดํ๋ ๋ช ๋ น์ด์ ๋ธ๋ ์ดํฌ ํฌ์ธํธ๋ฅผ ์ค์ ํ๋ค.
step into (si)๋ฅผ ํตํด ๋ค์ ์ฝ๋๋ฅผ ํ์ธํ๋ค.
๋๋ฒ๊น ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ณด๋ฉด, main ํจ์ ๋ด์์ ๋ฆฌํด ๋ช ๋ น์ด๋ฅผ ์คํํ์ ๋ ์คํ ์ต์๋จ์ ์๋ __libc_start_main+231 ์ ์ฝ๋๊ฐ ์คํ๋๊ณ , ๋ด๋ถ์์ __GI_exit ํจ์๋ฅผ ํธ์ถํ๋ ๊ฑธ ์ ์ ์๋ค.
๋ค์์ __GI_exit ํจ์ ๋ด๋ถ์ ๋ชจ์ต์ด๋ค.
๋ ๋ค๋ฅธ __run_exit_handlers ํจ์๋ฅผ ํ์ธํ ์ ์๋ค. ํด๋น ํจ์๋ ์ฝ๋์ ํฌ๊ธฐ๊ฐ ํฌ๋ฏ๋ก, ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฝ๋๋ฅผ ํตํด ๋ถ์ํด๋ณด์.
__run_exit_handlers
๋ค์์ __run_exit_handlers ํจ์์ ์ฝ๋์ด๋ค.
void
attribute_hidden
__run_exit_handlers (int status, struct exit_function_list **listp,
bool run_list_atexit, bool run_dtors)
{
const struct exit_function *const f = &cur->fns[--cur->idx];
switch (f->flavor)
{
void (*atfct) (void);
void (*onfct) (int status, void *arg);
void (*cxafct) (void *arg, int status);
case ef_free:
case ef_us:
break;
case ef_on:
onfct = f->func.on.fn;
#ifdef PTR_DEMANGLE
PTR_DEMANGLE (onfct);
#endif
onfct (status, f->func.on.arg);
break;
case ef_at:
atfct = f->func.at;
#ifdef PTR_DEMANGLE
PTR_DEMANGLE (atfct);
#endif
atfct ();
break;
case ef_cxa:
cxafct = f->func.cxa.fn;
#ifdef PTR_DEMANGLE
PTR_DEMANGLE (cxafct);
#endif
cxafct (f->func.cxa.arg, status);
break;
}
}
exit_function ๊ตฌ์กฐ์ฒด์ ๋ฉค๋ฒ ๋ณ์์ ๋ฐ๋ฅธ ํจ์ ํฌ์ธํฐ๋ฅผ ํธ์ถํ๋ ๊ฑธ ํ์ธํ ์ ์๋ค.
๋ฆฌํด ๋ช ๋ น์ด๋ฅผ ์คํํด ํ๋ก๊ทธ๋จ์ ์ข ๋ฃํ๋ค๋ฉด _dl_fini ํจ์๋ฅผ ํธ์ถํ๋ค.
exit_function ๊ตฌ์กฐ์ฒด์ ๋ชจ์ต์ ๋ค์๊ณผ ๊ฐ๋ค.
struct exit_function
{
/* `flavour' should be of type of the `enum' above but since we need
this element in an atomic operation we have to use `long int'. */
long int flavor;
union
{
void (*at) (void);
struct
{
void (*fn) (int status, void *arg);
void *arg;
} on;
struct
{
void (*fn) (void *arg, int status);
void *arg;
void *dso_handle;
} cxa;
} func;
};
_dl_fini
๋ค์์ ๋ก๋์ ์กด์ฌํ๋ _dl_fini ํจ์ ์ฝ๋์ ์ผ๋ถ์ด๋ค.
# define __rtld_lock_lock_recursive(NAME) \
GL(dl_rtld_lock_recursive) (&(NAME).mutex)
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));
์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด, _dl_load_lock ์ ์ธ์๋ก __rtld_lock_lock_recursive ํจ์๋ฅผ ํธ์ถํ๋ ๊ฑธ ํ์ธํ ์ ์๋ค.
๋งคํฌ๋ก๋ฅผ ํ์ธํด๋ณด๋ฉด, ํด๋น ํจ์๋ dl_rtld_lock_recursive๋ผ๋ ํจ์ ํฌ์ธํฐ์์ ์ ์ ์๋ค.
ํด๋น ํจ์ ํฌ์ธํฐ๋ _rtld_global ๊ตฌ์กฐ์ฒด์ ๋ฉค๋ฒ ๋ณ์์ด๋ค.
ํด๋น ๊ตฌ์กฐ์ฒด๋ ๋งค์ฐ ๋ฐฉ๋ํ๊ธฐ ๋๋ฌธ์ ํจ์ ํฌ์ธํฐ์ ์ ๋ฌ๋๋ ์ธ์์ธ dl_load_lock ๋ง์ ์ดํด๋ณด์.
_rtld_global
๋ค์์ gdb์์ _rtld_global ๊ตฌ์กฐ์ฒด๋ฅผ ์ถ๋ ฅํ ๋ชจ์ต์ด๋ค. ๊ตฌ์กฐ์ฒด ๋ด _dl_rtld_lock_recursive ํจ์ ํฌ์ธํฐ์๋ rtld_lock_default_lock_recursive ํจ์ ์ฃผ์๋ฅผ ์ ์ฅํ๊ณ ์๋ค.
๊ตฌ์กฐ์ฒด์ ํจ์ ํฌ์ธํฐ๊ฐ ์ ์ฅ๋ ์์ญ์ ์ฝ๊ธฐ ๋ฐ ์ฐ๊ธฐ ๊ถํ์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ๋ฎ์ด์ฐ๋ ๊ฒ ๋ํ ๊ฐ๋ฅํ๋ค.
_rtld_global ์ด๊ธฐํ
๋ค์์ ํ๋ก์ธ์ค๋ฅผ ๋ก๋ํ ๋ ํธ์ถ๋๋ dl_main ์ฝ๋์ ์ผ๋ถ์ด๋ค.
static void
dl_main (const ElfW(Phdr) *phdr,
ElfW(Word) phnum,
ElfW(Addr) *user_entry,
ElfW(auxv_t) *auxv)
{
GL(dl_init_static_tls) = &_dl_nothread_init_static_tls;
#if defined SHARED && defined _LIBC_REENTRANT \
&& defined __rtld_lock_default_lock_recursive
GL(dl_rtld_lock_recursive) = rtld_lock_default_lock_recursive;
GL(dl_rtld_unlock_recursive) = rtld_lock_default_unlock_recursive;
_rtld_global ๊ตฌ์กฐ์ฒด์ dl_rtld_lock_recursive ํจ์ ํฌ์ธํฐ๊ฐ ์ด๊ธฐํ๋๋ ๊ฑธ ํ์ธํ ์ ์๋ค.
'DreamHack > SystemHacking' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[DreamHack System Hacking] Linux Library exploit > __environ (0) | 2022.09.21 |
---|---|
[DreamHack System Hacking] Linux Library exploit > overwrite _rtld_global (1) | 2022.09.21 |
[DreamHack System Hacking] master_canary (0) | 2022.09.19 |
[DreamHack System Hacking] Master Canary - (2) (0) | 2022.09.19 |
[DreamHack System Hacking] Master Canary - (1) (0) | 2022.09.19 |