【发布时间】:2021-02-03 02:22:50
【问题描述】:
我最近阅读了 D_FORTIFY_SOURCE 以及它对易受攻击的函数所做的更改。我想弄乱它,因此制作了一个小的测试二进制文件。
测试二进制源代码为:
#include <stdio.h>
#include <stdlib.h>
//No ASLR/PIE
//Enable FORTIFY
//
//
//
void shell()
{
system("sh");
}
int flag = 0;
int main(int argc, char * argv[])
{
char buf [256];
fgets(buf, sizeof(buf), stdin);
printf(buf);
if(flag)
{
shell();
}
}
它不是为了做任何事情,只是为了尝试对 printf 的保护。
但是,当我编译程序时,它似乎并没有被“强化”
确切的 gcc 命令是:
gcc fsFORTIFIED.c -o fsFORTIFIED -m32 -no-pie -D_FORITFY_SOURCE=2 -O2
我确保设置了优化标志,但标准的 printf 函数仍然存在。 GDB给出了main的汇编:
0x080491c6 <+0>: lea ecx,[esp+0x4]
0x080491ca <+4>: and esp,0xfffffff0
0x080491cd <+7>: push DWORD PTR [ecx-0x4]
0x080491d0 <+10>: push ebp
0x080491d1 <+11>: mov ebp,esp
0x080491d3 <+13>: push esi
0x080491d4 <+14>: push ebx
0x080491d5 <+15>: push ecx
0x080491d6 <+16>: sub esp,0x120
0x080491dc <+22>: call 0x80490e0 <__x86.get_pc_thunk.bx>
0x080491e1 <+27>: add ebx,0x2e1f
0x080491e7 <+33>: mov eax,gs:0x14
0x080491ed <+39>: mov DWORD PTR [ebp-0x1c],eax
0x080491f0 <+42>: xor eax,eax
0x080491f2 <+44>: mov eax,DWORD PTR [ebx-0x8]
0x080491f8 <+50>: push DWORD PTR [eax]
0x080491fa <+52>: push 0x100
0x080491ff <+57>: lea esi,[ebp-0x11c]
0x08049205 <+63>: push esi
0x08049206 <+64>: call 0x8049050 <fgets@plt>
0x0804920b <+69>: mov DWORD PTR [esp],esi
0x0804920e <+72>: call 0x8049040 <printf@plt>
0x08049213 <+77>: add esp,0x10
0x08049216 <+80>: cmp DWORD PTR [ebx+0x2c],0x0
0x0804921d <+87>: jne 0x804923b <main+117>
0x0804921f <+89>: mov eax,DWORD PTR [ebp-0x1c]
0x08049222 <+92>: sub eax,DWORD PTR gs:0x14
0x08049229 <+99>: jne 0x8049242 <main+124>
0x0804922b <+101>: mov eax,0x0
0x08049230 <+106>: lea esp,[ebp-0xc]
0x08049233 <+109>: pop ecx
0x08049234 <+110>: pop ebx
0x08049235 <+111>: pop esi
0x08049236 <+112>: pop ebp
0x08049237 <+113>: lea esp,[ecx-0x4]
0x0804923a <+116>: ret
0x0804923b <+117>: call 0x80491a6 <shell>
0x08049240 <+122>: jmp 0x804921f <main+89>
0x08049242 <+124>: call 0x80492d0 <__stack_chk_fail_local>
在这里,我希望调用 printf_chk@plt,但它却调用了 printf@plt。 为了确保这一点,我运行了程序,并给它输入了 %3$x,它运行良好而不是停止。
我的问题是,为什么 GCC 没有正确实现 D_FORITFY_SOURCE,即使设置了优化标志?
感谢您的帮助
【问题讨论】:
-
D_FORITFY_SOURCE-->D_FORTIFY_SOURCE -
先尝试
gcc -v,但请阅读GCC的文档;也许也可以问gcc-help@gcc.gnu.orgmailing list -
您在未编辑代码的情况下编辑了问题中的命令。您是否复制/粘贴了两次,或者您实际运行的内容仍然存在拼写错误?
-
@PeterCordes 啊,我很抱歉。经过检查,原来的命令似乎确实有拼写错误(我以为只是在这篇文章中),这就是它无法通过检查编译的原因。我没有意识到 gcc 没有错误拼写标志的错误。问题解决了。感谢您的宝贵时间
-
-Dfoo=bar只是定义了一个预处理器宏,与文件顶部的#D_FORTIFY_SOURCE 2完全相同。只有少数特殊的宏名称会影响像 stdio.h 这样的头文件。对于-march=skylake之类的选项,GCC 只接受它识别的有效选项。但当然-Dfoo=bar对任何foo都有效,它只是不做任何事情,因为它不是glibc 标头在其#ifdefs 中使用的宏。
标签: c assembly gcc glibc fortify-source