如果您没有充分考虑引入漏洞的因素,漏洞利用开发可能会导致严重的麻烦。非决定论进入调试过程。特别是,调试器中的堆栈地址可能与正常执行期间的地址不匹配。出现此工件是因为操作系统加载程序放置了环境变量和程序参数before堆栈的开头:
由于您的易受攻击的程序不接受任何参数,因此环境变量可能是罪魁祸首。请确保它们在两次调用、shell 和调试器中是相同的。为此,您可以将调用包装在env
:
env - /path/to/stack
并使用调试器:
env - gdb /path/to/stack
($) show env
LINES=24
COLUMNS=80
在上面的例子中,gdb设置了两个环境变量,你可以进一步禁用它们:
unset env LINES
unset env COLUMNS
Now show env
应该返回一个空列表。此时,您可以开始调试过程以找到您想要跳转到的绝对堆栈地址(例如,0xbffffa8b
),并将其硬编码到您的漏洞中。
另一个微妙但重要的细节:调用和调用之间存在区别./stack
and /path/to/stack
: since argv[0]
准确地保存程序的调用方式,您需要确保相同的调用字符串。这就是我使用的原因/path/to/stack
在上面的例子中,不仅仅是./stack
and gdb stack
.
当学习利用内存安全漏洞时,我建议使用下面的包装程序,它可以完成繁重的工作并确保相等的堆栈偏移量:
$ invoke stack # just call the executable
$ invoke -d stack # run the executable in GDB
这是脚本:
#!/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