본문 바로가기

system/material

return-to-dynamic-linker

return-to-dl-resolve

return-to-dynamic-linker

  • x86

    • Elf32_Rel (8 byte)
    • Elf32_Sym (16 byte)
  • x64

    • Elf64_Rela (24 byte)

    https://code.woboq.org/userspace/glibc/elf/elf.h.html#659

    • Elf64_Sym (24 byte)

    https://code.woboq.org/userspace/glibc/elf/elf.h.html#528

 

lazy binding을 악용하여 공격할 수 있는 기법이다.

이에 쓰이는 JMPREL, SYMTAB의 구조는 위와 같고 이를 공격하는 것이다!

 

일단 64비트 기준으로 lazy binding 과정을 간단하게 설명하면 다음과 같다.

 dl_resolve(link_map, reloc_offset)

    • reloc_offset을 참조하여 JMPREL 접근
  1. JMPREL + reloc_offset*24(r_offset, r_info)

    • r_info를 참조하여 SYMTAB 접근
  2. SYMTAB + r_info*24(st_name, st_info, st_shndx, st_value, st_size)

    • st_name을 참조하여 STRTAB 접근
  3. STRTAB+st_name

    • 최종적으로 부를 함수의 이름을 가져옴
  4. 가져온 함수의 실제 라이브러리 영역으로 점프

 

좀 많이 이상하게 설명한 것 같은데.. 일단 내가 볼거니 추후 수정하도록 하겠다.

 

64비트 ret2dl의 경우 version 확인 코드를 우회해야 한다. 즉, 32비트 ret2dl과 다르게 libcleak해야 한다..

dt_versym0으로 때려버리면 나머지는 32비트와 똑같다.

 

예제로는 https://1ce0ear.github.io/2017/10/20/return-to-dl/ 여기의 bug.c를 64비트 ret2dl로 한 번 풀어보았다.

 

32비트 버전도 한 번 풀어보았다.

32비트는 dt_versym이 문제가 없을 줄 알았는데 문제가 있어서 이거때문에 삽질을 정말 많이했다..

 

위 코드가 dt_versym을 체크하는 코드다.

&l->l_versions[ndx]에 접근하면서 터지는데, 이는 bss+0x200같이 적은 곳에 쓰는게 아니라 bss+0x800같이 높은 곳에 써주면 해결된다.

왜 그런지 이유는 모르겠다.. 왜냐면 저 메모리는 readonly라서 바뀔리가 없기 때문이다..

 

어쨋든 일단 32비트로도 풀어봤다.


 

ref

https://1ce0ear.github.io/2017/10/20/return-to-dl/

https://www.lazenca.net/display/TEC/01.Return-to-dl-resolve+-+x86

https://www.lazenca.net/pages/viewpage.action?pageId=19300744


'system > material' 카테고리의 다른 글

peda special instruction  (0) 2019.11.11
linux kernel module 작성해보기  (0) 2019.11.11
unsortedbinbin_attck died..  (0) 2019.11.05
linux file structure attack  (0) 2019.10.28
ethereum assembly analysis using remix DEBUGGER plugin  (0) 2019.10.16