概述
“暴力破解”是一种攻击手段,在web攻击中,一般会使用这种手段对应用系统的认证信息进行获取。 其过程就是使用大量的认证信息在认证接口进行尝试登录,直到得到正确的结果。 为了提高效率,暴力破解一般会使用带有字典的工具来进行自动化操作。
理论上来说,大多数系统都是可以被暴力破解的,只要攻击者有足够强大的计算能力和时间,所以断定一个系统是否存在暴力破解漏洞,其条件也不是绝对的。 我们说一个web应用系统存在暴力破解漏洞,一般是指该web应用系统没有采用或者采用了比较弱的认证安全策略,导致其被暴力破解的“可能性”变的比较高。 这里的认证安全策略, 包括:
1.是否要求用户设置复杂的密码;
2.是否每次认证都使用安全的验证码(想想你买火车票时输的验证码~)或者手机otp;
3.是否对尝试登录的行为进行判断和限制(如:连续5次错误登录,进行账号锁定或IP地址锁定等);
4.是否采用了双因素认证;
5. ......
千万不要小看暴力破解漏洞,往往这种简单粗暴的攻击方式带来的效果是超出预期的!
我们可以通过“BurteForce”对应的测试栏目,来进一步的了解该漏洞。
一、基于表单的暴力破解登录
当登录失败的时候:
登录成功的时候:
一般做了防护的网站, 登录失败几次之后ip就会被限制登录, 由于靶场没有做任何防护, 所以可以直接暴力破解
方法一
这边可以使用hydra工具进行爆破,
由于目标是post方式, 先看一下post的表单参数:
所以就有如下命令:
hydra -l admin -P p.txt -s 80 -t 6 -f 127.0.0.1 http-post-form "/pikachu-master/vul/burteforce/bf_form.php:username=^USER^&password=^PASS^&submit=Login:username or password is not exists"
命令解读:
-l : 指定单个用户名, 适合在知道用户名爆破用户名密码时使用
-L : 指定多个用户名,参数值为存储用户名的文件的路径(建议为绝对路径)
-P : 指定多个密码,参数值为存贮密码的文件(通常称为字典)的路径(建议为绝对路径)
-s : 指定端口, 默认为80
-t : 指定爆破时的任务数量(可以理解为线程数),默认为16
-f : 一旦爆破成功一个就停止爆破
-o : 输出到指定文件
http-post-form: 使用post方式爆破, (可以用 hydra -U 来查看支持哪些方式)
后面的内容分别用 : (冒号) 来分成三部分,
第一部分是ip下的网站目录;
第二部分是post表单的参数名, ^USER^为爆破传入的用户名变量, ^PASS^为传入的密码变量
第三部分是爆破成功的唯一判断依据(重要), 可以根据登录后界面返回的关键字符串看到, 当登录失败的时候, 页面 会提示username or password is not exists。当然也可以使用-S来将爆破成功的依据变更为登录成功返回的关键字 符串, 默认是-F, 即登录失败的依据。
爆破成功, admin的密码为 123456
当然也可以用 -L参数来指定爆破多个用户名:
hydra -L user.txt -P passwd.txt -o out.txt -f 127.0.0.1 http-post-form "/pikachu-master/vul/burteforce/bf_form.php:username=^USER^&password=^PASS^&submit=Login:username or password is not exists"
方法二
用Burpsuite的intruder模块进行爆破攻击
抓包之后, 发送到intruder模块:
设置用户名和密码为爆破传值变量, 用cluster bomb笛卡尔积爆破, 同时用户名和密码分别用两个字典
其中, attack type:攻击模式设置类型如下
sniper:对变量依次进行破解, 多个标记依次进行。单参数爆破,多参数时同一个字典按顺序替换各参数,总之初始值有一个参数不变
battering ram:对变量同时进行破解。多个标记同时进行。多参数同时爆破,但用的是同一个字典。
pitchfork:每一个变量标记对应一个字典,取每个字典的对应项。 多参数同时爆破,但用的是不同的字典。
cluster bomb:每个变量对应一个字典,并且进行交集破解,尝试各种组合。适用于用户名+密码的破解。多参数做笛卡尔乘积模式爆破。
同时加载字典:
start attack, 查看结果:
看下是否还有其他用户:
完成。
二、验证码绕过(on server)
有两种情况:
第一, 不管用户名和密码对不对的情况下, 只要验证码错误, 就会提示:
第二, 当验证码输入对了, 密码错误提示密码错误; 密码正确提示登录成功:
结合源码分析
验证码的认证流程:
1. 打开登陆页面,向后台发送一个请求,当后台收到请求以后,会调用一个生成验证码的函数showvcode.php去生成一个验证码,回到前端变成一个图片返回给你,
同时将函数生成的值存到session['vcode']中。
可以看到, 验证码以明文的形式, 通过cookie的方式传给了前端, 这样很容易被抓包拦截下来。
2. 用户输入账号密码验证码提交的时候,后台对提交的验证码与session中的进行比较
可以看到, 没有对_SESSION['vcode']进行销毁, 使得验证码在Session持续的过程中一直有效。
如果验证成功就会提示你成功,如果验证失败就提示失败,然后
漏洞利用
利用Burpsuite抓包, 然后发送到repeater模块测试上述漏洞:
输入一个错误的密码, 可以看到返回的是密码错误的提示:
再换一个密码, go:
所以, 我们用intruder来爆破即可:
start attack 之后, 我们可以看到结果:
爆破完成。
并且我们也可看到, 验证码的明文通过cookie返回前端, 可以被抓包拦截:
修复
1. 一定要在后台将现在的验证码销毁,验证码一定是要一次一用的。
2. 也要对验证码设置一个超时时间,如果超过规定的比如一分钟,没有从前端获取到验证码信息,那就需要重新获取一次验证码
三、验证码绕过(on client)
另一种在客户端的情况,
分析
先随意输入一个错误的验证码, 发现直接弹窗提示验证码错误:
一看就是在网页前端判断了验证码, 没有通过服务端,
看一下网页源码:
找到对应的createCode()的js代码:
并且点击了Login登录之后, 触发了validate() 来判断验证码是否正确:
理清思路和验证流程之后, 绕过验证码就很简单了
漏洞利用
方法一
1. 首先我们可以将onsubmit调用的 validate()函数给去掉:
方法二
2. 既然验证码在前端就已经判断了, 那么服务端(后台)应该是不用再去验证vcode了
这里结合源码可以证明:
通过Burpsuite抓包, 将数据包中的vcode参数去掉 (因为不需要), 并发送到repeater模块测试是否需要验证vcode:
可以看到, 果然vcode可有可无, 那么就可以直接用Intruder模块爆破了, 步骤同上。
修复
验证码、Token等最好不要在前端生成和处理。
四、Token防爆破
与之前不同的是, 这次不用验证码了. 利用Token来防止无脑爆破,
当然不影响我们爆破, 只是增加了爆破的难度
分析
在前端网页可以看到, 有一个隐藏的input标签带有Token:
Token 是在服务端产生的。
如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位。如果这个 Token 在服务端持久化(比如存入数据库),那它就是一个永久的身份令牌。
Token 完全由应用管理,所以它可以避开同源策略
Token 可以避免 CSRF 攻击
Token 可以是无状态的,可以在多个服务间共享
Token是CSRF会用到....虽然这里并没有什么用...
漏洞利用
这里我们抓包分析一下Token的作用:
当我们正常提交token时候:
当token不正确时:
那么同样可以用Intruder模块进行爆破, 只不过需要在前端界面中提取出token值发送给服务端:
1. 先将username, password, token三个值都置为变量:
- 千万不选cluster bomb了, 不能和token参数做笛卡尔积, 会导致死循环, 这里选Pitchfork模式
2. 现在我们从前端网页中提取出token,
在option中的grep - extract, 打钩, 并点击add添加过滤条件, 点击refetch response找到响应包中的token 选中复制token值点击确定
将redirections选择为always:
3. 添加用户名和密码的字典:
4. 将token的参数设置好, 并且给第一次访问的token赋值 (不然开始就被不合法验证了, 无法开始):
5. 由于设置了token, 是一对一的验证, 只有获取上一个请求返回的taken值才能,做下一次请求, 因此只能单线程
在option中设置线程为1:
5. start attack, 发现长度不同的即为正确密码:
后记
从来没有哪个时代的黑客像今天一样热衷于猜解密码 ---奥斯特洛夫斯基