漏洞简介
东胜物流软件是青岛东胜伟业软件有限公司一款集订单管理、仓库管理、运输管理等多种功能于一体的物流管理软件。东胜物流信息管理系统 Shipping/FeeModifySource.aspx 接口存在SQL注入漏洞,未经身份验证的远程攻击者除了可以利用 SQL 注入漏洞获取数据库中的信息(例如,管理员后台密码、站点的用户个人信息)之外,甚至在高权限的情况可向服务器中写入木马,进一步获取服务器系统权限。
影响版本
fofa语法
(body="FeeCodes/CompanysAdapter.aspx" || body="dhtmlxcombo_whp.js" || body="dongshengsoft" || body="theme/dhtmlxcombo.css") && body="东胜"
漏洞分析
根据 Shipping/FeeModifySource.aspx 的代码引用<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FeeModifySource.aspx.cs" Inherits="DSWeb.Shipping.FeeModifySource" %>,在dll中找到DSWeb.Shipping.FeeModifySource的逻辑实现
protected void Page_Load(object sender, EventArgs e)
{
if (this.Request.QueryString["handle"] != null)
this.strHandle = this.Request.QueryString["handle"].ToString().Trim().ToLower();
if (this.Request.QueryString["oplb"] != null)
this.stroplb = this.Request.QueryString["oplb"].ToString();
if (this.Request.QueryString["id"] != null)
this.strFeeID = this.Request.QueryString["id"].ToString().Trim().ToLower();
if (this.Request.QueryString["applytype"] != null)
this.iApplyType = int.Parse(this.Request.QueryString["applytype"].ToString().Trim());
if (this.Request.QueryString["applystate"] != null)
this.iApplyState = int.Parse(this.Request.QueryString["applystate"].ToString().Trim());
if (this.Request.QueryString["checkstate"] != null)
this.iCheckState = int.Parse(this.Request.QueryString["checkstate"].ToString().Trim());
if (this.strHandle.Equals("apply"))
{
string cells = this.GetCells(this.strFeeID, this.iApplyType, this.iApplyState, this.iCheckState);
this.Response.ContentType = "text/xml";
cells.Replace("&", "&");
this.Response.Write(cells);
}
else if (this.strHandle.Equals("exist"))
{
this.Response.Write(this.IsExistFee(this.strFeeID));
}
else
{
this.Response.ContentType = "text/xml";
this.Response.Write("-2");
}
}
当handle=apply且applystate=0时,跟进GetCells方法
private string GetCells(
string tempFeeID,
int tempApplyType,
int tempApplyState,
int tempCheckState)
{
FeeDA feeDa = new FeeDA();
FeeModifyDA feeModifyDa = new FeeModifyDA();
if (tempApplyState == 0)
{
DataTable dataTable = new DataTable();
string strSql = $" SELECT {""} GID, FEESTATUS, FEENAME, CUSTOMERNAME, UNIT, UNITPRICE, QUANTITY,COMMISSIONRATE,AMOUNT, CURRENCY, EXCHANGERATE,FEEFRT,REMARK,ISADVANCEDPAY FROM ch_fee WHERE 1> 0 {$" AND GID = '{tempFeeID}'"} {" ORDER BY ENTERDATE ASC "}";
DataTable statusNameTable = this.getStatusNameTable(feeDa.GetExcuteSql(strSql).Tables[0]);
......
参数tempFeeID即外部用户可控参数id被直接拼接在string strSql = $" SELECT {""} GID, FEESTATUS, FEENAME, CUSTOMERNAME, UNIT, UNITPRICE, QUANTITY,COMMISSIONRATE,AMOUNT, CURRENCY, EXCHANGERATE,FEEFRT,REMARK,ISADVANCEDPAY FROM ch_fee WHERE 1> 0 {$" AND GID = '{tempFeeID}'"} {" ORDER BY ENTERDATE ASC "}";SQL语句中执行,无任何过滤或校验,从而造成SQL注入漏洞。
以及当 applystate!=0 时的多个分支
例如 applytype=1, checkstate=1 时:
strSql1 = $"SELECT GID,APPLYSTATUS, FEENAME, CUSTOMERNAME, UNIT, UNITPRICE, QUANTITY,COMMISSIONRATE,AMOUNT, CURRENCY,EXCHANGERATE,FRT,REMARK,ISADVANCEDPAY FROM ch_fee_modify WHERE FEEID = '{tempFeeID}' AND APPLYTYPE = {tempApplyType} AND APPLYSTATUS = {1} ";
- 参数类型确认:
tempFeeID为字符串类型(在SQL中使用单引号包裹) - 过滤机制缺失:仅进行了
.Trim().ToLower()处理,未做SQL注入防护 - 拼接方式:使用字符串插值
$"{tempFeeID}"直接拼接,未使用参数化查询 - 执行方式:通过
feeDa.GetExcuteSql(strSql)直接执行拼接的SQL
根据代码逻辑,触发不同SQL注入需要满足以下条件:
| 场景 | handle | applystate | applytype | checkstate | 触发位置 |
|---|---|---|---|---|---|
| 场景1 | apply | 0 | 任意 | 任意 | ch_fee表查询 |
| 场景2 | apply | 非0 | 1 | 1 | ch_fee_modify表(APPLYSTATUS=1) |
| 场景3 | apply | 非0 | 1 | 2 | ch_fee_modify表(APPLYSTATUS=2或3) |
| 场景4 | apply | 非0 | 1 | 3 | ch_fee_modify表(所有记录) |
| 场景5 | apply | 非0 | 2 | 1 | ch_fee_modify表(APPLYSTATUS=1) |
| 场景6 | apply | 非0 | 2 | 2 | ch_fee_modify表(APPLYSTATUS=2或3) |
| 场景7 | apply | 非0 | 2 | 3 | ch_fee_modify表(所有记录) |
漏洞复现
GET /Shipping/FeeModifySource.aspx?handle=apply&applystate=1&checkstate=1&applytype=1&oplb=1&id=SQLI_POC&val=b9733091-e978-4cb5-a845-765a82ca1217 HTTP/1.1
Host: dongsheng.mrxn.net

成功延时 5 秒

