ELF Technique - GOT Overwrite
GOT Overwrite란?
Dynamic Link 방식으로 컴파일된 바이너리가 공유 라이브러리를 호출할 때 사용되는 PLT와 GOT를 이용하는 공격 기법이다.
GOT Overwrite는 간단하게 설명하면 printf("/bin/sh") -> system("/bin/sh") 처럼
특정 함수의 got 값을 변경하여 원래 수행하고자 했던 함수외에 다른 함수를 호출하는 것을 말한다.
이를 실습하기 위해 간단한 바이너리를 만들었다.
[Got_Overwrite.c]
#include <stdio.h>
int main()
{
printf("/bin/sh");
return 0;
}
컴파일을 할때 gcc 옵션으로 카나리와 nx bit를 제거하였다.
물론 ASLR도 꺼줬다.
$ gcc -o Got_Overwrite Got_Overwrite.c -z execstack -fno-stack-protector
gdb를 이용하여 실습을 할 수 있다.
먼저
gdb에 아까 작성한 바이너리를 올리고 disas main으로 printf 함수의 plt를 구한다.
<main+25> 부분에 0x80482e0 이라는 printf함수의 plt 주소를 볼 수 있다.
그리고 main에 bp를 걸고 실행을 하여 printf()의 got를 확인한다.
x/3i [plt_address] 로 plt 주소의 instruction을 확인해보면 GOT안에 있는 값으로 jmp하는 것을 볼 수 있다.
이 GOT값을 system()의 실제 주소로 Overwrite 하면
printf("/bin/sh") ==> system("/bin/sh") 가 되고, 결과적으로 쉘을 실행시킨다.
got값을 변경하기 위해서는 gdb 명령어인 set을 사용하면 된다.
이상 GOT Overwrite에 대한 정리를 마친다.