第四章:思科IOS数据库结构分析

说实话,搞思科固件逆向这么多年,我最头疼的就是搞清楚它的数据库结构。不是技术有多难,而是思科这老哥藏得深。今天咱们就来扒一扒IOS的文件系统布局、NVRAM里到底存了什么,以及Running-Config和Startup-Config这对“双胞胎”是怎么工作的。

IOS文件系统布局:一个被隐藏的“小世界”

很多人以为思科路由器就是个黑盒子,跑着命令行。其实它内部有一套完整的文件系统。我当年第一次用dir命令看到flash里的目录结构时,说实话有点惊讶——这不就是个微型Linux吗?

典型的IOS文件系统布局是这样的:

flash:/
├── ios_image.bin          # 主系统镜像
├── config.text            # 启动配置文件
├── private-config.text    # 私有配置(加密部分)
├── crashinfo_xxx          # 崩溃转储信息
├── core_dump_xxx          # 核心转储
├── vlan.dat               # VLAN数据库(交换机)
├── multiple-fs/           # 多文件系统区域
└── lost+found/            # 文件系统修复残留

嗯,这里要注意一点:不同型号、不同IOS版本,文件系统布局会有差异。我在逆向一个Cisco 2901时,发现它的flash里居然有个隐藏分区,里面存着bootloader的备份。这玩意儿官方文档里可没写。

核心要点:IOS的文件系统本质上是一个扁平化的FAT-like结构,但思科做了很多魔改。比如文件名最长支持多少?我记得是48个字符,超过这个长度会被截断。这个坑我踩过——恢复数据时文件名对不上,折腾了两天。

NVRAM与启动配置数据库

NVRAM,全称Non-Volatile Random Access Memory。说白了就是断电不丢数据的RAM。思科路由器里,NVRAM主要干一件事:存Startup-Config

但问题来了——NVRAM到底有多大?

设备型号 NVRAM容量 典型用途
ISR 2800系列 256KB - 512KB 启动配置 + 日志缓冲区
ISR 4300系列 2MB - 8MB 启动配置 + 硬件看门狗记录
Catalyst 3750 512KB 启动配置 + VLAN信息
ASR 1000系列 16MB(共享) 启动配置 + 崩溃信息

你想想看,一个企业级路由器的启动配置,可能就几十KB。但NVRAM却给了几百KB甚至几MB。多出来的空间干嘛用?我逆向过几个固件后发现,思科把NVRAM分成了多个区域:

  • 配置区:存放startup-config,通常从偏移0x0000开始
  • 日志区:存放系统日志的环形缓冲区
  • 硬件状态区:记录硬件自检结果、温度阈值等
  • 保留区:用于未来扩展,或者存放一些“小秘密”

实战技巧:如果你在恢复数据时发现NVRAM里有多余的空间,别急着忽略。我曾经在一个被格式化的NVRAM里,从保留区挖出了三年前的配置备份。客户当场就愣住了——他自己都不知道还有这玩意儿。

Running-Config与Startup-Config的存储机制

这对“双胞胎”是思科配置管理的核心。很多人以为它们只是简单的文本文件,其实背后的存储机制挺有意思。

Running-Config:活在内存里的“影子”

Running-Config存在哪里?答案是DRAM。它不是一个独立的文件,而是IOS内核中一系列数据结构的“快照”。当你敲show running-config时,IOS会遍历这些数据结构,把它们序列化成文本输出。

我当年逆向这个机制时,发现了一个有趣的现象:Running-Config在内存中是以链表+哈希表的形式组织的。每个配置项是一个节点,节点之间通过指针连接。这样做的好处是增删改查都很快,但坏处是——如果内存出现位翻转(bit flip),配置就乱了。

// 简化后的内存结构示意
struct config_entry {
    char *key;              // 配置键,如 "hostname"
    char *value;            // 配置值,如 "Router1"
    struct config_entry *next;  // 链表指针
    uint32_t crc32;         // 校验和,防止内存损坏
};

看到那个crc32了吗?思科自己也怕内存出错。我在一次数据恢复中,就遇到过crc32校验失败导致配置加载不完整的情况。嗯,那台设备重启后直接进了ROMmon模式。

Startup-Config:NVRAM里的“定海神针”

Startup-Config的存储就规矩多了。它本质上是一个经过压缩和校验的文本文件,存放在NVRAM的配置区。思科用了什么压缩算法?我逆向后发现,大部分版本用的是LZSS(Lempel-Ziv-Storer-Szymanski)的变种。

为什么用压缩?说白了就是为了省空间。NVRAM容量有限,一个几百KB的配置文件压缩后可能就几十KB。而且压缩后还能顺便做一层“混淆”——虽然思科没明说,但这确实增加了逆向的难度。

注意:Startup-Config在写入NVRAM时,会先计算整个文件的MD5校验和,然后写入文件末尾。下次启动时,IOS会重新计算校验和并比对。如果对不上,就会报错并尝试从备份加载。这个机制我见过很多次——有人手动修改了NVRAM里的配置,结果重启后配置丢失,就是因为校验和没更新。

两者之间的“同步”机制

Running-Config和Startup-Config是怎么同步的?很多人以为copy running-config startup-config就是简单的文件复制。其实不然。

这个命令的执行流程是这样的:

  1. IOS遍历Running-Config的所有配置项
  2. 序列化成文本格式(就是你在CLI看到的样子)
  3. 用LZSS压缩算法压缩文本
  4. 计算压缩后数据的MD5校验和
  5. 将校验和追加到数据末尾
  6. 写入NVRAM的配置区
  7. 更新NVRAM中的配置索引表

你看,步骤还挺多的。我当年写了一个工具,可以直接从NVRAM dump里提取并解压Startup-Config。核心逻辑就是:找到配置区起始位置,读取数据,跳过末尾的校验和,然后解压。说起来简单,但实际做的时候踩了不少坑——比如不同IOS版本的压缩参数不一样。

避坑指南:我曾经遇到过一个案例,客户说设备配置丢了,但NVRAM dump里明明有数据。后来发现,是配置索引表被破坏了。索引表里记录了配置文件的起始偏移和长度,如果这个表坏了,IOS就找不到配置。但数据本身还在NVRAM里。这种情况下,手动扫描NVRAM的整个区域,找到LZSS压缩的魔数(magic number),就能恢复配置。

知识体系总览

说了这么多,咱们用一张图来总结一下思科IOS数据库结构的核心逻辑:

思科IOS数据库结构核心逻辑 硬件存储层 Flash存储器 存放IOS镜像、配置文件 NVRAM 存放Startup-Config DRAM 存放Running-Config 逻辑存储层 IOS文件系统 FAT-like结构 配置数据库 LZSS压缩 + MD5校验 内存数据结构 链表 + 哈希表 配置同步:copy running-config startup-config → 序列化 → 压缩 → 校验 → 写入NVRAM

这张图把硬件层和逻辑层的关系讲清楚了。Flash、NVRAM、DRAM是物理基础,文件系统、配置数据库、内存数据结构是逻辑抽象。它们之间通过特定的协议和算法进行交互。

说实话,搞懂这些结构,对数据恢复来说就是拿到了“地图”。你知道数据存在哪里、怎么存的、怎么校验的,自然就知道怎么找回来。

个人经验:我建议你在做逆向时,先拿一个已知配置的设备做“黄金样本”。把它的NVRAM dump出来,对照着分析。这样你就能快速建立起“正常状态”的认知模型。以后遇到损坏的设备,一眼就能看出哪里不对劲。


公众号:蓝海资料掘金营,微信deep3321