shell脚本之shellcode自动提取工具

  最近一直在忙着写论文。突然领导又分配任务,帮写个自动提取shellcode的脚本工具。因为之前,我们都是用objdump查看后,把shellcode一个个添加进去,很麻烦,害怕写错。所以说我们写这个工具还是挺有必要的。首先我们要先了解几个用到的命令。objdump,od,dd.这几个对于提取shellcode很有用。

  objdump 有点象那个快速查看之类的工具,就是以一种可阅读的格式让你更多地了解二进制文件可能带有的附加信息。这里我们讲用到-d -F 选项。-d disassemble. 反汇编   那些应该还有指令机器码的section。-F fileoffset.显示文件偏移量。是为了我们能够定位到出我们想要的shellcode。

  od 命令。dump files in octal and other formats. 就是可以以各种格式输出文件。 -t 输入格式,我选x1,表示十六进制一个字节为一个单位。

  dd命令。Copy a file converting and formatting according the operands.我用这个命令来提取shellcode。-bs选项,是每次读取的字节数。-if,输入文件。-of,输出文件。-skip,跳过的字节数,就是从objdump活得的偏移量。-count 复制的数量,这个我们通过计算获得。

  首先我们看下用来测试的execve2.asm:

Section .text
    global _start
_start:
    jmp short GotoCall
shellcode:
    
    pop esi
    xor eax,eax
    mov byte [esi + 7], al
    lea ebx,[esi]
    mov long [esi + 8],ebx
    mov long [esi + 12],eax
    mov byte al,0x0b
    mov ebx,esi
    lea ecx,[esi + 8]
    lea edx,[esi + 12]
    int 0x80
GotoCall:
    call shellcode
    db '/bin/shJAAAAKKKK'

  用nasm -f elf execve2.asm 会把文件'execve2.asm'汇编成'ELF'格式 的文件'execve2.o

  然后我们用 objdump -d -F execve2.o 来查看。

  

  <shellcode>与<GotoCall>之间的就是我们要提取的shellcode。首先我们看到<shellcode>和<GotoCall>的偏移量:0x112,0x12c。那么这个值就可以作为我们dd命令的skip值。我们要怎么提取这个偏移量呢。。。首先想到了awk工具,那么我们可以看看,这个偏移地址总是在最后一行,那么我们就可以先用grep命令把<shellcode>这行提取出来,然后再用awk把最后一个字段提取出来,得到0x112): 。然后我们在用字符串处理把)和:去掉就得到0x112。这是得到的是字符串,然后我们再用(())这个运算符来进行数值运算。就可以把0x112转换成十进制数字了。这样就可以得到我们想要的skip值。对于<GotoCall>的偏移量我们同理可得,然后用0x12c-0x112就可以得到我们要提取的字节数,也就是dd命令的count值。具体的我们来看我写的脚本吧。

extract_shellcode.sh 

总共有5个输入参数,第一个是输入的文件,execve2.o, 第二个是输出文件的格式execv2.raw,第三个是shellcode开始的标识,我们这里的开始标示是<shellcode>,第四个是结束标识<GotoCall>。第五个是选择我们要输出的格式,r表示只输出shellcode本身,c表示输出带有C语言的。即unsigned int shellcode[] ="";格式的。

#!/bin/bash

BEGIN=$(objdump -d -F $1 | grep “<$3>” | awk 'NR==1 {print $NF ;}')
BEGIN=${BEGIN%)*}
((BEGIN=BEGIN+0x0))
echo $BEGIN

END=$(objdump -d -F $1 | grep "<$4>" | awk 'NR==1 {print $NF ;}')
END=${END%)*}
((END=END+0x0))
echo $END

((VAR=END-BEGIN))
echo $VAR 

dd bs=1 if=$1 of=$2 skip=$BEGIN count=$VAR

if [ "$5" = "c" ]; then
    TMP=tmp;
    touch $TMP;
    echo "unsigned int shellcode[] =" > $TMP;
    od -t x1 $2 | awk '{$1="";print;}' | sed 's/\ /\\x/g' | sed '/^$/d;s/^/\"/g;s/$/\"/g' >> $TMP;
    cat $TMP | awk '{print;} END{print ";";}' > $2;
    rm $TMP;
fi

下面是我获得的execve2.raw格式的。

下面是生成C语言格式的:

 

下面是生成的execve2.c:

 

 

 

提取的结果和我们前面用objdump 看的execve2.o里面的是完全一样的。大功告成!

2013/4/29 13:58

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值