GOT Overwrite는 Dynamic Linking으로 생성된 실행파일이 공유라이브러리를 호출할 때 사용하는 GOT 값을 조작하는 공격 기법입니다.
GOT에는 실제 함수들의 주소가 존재하는데, 만약 호출하려고 하는 함수의 GOT값을 다른 함수의 GOT 값으로 변경하면 다른 함수가 호출되게 됩니다.
예를 들어 printf 함수를 호출했는데, printf 함수의 GOT 값을 system 함수의 GOT 값으로 바꿔버리면 system 함수가 호출됩니다.
실습을 한번 해보겠습니다.
#include <stdio.h>
int main() {
printf("cat flag");
return 0;
}
원래는 printf() 함수를 호출하여 cat flag를 출력하는 프로그램 입니다.
여기서 printf()와 system()의 got 값을 출력하고
gdb-peda$ elfsymbol printf
Detail symbol info
printf@reloc = 0
printf@plt = 0x8049030
printf@got = 0x804c00c
gdb-peda$ print system
$2 = {int (const char *)} 0xf7dffd00 <__libc_system>
printf()의 got 값을 system()의 got 값으로 덮어 씌워보면
gdb-peda$ set *0x804c00c=0xf7dffd00
gdb-peda$ continue
system("cat flag")가 실행이 되어 flag 값이 출력됩니다.
Continuing.
[Attaching after process 2188 vfork to child process 2194]
[New inferior 2 (process 2194)]
[Detaching vfork parent process 2188 after child exec]
[Inferior 1 (process 2188) detached]
process 2194 is executing new program: /usr/bin/dash
[Attaching after process 2194 vfork to child process 2195]
[New inferior 3 (process 2195)]
[Detaching vfork parent process 2194 after child exec]
[Inferior 2 (process 2194) detached]
process 2195 is executing new program: /usr/bin/cat
Hello World~
[Inferior 3 (process 2195) exited normally]
⚡ ⚙ root ~/pwnable/tech/GOT cat flag
Hello World~