手把手教你如何挖洞:CVE-2025-25257 Fortinet FortiWeb 匿名 SQL 注入漏洞动态调试实战
原文链接: https://mp.weixin.qq.com/s?__biz=Mzk0NTU5Mjg0Ng==&mid=2247492236&idx=1&sn=8d8564b4b92621d0ce1783198a801077
手把手教你如何挖洞:CVE-2025-25257 Fortinet FortiWeb 匿名 SQL 注入漏洞动态调试实战
原创 KCyber 自在安全 2025-07-13 00:01
最近一直比较忙,有段时间没有发文章了。后台有人问我写这么多技术文章花了多少时间?我想说再忙挤一挤时间还是有的,关键在于有没有兴趣写;还有人问我怎么学挖洞,正好今天看到这个漏洞,发现比较简单适合拿来入门学习,所以就想从如何深入调试分析的角度,教一下新手怎样分析漏洞。
环境搭建
下载虚拟机环境并提取固件。通过
mount
挂载磁盘,核心文件结构位于
rootfs.gz
:
刚好
binwalk
发布了新版本
binwalkv3
,采用
Rust
语言进行了代码重写,正好下载体验一把:
cargo install binwalk
binwalk -Me rootfs.gz
完美提取到了文件结构:
启动虚拟机后需要进行访问配置:
#配置管理接口
config system interface
edit port1
set ip *.*.*.* 255.255.255.0
set allowaccess ping https ssh http
next
end
#配置网关
config router static
edit 1
set gateway *.*.*.1
set device port1
next
end
#配置dns服务
config system dns
set primary 8.8.8.8
set secondary 8.8.4.4
end
v7.0.x
版本其实也可以通过配置命令进入底层
bash
。系统是
x86_64
结构,可以上传
gdbserver
进行调试。
漏洞分析
FortiWeb
启动的
Web
服务对应
/bin/httpsd
进程:
#netstat -anpt
tcp 0 0 :::8 :::* LISTEN 2804/httpsd
tcp 0 0 :::43 :::* LISTEN 2804/httpsd
# ps -l |grep 2804
S 0 2804 1 99.2m 26096 0:0 08:28 00:00:00 /bin/httpsd
S 0 4348 2804 4320 616 0:0 09:48 00:00:00 /bin/rotatelogs -t /var/log/apache_logs/access_log 1M
S 0 4349 2804 99.4m 16856 0:0 09:48 00:00:00 /bin/httpsd
S 0 10988 2804 100m 22184 0:0 12:23 00:00:00 /bin/httpsd
S 0 12267 2804 100m 21764 0:0 12:23 00:00:00 /bin/httpsd
加载
httpsd
,然后尝试搜索潜在注入触发点,可以找到多个
sql
语句:
以
get_fabric_user_by_token
函数为例,存在比较明显的字符串拼接:
向上搜索,在
fabric_access_check
函数中存在数据库操作,并且调用了
get_fabric_user_by_token
,输入参数来自于
header
头中的
Authorization
:
继续搜索
fabric_access_check
的调用点,定位到
sub_637E20
,该函数调用了
Apache
框架中
URL
处理的钩子注册函数
ap_hook_handler
:
__int64 sub_637E20()
{
ap_hook_handler(sub_637D60, 0LL, 0LL, 10LL);
return ap_hook_handler(sub_637DC0, 0LL, 0LL, 10LL);
}
路由规则定义为
fabric_widget_detail-handler
:
可以在配置文件
httpd.conf
中找到对应的
URL
定义:
<Location ~ "/api/v[0-9]/fabric/widget/[a-z]+">
SetHandler fabric_widget_detail-handler
</Location>
除此之外,还支持以下访问路由规则:
– •
fabric_widget-handler
->
/api/v[0-9]/fabric/widget
<Location ~ "/api/v[0-9]/fabric/widget">
SetHandler fabric_widget-handler
</Location>
- •
fabric_device_status-handler
->
/api/fabric/device/status
<Location "/api/fabric/device/status">
SetHandler fabric_device_status-handler
</Location>
以
/api/v1/fabric/widget/abc
为例,构造验证请求。
因为这里通过
sscanf
函数进行赋值, 所以字符串中不能含有空格,否则将会被截断,可以利用
/**/
绕过:
调试确定字符串直接拼接到了
SQL
语句,导致出现注入漏洞:
完整调用栈如下:
至于漏洞利用过程这里就不讲了,主要教大家如何发现和分析调试漏洞。
修复方式
新版本的
sql
语句采用了预编译模式:
由于传播、利用此文档提供的信息而造成任何直接或间接的后果及损害,均由使用本人负责,公众号及文章作者不为此承担任何责任。