以下面这个CVE为例调研了解一下如何找到漏洞。
CVE-2018-13379
简介
该漏洞是由于FortiOS SSL VPN的HTTP接口未正确处理特殊路径请求,允许未经身份验证的攻击者通过特制的HTTP资源请求下载系统文件。
原理
具体来说,FortiGate SSL VPN设备的/remote/fgt_lang接口原本设计用于动态加载管理界面的语言文件。当用户访问设备的管理界面时,前端会根据用户选择的语言(如英文、中文),通过接口加载对应的语言包。
接口是如何加载对应语言包的呢?它通过lang参数指定语言代码(如en表示英文)发送GET请求到服务器,服务器返回对应的JSON语言文件。
合法请求如下:
在代码实现中,接口/remote/fgt_lang内部映射到文件系统的 /migadmin/lang 目录,并通过以下逻辑拼接路径:
这个函数的作用是将lang变量的值格式化到一个文件路径字符串中,比如合法请求中lang="en",生成的字符串为/migadmin/lang/en.json,并将这个字符串写入缓冲区s。
这里自动附加文件扩展名,似乎我们只能读取json文件。
但是,实际上我们可以滥用snprintf的功能。snprintf函数最多将size-1(这里是64-1=63字符,因为要留一个字符位置给结束符/0)个字符写入输出缓冲区。因此,我们只需要构造特定的lang参数,使整个文件路径字符串超过缓冲区大小,后面的.json这5个字符就会被截断掉,然后我们就可以读取任何我们想读的东西。
攻击
对于攻击者来说,对于未修复CVE-2018-13379的FortiGate设备。发送以下请求即可触发漏洞攻击:
这里的lang参数为48字符长度的/../../../..//dev/cmdb/sslvpn_websession。
它会使得.json被截断,导致缓冲区s中的数据为/migadmin/lang/../../../..//dev/cmdb/sslvpn_websession。通过多层../返回到根目录,访问系统文件/dev/cmdb/sslvpn_websession,该文件是FortiGate设备存储SSL VPN会话数据的文件,包含用户名和明文密码等用户会话信息。
总的来说,此漏洞是身份验证前缺陷,这意味着攻击者无需对易受攻击的设备进行身份验证即可利用它向特定端口发送包含路径遍历序列的特制请求,以从设备读取任意文件。
防御
官方的防御方法是立即升级固件,升级到FortiOS 6.0.5+或官方修复版本,以根除漏洞。
我觉得大概解决方法是防火墙检测HTTP请求中是否包含路径遍历序列(../、..%2f),如果有就丢弃或者警报。然后Web应用防火墙进行输入验证,禁止lang参数包含特殊字符(/、.、%等)。还有就是设备限制访问源,仅允许受信任的IP访问SSL VPN管理接口。
漏洞挖掘
那么,如何发现固件中与通信相关的漏洞?
第一步:获取固件并解包
固件是嵌入在硬件设备中的软件,控制设备的基础功能(如路由器的网络处理、摄像头的数据传输)。来源包括:厂商官网、设备更新包、第三方漏洞库(如 Exploit Database)。
解包工具使用Binwalk,用来从固件文件中提取文件系统(类似解压zip文件)。
操作:
输出结果:
目的:获取设备内部运行的所有文件,为后续分析做准备。
第二步:识别网络服务程序
网络服务是在设备上运行的程序,负责处理网络请求(如Web接口、API服务)。常见服务有:httpd(Web服务器)、ssh(远程登录)、mqtt(物联网消息协议)。
那么如何找到网络服务程序呢?
操作:
httpd和lighttpd这两个是常见的Web服务器程序,负责处理HTTP请求。在固件中,它们通常是漏洞的入口点(如未授权接口、路径遍历等)。
这个操作可以在固件解包后的文件系统(squashfs-root)中,快速定位所有与Web服务相关的程序文件。
输出示例:
squashfs-root/usr/sbin/httpd # 找到Web服务程序
目的:定位处理网络请求的关键程序,后续分析其代码逻辑。
第三步:静态分析网络服务程序
静态分析是在不运行程序的情况下,通过反编译、查看代码结构等方式分析程序行为。
使用的工具为Ghidra,它的作用是将二进制文件(如 httpd)反编译为人类可读的伪代码。
操作步骤:
打开Ghidra→新建项目→导入文件httpd。选择正确的CPU架构(如 MIPS、ARM),点击“分析”。然后在“函数”列表中双击main函数,查看反编译结果。
接下来,我们如何定位HTTP路由逻辑,找到程序处理不同URL路径(如 /api、/remote)的代码呢?
比如对于/remote接口,我们在Ghidra的“已定义字符串”列表中搜索 /remote,找到包含该路径的字符串(如 /remote/fgt_lang)。然后,右键点击目标字符串 /remote/fgt_lang → 查找引用位置。Ghidra会显示所有引用该字符串的代码位置(通常是处理该URL的函数)。接下来双击交叉引用条目,Ghidra就会自动跳转到引用该字符串的代码位置。
此时可查看反编译后的伪代码,分析处理逻辑。
攻击面枚举(Attack Surface Enumeration)
我们不止可以查找 /remote这个接口,对于不同的设备功能,如VPN、Web管理、文件共享、API服务等,我们可以搜索不同的接口,找到不同的字符串。
推测接口路径:
VPN → /remote, /vpn, /sslvpn
管理后台 → /admin, /manage
文件操作 → /upload, /download
系统调试 → /debug, /test
如CVE-2018-13379是FortiOS SSL VPN的漏洞,它可能就是搜索VPN相关的 /remote接口找到的。
假设在 Ghidra 中找到如下伪代码:
漏洞点:未检查 lang 参数是否包含 ../,导致路径遍历。
第四步:追踪用户输入流
用户输入来源是攻击者可以控制的输入,如URL参数、HTTP头部、上传文件。我们进行数据流分析,追踪参数从获取到被使用的完整路径。
操作:
定位参数获取:在代码中找到 get_query_param("lang")。
追踪变量传递:查看 lang 变量如何传递到 fopen(path)。
检查过滤逻辑:确认是否调用了过滤函数(如 sanitize_path())。
常见危险函数:
尝试在 Ghidra 中搜索这些函数名,查看是否被用户输入直接控制。
第五步:识别未授权接口
还可以查找未认证的接口。
操作:
在代码中搜索 check_auth()、verify_token() 等认证函数。
确认处理 /remote/fgt_lang 的代码是否调用了这些函数。
漏洞代码示例:
本来想尝试复现一下找到CVE-2018-13379这个漏洞的过程的,但是FortiOS的存在漏洞的固件必须要购买它们的技术支持合同才能下载,在别的非官方渠道也没找到资源,于是作罢。