经验交流|系统安全修正|避免反射调用执行程序删除我的文件和目录
摘要:
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();
}
});
}
二、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;
}
}
}