即使使用“noexecstack”,堆栈也是可执行的
Stacks are executable even with `noexecstack`
我正在尝试保护我的应用程序免受缓冲区溢出攻击。除其他事项外,我正在使用不可执行的堆栈和 link 我的带有 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
只有一个问题。我所有的堆栈实际上都是可执行的:
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 calls and examined protection flags. In theory,应该是按照PT_GNU_STACK
初始化的。但就我而言,似乎 PT_GNU_STACK
被忽略并且 _dl_stack_flags
已使用默认权限初始化。
有谁知道是什么原因造成的?一切似乎都是正确的,但堆栈仍然是可执行的。
我正在使用 gcc 4.8.3 / glibc 2.11。
what could have caused this?
除了主可执行文件的 PT_GNU_STACK
具有正确的权限外,您 还 需要 PT_GNU_STACK
在 每个 中具有正确的权限 直接链接共享库。
如果这些库中的任何一个根本没有 PT_GNU_STACK
,或者有一个具有可执行权限,它将 "poison" 您的所有堆栈都具有可执行权限。
所以运行
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
您可能会看到至少一个库缺少堆栈或可执行堆栈。
P.S。我看到 Olaf 已经(部分)提出了这个建议。
Olaf 和 Employed Russian 将我推向了正确的方向。第三方共享对象使我的堆栈中毒。
但它没有直接链接到我的主要可执行文件。 ldd
和 lddtree
都没有显示任何带有 RWE 堆栈的库,所以我决定深入挖掘并编写一个脚本来检查当前映射到进程内存中的所有共享对象:
#!/bin/bash
if [ -z "" ]; then
echo "Usage: [=10=] <target>"
exit 1;
fi
kav_pid=`pidof `
for so in `cat /proc/$kav_pid/task/*/maps | awk '/.so$/ {print }' | sort | uniq`; do
stack_perms=`readelf -Wl $so | awk '/GNU_STACK/ {print }'`
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
是使用不同的工具链构建的,直到现在都没有引起注意。
Olaf,俄语雇员,谢谢!
我正在尝试保护我的应用程序免受缓冲区溢出攻击。除其他事项外,我正在使用不可执行的堆栈和 link 我的带有 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
只有一个问题。我所有的堆栈实际上都是可执行的:
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 calls and examined protection flags. In theory,应该是按照PT_GNU_STACK
初始化的。但就我而言,似乎 PT_GNU_STACK
被忽略并且 _dl_stack_flags
已使用默认权限初始化。
有谁知道是什么原因造成的?一切似乎都是正确的,但堆栈仍然是可执行的。
我正在使用 gcc 4.8.3 / glibc 2.11。
what could have caused this?
除了主可执行文件的 PT_GNU_STACK
具有正确的权限外,您 还 需要 PT_GNU_STACK
在 每个 中具有正确的权限 直接链接共享库。
如果这些库中的任何一个根本没有 PT_GNU_STACK
,或者有一个具有可执行权限,它将 "poison" 您的所有堆栈都具有可执行权限。
所以运行
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
您可能会看到至少一个库缺少堆栈或可执行堆栈。
P.S。我看到 Olaf 已经(部分)提出了这个建议。
Olaf 和 Employed Russian 将我推向了正确的方向。第三方共享对象使我的堆栈中毒。
但它没有直接链接到我的主要可执行文件。 ldd
和 lddtree
都没有显示任何带有 RWE 堆栈的库,所以我决定深入挖掘并编写一个脚本来检查当前映射到进程内存中的所有共享对象:
#!/bin/bash
if [ -z "" ]; then
echo "Usage: [=10=] <target>"
exit 1;
fi
kav_pid=`pidof `
for so in `cat /proc/$kav_pid/task/*/maps | awk '/.so$/ {print }' | sort | uniq`; do
stack_perms=`readelf -Wl $so | awk '/GNU_STACK/ {print }'`
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
是使用不同的工具链构建的,直到现在都没有引起注意。
Olaf,俄语雇员,谢谢!