我试图保护我的应用程序免受缓冲区溢出攻击。 除此之外,我正在使用不可执行的堆栈,并将我的二进制文件与noexecstack标记链接(通过将-Wl,-z,noexecstack给gcc)。
一切似乎都很好 – readelf确认PT_GNU_STACK指定正确的权限:
$ readelf -l target | grep -A1 GNU_STACK GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 10
execstack :
$ execstack -q target - target
只有一个问题。 我所有的堆栈都是可执行的:
configuration和构buildOpenCV以自定义FFMPEG安装
将Python链接到我在Windows上的C ++代码 – 链接器错误
自制内核链接器全局variables和内联string不能被访问
GNU链接器:替代–version脚本列出导出的符号在命令行?
root@170ubuntu16p04-64smp-1:~# cat /proc/12878/task/*/maps | grep stack 7ffcac654000-7ffcac675000 rwxp 00000000 00:00 0 [stack] 7fe540e66000-7fe541666000 rwxp 00000000 00:00 0 [stack] 7fe540665000-7fe540e65000 rwxp 00000000 00:00 0 [stack] 7fe53b800000-7fe53c000000 rwxp 00000000 00:00 0 [stack]
我已经捕获了allocate_stack调用并检查了保护标志。 理论上应该按照PT_GNU_STACK进行初始化。 但在我的情况,似乎PT_GNU_STACK被忽略, _dl_stack_flags初始化与默认权限。
有谁知道可能会造成这种情况? 一切似乎都是正确的,但堆栈仍然是可执行的。
我使用的是gcc 4.8.3 / glibc 2.11。
如何在centos6上分发c ++ 11共享库
为什么剥离的二进制文件仍然可以在反汇编的文件中有库调用信息?
如何在C ++的multithreading中调用非线程安全的DLL?
这可能是什么造成的?
除了具有正确权限的主要可执行文件的PT_GNU_STACK , 还需要在每个直接链接的共享库中具有正确权限的PT_GNU_STACK 。
如果这些库中的任何一个根本没有PT_GNU_STACK ,或者有一个具有可执行权限,那么它将会以可执行权限“中毒”所有堆栈。
所以跑吧
for j in $(ldd target | grep -o '=> .* ' | sed -e 's/=> //' -e '/^ *$/d' ); do out=$(readelf -Wl $j | grep STACK) [[ -z "$out" ]] && echo "missing GNU_STACK in $j" echo $out | grep -q RWE && echo "executable GNU_STACK in $j" done
你可能会看到至少有一个库缺少可执行的堆栈。
PS我看到奥拉夫已经(部分)提出这个建议。
奥拉夫和就业的俄罗斯人把我推向了正确的方向。 第三方共享对象正在中毒我的堆栈。
但它没有直接链接到我的主要可执行文件。 ldd和lddtree都没有显示任何带有RWE堆栈的库,所以我决定深入研究并编写一个脚本来检查当前映射到进程内存中的所有共享对象:
#!/bin/bash if [ -z "$1" ]; then echo "Usage: $0 <target>" exit 1; fi kav_pid=`pidof $1` for so in `cat /proc/$kav_pid/task/*/maps | awk '/.so$/ {print $6}' | sort | uniq`; do stack_perms=`readelf -Wl $so | awk '/GNU_STACK/ {print $7}'` if [ -z "$stack_perms" ]; then echo "$so doesn't have PT_GNU_STACK" elif [ "$stack_perms" != "RW" ]; then echo "$so has unexpected permissions: $stack_perms" fi done
它的工作! 我找到了一个RWE权限的库:
$ ./find_execstack.sh target /target/dir/lib64/lib3rdparty.so has unexpected permissions: RWE
为了确保这个库毒害了我的堆栈,我使用gdb打开了我的应用程序,并在dlopen设置了一个断点。 宾果! 这里是dlopen ing lib3rdparty.so之前的权限:
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
这是他们在dlopen :
7ffffffde000-7ffffffff000 rwxp 00000000 00:00 0 [stack]
事实证明, lib3rdparty.so是使用不同的工具链构建而成的,现在它已经被忽略了。
奥拉夫,就业俄罗斯,谢谢!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。