来源:互联网 发布:降温软件排行第一 编辑:程序博客网 时间:2024/05/19 00:37
OOB的全称为Out Of Bound,通常翻译为越界漏洞,光看名字也许既陌生又人畜无害,
觉得是编程考试才会遇到的奇怪名字。但前一阵子闹得满城风雨的heartbleed正是越界漏
洞的一种表现形式,是否又会令这三个不起眼的字母别有一番风味?下面,就让我们走进
OOB,探索心脏泣血背后的故事。
  要明白越界,首先应该明白什么是界。我们知道,任何程序,无非就是算法+数据结构,
数据结构保存在内存中,而内存是一块地址连续的区域,数据结构之外自然也会有内存,但
理论上使用者只能对数据结构之内的内存读和写,比如数组,数组是一种很常见的数据结构,
C语言中,数据是定长的,这个长度,就是数据的界,使用者只能在数组长度以内读和写,
但被C语言坑过的同学一定不会忘记,数据是非常容易越界的,因为数据的下标从零开始,
若一不小心把数组上限填成了长度,如array[index],其中index的值等于len,导致下标
index超过了len-1,也就是访问了数组长度外的内存,那么这就是个越界。
  再来回顾一下heartbleed漏洞的原理,其实非常简单,在SSL的数据包里有一个数据
结构,包含了数据的长度(len)和内容(payload),这个数据结构会经过一次memcpy,这
个函数的最后一个参数为复制长度len,如果len等于payload的长度,那相安无事,如果
len大于payload的长度,那就会发生越界访问,泄露多出来的那段内存。由于这个len
一个无符号整型,能够表示的最大值为65535,当payload的长度为0时,泄露内存达到最大
值,为65535byte,这就是heartbleed漏洞最大能泄露64K内存的原因。(想更进一步了解
细节的同学可以读这一段:OpenSSLheartbleed漏洞存在于ssl/dl_both.c文件中,SSLv3
记录的内容包括tpyelen payload,会在内存中通过OpenSSL_malloc 函数分配
1+2+payload+padding 大小个字节,最大可以分配1+2+65535+16个字节,最后调用memcpy
函数复制payload个字节。如果payload大小小于len就会发生泄漏。)没错,就是这么简
单,就是这么个大一新生都必考的C语言知识点,只要放到合适的位置,就会引发满城风雨
的安全危机。
  说了这么多,原理应该都清楚了,不过不比划点代码总感觉有点虚。写个简单点的代码模拟一下这个过程,代码如下:
void heartbleed(int pos)
{
  const int max = 3;
  int ssl[max]={1,2,3};
  printf("%x", *(ssl + pos));
}


这是个非常简单的函数,名叫heartbleed,它只接受一个参数,就是pos。这个函数的
作用,就是打印数组ssl偏移pos的内容,实际就是ssl[pos]。不过要提醒的是,这个ssl
数组长度只有3
按理说,使用者仅能访问数组内的信息,但由于这里没有对pos进行判断,因此存在越
界漏洞。好,现在测试这个函数。抛开数组未初始化的问题,当pos<max时,函数工作正常,

但当pos==max,奇怪的东西就混进来了(图1
): 
如图1所示,当pos=3时,打印了个7691eb80。这是个什么呢?让我们反汇编看看:
01281870 >    55            push    ebp
01281871      8BEC          mov     ebp, esp
01281873      83EC 14       sub     esp, 14
01281876      A1 00302801   mov     eax, dword ptr [__security_cooki>
0128187B      33C5          xor     eax, ebp
0128187D      8945 FC       mov     dword ptr [ebp-4], eax
01281880      C745 EC 03000>mov     dword ptr [ebp-14], 3
01281887      C745 F0 01000>mov     dword ptr [ebp-10], 1
0128188E      C745 F4 02000>mov     dword ptr [ebp-C], 2
01281895      C745 F8 03000>mov     dword ptr [ebp-8], 3
0128189C      8B45 08       mov     eax, dword ptr [ebp+8]
0128189F      8B4C85 F0     mov     ecx, dword ptr [ebp+eax*4-10]
012818A3      51            push    ecx
012818A4      68 00212801   push    01282100                 ;  ASCII "%x"
012818A9   .  FF15 90202801 call    dword ptr [<&MSVCR110.printf>]   ;
\printf
012818AF   .  83C4 08       add     esp, 8
012818B2   .  8B4D FC       mov     ecx, dword ptr [ebp-4]
012818B5   .  33CD          xor     ecx, ebp
012818B7   .  E8 44F7FFFF   call    __security_check_cookie
012818BC   .  8BE5          mov     esp, ebp
012818BE   .  5D            pop     ebp
012818BF   .  C3            retn

  从这段反汇编码可以看出,数组是从ebp-10ebp-8,而打印的位置则是ebp-10+eax*4
这个eax保存的就是pos的值。当eax=3,读取的内容为ebp-10+C,即为ebp-40x0128187D
处正好对ebp-4赋值,往上看一看,原来是security_cookie异或上ebp的值。
  因为输入的参数posint,是有正负值的,因此实际能够读取的范围为ebp-10-32768*4
ebp-10+32768*4256K内存,除了ebp-10ebp-8这一段,其它均为泄露。至于泄露的
危害,heartbleed 漏洞相信已经给大家狠狠地上了一课,前面已经说了,数据结构外面是
什么?还是数据结构,漏洞总是存在的,是否有价值的关键在于,这是保存什么的数据结构,
如上面的security_cookie异或上ebp的值,如果能写,可以绕过GS的安全检查保护,如
果保存的是银行账户和密码的验证,那就成了又一场血雨腥风。

0 0
原创粉丝点击