shellcode之三:shellcode编写

声明:主要内容来自《The Shellcoder's Handbook》,摘录重点作为笔记并加上个人的一些理解,如有错,请务必指出。


系统调用


Shellcode是一组可注入的指令,可在被攻击的程序内运行。由于shellcode要直接操作寄存器,通常用汇编语言编写并翻译成十六进制操作码。我们想让目标程序以不同与设计折预期的方式运行,操纵程序的方法之一是强制它产生系统调用。


在Linux里有两种方法来执行系统调用。间接的方法是libc,直接的方法是用汇编指令调用软中断执行系统调用。在Linux里,程序通过int 0x80软中断来执行系统调用,调用过程如下:

1、把系统调用编号载入EAX;

2、把系统调用的参数压入其他寄存器;最多支持6个参数,分别保存在EBX、ECX、EDX、ESI、EDI和EBP里;

3、执行int 0x80指令;

4、CPU切换到内核模式;

5、执行系统函数。


如何得到一个shellcode


注意两点:
1、shellcode应该尽量紧凑,这样才能注入更小的缓冲区;

2、shellcode应该是可注入的;当攻击时,最有可能用来保存shellcode的内存区域是为了保存用户的输入而开辟的字符数组缓冲区。因此shellcode不应包含空值(/x00),在字符数组里,空值是用来终止字符串的,空值的存在使得把shellcode复制到缓冲区时会出现异常。


下面以exit()系统调用为例写一个shellcode。exit()的系统编号为1。用汇编指令实现:

Section .text
    global _start
_start:
    mov ebx,0
    mov eax,1
    int 0x80
用nasm编译生成目标文件,然后用GNU链接器链接目标文件,最后用objdump显示相应的操作码(下图的标号为_start部分):
sep@debian66:~/shellcode$ nasm -f elf shellcode.asm
sep@debian66:~/shellcode$ ld -o shellcode shellcode.o 
sep@debian66:~/shellcode$ objdump -d shellcode

shellcode: file format elf32-i386

Disassembly of section .text:

08048080 <_start>:
 8048080: bb 00 00 00 00 mov $0x0,%ebx
 8048085: b8 01 00 00 00 mov $0x1,%eax
 804808a: cd 80          int $0x80
sep@debian66:~/shellcode$
shellcode[] = {"/xbb/x00/x00/x00/x00/xb8/x01/x00/x00/x00/xcd/x80"},可以发现里面出现很多空值,基于shellcode的可注入性,我们需要找出把空值转换成非空操作码的方法。有两种方法:

1、直接用其他具有相同功能的指令替换那些产生空值的指令;

2、在运行时用指令加上空值。


第2个方法比较复杂,暂时先讨论第1个方法。根据objdump的结果,发现mov ebx,0和mov eax,1均产生空值。了解汇编语言的话,可修改为以下代码:

Section .text
    global _start
_start:
    xor ebx,ebx
    mov al,1
    int 0x80
编译、链接、反汇编.text段:
sep@debian66:~/shellcode$ nasm -f elf shellcode.asm
sep@debian66:~/shellcode$ ld -o shellcode shellcode.o 
sep@debian66:~/shellcode$ objdump -d shellcode

shellcode: file format elf32-i386

Disassembly of section .text:

08048080 <_start>:
 8048080: 31 db xor %ebx,%ebx
 8048082: b0 01 mov $0x1,%al
 8048084: cd 80 int $0x80
sep@debian66:~/shellcode$

可以看到shellcode的空值消失了,长度也减少了。该shellcode是可注入的。


派生shell


如何写一个派生shell的shellcode,参考原书P39,这里不详述。我现在只需对shellcode的获取有个大致的了解,实现时再看细节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值