본문 바로가기

SYSTEM HACKING

[SWING] Pwnable 03 - PLT&GOT

라이브러리

 

 

링크

 

#include <stdio.h>
int main() {
  puts("Hello, world!");
  return 0;
}

 

PLT&GOT

 

Procedure Linkage Table & Global Offset Table

라이브러리에서 동적 링크된 심볼의 주소를 찾을 때 사용하는 테이블

 

runtime resolve

바이너리 실행 -> ASLR이 라이브러리 임의 주소에 매핑

-> 라이브러리 함수 호출 시 함수 이름으로 라이브러리에서 심볼 탐색

-> 함수 정의 발견된 주소로 실행 흐름 옮김

 

반복적으로 호출되는 함수의 정의 매번 탐색하는 것은 비효율적

-> ELF는 GOT 테이블에 resolve된 함수의 주소를 저장

-> 나중에 함수 호출되면 저장된 주소 꺼내서 사용

 

#include <stdio.h>
int main() {
  puts("Resolving address of 'puts'.");
  puts("Get address from GOT");
}

 

resolve 되기 전

 

 

아직 puts 주소를 찾기 전이므로 puts GOT 엔트리 0x404018에는 함수 주소 대신 .plt 섹션 어딘가의 주소 0x401030이 적혀있다.

 

main()에서 puts@plt 호출하는 지점에 종단점 설정하고 내부로 따라간다.

 

 

PLT에서는 puts의 GOT 엔트리 값 0x401030으로 실행 흐름을 옮긴다.

 

 

pwndbg 컨텍스트 DISASM은 프로그램에서 명령어가 호출되는 순서인 제어 흐름(Control flow) 보여준다.

실행 흐름을 따라가면 puts 주소를 구하고, GOT 엔트리에 주소를 쓰는 함수 _dl_runtime_resolve_fxsave가 호출될 것이다.

 

ni를 반복 수행해서 _dl_runtime_resolve_fxsave 안으로 진입하자.

7번쯤 하면 된다.

 

 

 

finish 명령어로 함수를 빠져나오면,

puts GOT 엔트리에 libc 영역 내 실제 puts 주소인 0x7ffff7e02ed0가 쓰여있다.

 

resolve 된 후

 

puts@plt 두번째 호출할 때는 바로 puts가 실행된다.

puts GOT 엔트리에 libc 영역 내 실제 puts 주소인 0x7ffff7e02ed0가 쓰여있기 때문이다.

 

 

PLT & GOT는 동적 링크된 바이너리에서 라이브러리 함수 주소를 찾고 기록할 때 사용되는 중요한 테이블이다.

그러나 PLT에서 GOT를 참조해 실행 흐름을 옮길 때 GOT 값을 검증하지 않는 취약점이 있다.

 

앞에서 puts GOT 엔트리에 저장된 값을 공격자가 임의로 변경할 수 있었다면, puts 호출 시 원하는 코드를 실행할 수 있다.

 

GOT 엔트리에 저장된 값을 임의로 변조할 수 있는 수단이 있다고 가정하고 gdb로 실험을 해보자.

got 바이너리에서 main() 내 두번째 puts 호출 직전에 puts GOT 엔트리를 "AAAAAAAA"로 변경하고 실행하면 실제 실행 흐름이 "AAAAAAAA"로 옮겨진다.

 

 

GOT Overwrite

GOT 엔트리에 임의의 값을 오버라이트하여 실행 흐름을 변조하는 공격 기법

일반적으로 임의 주소에 임의의 값을 오버라이트하는 수단을 가지고 있을 때 수행

 

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

[SWING] Pwnable 04 - ptmalloc2  (0) 2023.11.11
[SWING] Pwnable 04 - Format String Bug  (0) 2023.11.11
[SWING] Pwnable 03 - NX&ASLR  (0) 2023.09.25
[SWING] Pwnable 03 - 스택 카나리  (0) 2023.09.25
[SWING] Pwnable 02 - Stack Buffer Overflow  (0) 2023.09.25