dvwa靶场
这个靶场是几个月前开始的,然后中间可能因为有各种事情拖沓,还剩了一点,终于把它全部弄完啦,真不容易啊。
前言
我把dvwa靶场的三个等级low,medium,high每关都做出了相应的题解,应该看起来会清晰一点。
我这里引用的dvwa靶场是来自https://github.com/digininja/DVWA/archive/master.zip 记得看readme文件,配置好相关环境,然后就可以开始啦。
1、Burte Force
low
使用burp暴力破解,得到账户名密码为:admin/password
然后尝试登录,登录成功

medium
和low一样
high
和low一样
2、Command Injection
low
执行命令
1 | 127.0.0.1 | hostname |
即可得到主机名,可命令执行得到其他敏感信息。

medium
和low一样
high
执行命令
1 | 127.0.0.1 || hostname |
即可得到主机名,可命令执行得到其他敏感信息。

3、CSRF
low
用burp抓包分析,没有设置token,也不需要输入原来密码,通过get请求来提交修改信息的,可以直接修改密码,然后复制url,只要受害者点击该url密码就会被修改。

将密码改为222,复制url:
1 | http://127.0.0.1:8099/dvwa/vulnerabilities/csrf/?password_new=222&password_conf=222&Change=Change |
当点击此链接时,密码被修改:

后来有了另一种思路,一般csrf看Referer和origin字段,如果去掉这两个字段响应还一样,而且没加什么验证的手段,则可能存在csrf漏洞,此时可以在burp生成poc,验证一下:

medium
和low一样
high
和low一样
4、File Inclusion
low
里面有三个文件,点开可以看到在url中是get方式的。
当尝试输入:
file4.php
发现了一个隐藏的文件:

medium
和low一样
high
和low一样
5、File Upload
low
尝试上传php后缀文件,比如1.php文件,发现上传成功:

可以看到文件的路径暴露出来了,然后利用第4关的文件上传漏洞,可以访问到:

medium
当尝试上传php后缀时,发现上传不成功

用burp抓包分析,看到显示了Content-Type

修改Content-Type为允许的:
将内容改为image/png,发现上传成功:

使用蚁剑连接,连接成功:
1 | url: |

high
制作一句话木马:
1 | copy 2.jpg/b+55.php/a 66.jpg |

上传66.jpg,成功,可以看到路径:

然后利用第2关的命令注入,将66.jpg改成66.php
1 | || ren ..\..\hackable\uploads\66.jpg 66.php |
再利用蚁剑连接一句话木马:
1 | url: |

6、SQL Injection
low
本关存在字符型注入,当输入单引号时,会出现报错信息,可以利用报错注入;输入正常的用户id时会有回显,也可以利用union联合注入。
下面我采用的是报错注入:
6.1获得数据库名
1 | 构造payload:1'or+info()+'1 |
(此处就是通过构造一个在数据库中不存在的函数info()使其报错,就会出现数据库名)
可以看到数据库名为dvwa

6.2获得数据库用户名
此时,可以将info()替换成报错函数,查询出其他信息,如数据库用户名:
1 | 1'or+updatexml(1,concat(0x7e,user(),0x7e),1)+'1 |
得到数据库用户名为root@localhost

medium
中级的是一个下拉列表,则可能存在数字型的注入。
用burp抓包,构造id=2+and+1=1和id=2+and+1=2,结果不一样。
一样也采用报错注入:
6.1获得数据库用户名
1 | payload:id=2+and+info() |
得到数据库名为dvwa

6.2获得数据库用户名
1 | payload:id=2+and+updatexml(1,concat(0x7e,concat(user()),0x7e),1) |
得到数据库用户名为root@localhost

high
输入奇数个单引号和输入偶数个单引号回显不一样,可以采用基于布尔型的盲注。
6.1获得数据库用户名
获得数据库名的第一个字母
1 | 构造payload: |
当字母等于’r’时,即回显正确时,会出现如下图,可依次类推其他字母。

其余不正确的字母都是没有回显:

7、SQL Injection(Blind)
low
采用盲注,发现输入奇数的单引号和偶数的单引号回显不一样,是字符型的注入:
1 | 构造payload: |
当字母为’r’时,回显是存在,说明数据库用户名第一个字母为’r’

当其他不正确的字母时,回显是不存在:

medium
采用盲注,发现输入id=1/1和id=1/0回显不一样,是数字型的注入:
1 | payload: |
当第一个字母的ascii码值为114,即对应字母’r’时,出现存在信息,说明数据库用户名第一个字母为’r’,可依次类推其他字母。

当字母不正确时,会出现不存在的回显:

high
采用盲注,本关为基于字符型的注入
1 | payload: |
当字母等于’r’时,即回显正确时,会出现存在,可依次类推其他字母。

其余不正确的字母都是回显不存在:

8、Weak Session IDs
low
当用户登录后,在服务器就会创建一个会话(session),叫做会话控制,接着访问页面的时候就不用登录,只需要携带session去访问。
sessionID作为特定用户访问站点所需要的唯一内容。如果能够计算或轻易猜到该sessionID,则攻击者将可以轻易获取访问权限,无需录直接进入特定用户界面,进而进行其他操作。
用burp抓包,可以看到cookie,将cookie复制放到hackbar中验证一下:

当删掉这个phpsessid中的某个值时,会退出登录,是完整的时,则在登录状态:

medium
用burp抓包,查看cookie。
是基于时间戳生成dvwaSesion的,在网上找到一个转换时间戳工具

转换之后,放到hackbar中

high
burp抓包发现,dvwaSesion值很像md5加密,使用md5解密,发现是对从零开始的整数进行加密。

构造payload使用火狐的hackbar提交即可。
9、XSS(DOM)
low
页面有一个选择框,任意选择一个时。是get型的,在url中可以看到选择的类型,
1 | 构造payload:<script>alert(/xss/);</script> |
成功出现弹窗。

medium
这里的话要闭合select标签
1 | payload: |

high
采用了白名单,采用#可以绕过后台效验
1 | payload: |

这里我发现在edge浏览器中可以直接弹出弹窗,而在火狐中不能,于是我在火狐中使用hackbar尝试了一下,发现可以成功:

10、XSS(Reflected)
low
1 | payload:<script>alert(1)</script> |

medium
1 | payload:<a href=javascript:alert(1)>xss</a> |
点击下面的超链接即可出现弹窗。

high
1 | payload:<img src=111 onerror=alert(1)> |

11、XSS(Stored)
low
这是一个留言框,在第二个内容框中输入payload:
1 | <script>alert(1)</script> |
存储型的payload会一直有效,当你再次输入一个正常的留言时,也会弹出弹窗。

medium
在第二个输入框多次尝试无果,换到第一个输入框,发现有长度限制,用burp抓包,在第一个变量名处输入payload:
1 | <SCRIPT>alert(1)</SCRIPT> |

放包,看到页面成功出现弹窗:

high
用burp抓包,在第一个输入框的变量后面尝试,payload为:
1 | <img src=111 onerror=alert(1)> |
放包,看到页面成功出现弹窗。

12、CSP Bypass
low
CSP,即内容安全策略。开发者在开发过程中设置了一个类似于白名单的策略,要信任某个页面,哪些外部资源可以执行,哪些不可以,这可以从根本上防御XSS。
分析页面源码,可以看到设置的白名单:

点进一个白名单的链接,构造恶意的payload,可以看到生成了一个链接

将链接复制到输入框中,可以产生弹窗
听说由于这个网站是国外的,所以访问比较慢,有可能不会出现弹窗,我就是那个有可能中的一个,没关系,原理知道是这个就行啦。
medium
这里csp限制了nonce,而nonce-source,仅允许特定的内联脚本块。如源码中:nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=’

所以这里可以设置payload:
1 | <script nonce=TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=>alert(111)</script> |
即可成功出现弹窗:

high
先看一下csp头部信息,只有script-src ‘self’;即只允许本界面加载JavaScript执行。
查看服务器端的源代码,因为生成的script标签中src指向source/jsonp.php?callback=solveNum,然后将它加入到dom节点中。但是我们一般无法修改服务器上的jsonp.php文件,但是可以看到源码中会接收include参数,因此可以利用include参数作为注入点。

1 | 构造payload: |
成功出现弹窗:

13、JavaScript
low
这里的规则是成功提交success算成功。
在这里输入success和ChangeMe,都显示不对。通过用burp抓包,对比两个的请求包,可以发现它们的token是一样的。

所以猜测token可能是前端生成的。查看源码发现的确是在前端生成,且是将rot13加密的结果进行md5加密的结果作为token的值。
首先在控制台查看正确的token值:

然后替换掉原来success中错误的,可以看到成功完成:

medium
在这里,输入success和ChangeMe都错误,用burp抓包,分析两者的token区别。同样可以看到token值一样。

此关中生成token的方式是:“XX”+phrase变量的值+“XX”字符串反转。
可以看到ChangeMe的token为:token=XXeMegnahCXX
所以只需将success的token改为:token=XXsseccusXX

high
在这里,同样用burp分别抓包,分析两者的token值,发现一样:

查看源代码发现,这里的token加密引入了一个js文件。
先用还原工具(http://deobfuscatejavascript.com/#)将源代码还原,找到关键代码:
1 | function do_something(e) { |
执行的先后顺序依次是token_part_1,token_part_2(因为有300毫秒的延迟,所以在token_part_1后面),token_part_3(当点击按钮时,触发该事件)。
先在输入框中输入success,
然后在控制台依次输入:
1 | token_part_1("ABCD",44) |

最后点击submit即可成功:
