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 报头。也就是说现在服务器通过一个模式匹配,过滤了