Exit handler overwrite

chk_pass·2024년 4월 15일
0

glibc 2.34이후 훅변수가 사라지면서 aaw 취약점이 있어도 덮을 곳이 사라지는 문제가 생겼다. 이런 상황에서 보통 libc got를 덮는 방법도 많이 쓰지만 또 다른 방법을 소개하고자 한다.
바로 exit_handler함수를 이용하는 방법이다.
인자를 직접 지정해줄 수 있으므로 활용성이 좋고, libc got를 덮으면 오류가 나는 상황에서 활용할 수 있다.



조건: 총 2번의 aaw가 가능할 때 ⇒ libc_base필요(fs_base와 initial은 모두 libc 기준으로 구할 수 있음)


<익스 시나리오>

  1. fs_base+0x30의 위치에 p64(0) 덮기 (덮을 수 없다면 값을 leak해도 됨)
  2. initial+0x10에 p64(4), initial+0x18에 호출하고 싶은 함수를 0x11만큼 rol한 값 , initial+0x20에 인자 주소 덮기
  3. exit함수 실행




<원리>

exit함수 내부의 __run_exit_handler는 특정 루틴 상 initial+0x18 포인터 값을 가져와 demangling과정(0x11만큼 ror하고 fs+0x30의 값과 xor함)을 거친 후 initial+0x20을 인자로 하여 실행됨.

<__run_exit_handler> 어셈블리 코드 내부>

  1. rcx (=initial+0x10)이 4라면 +208의 위치로 jmp

  1. 마지막에 rdi에 r13을 넣고 rax실행

rax는 무엇인가?(함수포인터) ⇒ initial+0x18위치의 값을 가져온다음 0x11만큼 ror하고 fs+0x30의 값과 xor한 값에 해당.

r13은 무엇인가?(인자)⇒ +215를참고하면 initial+0x20에 해당

0개의 댓글