小台的IT备忘录  
脑子越来越不好用,只能依靠烂笔头了~

原理很简单:使用Global.asax中的Application_BeginRequest(object sender, EventArgs e)事件,实现表单或URL提交数据的获取,然后通过SQLInjectionHelper类完成恶意代码的检查。

本代码只是考虑到通用性和部署简易性,因为项目已经开发完毕,并已经上线,为避免大量修改,才写的这个通用程序,大家可以在这里面加入不需要检查的表单值,这样不检查某些字段也是可以实现的。

直接贴代码:

Global.ascx.cs

//在接收到一个应用程序请求时触发。对于一个请求来说,它是第一个被触发的事件,请求一般是用户输入的一个页面请求(URL)。
    void Application_BeginRequest(object sender, EventArgs e)
    {
        //Response.Write("通用注入检查");
        bool result = false;
       
        if (Request.RequestType.ToUpper() == "POST")
        {
            result = SQLInjectionHelper.ValidUrlPostData();//Post数据检查
        }
        else
        {
            result = SQLInjectionHelper.ValidUrlGetData();//Get数据检查
        }
       
        if (result)
        {
            Response.Write("您提交的数据有恶意字符!");           
            Response.Write("<script>alert('您提交的数据有恶意字符!');<//script>");
            Response.End();
        }
    }

SQLInjectionHelper.cs注入检测辅助类

 

/// <summary>
    /// 获取Post的数据
    /// </summary>
    public static bool ValidUrlPostData()
    {
        bool result = false;

        for (int i = 0; i < HttpContext.Current.Request.Form.Count; i++)
        {
            result = ValidData(HttpContext.Current.Request.Form[i].ToString());
            if (result)
            {
                break;
            }//如果检测存在漏洞
        }
        return result;
    }

    /// <summary>
    /// 获取QueryString中的数据
    /// </summary>
    public static bool ValidUrlGetData()
    {
        bool result = false;

        for (int i = 0; i < HttpContext.Current.Request.QueryString.Count; i++)
        {
            result = ValidData(HttpContext.Current.Request.QueryString[i].ToString());
            if (result)
            {
                break;
            }//如果检测存在漏洞
        }
        return result;
    }

    /// <summary>
    /// 验证是否存在注入代码
    /// </summary>
    /// <param name="inputData"></param>
    public static bool ValidData(string inputData)
    {
        //里面定义恶意字符集合
        //验证inputData是否包含恶意集合
        if (Regex.IsMatch(inputData, GetRegexString()))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    /// <summary>
    /// 获取正则表达式
    /// </summary>
    /// <param name="queryConditions"></param>
    /// <returns></returns>
    private static string GetRegexString()
    {
        //构造SQL的注入关键字符
    string[] strBadChar = {"and"
    ,"exec"
    ,"insert"
    ,"select"
    ,"delete"
    ,"update"
    ,"count"
    ,"from"
    ,"drop"
    ,"asc"
    ,"char"
    ,"or"
    //,"*"
    ,"%"
    ,";"
    ,":"
    ,"\'"
    ,"\""
    ,"-"
    ,"chr"
    ,"mid"
    ,"master"
    ,"truncate"
    ,"char"
    ,"declare"
    ,"SiteName"
    ,"net user"
    ,"xp_cmdshell"
    ,"/add"
    ,"exec master.dbo.xp_cmdshell"
    ,"net localgroup administrators"};

        //构造正则表达式
        string str_Regex = ".*(";
        for (int i = 0; i < strBadChar.Length - 1; i++)
        {
            str_Regex += strBadChar[i] + "|";
        }
        str_Regex += strBadChar[strBadChar.Length - 1] + ").*";

        return str_Regex;
    }

 

测试代码:
1 建立表单,测试Post数据
2 直接使用Response.Redirect("TestSQLInjection.aspx?Id=100&cc=200&dd=300")或构造URL参数,测试Get数据

在App_Code文件夹下建立SQLInjectionHelper.cs类

内容:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Text;
using System.Text.Regularexpression_r_r_r_rs;

/// <summary>
///SQLInjectionHelper 的摘要说明
/// </summary>
public class SQLInjectionHelper
{
    /// <summary>
    /// 获取Get的数据
    /// </summary>
    public static bool ValidUrlGetData()
    {
        bool result = false;

        for (int i = 0; i < HttpContext.Current.Request.QueryString.Count; i++)
        {
            result = ValidData(HttpContext.Current.Request.QueryString[i].ToString());
            if (result)
            {
                //如果检测存在漏洞
                break;
            }
        }
        return result;
    }

    /// <summary>
    /// 获取Post的数据
    /// </summary>
    public static bool ValidUrlPostData()
    {
        bool result = false;

        for (int i = 0; i < HttpContext.Current.Request.Form.Count; i++)
        {
            result = ValidData(HttpContext.Current.Request.Form[i].ToString());
            if (result)
            {
                //如果检测存在漏洞
                break;
            }
        }
        return result;
    }

    /// <summary>
    /// 验证是否存在注入代码
    /// </summary>
    /// <param name="inputData"></param>
    public static bool ValidData(string inputData)
    {
        //里面定义恶意字符集合
        string[] checkWord = { "and", "exec", "insert", "select", "delete", "update", "count", "from", "drop", "asc", "char", "*", "%", ";", ":", "\'", "\"", "chr", "mid", "master", "truncate", "char", "declare", "SiteName", "net user", "xp_cmdshell", "/add", "exec master.dbo.xp_cmdshell", "net localgroup administrators" };
        if (inputData == null || inputData == "")
        {
            return false;
        }
        else
        {
            foreach (string s in checkWord)
            {
                //验证inputData是否包含恶意集合
                if (inputData.ToString().ToLower().IndexOf(s) > -1)
                {
                    return true;
                }
                else
                {
                    continue;
                }
            }
            return false;
        }

    }
}


建立全局应用程序类:global.asax

内容:

<%@ Application Language="C#" %>

<script runat="server">

    void Application_Start(object sender, EventArgs e)
    {
        //在应用程序启动时运行的代码

    }
   
    void Application_End(object sender, EventArgs e)
    {
        //在应用程序关闭时运行的代码

    }
       
    void Application_Error(object sender, EventArgs e)
    { 
       

    }

    void Session_Start(object sender, EventArgs e)
    {
        //在新会话启动时运行的代码

    }

    void Session_End(object sender, EventArgs e)
    {
        //在会话结束时运行的代码。
        // 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
        // InProc 时,才会引发 Session_End 事件。如果会话模式
        //设置为 StateServer 或 SQLServer,则不会引发该事件。

    }

    //在接收到一个应用程序请求时触发。对于一个请求来说,它是第一个被触发的事件,请求一般是用户输入的一个页面请求(URL)。
    void Application_BeginRequest(object sender, EventArgs e)
    {
        //检查是否有注入
        bool result = false;

        if (Request.RequestType.ToUpper() == "POST")
        {
            result = SQLInjectionHelper.ValidUrlPostData();//Post数据检查
        }
        else
        {
            result = SQLInjectionHelper.ValidUrlGetData();//Get数据检查
        }

        if (result)
        {
            Response.Write("您提交的数据有恶意字符!");
            Response.End();
        }
    }
      
</script>

 

在你的站点上测试就可以了

posted on 2016-06-21 15:56  taiyonghai  阅读(1289)  评论(0编辑  收藏  举报