标题 简介 类型 公开时间
关联规则 关联知识 关联工具 关联文档 关联抓包
参考1(官网)
参考2
参考3
详情
[SAFE-ID: JIWO-2024-3177]   作者: 小螺号 发表于: [2022-09-16]

本文共 [180] 位读者顶过

  1. 对于路径 https://www.glassdoor.com/Job/?xss 下的任何页面,所有 URL 参数都反映在 Javascript 脚本标记中。缺乏清理意味着我们可以使用 https://www.glassdoor.com/Job/?xss=</script 将 </script 注入页面,但是由于 WAF,我们不能简单地转义脚本标签并执行我们自己的
  2. optimizelyEndUserId cookie 值反映在页面中,位于 URL 参数之后。通过将此与步骤 1 中的问题结合起来。我们可以通过将有效负载分成两部分来执行任意 javascript 来绕过 WAF。然而,这是一个自我 XSS,因为我们不能强迫我们的受害者发送自定义 cookie。
  3. 我们可以通过缓存中毒来解决这个问题。遗憾的是 https://www.glassdoor.com/Job 下的页面没有被缓存,但 https://www.glassdoor.com/Award/ 下的所有页面都被缓存了。
  4. 经过一些测试,我发现路径遍历字符/../(也称为点段)正在被缓存前端服务器规范化,但未被后端 Web 应用程序规范化(RFC 3986 5.2.4的分歧)。这意味着路径 https://www.glassdoor.com/Job/../Award/blah?xss=</script 将被视为 https://www.glassdoor.com/Award/blah?xss= </script 由缓存服务器缓存,但 https://www.glassdoor.com/Job/../Award/blah 的内容将由网络服务器返回,因为缺乏规范化
  5. 因此,通过将带有我们有效负载的请求发送到 https://www.glassdoor.com/Job/../Award/blah?xss=</script(以及 cookie 中的其余有效负载),我们可以成功获取我们的 XSS。网络服务器会将其解释为 https://www.glassdoor.com/Job/ 下的页面,并使用我们注入的 XSS 有效负载返回内容,而缓存服务器会将其解释为 https://www.glassdoor.com /Award/blah?xss=</script 导致响应被缓存
  6. 届时访问 https://www.glassdoor.com/Award/blah?xss=</script 我们的 XSS 将触发
  7. 使用 https://glassdoor.com/mz-survey/interview/collectQuestions_input.htm 也可以实现存储的 XSS,其行为与 非常相似/Job,但 XSS 都在标头和 cookie 中,因此在 URL 中发送参数没有必要。
  8. 发送带有 XSS 的标头和 cookie 的 https://www.glassdoor.com/mz-survey/interview/collectQuestions_input.htm/../../../Award/blah 将导致存储在 https 下的 xss: //www.glassdoor.com/Award/blah

存储的 XSS PoC [出自:jiwo.org]

<br />

我的 XSS 方法论

  • 在测试 XSS 时,重要的是要考虑所有类型的利用,并注意所有看起来有趣的东西。

  • 即使某些东西现在可能无法利用,也要尝试看看它在链式利用中的潜力。

  • 很多时候,漏洞利用链是由无法利用的链接组成的,这些链接本身是无用的,但当链接在一起时可能是致命的。

  • 在 Glassdoor 中,我在/Job/new-york-ny-compliance-officer-jobs-SRCH_IL.0,11_IC1132348_KO12,42069.htm

  • 我发现参数名称(和值也是)反映在未处理的响应中

  • 看到这个我很惊讶,因为这应该很早就被发现了。Glassdoor 程序有近 800 份提交,所以我没有错误地认为我是唯一注意到它的人

  • 该参数反映在脚本标签中的字符串中,因此要实现 XSS,我有 2 个选项

    1. 转义字符串并注入 javascript
    2. 关闭脚本标签并注入通用 XSS 有效负载
  • 对于第一个选项,字符串似乎已经用反斜杠转义了,不幸的是绕过这个很难。

  • 但是,我的第二个选项具有更大的潜力,因为没有对用户输入进行清理,因此注入结束脚本标签应该可以解决问题

  • 然而,在我输入的那一刻?</script>(为了便于阅读,此处为 URL 解码)我的请求立即被 WAF 关闭并阻止。这是非常期待的,但是我早餐吃WAF>:)

  • 在尝试与 WAF 对抗之前,我们必须了解游戏规则。

  • 我看到人们在尝试绕过 WAF 时犯的一个常见错误,或者只是一般的过滤器,是他们复制和粘贴通用 WAF 绕过有效负载,而没有真正理解WAF 阻止他们的请求的*原因。*根据我的经验,喷涂和祈祷WAF通常是浪费时间,因此最好手动测试它们,最重要的是了解它们

  • 所以我绕过 WAF 的第一步是从一个被阻止的有效负载开始,然后逐个字符地删除,直到 WAF 让我通过

  • 幸运的是,我们很快就与 WAF 达成协议。我所要做的就是删除大于>号,我得到了 200。

  • 所以现在的问题是它还有什么不喜欢的?似乎之后的任何角色</script都会引起 WAF 的注意,</scriptaaa例如

  • 如果 WAF 真的阻塞了,这将是一个大问题</script*,但幸运的是,WAF 确实允许空格字符,例如%20(space),这意味着最终,脚本标签将在下一个即将到来的大于>号时关闭

  • 所以现在,下一步转向寻找一个新的未经处理的注入点,这将允许我们关闭脚本并注入一个 HTML XSS 有效负载

  • 我试图查看是否可以将有效负载分解成带有其他参数的部分,但是它也被阻止了。似乎 WAF 规则应用于整个 URL,而不是单个参数。幸运的是,我之前绕过了这些类型的 WAF

  • 我的第一个 goto 技术是基于字母数字的 HTTP 参数污染,我过去已经使用它来绕过这个程序中的类似 WAF。

  • 字母数字参数污染滥用了反射查询的字母数字顺序,因此可以通过将有效负载向后分解为不同的参数来绕过这样的 WAF

  • 不幸的是,这里的情况似乎并非如此,但我将发布一篇关于我如何使用这种技术来实现反射型 XSS 的文章

  • 此时我对这个端点失去了一点希望,所以我决定寻找链环漏洞而不是独立漏洞。这是我开始看饼干的时候

  • 这时我注意到在注入点旁边,实际上有一个值来自optimizelyEndUserId我请求中的 cookie。

  • 我需要做的就是关闭脚本标签并注入 HTML。注入><svg>cookie 似乎可以解决问题。

  • 现在我需要实际执行javascript。我们已经克服了困难的部分,所以现在当我们能够通过 WAF 偷运一个 svg 标签时,剩下的应该很容易

  • 一个非常通用的 WAF 绕过有效负载似乎可以解决问题:><svg/onload=a=self['aler'%2B't']%3Ba(document.domain)>

  • 现在我们得到了一个看起来像这样的 XSS:

    GET /Job/new-york-ny-compliance-officer-jobs-SRCH_IL.0,11_IC1132348_KO12,42069.htm?attack=VULN%3C/script%20 HTTP/2 Host: www.glassdoor.com Cookie: optimizelyEndUserId=BRUH><svg/onload=a=self['aler'%2B't']%3Ba(document.domain)> User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0 Content-Length: 0

  • 然而,它是一个自我 XSS,只有在我们能够控制 cookie 时才存在

  • 然而,这可能会升级为带有缓存中毒的反射 XSS,所以这就是我接下来开始寻找的东西(我知道我在描述中说过存储 XSS,我保证我们会很快到达那里!)

寻找宽松规则的缓存方法

  • 在进行初始侦察时,我总是喜欢测试缓存以查看其行为方式。
  • 如果我看到一个被缓存的路径,我总是尝试测试它的限制。许多网站对如何缓存特定路径和文件都有独特的规则,因此手动测试这些规则是熟悉缓存服务器的好方法
  • 当我第一次手动测试这些缓存规则时,我通常会先尝试弄乱扩展。我将删除、添加或更改扩展,并始终仔细观察响应的缓存标头和内容
  • 在我弄乱了扩展之后,我将测试路径本身
  • 例如,在 Glassdoor 中,我注意到它https://www.glassdoor.com/Award/new-york-ny-compliance-officer-jobs-SRCH_IL.0,11_IC1132348_KO12,42069.htm正在被缓存
  • 我截获了请求并将其发送到 Burp 中继器进行进一步检查
  • 当我更改扩展名时,我注意到当我得到一个 404 页面时,我仍然得到 MISS/HIT 缓存头。
  • 这立即让我想到缓存或没有缓存有某种模式,而不是被缓存的硬编码文件
  • 然后我走上了小路。我试过https://www.glassdoor.com/Award/somerandomfile了,发现它给了我相同的 404 页面和相同的缓存头。
  • 那时我非常有信心,我弄清楚了规则是什么,但为了以防万一进行了测试https://www.glassdoor.com/randompath/somerandomfile,这给了我一个 404 但没有缓存
  • 所以现在假设规则是相同的/Award/*,这意味着/Award路径下的所有内容都被缓存了
  • 有一段时间,我拼命寻找某种头部 XSS 来获得 Web Cache Poisoning,但不幸的是我空手而归。然而,这个发现对我来说仍然非常棒。虽然它本身不是一个漏洞,但它是一个非常宽松的规则,并且有很大的潜力与漏洞挂钩

链接漏洞利用

  • Web Cache Poisoning 可用于许多事情。首先想到的是 1) 存储型 XSS 2) 将不可利用的 XSS 升级为反射型 XSS 3) DoS

  • 在我发现缓存规则的时候,我已经意识到了无法利用的 XSS 中/Job/new-york-ny-compliance-officer-jobs-SRCH_IL.0,11_IC1132348_KO12,42069.htm?VULN%3C/script%20,因此尝试将这两个错误链接到反射 XSS 漏洞中感觉就像是自然而然的事情

  • 我回到工作路径做更多的研究。我想看看是否还有其他易受自身 XSS 攻击的端点,并且确实存在。

  • 我发现Job路径下的每个页面都容易受到self XSS的攻击,太棒了!我更进一步,注意到即使是应该是 404 的页面,实际上也返回了 200,并且太容易受到自身 XSS 的攻击。

  • 因此,回顾一下重要信息:

    1. CDN 有一个规则会缓存/Award/*
    2. 上有一个自我 XSS 漏洞/Job/*
  • 这两个漏洞的攻击面不是"静态的",而是依赖于一个非常宽松的通配符模式,这让我想到:"这些模式真的 能接受任何东西吗?服务器会将模式优先于特殊的 URL 语法(例如点段/../),还是将 URL 规范化然后匹配模式?"

  • 或者换句话说:"后端服务器和前端服务器的 URL 解析器都会规范化点段吗?"

  • 为了测试这一点,我在假设 URL 解析器标准化点段的情况下尝试了这两个有效负载:

    1. /Award/../this_should_not_cache
    2. /Job/../this_should_give_a_404
  • 令我惊讶的是,它们产生了相互矛盾的结果

  • 奖励负载没有被缓存,这意味着前端服务器的 URL 解析器在匹配缓存规则之前会规范化点段

  • 但是,作业路径返回 200,这意味着 Web 服务器没有规范化点段。

  • 所以总结这个简短的测试,我们可以说前端服务器和后端服务器在如何解析点段方面存在分歧

  • 知道了这一点,我们可以构造以下有效载荷:

    GET /Job/../Award/RANDOMPATHTATDOESNOTEXIST?cachebuster=046&attack=VULN%3C/script%20 HTTP/2 Host: www.glassdoor.com Cookie: optimizelyEndUserId=BRUH><svg/onload=a=self['aler'%2B't']%3Ba(document.domain)> User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0 Content-Length: 0

  • 由于网络服务器不会对点段进行规范化,因此我们将通过 XSS 获得响应

  • 但是,由于前端将规范化点段,它将被缓存(并存储)在/Award/RANDOMPATHTATDOESNOTEXIST?cachebuster=046&attack=VULN%3C/script%20

  • 所以现在,当受害者访问时https://glassdoor.com/Award/RANDOMPATHTATDOESNOTEXIST?cachebuster=046&attack=VULN%3C/script%20,他们会从 CDN 中获取带有 XSS 的存储响应

存储型 XSS

  • 因此,一旦我能够获得反射 XSS 的有效 PoC,我立即报告。

  • 但是,我仍然不够满意,因为我知道存储型 XSS 在适当的条件下应该是可能的

  • 所以我一直在寻找一个真正所有基于标题的 XSS,并且行为类似于/Job/*,在它下面的每个页面下都可能存在 XSS。

  • 那是我记得我第一次向 glassdoor 报告的时候,它是 http://glassdoor.com/mz-survey/start_input.htm 中通过字母数字有序参数污染反映的 XSS(当时它仍在分流中,所以它不是固定的)。

  • 我想也许我也能在那里找到一个标头 XSS,所以我一直在寻找

  • 对我来说幸运的是,报告中反映的 XSS 也容易受到完整标头 XSS 的攻击!但它的行为不像/Job/*它下面的每个页面都容易受到攻击,所以它几乎没用

  • 我确实记得不仅有一个端点易受攻击,还有很多其他端点

  • 幸运的是,我最终能够找到一个端点,它既容易受到标头 XSS 的攻击,又表现得像/Job/*在测试了我之前报告的每个易受攻击的端点并得到了这个:https://glassdoor.com/mz-survey/interview/收集问题_输入.htm/

  • 有效载荷看起来像这样

    GET /mz-survey/interview/collectQuestions_input.htm/../../../Award/RANDOMPATHTATDOESNOTEXIST123?cachebuster=050 HTTP/2 Host: www.glassdoor.com X-Forwarded-For: VULN X-Forwarded-For: VULN><svg/onload=selfalert> Cookie: gdId=VULN%22</script%20 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8

  • 将 XSS 有效负载拆分为 2 个标头和一个 cookie 的原因是绕过 WAF,因为我无法将整个有效负载放入一个 cookie 或标头

  • X-Forwarded-For 标头反映在 cookie 之后,因此我继续有效载荷的机会就在那里。

  • 不幸的是,WAF 对 X-Forwarded-For 标头更加严格,因为我无法使用任何特殊字符

  • 有趣的是,还有另一个很酷的标头混淆,WAF 只阻止了第一个 X-Forwarded-For 标头,但网络服务器解释并反映了两者。这让我可以轻松绕过 WAF,方法是为第一个 X-Forwarded-For 标头提供有效值,但在第二个 X-Forwarded-For 标头中提供我的 XSS 有效负载的其余部分。这可以在上面的有效载荷中看到

评论

暂无
发表评论
 返回顶部 
热度(180)
 关注微信