漏洞简介
东胜物流软件是青岛东胜伟业软件有限公司一款集订单管理、仓库管理、运输管理等多种功能于一体的物流管理软件。东胜物流信息管理系统 MvcShipping/MsBaseInfo/GetProParentModuTreeList 接口存在SQL注入漏洞,未经身份验证的远程攻击者除了可以利用SQL注入漏洞获取数据库中的信息(例如,管理员后台密码、站点的用户个人信息)之外,甚至在高权限的情况可向服务器中写入木马,进一步获取服务器系统权限。
影响版本
fofa语法
(body="FeeCodes/CompanysAdapter.aspx" || body="dhtmlxcombo_whp.js" || body="dongshengsoft" || body="theme/dhtmlxcombo.css") && body="东胜"
漏洞分析
根据.NET MVC框架特点找到DSWeb.MvcShipping中对于路由的定义
using System.Web.Mvc;
#nullable disable
namespace DSWeb.MvcShipping;
public class MvcShippingRegistration : AreaRegistration
{
public override string AreaName => "MvcShipping";
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute("MvcShipping_default", "MvcShipping/{controller}/{action}/{id}", (object) new
{
action = "Index",
id = UrlParameter.Optional
});
}
}
GetProParentModuTreeList
在DSWeb.MvcShipping.Controllers下找到MsBaseInfoController里的GetProParentModuTreeList()方法
public ContentResult GetProParentModuTreeList(string PARENTID)
{
List<CustomDbParamter> dbparams = new List<CustomDbParamter>();
CustomDbParamter customDbParamter1 = new CustomDbParamter();
((DbParameter) customDbParamter1).ParameterName = "@oper";
((DbParameter) customDbParamter1).DbType = (DbType) 16 /*0x10*/;
((DbParameter) customDbParamter1).Direction = (ParameterDirection) 1;
((DbParameter) customDbParamter1).Value = (object) Convert.ToString(this.Session["USERID"]);
dbparams.Add(customDbParamter1);
CustomDbParamter customDbParamter2 = new CustomDbParamter();
((DbParameter) customDbParamter2).ParameterName = "@strCondition";
((DbParameter) customDbParamter2).DbType = (DbType) 16 /*0x10*/;
((DbParameter) customDbParamter2).Direction = (ParameterDirection) 1;
((DbParameter) customDbParamter2).Value = (object) $" and PARENTID='{PARENTID}'";
dbparams.Add(customDbParamter2);
string str = Convert.ToString(this.Session["LANGUAGES"]);
string prcName = "P_userRight";
if (string.op_Equality(str, "en-us"))
prcName = "P_userRight_Ename";
string rptJsonResult = RptHelper.GetRptJsonResult(0, 100, PubSysDAL.GetMsSqlPrcDataSet(prcName, dbparams, "Result_Set"), "Result_Set", false);
return new ContentResult() { Content = rptJsonResult };
}
非常明显的SQL注入漏洞:参数PARENTID被直接拼接进SQL语句中$" and PARENTID='{PARENTID}'";执行,从而导致的注入漏洞。
当然,此Controller下的多个方法也存在类似的SQL注入漏洞
GetCustomerRefList
// MsBaseInfoDAL.cs
public static List<CustomerRefModel> GetCustomerRefList(string strCondition) {
// ...
if (!string.IsNullOrEmpty(strCondition))
strSql.Append(" and " + strCondition); // 直接拼接外部输入
// ...
using (IDataReader idataReader = DatabaseFactory.CreateDatabase().ExecuteReader((CommandType) 1, strSql.ToString()))
// CommandType 1 是 CommandType.Text,直接执行拼接后的字符串
}
condition 参数完全受控于用户,攻击者可以构造恶意 SQL 语句,绕过正常的业务逻辑。由于是 MSSQL 环境,攻击者可以利用 UNION SELECT 获取其他表(如 [user])的数据,或者利用 WAITFOR DELAY 进行时间盲注。
GetModuTreeRefList
// MsBaseInfoController.cs
public ContentResult GetModuTreeRefList(string PARENTID) {
string strCondition = $"PARENTID='{PARENTID}'"; // 字符串插值拼接
// 后续逻辑中虽然有 if else 判断 PARENTID 的值,但如果传入的值不匹配任何 if 条件,
// strCondition 依然保持初始的拼接结果,并传入 DAL。
List<ModuTreeRefModel> moduTreeRefList = DSWeb.MvcShipping.DAL.MsBaseInfoDAL.MsBaseInfoDAL.GetModuTreeRefList(strCondition, ...);
}
虽然代码中有针对特定 GUID 的 if 判断,但攻击者只需传入一个不符合这些条件的恶意字符串,即可绕过逻辑。
SaveUserQuerySetting
// MsBaseInfoDAL.cs
public static DBResult SaveUserQuerySetting(..., string userid, string formname, ...) {
// 虽然部分参数使用了参数化查询,但 Delete 语句是拼接的:
DbCommand sqlStringCommand2 = database.GetSqlStringCommand($"Delete from user_query_setting where formname='{formname}' and userid='{userid}' ");
database.ExecuteNonQuery(sqlStringCommand2, transaction);
}
攻击者可以通过 formname 参数注入恶意 SQL。由于紧接着会执行删除操作,这可能导致 user_query_setting 表中的数据被全部清空(通过 1' OR '1'='1)。
以及其他接口均存在类似的 condition 拼接问题,分析逻辑一致:
GetPortRefListGetOurPortRefListGetOpEdiLogGetGoodsRefListGetStlModeListGetAllBANKListGetCodeRptFeeGroupGetCwAccitemsCurrencyList
漏洞复现
GET /MvcShipping/MsBaseInfo/GetProParentModuTreeList?PARENTID=SQLI_POC&&_dc=1678901234567&page=1&start=0&limit=25 HTTP/1.1
Host: dongsheng.mrxn.net

成功延时 5 秒


