含__attribute__((constructor))与函数指针的漏洞代码技术问询
漏洞代码分析与疑问解答
先贴出完整代码:
#include <stdio.h> #include <string.h> //Ignore this thing __attribute__((constructor)) void setup(){ setvbuf(stdout,NULL,2,0); setvbuf(stderr,NULL,2,0); setvbuf(stdin,NULL,2,0); } int main() { printf("What's you name?\n"); char name[100]; fgets(name,100,stdin); void(*Kekpointer)() = (void(*)())&name; Kekpointer(); return 0; }
核心疑问解析
1. void(*Kekpointer)() 是什么类型的指针?
这是指向「无参数、返回值为void的函数」的指针,也就是标准的函数指针。
拆解语法逻辑:
- C语言中
()的优先级高于*,必须用括号把*Kekpointer括起来——如果写成void* Kekpointer(),会被解释成「返回void指针的函数」,和函数指针完全是两回事。 - 完整结构
void (*指针变量名)()的含义是:该指针存储的地址指向一个函数,这个函数不需要输入参数,执行后也不返回任何值。 - 正常情况下这类指针用来存储合法函数的地址,通过指针调用函数;但这段代码把栈数组的地址塞进去,强行当成函数地址来用。
2. (void(*)())&name 是类型转换吗?
是的,这是强制类型转换,目的是把数组指针转换成函数指针。
&name取的是栈数组name的首地址,它的原生类型是char (*)[100](指向包含100个char元素的数组的指针)。(void(*)())是强制转换的目标类型,也就是前面说的「无参数、返回void的函数指针」。- C语言不允许不同类型的指针直接赋值,所以必须通过强制转换绕过类型检查,才能把
&name的值赋值给Kekpointer。
3. __attribute__((constructor)) 修饰的setup函数影响漏洞吗?
完全不影响漏洞的核心逻辑,它只是个辅助调试的工具。
__attribute__((constructor))是GCC的扩展属性,作用是让被修饰的函数在main()执行之前自动运行。- 这里的setup函数调用
setvbuf把标准输入、输出、错误流都设置为无缓冲模式(参数2对应_IONBF),目的是让printf的提示信息立刻显示在终端,不会因为缓冲区缓存导致调试时看不到输出。 - 它既不会改变栈的执行权限,也不会影响输入存储或函数指针的调用逻辑,对漏洞利用没有直接作用。
漏洞原理与利用思路
这段代码的致命漏洞在于直接将栈上数组的地址当作函数指针调用:
- 数组
name存放在栈中,当用户输入的内容是可执行的机器指令(即shellcode)时,调用Kekpointer()就会跳转到栈上执行这段指令。 - 利用的前提是程序运行环境允许栈执行代码:现代操作系统默认开启DEP(数据执行保护)禁止栈执行,所以需要编译时加
-z execstack选项关闭栈保护,或者目标系统本身未开启DEP。 - 实际利用时,只需输入对应架构的shellcode(比如x86架构的
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80),就能触发远程shell。
内容的提问来源于stack exchange,提问作者Haaziq Jamal
相关产品推荐
相关产品推荐

