DVWA靶场保姆级通关教学
DVWA靶场保姆级通关教学
原创 Z1eaf 泷羽Sec-Z1eaf 2025-02-20 13:36
DVWA介绍
DVWA(Damn Vulnerable Web Application)
一个用来进行安全脆弱性鉴定的PHP/MySQL Web 应用,旨在为安全专业人员测试自己的专业技能和工具提供合法的环境,帮助web开发者更好的理解web应用安全防范的过程。
另外,DVWA 还可以手动调整靶机源码的安全级别,分别为 Low,Medium,High,Impossible,级别越高,安全防护越严格,渗透难度越大。
Brute Force
一个登录页面,先随便输入账号密码
Low
使用burpsuite拦截数据包,发送到Intruder
模块,在username
和password
处添加playload,然后载入字典,开始攻击
爆破成功,账户/密码:admin/password
medium
这一关的操作步骤与Low
的是一样的,使用burpsuite拦截数据包,发送到Intruder
模块,在username
和password
处添加playload,然后载入字典,开始攻击
区别就是:源码中增加了mysql_real_escape_string函数
,这个函数会对字符串的特殊符号进行转义,基本上能抵御SQL注入。此外,该关卡的爆破速度明显下降,这是因为有sleep()函数
,在破解失败后,程序会停止运行两秒钟。
High
输入账号admin
,密码随意,然后使用burpsuite拦截抓包
拦截包,对其进行查看,我们可以发现存在token
验证的情况
设置playload位置
数据包被拦截后,发送到Intruder
模块,添加playload位置,选择攻击模式:Pitchfork
载入playload1
playload1位置为密码
,我们载入密码字典
载入playload2
playload2位置为token
,我们选择递归提取
然后,我们去该模块设置处,找到检索-提取
,点击添加
接着点击获取响应
,找到token
的value值
,选中它且复制。
回到playload2处,我们将复制的value值粘贴
设置线程
然后在爆破模块的options
设置好网络重试次数为0,避免token错位
然后设置好重定向
紧接着,在资源池
设置好最大并发数为1
开始攻击,完成爆破
Command Injection
Low
观察页面,让我们输入IP地址,对其进行ping
我们输入127.0.0.1
,点击提交,发现返回的数据和我们在cmd执行命令:ping 127.0.0.1
回显基本一样。 乱码原因可能是网页编码问题
解决乱码方法
打开根目录,找到dvwa/inclides
目录下的的dvwaPage.ini.php
文件。
打开文件,搜索utf-8
,将其替换成GBK
或GB2312
刷新页面,解决乱码情况
回到关卡
我们知道这是执行ping
命令,所以我们使用命令连接符来进行执行命令注入。
常见的命令连接符
– &
:前面一个命令无论是否执行,后面的命令都能执行,两个命令都执行
-
&&
:前面一个命令执行成功后,才能执行后面一个命令,两个命令都执行 -
|
:前面一个命令无论是否执行,后面的命令都能执行且只执行后面一个 -
||
:前面一个命令不能正常执行后,才能执行后面一个命令
我们使用“|”符号作为连接符让计算机做出除ping以外的操作实现命令注入
127.0.0.1|dir
Medium
我们分析一下源码,看看和Low级的关卡有什么区别
我们可以看到源码把&&
和;
过滤了
那我们使用&
或|
还是可以的
127.0.0.1&dir127.0.0.1|dir
High
老套路,分析源码
我们仔细观察可以发现在过滤|
时,后面接了一个空格,所以过滤的是|
,这意味着这个过滤其实是是没有用的,因为,我们只需要在|
后接上命令,不保留空格,我们依然可以使用这个命令连接符进行命令注入
127.0.0.1|dir
CSRF
Low
这一个的网站是让我们修改密码,那我们先输入密码,点击提交
提交后,使用burpsuite抓包,我们分析数据包,发现是Get
请求,URL显示password。
为了更直观的利用CSRF漏洞,我们复制这个URL,然后修改password
dvwa:9998/vulnerabilities/csrf/?password_new=456789&password_conf=456789&Change=Change#
然后在新标签中输入修改后的URL
修改密码成功,CSRF攻击完成
网站的本意是希望用户在网站内更改密码,而我通过控制url的传参就能使我能在网站之外执行更改密码的操作。那么当我知道一个网站有csrf漏洞后也可以通过构造url的方式让别人点击执行他意想之外的行为
Medium
查看源码,发现多了一处验证,通过验证Referrer
字段来验证请求是否从网站本身发起的,若不是就不执行后续操作。
输入账户密码,然后使用burpsuite进行抓包,分析数据包,我们可以看到referrer字段是网页路径
既然如此,那我们就构造一个页面,在html文件内放入一个a标签,链接为:修改密码的URL。当被害人点击时就会触发更改密码的操作。
打开文件,点击链接
使用burpsuite抓包,然后在请求头添加referrer字段:
Referer: http://dvwa:9998/vulnerabilities/csrf/?password_new=passwd&password_conf=passwd&Change=Change
重放,密码修改成功
High
我们分析一下源码,可以看到源码中多了token
校验,每次登录都会校验token是否正常,如果想要执行更改密码操作,那我们就必须要知道正常用户的token值
获得用户token的方式有两种:
– 构造一个页面让用户点击,点击之后偷偷的读取用户登录网站的token,把token加到自己构造的更改密码的表单上做让用户点击完成攻击,但由于同源策略,一半无法获得token,也有解决方法,但那个更繁琐,这里不赘述了
- 如果用户网站上刚好有存储型漏洞,可以利用存储型漏洞与csrf漏洞配合,即通过存储型漏洞获得token再利用csrf漏洞结合拿到的token完成攻击
因此,为验证漏洞,我们假设是通过存储型XSS漏洞获得user_token:57ccfed74284e085d0297ae4523567f
然后我们还是使用前面的构造的html文件,点击链接后,使用burpsuite抓包,将token值拼接。
发送请求,回到页面,发现密码修改成功
File Inclusion
Low
进入关卡,我们可以看到有3个php文件链接
点击其中一个查看,可以看到页面,没有返回文件内容
为了验证漏洞,我在WWW文件夹
内创建了一个flag.txt
。
一开始,我们是不知道文件具体路径,但是我们可以先随便输入几个../
,回显报错信息。
根据报错信息,那我们构造playload获取flag
../../../flag.txt
Medium
分析源码,我们可以发现http://
、https://
、../
、..\
被过滤掉了
那只能构造playload,利用双写绕过
....//....//....//flag.txt
High
分析源码,使用fnmatch()函数
对page参数进行过滤,要求page参数的值必须以file开头,这样服务器才包含相应文件。
既然如此,那我使用file伪协议结合文件路径构造playload
file://E://phpstudy_pro//WWW//flag.txt
File upload
因为是文件上传,我们先创建一个.php文件。
Low
我们先直接上传文件,可以看到,.php文件
已经成功上传,没有任何验证机制
Medium
分析源码,我们可以看到验证机制主要是检查请求中的上传文件类型是否为image/jpeg
先将muma.php
改为muma.jpg
然后在页面上传文件,使用burp suite抓包,再将muma.jpg
改为muma.php
修改后放行,上传成功
High
这一关,我们得制作图片马进行上传
先打开cmd,输入命令
copy muma.php+1.png 666.jpg
然后将图片上传
回到文件包含的low关卡,在URL载入playload
http://dvwa:9998/vulnerabilities/fi/?page=../upload/666.png
Insecure CAPTCHA
Low
分析源码
服务器将密码修改操作分成两步进行。首先,服务器检查用户输入的验证码,如果验证通过,服务器返回一个表单。然后,客户端提交POST请求,服务器完成更改密码的操作。但是,存在一个逻辑漏洞,即服务器仅通过检查Change
和step
参数来判断用户是否已经输入了正确的验证码。
因此,攻击者可以通过修改HTTP请求中的参数来绕过验证码验证,达到修改密码的目的
输入密码和确认密码,点击提交。
然后使用burpsuite抓包,将step=1
修改为step=2
修改好,将数据包放行
Medium
分析源码
在中等安全级别的代码中,第二步处理逻辑增加了对验证码是否通过(passed_captcha)的判定。如果passed_captcha
为true
,则认为验证码正确。通过修改HTTP请求中的参数,攻击者同样可以绕过验证码验证
输入密码和确认密码,点击提交。
然后使用burpsuite抓包,将step=1
修改为step=2
、passed_captcha=true
修改好,将数据包放行
High
分析源码
在高安全级别的代码中,服务器的验证逻辑是当谷歌返回的验证结果($resp)是false,并且参数g-recaptcha-response不等于特定值(hidd3n_valu3),或者HTTP请求头的User-Agent参数不等于reCAPTCHA时,就认为验证码输入错误。反之,则认为已经通过了验证码的检查。
因此,攻击者可以通过修改HTTP请求中的g-recaptcha-response
和User-Agent参数
来绕过验证码验证
输入密码,进行提交
然后使用burpsuite抓包,修改g-recaptcha-response=hidd3n_valu3
和User-Agent=reCAPTCHA
修改好,将数据包放行。页面回显修改成功
SQL Injection
Low
可以看到输入ID,回显用户信息
输入1’
,页面回显报错信息。根据判断信息可以知道形成注入的符号是单引号
使用万能密码
1' or 1=1#
成功爆出所有用户信息
Medium
这一关不能进行语句输入,而是使用复选框
点击Submit
,然后使用burpsuite抓包
将数据包发送到重放器模块,重新构造语句
将1
修改为1′
,然后发送。回显报错信息,根据报错信息可以确定是一个数字型注入
然后构造playload
1 or 1=1#
High
页面与前面不一样
点击链接会弹出另外一个页面
输入id后提交,回显用户信息
先判断注入型,输入1′
,页面报错
然后构造playload
SQL Injection (Blind)
Low
页面输入1
,回显数据存在页面
页面输入1′
,回显数据不存在
没有报错信息回显,我们使用布尔盲注
判断注入点
1' and 1=1#
判断数据库名长度
1' and length(database())=4#
爆数据库名
使用substr()函数
,逐一判断为:dvwa
1' and ascii(substr(database(),1,1))>97#
判断表名长度
1' and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>1#
爆表名
1' and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>1#
判断列名长度
1' and length((select group_concat(column_name) from information_schema.columns where table_name="user" and table_schema=database()))>1#
爆列名: user和password
1' and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>1#
爆数据
然后再使用二分法猜解user字段
的值:(用户名)
1' and ascii(substr((select user from users limit 0,1),1,1))=xxx#(第一个字符)1' and ascii(substr((select user from users limit 0,1),2,1))=xxx #(第二个字符) ......
猜解password字段
的值:(密码)
1' and ascii(substr((select password from users limit 0,1),1,1))=xxx #(第一个字符).....
Medium
这一关使用的是复选框
点击提交,使用burpsuite抓包,然后判断注入点
1+and+1=1#
页面回显
说明还是可以使用布尔盲注的手法,和Low关卡一样
High
分析源码
可以看到,High级别的代码利用cookie传递参数id,当SQL查询结果为空时,会执行函数sleep(seconds),目的是为了扰乱基于时间的盲注。
同时在 SQL查询语句中添加了LIMIT 1,希望以此控制只输出一个结果。但是我们可以通过#
将其注释掉。
因此,和前面的SQL注入一样,但由于服务器端执行sleep函数,会使得基于时间盲注的准确性受到影响,这里我们只能使用基于布尔的盲注。具体步骤可以参考Low关卡。
Weak Session IDs
Low
在低级别,会话ID是通过递增的方式生成的,这种方式容易被攻击者猜测,从而增加了会话劫持攻击的风险。
攻击者可以通过观察会话ID的变化来预测下一个有效的会话ID
Medium
在中级别,会话ID是基于时间戳
生成的。虽然这增加了猜测的难度,但如果攻击者能够预测受害者在特定时间点进行操作,仍然可能发起会话劫持攻击
High
高级别使用了md5函数对会话ID进行加密处理,这增加了攻击者直接猜测会话ID的难度。但由于会话ID仍然是以可预测的方式递增,通过md5解密工具仍有可能被破解。
XSS(DOM)
Low
页面显示一个复选框,我们选择English
使用开发者工具查看源码和观察Url
分析得出:选择下拉列表内容,选择的值会赋给 default 并添加到 url 的末尾,再将其传给 option 标签的 value 结点。也就是说我们可以注入一些 JS 代码进去,然后这部分会被包含到 lang 变量中,最终回显到页面上。
构造playload
<script>alert(document.cookie)</script>
Medium
分析源码
array_key_exists()函数
检查某个数组中是否存在指定的键名,如果键名存在返回 true,键名不存在则返回 false。stripos(string,find,start)函数
查找字符串在另一字符串中第一次出现的位置(不区分大小写),header()函数
向客户端发送原始的 HTTP 报头。也就是说现在服务器通过一个模式匹配,过滤了