跨站脚本上下文
在测试反射型和存储型XSS时,一个关键的任务就是识别XSS上下文:
攻击者可控数据出现在响应中的位置。
应用程序对该数据进行的任何输入验证或其他处理。
根据这些细节,选择一个或多个候选的XSS有效载荷,并测试它们是否有效。
注意
我们已经建立了一个全面的XSS速查表,以帮助测试Web应用程序和过滤。你可以按事件和标签进行筛选,并查看哪些载体需要用户交互。速查表还包含AngularJS沙箱逃逸和许多其他部分,以便协助进行XSS研究。
HTML标签之间的XSS
当XSS上下文是HTML标签之间的文本时,你需要引入一些新的HTML标签,用于触发JavaScript的执行。
一些执行JavaScript的有用方法:
LAB
LAB
LAB
LAB
LAB
LAB
HTML标签属性中的XSS
当XSS上下文进入到HTML标签属性值时,有时可以终止属性值、关闭标签,并引入一个新标签。
在这种情况下,更常见的是,尖括号被阻拦或被编码,因此你的输入无法逃脱其所在的标签。只要能终止属性值,一般就可以引入一个新属性来创建一个可执行脚本的上下文,如事件处理器。
上述有效载荷创建了一个onfocus
事件,该事件将在元素获得焦点时执行JavaScript,同时还添加了autofocus
属性,以尝试在没有任何用户交互的情况下自动触发onfocus
事件。最后,它添加了x="
以优雅地修复后续的标记。
LAB
有时,XSS上下文进入的是一种HTML标签属性,它本身就可以创建一个可执行脚本的上下文。在这里,你可以执行JavaScript,而无需终止属性值。例如,如果XSS上下文进入锚标签的href
属性,则可以使用javascript
伪协议来执行脚本。
LAB
或许你会遇到对尖括号进行编码但仍允许注入属性的网站。有时,即使在通常不会自动触发事件的标签内(如Canonical标签),这些注入也是可能的。你可以使用Chrome上的访问键和用户交互来利用这种行为。访问键允许你提供引用特定元素的键盘快捷键。accesskey
属性则允许你定义一个字母,当该字母与其他按键(这些按键在不同的平台上有所不同)一起按下时,将触发事件。在下一个实验中,你可以尝试使用访问键,并利用Canonical标签。你可以使用PortSwigger Research发明的一种技术在隐藏的输入字段中利用XSS。
LAB
XSS到JavaScript
当XSS上下文为响应中的某些现有的JavaScript时,可能会出现各种各样的情况,需要使用不同的技术来进行成功的利用。
终止现有脚本
在最简单的情况下,可以简单地关闭封装现有JavaScript的脚本标签,并引入一些新的HTML标签来触发JavaScript的执行。例如,如果XSS上下文如下:
那么可以使用以下有效载荷跳出现有的JavaScript并执行自己的JavaScript:
这种方法能够起效的原因是,浏览器首先进行HTML解析,以识别包括脚本块在内的页面元素,然后才进行JavaScript解析,以理解并执行嵌入的脚本。上述有效载荷会破坏原始脚本,留下一个未终止的字符串字面值。但这并不妨碍后续的脚本按正常的方式解析和执行。
LAB
跳出JavaScript字符串
如果XSS上下文位于一个引号字符串字面值内,通常可以跳出字符串直接执行JavaScript。必须修复XSS上下文后的脚本,因为任何语法错误都会导致整个脚本无法执行。
一些跳出字符串字面值的有用方法:
LAB
一些应用程序会尝试用反斜杠转义任何单引号字符,以防止输入从JavaScript字符串中跳出。字符前的反斜杠会告诉JavaScript解析器,该字符应按字面意思解释,而不是解释为特殊字符,如字符串终止符。在这种情况下,应用程序经常会犯一个错误,就是没有转义反斜杠字符本身。这意味着攻击者可以使用他们自己的反斜杠字符来抵消应用程序添加的反斜杠字符。
例如,假设输入:
被转换为:
你现在可以使用替代的有效载荷:
它被转换为:
这里,第一个反斜杠意味着第二个反斜杠作为字面意义解释,而不是作为特殊字符。这等于引号现在被解释为字符串终止符,因此攻击成功。
LAB
某些网站通过限制你被允许使用的字符来使XSS变得更加困难。这可以是在网站层面进行,也可以通过部署WAF来阻止你的请求到达网站。在这些情况下,你需要尝试使用其他方式来调用绕过这些安全措施的函数。一种方法是将throw
语句与异常处理器一起使用。使你能够在不使用括号的情况下将参数传递给函数。以下代码将alert()
函数赋给全局异常处理器,throw
语句将1
传递给异常处理器(在本例中为alert
)。最终结果是,调用以1
作为参数的alert()
函数。
有多种方式可以使用这种技术调用不带括号的函数。
下一个实验演示了一个过滤某些字符的网站。你必须使用与上述类似的技术才能解决它。
LAB
利用HTML编码
当XSS上下文是引号标签属性中的某些现有JavaScript(如事件处理器)时,可以利用HTML编码来绕过某些输入过滤。
当浏览器解析出响应中的HTML标签和属性时,在进一步处理之前,它将对标签属性值进行HTML解码。如果服务器端应用程序阻拦或清理了一些用于成功执行XSS攻击所需的字符,你通常可以通过对这些字符进行HTML编码来绕过输入验证。
例如,如果XSS上下文如下所示:
并且应用程序会阻拦或转义单引号字符,你可以使用以下有效载荷来跳出JavaScript字符串并执行你自己的脚本:
'
序列是表示撇号或单引号的HTML实体。因为浏览器在解释JavaScript之前会对onclick
属性的值进行HTML解码,所以该实体会被解码为引号,而引号会成为字符串分割符,这样攻击就会成功。
LAB
JavaScript模板字面值中的XSS
JavaScript模板字面值是允许嵌入JavaScript表达式的字符串字面值。嵌入的表达式会被求值,通常会被连接到周围的文本中。模板字面值使用反引号封装,而不是普通的引号,嵌入的表达式使用${...}
语法进行标识。
例如,以下脚本将打印一条包含用户的显示名称的欢迎消息:
当XSS上下文进入JavaScript模板字面值时,无需终止字面值。相反,你只需要使用${...}
语法嵌入一个在处理字面值时将被执行的JavaScript表达式。例如,如果XSS上下文如下所示:
那么你可以使用以下有效载荷来执行JavaScript,而无需终止模板字面值:
LAB
通过客户端模板注入进行XSS
一些网站使用客户端模板框架(如AngularJS)动态渲染网页。如果它们以不安全的方式将用户输入嵌入这些模板中,攻击者就有可能注入自己的恶意模板表达式,从而发起XSS攻击。
阅读更多
Last updated