1. EmojiCTF2024 Web赛题解析与实战复盘
去年参加EmojiCTF的经历让我记忆犹新——那是一个用表情符号作为主要交互方式的特殊CTF赛事。作为Web方向的参赛者,我遇到了不少令人拍案叫绝的题目设计。今天就来拆解其中最具代表性的几道Web题目,分享解题思路的同时,也会还原当时踩过的坑。
2. 赛事环境与基础准备
2.1 比赛环境配置要点
EmojiCTF的Web题目通常运行在定制化的Docker容器中,每个实例会分配独立端口。我习惯使用以下工具链:
- Chrome浏览器 + HackTools插件(内置编码转换功能)
- Burp Suite Community版(抓包改包必备)
- Python3环境(用于快速编写爆破脚本)
- 自制的Emoji解码工具(后文会分享源码)
重要提示:比赛网络通常限制境外IP访问,建议提前测试代理延迟。我在第一小时就因网络问题浪费了大量时间。
2.2 Emoji编码特征识别
题目中常见的编码形式包括:
- 直接Unicode呈现(如🚩→U+1F6A9)
- URL编码(%F0%9F%8E%89)
- Base64编码后的Emoji(8J+NqQ==)
- 自定义替换密码(⭐=A,🔥=B等)
3. 典型题目深度剖析
3.1 表情盲注题(Web100)
题目描述:一个仅用emoji作为查询参数的搜索框
解题过程:
- 输入🐶返回"找到1条结果",输入🐱返回"找到0条结果"
- 通过Burp拦截发现参数为?search=%F0%9F%90%B1
- 确认存在布尔型注入特征:
- 🐶' AND 1=1-- → 正常返回
- 🐶' AND 1=2-- → 无结果
最终payload:
import urllib.parse emoji_payload = "🐶' UNION SELECT flag FROM flags--" encoded = urllib.parse.quote(emoji_payload) print(f"最终URL:http://ctf.example.com/?search={encoded}")3.2 Cookie伪造题(Web200)
题目首页只有😊和😢两个按钮,点击后显示不同表情
关键突破点:
- 发现Cookie中有user=😊_😊_😢的base64形式
- 解码后尝试修改表情顺序:
- 😊_😢_😊 → 返回403
- 😊_😊_😊 → 显示管理员菜单
- 在第三个位置插入🚩获取flag
调试技巧:
// 控制台快速生成Cookie function genCookie(emojis) { return btoa(emojis.join('_')).replace(/=+$/, ''); } console.log(genCookie(['😊','😊','🚩']));4. Emoji处理工具开发
4.1 Python解码工具
import emoji from urllib.parse import unquote def decode_emoji(input_str): if '%' in input_str: return unquote(input_str) try: return emoji.demojize(input_str) except: return input_str.encode('unicode-escape').decode()4.2 常见问题排查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| Emoji显示为方框 | 终端编码问题 | 改用iTerm2或Windows Terminal |
| 提交后参数丢失 | 中间件过滤 | 尝试HTML实体编码(😀) |
| 响应乱码 | 字符集不匹配 | 添加Header:Content-Type: text/html; charset=utf-8 |
5. 高级技巧与防御方案
5.1 Emoji混淆技术
去年有一道题将flag藏在零宽度空格修饰的Emoji中:
const hiddenFlag = '🏳️🌈'.replace(/[\u200B-\u200D\uFEFF]/g, '');5.2 防御建议
对于开发者:
- 使用emoji-regex库严格校验输入
- 在WAF规则中添加Emoji的Unicode范围检测
- 避免直接拼接Emoji到SQL语句
6. 实战演练:复现2024赛题
6.1 题目还原步骤
- 准备Docker环境:
FROM python:3.9 RUN pip install flask emoji COPY app.py /app/ CMD ["python", "/app/app.py"]- 核心漏洞代码:
@app.route('/search') def search(): query = request.args.get('q', '') if '🚩' in query: return "检测到敏感表情!" return f"搜索结果:{query}"6.2 绕过检测的方法
使用组合字符绕过:
- 🚩 → 🏴 + ⚐(Unicode组合)
- URL编码:%F0%9F%8F%B4%EF%B8%8F%E2%9A%90
7. 赛后总结与提升建议
通过这次比赛,我整理出Emoji相关的Web安全知识体系:
- 编码转换:Unicode/URL/Base64互转
- 注入检测:布尔型/时间型盲注特征
- 模糊测试:使用fuzzdb的emoji字典
- 流量分析:Wireshark识别异常编码
建议想要备赛的同学:
- 熟记Unicode中Emoji的编码范围(U+1F300到U+1F5FF等)
- 收集各类CTF中的Emoji题目建立本地题库
- 开发自己的编码转换工具链
那次比赛最后一道Web400的题目,我花了3小时才意识到需要把🐌(蜗牛)表情延迟作为时间盲注的判断依据。这种非传统的出题思路正是EmojiCTF的魅力所在,也提醒我们Web安全研究需要跳出固定思维模式。