经验交流|系统安全修正|避免反射调用执行程序删除我的文件和目录

摘要:

1、我网站有个在线测试功能,通过Ajax调用后台一个方法并返回方法
2、后台的方法是eKing.EkUtil.Helpers.eKingEkUtilHelper,一个工具类
3、工具类里面有文件/目录的删除操作
4、我用ExampleUtilHandler做Ajax中转反射调用eKingEkUtilHelper里面的方法
5、(安全漏洞)如果别人知道我的规则和文件操作的方法名,外部执行就有可能读取我的服务器文件内容或删除我服务器的文件
6、修正方式(见下文)
 
原文链接:
 
一、在线测试功能样例:

在线测试样例

在线测试样例

 

在线示例的JavaScript代码

 

                function GetAjaxData() {


                    var ajxData = [];

                    ajxData.push({ name: "DllName", value: "eKing.EkUtil" });
                    ajxData.push({ name: "MethodName", value: "IdCardNumberToStar" });
var MP1 = CtrlGetValue("txt_Input", false, false);

ajxData.push({ name: "ParamsCount", value: "1" });
ajxData.push({ name: "_MP1", value: MP1 });

                    return ajxData;
                }

                // 确定操作 //
                function OkOper() {

                    var ajxData = GetAjaxData();
                    var ajaxUrl = GlobalPhyPath + "/Handlers/ExampleUtilHandler.ashx";

                    $.ajax({
                        cache: false,
                        async: true,
                        url: ajaxUrl,
                        data: ajxData,
                        type: "post",
                        success: function(data) {
                            var outputCtrl = document.getElementById("txt_Result");

                            outputCtrl.value = data;

                            document.getElementById("span_exectime").innerHTML = new Date();
                        }
                    });
                }

示例链接:

IdCardNumberToStar|身份证号码转星号

二、eKingEkUtilHelper工具类的方法

 
 
 
三、ExampleUtilHandler的逻辑代码
 

ExampleUtilHandler.ashx原逻辑代码

 

<%@ WebHandler Language="C#" Class="ExampleUtilHandler" %>

using System;
using System.Web;
using System.Collections.Generic;

public class ExampleUtilHandler : IHttpHandler {
    
    /// <summary>
    /// 
    /// </summary>
    /// <param name="context"></param>
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";

        string theResult = null;
        try
        {
            theResult = ToResult(context, null);
        }
        catch (Exception err)
        {
            theResult = "[系统异常]:" + err.Message;
        }

        // 编码格式 //
        context.Response.ContentEncoding
            =
            System.Text.Encoding.GetEncoding("gb2312"); // System.Text.Encoding.UTF8;

        context.Response.Write(theResult);
    }

    /// <summary>
    /// List-string的值转成object[] - ListStringToObjArray +
    /// </summary>
    /// <param name="sList"></param>
    /// <returns></returns>
    protected object[] ListStringToObjArray
        (System.Collections.Generic.List<string> sList)
    {
        int iCount = sList.Count;
        
        object[] p = new object[iCount];

        for (int i = 0; i < iCount; ++i)
        {
            p[i] = sList[i];
        }

        return p;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="context"></param>
    /// <param name="paramsSize"></param>
    /// <returns></returns>
    protected List<string> ListStringParamsGet(HttpContext context, int paramsSize)
    {
        List<string> theResult = new List<string>();

        string str = null;
        int paramsSizeAddOne = paramsSize + 1;
        for (int i = 1; i < paramsSizeAddOne; ++i)
        {
            str = context.Request.Form["_MP" + i.ToString()];
            theResult.Add(str);  
        }

        return theResult;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="context"></param>
    /// <param name="xdbHelper"></param>
    /// <returns></returns>
    protected string ToResult(HttpContext context, SlowX.DAL.Helpers.DBHelper xdbHelper)
    {
        string methodName = context.Request.Form["MethodName"];

        if (methodName == null || methodName.Length == 0)
        {
            return "[系统异常]:方法名不能为空。";
        }
        
        string dllName = context.Request.Form["DllName"];
        int paramsSize = int.Parse(context.Request.Form["ParamsCount"]);
        List<string> pList = ListStringParamsGet(context, paramsSize);

        Type utType = null;
        object ut = null;

        string lowerDllName = null;

        if (dllName == null)
            lowerDllName = "";
        else
            lowerDllName = dllName.Trim().ToLower();

        switch (lowerDllName)
        {
            case "slowx.createcodeexampleutil":
                SlowX.CreateCodeExampleUtil.Helpers.CreateCodeExampleUtilHelper
                createCodeExampleUtil
                =
                SlowX.CreateCodeExampleUtil.Helpers.CreateCodeExampleUtilHelper.GetInstance();

                utType = createCodeExampleUtil.GetType();
                ut = createCodeExampleUtil;
                break;
            case "slowx.createcodeutil":
                SlowX.CreateCodeUtil.Helpers.SlowXCreateCodeUtilHelper
                createCodeUtil
                =
                SlowX.CreateCodeUtil.Helpers.SlowXCreateCodeUtilHelper.GetInstance();

                utType = createCodeUtil.GetType();
                ut = createCodeUtil;
                break;
            case "eking.ekutil":
                eKing.EkUtil.Helpers.eKingEkUtilHelper
                   ekUtil
                   =
                   eKing.EkUtil.Helpers.eKingEkUtilHelper.GetInstance();

                utType = ekUtil.GetType();
                ut = ekUtil;
                break;
            case "slowx.tool":
                SlowX.Tool.Utils.Util tool
                =
                SlowX.Tool.Utils.Util.GetInstance();

                utType = tool.GetType();
                ut = tool;
                break;
            default:
                SlowX.ExampleUtil.Utils.Util
                utH
                =
                SlowX.ExampleUtil.Utils.Util.instance;

                utType = utH.GetType();
                ut = utH;
                break;

        }
         
         
        System.Reflection.MethodInfo mi 
            =
            utType.GetMethod(methodName);

        if (mi == null)
        {
            return "没有找到对应的方法";
        }

        object[] p = ListStringToObjArray(pList);

        object obj = mi.Invoke(ut, p);

        if (obj == null)
            return "null";

        return obj.ToString();
    }
    
    public bool IsReusable {
        get {
            return false;
        }
    }

}

 

安全漏洞:

(1)DllName:eKing.EkUtil
(2)MethodName:FileDelete
(3)参数:文件路径
 
就有可能通过Ajax执行删除我服务器的文件
 
四、修正方式
 
就有可能通过Ajax执行删除我服务器的文件

 

修正后的eKingEkUtilHelper

 

using eKing.EkUtil.IHelpers;
using System;
using System.Collections.Generic;
using System.Reflection;

namespace eKing.EkUtil.Helpers
{
    /// <summary>
    /// 
    /// </summary>
    public partial class eKingEkUtilHelper
        :
        IeKingEkUtilHelper
    {
        /// <summary>
        /// 
        /// </summary>
        protected readonly static eKingEkUtilHelper
            m_instance
            =
            new eKingEkUtilHelper();

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static eKingEkUtilHelper GetInstance()
        {
            return m_instance;
        }

        /// <summary>
        /// 
        /// </summary>
        public eKingEkUtilHelper()
        {
             
        }


        /// <summary>
        /// List-string的值转成object[] - ListStringToObjArray +
        /// </summary>
        /// <param name="sList"></param>
        /// <returns></returns>
        protected object[] ListStringToObjArray
            (System.Collections.Generic.List<string> sList)
        {
            int iCount = sList.Count;

            object[] p = new object[iCount];

            for (int i = 0; i < iCount; ++i)
            {
                p[i] = sList[i];
            }

            return p;
        }

        /// <summary>
        /// 反射调用
        /// </summary>
        /// <param name="methodName"></param>
        /// <param name="pList"></param>
        /// <returns></returns>
        public string InvokeCall(string methodName, List<string> pList)
        {
            if (methodName == null || methodName.Length == 0)
            {

                throw new Exception
                    (
                        "方法:"
                        + MethodBase.GetCurrentMethod().ReflectedType.FullName
                        + " "
                        + MethodBase.GetCurrentMethod().ToString()
                        + " 发生异常:"
                        + "传入的字符串参数:"
                        + "methodName"
                        + "为null或为空。"
                    ); 
            }

            methodName = methodName.Trim();

            if (methodName.Length == 0)
            {

                throw new Exception
                    (
                        "方法:"
                        + MethodBase.GetCurrentMethod().ReflectedType.FullName
                        + " "
                        + MethodBase.GetCurrentMethod().ToString()
                        + " 发生异常:"
                        + "传入的字符串参数:"
                        + "methodName"
                        + "为null或为空。"
                    );
            }
            

            string lowerMethodName = methodName.Trim().ToLower();

            switch (lowerMethodName)
            {
                case "dirdelete":
                case "dircreatebyfullfilename":
                    return methodName+"方法不允许执行";
                default:
                    break;
            }

            Type utType = this.GetType();

            System.Reflection.MethodInfo mi
                =
                utType.GetMethod(methodName);

            if (mi == null)
            {
                return "没有找到对应的方法";
            }

            object[] p = ListStringToObjArray(pList);

            object obj = mi.Invoke(this, p);

            if (obj == null)
                return "null";

            return obj.ToString();
        }
    }
}

 

修正后的ExampleUtilHandler

 

<%@ WebHandler Language="C#" Class="ExampleUtilHandler" %>

using System;
using System.Web;
using System.Collections.Generic;

public class ExampleUtilHandler : IHttpHandler {
    
    /// <summary>
    /// 
    /// </summary>
    /// <param name="context"></param>
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";

        string theResult = null;
        try
        {
            theResult = ToResult(context, null);
        }
        catch (Exception err)
        {
            theResult = "[系统异常]:" + err.Message;
        }

        // 编码格式 //
        context.Response.ContentEncoding
            =
            System.Text.Encoding.GetEncoding("gb2312"); // System.Text.Encoding.UTF8;

        context.Response.Write(theResult);
    }

    /// <summary>
    /// List-string的值转成object[] - ListStringToObjArray +
    /// </summary>
    /// <param name="sList"></param>
    /// <returns></returns>
    protected object[] ListStringToObjArray
        (System.Collections.Generic.List<string> sList)
    {
        int iCount = sList.Count;
        
        object[] p = new object[iCount];

        for (int i = 0; i < iCount; ++i)
        {
            p[i] = sList[i];
        }

        return p;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="context"></param>
    /// <param name="paramsSize"></param>
    /// <returns></returns>
    protected List<string> ListStringParamsGet(HttpContext context, int paramsSize)
    {
        List<string> theResult = new List<string>();

        string str = null;
        int paramsSizeAddOne = paramsSize + 1;
        for (int i = 1; i < paramsSizeAddOne; ++i)
        {
            str = context.Request.Form["_MP" + i.ToString()];
            theResult.Add(str);  
        }

        return theResult;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="context"></param>
    /// <param name="xdbHelper"></param>
    /// <returns></returns>
    protected string ToResult(HttpContext context, SlowX.DAL.Helpers.DBHelper xdbHelper)
    {
        string methodName = context.Request.Form["MethodName"];

        if (methodName == null || methodName.Length == 0)
        {
            return "[系统异常]:方法名不能为空。";
        }
        
        string dllName = context.Request.Form["DllName"];
        int paramsSize = int.Parse(context.Request.Form["ParamsCount"]);
        List<string> pList = ListStringParamsGet(context, paramsSize);

        string lowerDllName = null;

        if (dllName == null)
            lowerDllName = "";
        else
            lowerDllName = dllName.Trim().ToLower();

        switch (lowerDllName)
        {
            case "slowx.createcodeexampleutil":
                SlowX.CreateCodeExampleUtil.Helpers.CreateCodeExampleUtilHelper
                createCodeExampleUtil
                =
                SlowX.CreateCodeExampleUtil.Helpers.CreateCodeExampleUtilHelper.GetInstance();

                return createCodeExampleUtil.InvokeCall(methodName, pList);
            case "slowx.createcodeutil":
                SlowX.CreateCodeUtil.Helpers.SlowXCreateCodeUtilHelper
                createCodeUtil
                =
                SlowX.CreateCodeUtil.Helpers.SlowXCreateCodeUtilHelper.GetInstance();

                return createCodeUtil.InvokeCall(methodName, pList);

            case "eking.ekutil":
                eKing.EkUtil.Helpers.eKingEkUtilHelper
                   ekUtil
                   =
                   eKing.EkUtil.Helpers.eKingEkUtilHelper.GetInstance();

                return ekUtil.InvokeCall(methodName, pList);
            case "slowx.tool":
                SlowX.Tool.Utils.Util tool
                =
                SlowX.Tool.Utils.Util.GetInstance();

                return tool.InvokeCall(methodName, pList);
            default:
                SlowX.ExampleUtil.Utils.Util
                utH
                =
                SlowX.ExampleUtil.Utils.Util.instance;

                return utH.InvokeCall(methodName, pList);

        }
         
     
    }
    
    /// <summary>
    /// 
    /// </summary>
    public bool IsReusable {
        get {
            return false;
        }
    }

}

 

posted @ 2018-08-12 08:58  看代码`lookdaima.com  阅读(157)  评论(0编辑  收藏  举报