思科Catalyst2960交换机中的CVE-2017-3881漏洞分析思科Catalyst 2960交换机中的CVE-2017-3881漏洞分析,
本⽂讲的是 思科Catalyst 2960交换机中的CVE-2017-3881漏洞分析
2017年3⽉17⽇,思科官⽅⽹站发布公告称Cisco IOS&IOS XE Software 集管理协议(Cluster Management Protocol)存在远程执⾏代码漏洞(CVE-2017-3881)。
该漏洞是思科在研究CIA泄漏⽂档“Vault 7”的过程中发现的,攻击者可以在未授权的情况下远程重启受影响的设备或越权执⾏代码。造成该漏洞的主要原因是由于没有限制CMP-specific Telnet仅可⽤于内部与本地的集成员之间的通信,⽽是可⽤于连接任何受影响的设备,以及对于变形过的CMP-specific Telnet选项设置的错误处理。当⽤Telnet连接⼀个受影响设备的过程中,攻击者可以通过发送⼀个变异过的CMP-specific Telnet选项设置来建⽴与该设备的连接,利⽤此⽅法攻击者可以远程执⾏任意代码来完全控制此设备或者使得该设备重启。截⽌到发稿时,思科还没有修复集管理协议中的远程执⾏代码漏洞CVE-2017-3881。
Vault 7的⽂档揭⽰了远程执⾏代码漏洞的测试过程,该漏洞没有利⽤源代码⽽是以交互模式或设置模式启动。交互模式通过telnet发送有效载荷,并在相同的telnet连接的上下⽂中⽴即向攻击者提供命令shell:
Started ROCEM interactive session - successful:
root@debian:/home/user1/ops/adverse/adverse-1r/rocem# ./rocem_c3560-ipbase-mz.122-35.SE5.py -i 192.168.0.254
[+] Validating data/interactive.bin
[+] Validating data/set.bin
[+] Validating data/transfer.bin
[+] Validating data/unset.bin
****************************************
Image: c3560-ipbase-mz.122-35.SE5
Host: 192.168.0.254
Action: Interactive
****************************************
Proceed? (y/n)y
Trying 127.0.
[*] Attempting connection to host 192.168.0.254:23
Connected to 127.0.0.1.
Escape character is '^]'.
[+] Connection established
[*] Starting interactive session
User Access Verification
Password:
MLS-Sth#
MLS-Sth# show priv
Current privilege level is 15
MLS-Sth#show users
Line User Host(s) Idle Location
* 1 vty 0 idle 00:00:00 192.168.221.40
Interface User Mode Idle Peer Address
MLS-Sth#exit
Connection closed by foreign host.
利⽤设置模式,修改开关内存为后续telnet的越权连接做准备:
Test set/unset feature of ROCEM
DUT configured with target configuration and network setup
DUT is accessed by hopping through three flux nodes as per the CONOP
Reloaded DUT to start with a clean device
From Adverse ICON machine, set ROCEM:
root@debian:/home/user1/ops/adverse/adverse-1r/rocem# ./rocem_c3560-ipbase-mz.122-35.SE5.py -s 192.168.0.254 [+] Validating data/interactive.bin
[+] Validating data/set.bin
[+] Validating data/transfer.bin
[+] Validating data/unset.bin
****************************************
Image: c3560-ipbase-mz.122-35.SE5
Host: 192.168.0.254
Action: Set
****************************************
Proceed? (y/n)y
[*] Attempting connection to host 192.168.0.254:23
[+] Connection established
[*] Sending Protocol Step 1
[*] Sending Protocol Step 2
[+] Done
root@debian:/home/user1/ops/adverse/adverse-1r/rocem#
Verified I could telnet and rx priv 15 without creds:
root@debian:/home/user1/ops/adverse/adverse-1r/rocem# telnet 192.168.0.254
Trying 192.168.
Connected to 192.168.0.254.
Escape character is '^]'.
MLS-Sth#
MLS-Sth#show priv
Current privilege level is 15
MLS-Sth#
在研究此漏洞时,我们发现了⼀个对我们有⽤的信息——telnet调试输出:
14. Confirm Xetron EAR 5355 - Debug telnet causes anomalous output
1.Enabled debug telnet on DUT
2.Set ROCEM
3.Observed the following:
000467: Jun 3 13:54:09.330: TCP2: Telnet received WILL TTY-SPEED (32) (refused)
000468: Jun 3 13:54:09.330: TCP2: Telnet sent DONT TTY-SPEED (32)
000469: Jun 3 13:54:09.330: TCP2: Telnet received WILL LOCAL-FLOW (33) (refused)
000470: Jun 3 13:54:09.330: TCP2: Telnet sent DONT LOCAL-FLOW (33)
000471: Jun 3 13:54:09.330: TCP2: Telnet received WILL LINEMODE (34)
000472: Jun 3 13:54:09.330: TCP2: Telnet sent DONT LINEMODE (34) (unimplemented)
000473: Jun 3 13:54:09.330: TCP2: Telnet received WILL NEW-ENVIRON (39)
000474: Jun 3 13:54:09.330: TCP2: Telnet sent DONT NEW-ENVIRON (39) (unimplemented)
000475: Jun 3 13:54:09.330: TCP2: Telnet received DO STATUS (5)
000476: Jun 3 13:54:09.330: TCP2: Telnet sent WONT STATUS (5) (unimplemented)
000477: Jun 3 13:54:09.330: TCP2: Telnet received WILL X-DISPLAY (35) (refused)
000478: Jun 3 13:54:09.330: TCP2: Telnet sent DONT X-DISPLAY (35)
000479: Jun 3 13:54:09.330: TCP2: Telnet received DO ECHO (1)
000480: Jun 3 13:54:09.330: Telnet2: recv SB NAWS 116 29
000481: Jun 3 13:54:09.623: Telnet2: recv SB 36 92 OS^K'zAuk,Fz90X
000482: Jun 3 13:54:09.623: Telnet2: recv SB 36 0 ^CCISCO_KITS^Ap
注意最后⼀⾏接收到的CISCO_KITS的选项,时候证明这是⼀个重要的字符串。
根据思科⽬前的公布的情况,总共有318款产品受此漏洞影响,详细产品列表请见附录,
⽬前以下只有两种产品不受此漏洞的影响:
1.运⾏Cisco IOS Software 但是没有在上述受影响列表内的设备不受影响。
2.运⾏Cisco IOS XE Software但是不包含CMP协议⼦系统的产品不受影响。
CVE-2017-3881的检测⽅法
运⾏Cisco IOS 与IOS XE 软件的设备均需要确认Telnet的设置选项是否为接受任何连接请求。运⾏Cisco IOS XE软件的设备还需要额外确认软件镜像中是否存在CMP⼦系统。
对于运⾏Cisco IOS XE软件的设备,要确认软件镜像下是否存在CMP⼦系统,可以在该设备的CLI下输⼊以下命令:
show subsys class protocol | include ^cmp
下⾯的例⼦为软件镜像中存在CMP⼦系统的结果:
下⾯的例⼦为软件镜像中不存在CMP⼦系统的结果:
要确认设备是否配置为接受任何Telnet连接请求,可以在该设备的CLI下输⼊以下命令:
show running-config | include ^line vty|transport input
运⾏此命令可得到多种结果,⽐如:
1.在line vty配置⾏后缺少transport input配置⾏说明该设备在处理来⾃虚拟终端(VTY)的链接访问时采⽤的是⼀系列默认协议,这些协议包扩Telnet的协议,该设备将接受任何来⾃VTY的Telnet连接请求,因
此这是⼀个受该漏洞影响的配置:
2.设备被特地配置为在处理部分可⽤VTY的连接请求时仅接受SSH协议,然⽽编号为6-15的VTY仍然使⽤默认协议。该设备在处理这些特定的VTY连接请求时仍然会接受任何Telnet请求,因此这是⼀个受漏洞影响的配置:
3.在处理与所有VTY的连接时,使⽤任何可⽤的协议。Telnet协议也会被使⽤,因此这是⼀个受漏洞影响的配置:
4.对于所有的VTY连接请求,仅允许使⽤SSH协议。任何使⽤Telnet的VTY连接均不会通过,因此这不是⼀个受漏洞影响的配置:
5.对于来⾃VTY的连接请求,Telnet和SSH协议均被允许。利⽤Telnet连接该设备的请求均会通过,因此这是⼀个受漏洞影响的配置:
要查询Cisco IOS Software的版本信息,管理员可以登录到设备,在CLI下使⽤show version命令来查看系统相关信息。如果该设备在运⾏Cisco IOS Software,系统信息会有类似于Cisco Internetwork Operating System Software or Cisco IOS Software条⽬的出现。要查询Cisco IOS XE Software的版本信息,可以同样在CLI下使⽤show version命令来查询,如果该设备在运⾏Cisco IOS XE Software,会有类似于Cisco IOS XE Software的条⽬出现。
CVE-2017-3881的运⾏原理分析
集管理的切换
假设,我们现在有两个Catalyst 2960交换机,这两个集设置交换机之间是主从切换关系。主交换机能够在从站上获得特权命令shell,正像上⾯提到的那样,telnet被⽤作集成员之间的命令协议。
现在来查它们之间的集通信,以下这些应该都能在主交换机配置中到:
cluster enable CLGRP 0
cluster member 1 xxx
这就会将附近的交换机作为集从站添加进来。 rcommand <num>允许从主接⼝的从设备上获取接⼝命令:
catalyst1>rcommand 1
catalyst2>who
Line      User      Host(s)              Idle      Location
*  1 vty 0                idle                00:00:00 10.10.10.10
Interface      User        Mode                    Idle    Peer Address
我们来看看rcommand⽣成的命令:
cve漏洞库这看起来更像telnet的连接请求,集管理协议在内部使⽤Telnet作为集成员之间的信令和命令协议。
好的,运⾏show version可以看到更多的连接协议:
catalyst2>show version
Cisco IOS Software, C2960 Software (C2960-LANBASEK9-M), Version 12.2(55)SE1, RELEASE SOFTWARE (fc1)
Telnet协议实际上被封装在第2层LLC数据包中,我们将在源地址和⽬的地址字段中注意到⼀些零散的MAC地址内的IP数据包。在这些IP数据包之内,存有具有telnet会话的TCP协议:
思科Catalyst 2960交换机中的CVE-2017-3881漏洞分析
telnet会话通常在telnet选项协商之前,其中就包括终端窗⼝的⼤⼩,终端类型等。
我们可以看到⼀个telnet选项被转移到服务器端:
如上图所⽰,我们可以看到从主交换机发送到从站的telnet选项“CISCO_KITS”。在执⾏利⽤期间,CIA泄漏的Vault 7⽂档中也存在相同的字符串。
固件的分析
固件位于交换机上的flash:<version>.bin:
catalyst2#dir flash:
Directory of flash:/
2  -rwx    9771282  Mar 1 199
3 00:13:28 +00:00  c2960-lanbasek9-mz.122-55.SE1.bin
3  -rwx        2487  Mar 1 1993 00:01:53 +00:00 
内置的ftp客户端允许将此固件传输到任意ftp服务器,我们现在⽤⼆进制⽂件来分析和提取⽂件的内容:
$ binwalk -e c2960-lanbasek9-mz.122-55.SE1.bin
DECIMAL      HEXADECIMAL    DESCRIPTION
--------------------------------------------------------------------------------
112          0x70            bzip2 compressed data, block size = 900k
为了⽅便对所得到的⼆进制数进⾏静态分析,我们可以先了解⼀下固件负载偏移量。在引导过程中,该偏移量将体现在串⾏控制台:
Loading "flash:c2960-lanbasek9-mz.122-55.SE1.bin"...@@@@@@@@@@@@@@@@@@@@@@
File "flash:c2960-lanbasek9-mz.122-55.SE1.bin" uncompressed and installed,
entry point: 0x3000
<
CPU架构是PowerPC 32位BigEndian,将⼆进制⽂件加载到0x3000:
字符串的发现
在了解了IDA中的⼤部分功能后,我们可以看到固件末尾的字符串的交叉错误:
思科Catalyst 2960交换机中的CVE-2017-3881漏洞分析
“CISCO_KITS”字符串由return_cisco_kits函数引⽤,该函数只将该字符串返回为char *。我们将重点关注调⽤return_cisco_kits的
call_cisco_kits函数0x0004ED8C:
思科Catalyst 2960交换机中的CVE-2017-3881漏洞分析
因为telnet代码对于客户端和服务器⽽⾔是对称的,我们实际上可以看到发送到服务器端的缓冲区的格式 – %c%s%c%d:%s:%d :,这实际上与发送缓冲区为 x03CISCO_KITS  x012 :: 1的观察到的请求命令是⼀致的:
if ( telnet_struct->is_client_mode ) // client mode? then send "CISCO_KITS" string{
if ( telnet_struct->is_client_mode == 1 )
{
cisco_kits_string_2 = (char *)return_cisco_kits();
int_two = return_2();
tty_str = get_from_tty_struct((telnet_struct *)telnet_struct_arg->tty_struct);
*(_DWORD *)&telnet_struct_arg->tty_struct[1].field_6D1;
format1_ret = format_1(
128,
(int)&str_buf[8],
"%c%s%c%d:%s:%d:",
3,
cisco_kits_string_2,
1,
int_two,
tty_str,
0);
telnet_struct = (telnet_struct *)telnet_send_sb(
(int)telnet_struct_arg,
36,
0,
&str_buf[8],
format1_ret,
v8,
v7,
v6);
}}
注意事项有两个%s字符串修饰符,但是在CISCO_KITS的协议样本中只有⼀个字符串实际存在,第⼆个字符串是空的,并且被限制在两个字符之间。通过进⼀步观察相同功能的控制流程,我们注意到处理第⼆个字符串时所发⽣的过程:
for ( j = (unsigned __int8)*string_buffer; j != ':'; j = (unsigned __int8)*string_buffer )// put data before second ":" at &str_buf + 152{
str_buf[v19++ + 152] = j;
++string_buffer;}
我们在第⼆个%s字符串中发送的数据实际上被复制到了:char,⽽会不检查⽬标缓冲区驻留在堆栈上的⽬标边界,这会造成缓冲区溢出:获取代码执⾏权限
获取指令指针的控制很容易,因为指令指针已被我们发送的缓冲区给覆盖了。但问题是驻留在内存中的栈和堆是不可执⾏的,这实际上是启⽤数据和指令缓存的效果:
思科Catalyst 2960交换机中的CVE-2017-3881漏洞分析
由于没有办法在堆栈上执⾏代码,所以我们不得不将其⽤作数据缓冲区并重新使⽤固件中的现有代码。链接函数epilogs来执⾏任意的内存写⼊,看看0x00F47A34的反编译函数:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。