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

摘要:

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;
}
}

}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值