tha*_*man 39 c security buffer-overflow memory-safety fortify-source
我在CentOS 6.4 32位上,并试图在程序中导致缓冲区溢出.在GDB中它可以工作.这是输出:
[root@localhost bufferoverflow]# gdb stack
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/bufferoverflow/stack...done.
(gdb) r
Starting program: /root/bufferoverflow/stack
process 6003 is executing new program: /bin/bash
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.el6_4.2.i686
sh-4.1#
Run Code Online (Sandbox Code Playgroud)
然而,当我自己运行程序堆栈时它会出现故障.为什么会这样?
mav*_*vam 98
如果您没有充分考虑将非确定性引入调试过程的因素,那么漏洞利用开发可能会导致严重的问题.特别是,调试器中的堆栈地址可能与正常执行期间的地址不匹配.发生此工件是因为操作系统加载程序在堆栈开始之前放置了环境变量和程序参数:

由于您的易受攻击程序不接受任何参数,因此环境变量可能是罪魁祸首.确保它们在调用,shell和调试器中都是相同的.为此,您可以将调用包装在env:
env - /path/to/stack
Run Code Online (Sandbox Code Playgroud)
并使用调试器:
env - gdb /path/to/stack
($) show env
LINES=24
COLUMNS=80
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,gdb设置了两个环境变量,您可以进一步禁用它们:
unset env LINES
unset env COLUMNS
Run Code Online (Sandbox Code Playgroud)
现在show env应该返回一个空列表.此时,您可以启动调试过程以查找您想要跳转到的绝对堆栈地址(例如0xbffffa8b),并将其硬编码到您的漏洞利用中.
另一个微妙但重要的细节:调用./stack和之间有区别/path/to/stack:因为argv[0]保存程序的方式完全是你调用的,你需要确保相等的调用字符串.这就是为什么我/path/to/stack在上面的例子中使用而不仅仅是./stack和gdb stack.
当学习利用内存安全漏洞时,我建议使用下面的包装程序,它可以解决繁重问题并确保相同的堆栈偏移:
$ invoke stack # just call the executable
$ invoke -d stack # run the executable in GDB
Run Code Online (Sandbox Code Playgroud)
这是脚本:
#!/bin/sh
while getopts "dte:h?" opt ; do
case "$opt" in
h|\?)
printf "usage: %s -e KEY=VALUE prog [args...]\n" $(basename $0)
exit 0
;;
t)
tty=1
gdb=1
;;
d)
gdb=1
;;
e)
env=$OPTARG
;;
esac
done
shift $(expr $OPTIND - 1)
prog=$(readlink -f $1)
shift
if [ -n "$gdb" ] ; then
if [ -n "$tty" ]; then
touch /tmp/gdb-debug-pty
exec env - $env TERM=screen PWD=$PWD gdb -tty /tmp/gdb-debug-pty --args $prog "$@"
else
exec env - $env TERM=screen PWD=$PWD gdb --args $prog "$@"
fi
else
exec env - $env TERM=screen PWD=$PWD $prog "$@"
fi
Run Code Online (Sandbox Code Playgroud)
缓冲区溢出在gdb和segfaults下运行的原因是gdb禁用地址空间布局随机化.我相信这在gdb版本7中默认打开.
您可以通过运行此命令来检查:
show disable-randomization
Run Code Online (Sandbox Code Playgroud)
并设置它
set disable-randomization on
Run Code Online (Sandbox Code Playgroud)
要么
set disable-randomization off
Run Code Online (Sandbox Code Playgroud)
以下是在终端中使用相同堆栈运行程序的简单方法gdb:
首先,确保您的程序编译时没有堆栈保护,
gcc -m32 -fno-stack-protector -z execstack -o shelltest shelltest.c -g
和ASLR被禁用:
echo 0 > /proc/sys/kernel/randomize_va_space
注意:我的机器上的默认值是2,在更改之前请注意.
然后像这样运行你的程序(终端和gdb):
env -i PWD="/root/Documents/MSec" SHELL="/bin/bash" SHLVL=0 /root/Documents/MSec/shelltest
env -i PWD="/root/Documents/MSec" SHELL="/bin/bash" SHLVL=0 gdb /root/Documents/MSec/shelltest
Run Code Online (Sandbox Code Playgroud)
内gdb,确保unset LINES和COLUMNS.
注意:我通过使用测试程序获得了这些环境变量.
这两个运行将为您提供指向堆栈顶部的相同指针,因此如果您尝试利用远程托管的二进制文件,则不需要远程脚本恶作剧.