GOT Overwrite는 Dynamic Link 방식으로 컴파일된 바이너리가 공유 라이브러리를 호출할 때 사용하는 PLT(Procedure Linkage Table)와 GOT(Global Offset Table)를 이용하여 최종적으로 GOT의 주소값을 변조하는 공격 기법입니다.
Dynamic Link로 컴파일된 바이너리 파일은 함수를 호출 할 때 시스템의 공유 라이브러리를 참고하는데, GOT의 주소를 참조하는 PLT와 실제 함수의 주소값이 들어있는 GOT를 이용해 PLT가 참조하는 GOT의 값을 공격자가 원하는 함수의 주소로 변조하여 해당 바이너리에 존재하지 않는 공격자가 원하는 함수를 실행할 수 있습니다.
해당 글에서는 간단하게 GOT Overwrite을 실습 해보겠습니다.
취약한 코드 생성
아래 코드는 gets 함수로 buf의 값을 사용자가 입력하고 puts 함수로 buf의 값을 출력하는 프로그램입니다.
//got.c
#include <stdio.h>
int main(void) {
char buf[20];
gets(buf);
puts(buf);
return 0;
}
컴파일 할 때는 아래의 옵션을 사용합니다.
$ gcc -m32 -no-pie -fno-pic -o got got.c
Exploit
puts 함수의 GOT에 system 함수의 주소를 덮어씌우고 gets 함수에서 사용자가 입력한 값을 system 함수로 실행시키게 하는것이 목표이다.
gef➤ disas 0x400980
Dump of assembler code for function setvbuf@plt:
0x0000000000400980 <+0>: jmp QWORD PTR [rip+0x20363a] # 0x603fc0 <setvbuf@got.plt>
0x0000000000400986 <+6>: push 0xc
0x000000000040098b <+11>: jmp 0x4008b0
End of assembler dump.