Home 应用安全 Cisco ASA IKE Buffer Overflow (CVE-2016-1287)

Cisco ASA IKE Buffer Overflow (CVE-2016-1287)

by zinan

 

1.背景:

在上月10号,Cisco发布了编号为CVE-2016-1287的缓冲区溢出漏洞补丁,思科ASA自适应安全设备是充当一个应用感知防火墙,网络病毒,入侵防御系统和虚拟专用网络(VPN)服务器的IP路由器,它被标榜为“业界部署最广的状态防火墙”,当部署了VPN,可为移动办公提供访问公司内部网络的功能。

2.摘要:

这次漏洞发生在Cisco ASA系统在处理Internet密钥交换协议(IKE)的代码中,远程攻击者可让Cisco ASA设备重启或执行任意代码。

漏洞是由于缓冲区边界检查不严而造成了堆溢出,一个攻击者可以向受影响的设备发送一组精心构造的UDP数据包来攻击系统,这个漏洞允许攻击者远程执行任意代码,或使设备重启。漏洞影响IKE版本1v1)和版本2v2),但是本文主要介绍IKEv1

3.影响范围:

根据Cisco官方提供的报告,包括但不仅限于下列产品受影响:

Cisco ASA 5500 Series Adaptive Security Appliances

Cisco ASA 5500-X Series Next-Generation Firewalls

Cisco ASA Services Module for Cisco Catalyst 6500 Series Switches and Cisco 7600 Series Routers

Cisco ASA 1000V Cloud Firewall

Cisco Adaptive Security Virtual Appliance (ASAv)

Cisco Firepower 9300 ASA Security Module

Cisco ISA 3000 Industrial Security Appliance

4.漏洞分析:

4.1协议原理:

         IKEInternet key exchange):Internet密钥交换协议,属于混合协议,由Internet安全关联和密钥管理协议(ISAKMP)和两种密钥交换协议OAKLEYSKEME组成。

IKE协议过程中,提供了一个可选的分片功能,IKE分片是将一个较大的数据包分割成多个较小的碎片发送,碎片的详细结构如下图所示:

1.jpg

每一个碎片都属于IKE的载荷,其前面必须是IKE报文头,IKE头部中的载荷类型字段应设置为碎片载荷类型值0x84。对于每个碎片头部中Next_PayloadRESERVED字段必须设置为0,同一组碎片Fragment_ID字段必须设为相同的值,Fragment_Number字段自第一个碎片设置为1开始逐个递增,Flags属于结束标识位,只在最后一个碎片中设置。

但是,并不是每次IKE过程都会分片,除非在此之前通信双方有一个协商过程来表明自己支持此功能。在IKEv1中,协议发起方若支持分片功能则会在新的协商报文中包含具有“FRAGMENTION”标识的vendorID载荷,若应答方也支持分片功能,则会在返回的协商报文中也包含相同的vendorID载荷,过程如下:

Initiator                                     Responder

———–                                     ———–

   HDR, SA,

        [VID(FRAGMENTION)]  –>

                                <–   HDR, SA,

                                           [VID(FRAGMENTION)]

4.2代码分析:

对于应答方,当接收到IKE碎片报文,将会触发两个关键的函数,ikev1_add_rcv_frag()ikev1_reassemble_pkt(),其中第一个函数作用是接收到每一个碎片添加到重组队列中,第二个函数在所有碎片接收完成后将其重组为一个完整的报文。

在新收到一个新的碎片后,ikev1_add_rcv_frag()函数都会重新计算重组后的报文长度。下列摘选了ikev1_add_rcv_frag()函数的相关代码片段:

mov eax,[eax]                             

mov ecx,[ebp+var_150]            ;新接收到的碎片长度

mov eax,[eax+4]                         ;取出原重组队列的长度

lea eax,[ecx+eax-8]                    ;将新接收到的碎片长度加上已接收到的重组队列长度再减去8

cmp eax,7FFFh

mov [ebp+var_158],eax            ;储存新的重组队列长度

         当所有的碎片接收完成后,ikev1_reassemble_pkt()函数将会在内存中申请一块连续的空间存放重组后的报文,相关代码如下:

mov eax,[ecx+4]                                   ;取出重组报文的长度

add eax,8

mov [esp],eax                                       ;长度参数入栈

call my_malloc                                               ;申请内存

mov ecx,[eax]                                        ;下一个碎片的内存地址

test ecx,ecx

jz

movzx eax,word ptr [ecx+2]             ;获取碎片长度

add edi,1

ror ax,8

movzx eax,ax

sub eax,8

mov [ebp+len],eax

mov eax,[ebp+var_140]

lea edx,[ebx_eax+4]

lea eax,[ecx+8]

move cx,[ebp+len]

mov [esp],edx                                       ;目的地址参数

mov [esp+4],eax                                  ;源地址参数

mov [esp+8],ecx                                  ;拷贝长度

call my_memcpy…

ikev1_add_rcv_frag()函数中存在着逻辑问题,对于每一个接收到的碎片,虽然代码检查了长度的最大值,但却没有检查最小值,并且在每接收到一个碎片后,都会减去它的头部长度8字节,若攻击者构造一组分片包,但其中一个碎片不包含数据段,并将Payload_Length字段设置为小于头部长度的8字节的值,那么存在漏洞的设备在接收到这组分片后,会错误的计算重组队列长度,使得重组队列的长度小于实际接收碎片的总长度,那么在ikev1_reassemble_pkt()函数的内存复制阶段就会发生堆溢出错误。

5.实测

         在支持IKEv1的测试机上开启debug模式后看到当收到一个IKEv1的分片协商报文后,设备也构造了一个协商报文做为应答:

2.jpg

Wireshark抓包显示如下:

发起方

3.jpg

应答方

4.jpg

接下来构造一组分片包,并将其中一个碎片的Payload_Length字段设置为1,并不带数据段:

5.jpg

畸形碎片结构:

6.jpg

若存在漏洞的设备接收到这组分片,将会触发漏洞。

 

POC & EXP: 

CVE-2016-1287

参考:

http://www.weizn.net/?post=169

http://weizn.net/pdf/MS-IKEE.pdf 

打赏
1 comment

You may also like

1 comment

Dim B. 2016年4月30日 - 下午7:58

对于POC密码.ZIP可用?
Is the password for the .zip available please?

Reply

Leave a Comment

*

code

error: Alert: Content is protected !!