代码注入

定义:将恶意代码注入程序中执行

简单的说就是骇客如果发现有2.3小节中说的字符串漏洞,那么骇客就可以利用这个漏洞来还行他想执行的程序。

骇客可能盱眙构造出一个字符串,其中包含一个指向某些恶意代码的指针。当子例程但会返回时,控制就被转移到那段恶意的代码。这样恶意代码就会以与该有漏洞的程序相同权限运行。骇客通常都以“以root或其他较高全选运行”的程序为目标,恶意代码可以执行以其他任何形式编程所能执行的功能,不过它们通常只是简单的在受害机器上开一个远程shell,鉴于此,被注入的恶意代码也被成为shellcode。

恶意参数特征:

  1. 有漏洞的程序必须接受他作为合法的输入
  2. 参数以及其他科控制的输入,必须倒是与漏洞的代码路径得到执行
  3. 参数不能再程序将控制权转移到shellcode之前导致程序异常终止

接下来就将一个书中使用代码注入的例子:

书中例子是在Red Hat Linux9.0系统中实现。 本书是10年前编写,有些例子已经比较难实现,微软已经彻底弃用gets()函数,所以不是很好实现,但是程序的原理还是一样的 。

  1. 首先需要一个二进制文件,文件名为:exploit.bin,内容如图2.6.1
  2. 在执行程序时将二进制文件定向:./BufferOverFlow < exploit.bin
图2.6.1

在二进制数据文件中,除了末尾不能包含任何换行或空字符(null),因为利用程序依赖于gets()函数的调用。

执行过程及结果:

图2.6.2
图2.6.3

漏洞利用的工作原理:

  1. 二进制数据的开始16个字节填入密码锁分配的空间中,程序分配了12个自己的控件,但编译程序的gcc在栈上为其分配16个字节。
  2. 接下来的12个字节的二进制数据填充编译器为栈16字节对齐而多分配的12字节,由于已经分配4字节的函数调用返回地址,因此编译器值分配了12字节。
  3. 返回地址被覆盖,使得程序从isPasswdOkay()返回后可以继续执行,这就导致了栈中保存的代码被执行
  4. 建立一个0值并且用其截断参数列表,这个是必不可少的,因为利用漏洞的过程中,传递给系统调用的参数中必须包含一个以空指针的字符指针列表,这是利用数据中间不能直接包含空字符。
  5. 系统调用号被设为0xb,在linux中代表execve()系统调用
  6. execve()函数调用必须需要3个参数,参数位于12-13行
  7. 执行execve()系统调用,导致linux的calendar程序被调用

对代码的逆向工程可以确定在栈帧中从缓冲区到返回地址的精确偏移量,这就允许对注入的shellcode进行定位,然而有时并不需要如此苛刻的条件。例如返回地址的位置可以通过在一个近似的返回地址范围内进行多次试验而得到。假设程序运行在32位结构的机器上,那么返回地址通常是4字节对齐的,及时返回地址有一定的偏移量也只有4个可能,也可以通过在shellcode前面加入多个nop指令是测试更加精确,利用代码仅需要在一连串的nop指令中插入一个合适的jmp指令就可以执行shellcode了。

很多实现栈粉碎攻击都是这种形式发生,即覆盖返回地址,将控制权转移到注入的代码。那种简单的将返回地址修改为代码中其他地址的方式并不常用,部分原因是因为这些漏洞难以发现,需要骇客完全掌握可以顺利绕过检查的程序逻辑,并且对攻击者而言用处不大,因为能获得对程序本身的控制权而不是执行任意的代码。

发表评论

电子邮件地址不会被公开。 必填项已用*标注