web安全靶场之暴力破解篇
简单的四位数字
访问靶场,页面提示用户名是admin,密码是四位纯数字。
接着输入用户名 admin
,密码随便输入,使用 burp 抓包即可,右击空白处,选择 Send to intruder
接着来到 Intruder
模块,由于这里我们知道用户名为 admin
,但是不知道密码,故而攻击模式选择 Sniper
模块即可。
然后选中密码的值,点击 Add
设置为变量。
将密码的值设置为变量之后,我们点击 Payloads
设置密码字典。由于密码是某个范围的纯数字,因此 Payload Type
选择 Numbers
。
最后点击 Start attack
即可。
最后等待暴破即可,由于登陆成功和登陆失败返回的内容长度是不一样的,故而可以通过长度值排序,定位到登陆成功的那条。
Top100
访问靶场,提示用户名是 admin
密码是弱口令,我们这里可以加载弱口令字典进行暴破。具体字典可以通过 github 自行收集,我这里使用我特意制作的字典。
同上一关一样,先进行抓包,然后将其发送到 Intruder
模块。然后依旧将密码处设置为变量。
点击 Payloads
设置密码字典,可以是一个列表,也可以是一个文件,如果是从字典文件读取密码到 burp 中,将 Payload Type
设置为 Simple list
,如果是在爆破的时候直接从字典中读取密码,选择 Runtime file
。
最后点击 Start attack
。注意:这里的字典路径,建议不要使用带有中文的路径,不然可能会出错。
依旧是根据返回长度不同来判断登陆是否成功,当然有些网站登录成功可能会进行 301 跳转,则那时可以通过响应状态码判断,最终得到密码 qewr1234
。
Top100 Json
来到靶场,通过查看页面源代码,发现是以 JSON 格式传入的用户名和密码。
老套路,burp 抓包 然后发送到 Intrude
模块,只是传输数据的格式不同,实际上暴破方法还是一样的。
设置密码为变量
设置字典
暴破结果
得到密码为 zxcvbnm
,同时服务器返回的数据也是 JSON 格式。
不失效的验证码
访问靶场发现登陆页面存在验证码,用户名 admin,密码为弱口令。
经过测试,发现登陆时确实需要输入验证码,并且需要与显示验证码匹配。我们登陆时抓取数据包,右键将其发送到 Repeater
模块,叫做重发器,我们可以在这里进行重复发送数据包。
经过多次发送测试发现,只要在 Proxy
模块中的数据包不放,则这里的验证码一直是有效的。
故而该验证码就是不失效的验证码,可以重复利用。但是如果把 Proxy
模块中的数据包放掉,则会是一个重新的请求,重新获取验证码,原验证码失效,我们可以进行测试,将 Proxy
数据包放掉。
再次在重发器中发送数据包,发现提示验证码错误。那么我们就知道,只要不把抓的数据包放掉,则该验证码可以重复使用,故而重新抓包,将其发送到 Intruder
模块。
设置变量
设置字典
暴破结果
得到密码为 qwe123..
前端加密
来到靶场,发现用户名为 admin 密码提示为 Burp 自带的字典。
使用 Burp 进行抓包,发现输入的密码以加密的形式传给了服务器,先将其发送到 Intruder
模块。
接着来到网页源码中查看,发现在提交的时候会触发 Javascript 的 md5_enc()
函数,该函数的作用则是将密码进行 md5 加密,然后传给服务器。
因此,服务器接受到的密码是以 MD5 形式进行传输的。故而我们在暴破的时候,也需要将我们使用的密码进行 MD5 加密,Burp 工具是提供了这一功能的。
设置变量
设置字典
这里需要将字典的值以 MD5 加密之后 发给服务器。
暴破结果
得到密码的MD5值为:52763ce1866767ba49826556ee37571c
,解密之后得到 Fucker
。
HTTP Basic 认证
访问靶场出现让我们输入用户名和密码:
当我们点击 取消 则返回 401 状态码。并提示我们未认证。
再次刷新页面,则需要重新输入用户名和密码。这里使用的是 HTTP Basic
认证,中文名称为 简单认证。它通常通过中间件的设置,让用户访问某个目录下的文件需要输入用户名和密码。
tomcat 的管理后台使用的就是该认证。
这里说下该认证的原理:
接着我们输入用户名 admin
密码随便输入,使用 burp 进行抓包,框选 Basic
后面的 base64 编码,然后右键选择 Convert selection
-> Base64
-> Base64-decode
对其进行 base64 编码。
发现这里确实如上所说,用户名和密码以冒号进行分割, 并进行 base64 编码后发给了服务器,右键将其发送到 Intruder
模块。
用户名还为 admin,密码是未知的,故而我们这里将其全选,然后设置为变量。攻击类型为 Sniper
。
接着设置字典,刚刚提到,Basic 认证是以 用户名:密码 的形式进行 base64 编码之后发送给服务器的,故而我们这里也需要将字典的内容进行编码。
在 Payload processing
中点击 add
,设置前置为 admin:
,然后点击(Encode) 选择 Base64-encode
,设置这里的作用是,当 burp 工具从字典中读取每个密码的时候,都会在其前面加上 admin:
,例如 burp 读取的字段内容为 qwer1234
,经过添加前缀之后就为 admin:qwer1234
,最后经过 base64 编码就为 admin:qwer1234
的 base64 编码。
由于 base64 编码的内容可能会存在诸如 = 和 + 的内容,burp 默认会对其进行 URL 编码,这里在 Payloads
选项卡底部取消勾选不编码即可。
最后点击 start attack
即可。
前面提到过,basic 在认证成功的时候会返回状态码 200,故而这里也可以通过状态码进行排序。
由于用户名和密码是经过 base64 编码的,故而我们这里右键解码即可。最终得到密码 admin123
。
返回特征匹配
访问靶场,得到如下提示:
发现登陆失败返回如下内容:
这一关则考的是,登陆成功和登陆失败,返回的内容长度以及状态码是相同的,前面我们都是通过状态码和内容长度来判断登陆是否成功,那么这一关,我们该如何判断呢?
其实,尽管成功和失败返回内容的长度一致,但是成功和失败返回的内容肯定是截然不同的,因此我们可以提取登陆失败返回的值,然后在诸多数据包中进行标记,没有该标记的则就是成功的包。
那么这里,登陆失败返回的特征则是存在内容 x1ongsec{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
,这里可能会问,为什么不匹配登陆失败这个关键字呢?众所周知,burp 是国外所开发的工具,故而对中文适配性不是很好。因此尽量匹配英文特征。
按照往常一样,先使用 burp 抓取登陆时的数据包,然后将其发送到 Inteuder
设置字典
设置返回特征匹配:
来到 Intruder
模块的 Settings
选项中,然后找到 Grep Match
先点击 clear
将其清空。
接着将登陆失败的特征 x1ongsec{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
设置到其中。
最后点击 Start attack
开始即可。
经过排序,发现当 密码为 admin123
时,则没有匹配到内容 x1ongsec{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
。查看其响应包,发现为登陆成功的数据包。
故而密码为 admin123
。
数据库泄露之撞库
这里提供了字典的下载,点击将字典下载即可。
简单的说一下撞库的概念,意思是拿到某公司网站A的数据库,使用其密码登录网站B。称之为撞库。
第一列为用户名,第二列为密码。这里可以使用 Linux 系统的 awk
命令获取第一行和第二行的内容,并将其输出到相应文件中。
1 | root@ls-rK8rbuXz:~# awk '{print $1}' db.txt >> username.txt |
接着使用 bp 抓取 登陆时的数据包,然后将其发送到 intruder
模块。
这里与以往不同的是,我们并不知道用户名以及密码,都需要从字典文件中读取,故而 attack type
需要选择 Pitchfork
,让用户名参数和密码参数都拥有自己独立的字典。
如果不太了解 burpsuite 工具的 Intrude 相应的 attack type
请移步百度。
为参数1用户名处设置字典:
为参数2密码处设置字典:
之后开始攻击即可。
得到用户名 liujing
密码 qweasdzxc
。
时间戳 token
使用 burp 抓取登陆时的数据包,发现存在 token 。token 是一种由服务器生成的一段校验值,然后返回给用户,用户每次请求时需要带着服务器生成的 token 去请求。不然服务器会认为这不是用户发起的请求。
综上所述,就增加了我们暴破的难度,由于是在用户请求时就会在 POST 请求体里面提交 token,故而 token 肯定会在前端显示,我们查看页面源代码。
发现这里存在隐藏的输入框 token
,当用户点击登陆的时候,会触发 JavaScript 的 md5_encrypt
方法,会将当前时间戳加密成 md5 之后作为 token 的值,提交给服务器。
故而我们这里知道,token 值的生成是有迹可循的,也就是说,提交的时间戳进行 md5 加密之后 就是 token。
时间戳是从 1970 年 1 月 1 日(UTC/GMT的午夜)开始所经过的秒数
但是由于 burp 自身无法生成当前时间戳的字典,只能是当前日期。
所以需要编写 Python 脚本:
1 | import requests |
得到密码登录即可。
返回在前端的 token
访问靶场出现如下页面:
使用 burp 抓取登陆时的数据包,发现将用户名、密码和 token 值一并提交给服务器。
查看前端代码,发现页面源码中存在隐藏的输入框,并且有默认值,每次刷新该值都会变。故而推断这是由服务端生成的 token 值然后返回在前端,而我们用户需要带着最新的 token 去请求服务器,不然会提示 Token Error
。
重复利用的 token:
那么我们就需要在每次 burp 暴破请求时,提取页面的 token 值一并提交给服务器,我们将该数据包发送到 Intruder
模块。
这里已知用户名为 admin
,因此用户名可固定,而随之变化的是 password
和 token
,于是将其设置为变量,并设置 pitchfork
模式。
接着来到 Payloads
页面。先为密码设置字典:
再为 token 设置为 Recursive grep
递归筛选
接着来到 Settings
选项从页面中提取 token 值。框选 token 值即可自动生成表达式进行提取。
最后点击 Start attack
最后得到密码 abcd1234
。
验证码识别
分析
访问靶场,出现如下页面:
经过测试,发现必须输入正确的验证码且验证码不能重复利用,因此在 Less-4 的方法就不能使用了。
这里需要使用的方法则是验证码识别。
环境准备
插件下载
这里我们使用到的验证码识别插件是captcha-killer-modified
Github 项目地址:https://github.com/f0ng/captcha-killer-modified
项目下载
主要是用 codereg.py
(需要提前准备python3的环境),且该项目源码包含用法和常见问题文档。
Github 项目地址:https://github.com/f0ng/captcha-killer-modified/blob/main/codereg.py
源码如下:
1 | # -*- coding:utf-8 -*- |
项目依赖安装
在使用 codereg.py
之前,需要提前安装 python3
环境,并安装其对应的 pip
。
1 | # pip |
项目报错解决
不出意外的话,你在运行脚本的时候会提示如下错误:
1 | TypeError: The port is required to be int. |
解决方法将11行的字符串 “8888” 修改为 int 类型的 8888,如下:
1 | parser.add_argument("-p", help="http port",default=8888) |
保存之后再次运行即可。
导入插件
在 burp 的工具栏中点击 Extensions
-> Installed
中找到 Burp Extensions
点击 Add
选择插件路径(尽量不要包含中文路径)
点击 Next ,最后点击 Close
。
注意:该插件仅支持高版本的 Burpsuite,低版本的请使用:captcha-killer.0.1.2.jar,具体自行百度。
识别工作
使用插件
首先获取验证码的生成地址,通常右击验证码点击检查即可在 src 中看到地址:
访问该地址,然后 burp 抓包,将其发送到验证码识别插件:
依次点击:
该模版的默认接口URL 为 本地的 8080 端口,可以根据运行 codereg.py
的地址和端口自行修改。
接着在本地运行 codereg.py
文件,启动接口。
如果提示其他错误,请参考作者的 F&Q:https://github.com/f0ng/captcha-killer-modified/blob/main/FAQ.md
如果直接访问接口地址,可以提示 404 not found
属正常现象
项目启动成功之后,来到插件面板点击识别:
据作者宣称识别率达到 85%,经过测试,发现识别率还是可以的。
验证码识别暴破
以上都完成之后,我们抓取登陆时的数据包:
将 Attack Type
设置为 Pitchfork
然后将密码和验证码设置为变量。
来到 Payloads
选项先设置密码字典:
验证码字典则选择由插件生成:
最后点击 Start attack
即可。由于验证码识别准确率只有 85%
左右,故而可能刚刚把正确密码的验证码识别错误了。故而可能需要多试几次。
而我这里刚好把正确密码的验证码输入错误了,故而错过了正确密码。
不过这里发现了一点小技巧,将线程为1可以增加验证码的识别准确率:
最终得到密码为 Qwer1234!@#$
。
安全的后台管理系统
修复建议
对于暴力破解等漏洞的防护,如果从用户的角度如下:
- 设置强密码
- 定期更新密码
- 避免多平台使用同一密码
如果从开发角度如下:
- 注册用户时强制用户的密码必须包含大小写字母、数字等字符
- 设置复杂的验证码
- 如果有必要的情况下,建议从数据库层面将某个用户错误此处达到一定次数时锁定N分钟。
示例代码
本关卡主要为修复暴力破解漏洞,因此是从数据库层面,当用户错误此处达到3次,则锁定2分钟,2分钟后自动解锁。当然也有弊端,致使正常的用户也无法通过 admin 用户登录到网站。
源码如下:
1 |
|