1. 网络不是法外之地,学习网络安全只是为了更好地保护网络安全
2. 文中内容仅为学习交流,涉及到的工具和方法均不能用于破坏网络安全
该笔记仅在优快云中发表,如转载请大家注明出处。
优快云:http://blog.youkuaiyun.com/elang6962?viewmode=contents
-
PhpStudy=0.4公测版
-
OS:Kali Linux 2019.4
-
DVWA:1.9
上一篇中记录了在Kali 2019.4中利用phpstudy搭建dvwa的过程,这一篇是完整的DVWA练习记录,内容长,很肝!
1 Brute Force 暴力破解
1.1 使用工具
- 抓包/破解:OWASP ZAP
- 代理插件:火狐FoxyProxy
1.2 Low
思路:
- 输入正确的用户名和密码,提交观察。这里自动填写了用户名和密码,点提交就行。看到出现一句欢迎语和一张图片,同时F12看到请求方法是GET,当然看URL里带了用户名和密码也就知道了。
- 输入错误的用户名和密码,提交观察。直接删除密码点提交,提示“用户名或密码错误”。
- 准备抓包破解。FoxyProxy添加一个8081端口的本地代理,ZAP在选项-local proxies里设置了8081端口,因为有时会把ZAP和Burp同时开,避免端口冲突。
- 抓包。Foxy开启代理,为了做戏,密码处填个错的,点击提交。这里我出现了浏览器不信任127.0.0.1,看了下URL变成了https,点高级-继续访问。然后ZAP就抓到了包。
- 暴力破解。点击抓到的包,上图右上角请求处查看URL,找到那个URL有用户名和密码的包,点右键-选择FUZZ。这里FUZZ可能会带有一个Fuzz Locations,一般都是错的,删掉后选择用户名的payloads也就是
admin
,点击右边的Add按键,在弹出的对话框随便输入几个用户名,有admin
就行;密码同理,有password
就行,点击Start Fuzzer
。
- 观察结果。ZAP做不到成功后自动停止,只能从响应中观察哪个是成功的。这里因为自己玩,总共没几个组合,直接从结果里看了。响应中有一个4424字节,其他都是4381,这就可以猜测4424就是成功了,点击在ZAP中查看果然能看到那句欢迎语。
结束后分析DVWA的PHP源代码,Low等级拿到用户输入的用户名和密码后,对密码进行了md5,然后就直接到数据库里查询,没有任何保护。
1.3 Medium
依据Low的思路,依旧使用ZAP执行暴力破解,还是可以成功,但明显FUZZ的时间变久了。从截图看,每个请求的RTT时间是秒级的,看了源代码,在请求失败时会sleep2秒,这里不懂为什么RTT中记录的时间会比2秒多那么多。
1.4 High
思路:
- 先从最简单的ZAP暴力开始,非常快的结束了。仔细看ZAP可以发现,所有包的响应都是0字节,且状态码是302。这时候想到看看请求包和响应包有什么特殊的地方,很明显的看到请求包的url中多了个
user_token
,先瞧瞧是不是它的原因。
- 这时候继续用zap抓包,回到页面分别测试2次正确输入和2次错误输入,再来看包的内容。点开1号正确包,可以看到url和referer处都有
user_token
,但二者不同;再点第二个包,2个位置依旧不同,且url中的user_token
与第一个包不同,到这里就可以判断这个user_token
是每次请求都会改变的,不论输入的用户名密码组合是否正确。错误的2个包已经没必要看了。这里第一个包的referer
就有token是因为直接在第一次抓包后的页面中进行这一步。
- 已经确定是
user_token
的问题就好办了,先从响应中找到它。查看页面源代码,可以直接搜索user_token
。
- 现在可以大致知道规则,即每次点击提交,响应中会返回一个
user_token
,在下一次提交时带上。
- 那么第0个
user_token
是怎么来的?是第一次点击进入Brute Force模块时的响应中返回的。很明显,ZAP这类工具没法用了,必须手动从响应中拿出user_token
并放入下一个请求中,也就是要自己动手。这里有两个思路:
-
- 一是按照上面那个图一直进行下去,从第一次进入模块之后就不断重复“提交-获取token-提交”,直到发现成功flag或者payloads消耗光。
request Brute Force
get response
while 1:
user_token = user_token in response
send request(username,password,user_token)
get response
# 思路一的代码
import urllib.request as urllib2
import re
from urllib import request
IP = '127.0.0.1'
USERFILE = '' # username的字典
PASSFILE = '' # password的字典
COOKIE = '' # 手动查看后加入
# 由字典生成列表
usernames = [x[:-1] for x in open(USERFILE,'r')]
passwords = [x[:-1] for x in open(PASSFILE,'r')]
# 访问首页
response = request.urlopen(request.Request('http://' + IP + '/dvwa/vulnerabilities/brute/',headers={'Cookie':COOKIE}))
content = response.read().decode('utf-8')
for username in usernames:
for password in passwords:
# 获取user_token
user_token = re.findall("(?<=<input type='hidden' name='user_token' value=').+?(?=' />)",content)[0]
# 发送request
url = 'http://' + IP + '/dvwa/vulnerabilities/brute/?username='+username+'&password='+password+'&Login=Login&user_token='+user_token
response = request.urlopen(request.Request(url,headers={'Cookie':COOKIE}))
content = response.read().decode('utf-8')
# 确认结果
print('用户名:'+username)
print('密码:'+password)
if 'Username and/or password incorrect.' in content:
print('结果:失败')
else:
pr