原文地址:https://brutelogic.com.br/blog/xss-limited-input-formats/
我们一般测试XSS漏洞通常是没有任何字符限制,但有时XSS入口点的操作是有限的,我们接下来将看到一些受限情况下的 XSS 利用技巧
电子邮件
电子邮件地址在表单中广泛使用,并在web应用程序的不同部分多次显示。为了演示我们如何简单地调整我们的XSS,各位可以到这进行测试。
所有不是电子邮件格式的输入都会被应用程序返回“INVALID”响应
我们猜测PHP的filter_var(或filter_input)函数的FILTER_VALIDATE_EMAIL标志只执行验证,没有真正的清理,试试传递@x.y
进行验证,但事实并非如此。
根据RFC822,要想绕过验证机制并实现XSS的解决方案就是使用一个简单且完全有效的电子邮件地址。
最终payload:
"<svg/onload=alert(1)>"@x.y
URL(无查询)
URL格式的输入有时会以HTML元素的“href”(超文本引用)结尾,就像我们在这里看到的那样。在我们的示例中,如果我们点击“click me”,该页面会将访问者发送到Google搜索网站。
同样没有处理,只是使用PHP的filter_var或filter_input函数的FILTER_VALIDATE_URL标志带来的验证。通过“protocol://reference”格式,可以很快发现我们可以使用JavaScript伪协议而不是HTTP协议
因为在JavaScript伪协议中,我们在“:”后面使用JS代码,双斜杠使payload无效,因为它们将整个行转换为注释。有一种解决方案,我们使用一个新的行字符(%0A),但是是双编码的,因为它需要在浏览器重定向中结束,而一个编码的新行只反映在页面的源代码中。
所以我们的最终payload是:
javascript://%250Aalert(1)
3. URL(带查询)
前一种情况的变体,我们还需要在URL中附加查询。你可以在这里查看。
一个简单的“?1”就足以传递过滤器,但它不会创建有效的JS语法。
javascript://%250Aalert(1)//?1
我们也可以使用三元运算符:
javascript://%250A1?alert(1):0
可能存在与所提供的URL进行验证。这也很容易绕过以下形式,我们的最终paylaod:
javascript://https://domain.com/%250A1?alert(1):0
Key
最麻烦的测试就是具有固定长度字符的格式。这种输入的最好例子是密钥输入,就像API一样。因为必须考虑严格的限制因素进行测试,所以很容易被自动化工具和人工检查所遗漏。
正如我们所看到的,任何与示例键长度不同的输入都将返回为无效。我们只需要使用一些额外的伪字符来完成MD5哈希的32个字符长度并触发弹出窗口。
最终payload:
12345678901<svg onload=alert(1)>