Cross-Site Scripting 简称为“CSS”,为避免与前端叠成样式表的缩写"CSS"冲突,故又称XSS。
<非持久化>攻击者事先制作好攻击链接, 需要欺骗用户自己去点击链接才能触发XSS代码(不会存储在服务器,不会经过数据库),一般容易出现在搜索页面。
<持久化>代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,每当有用户访问该页面的时候都会触发代码执行,这种XSS非常危险,容易造成蠕虫,大量盗窃cookie(虽然还有种DOM型XSS,但是也还是包括在存储型XSS内)。
基于文档对象模型Document Objeet Model(DOM)的一种漏洞。DOM是一个与平台、编程语言无关的接口,它允许程序或脚本动态地访问和更新文档内容、结构和样式,处理后的结果能够成为显示页面的一部分。DOM中有很多对象,其中一些是用户可以操纵的,如uRI ,location,refelTer等。客户端的脚本程序可以通过DOM动态地检查和修改页面内容,它不依赖于提交数据到服务器端,而从客户端获得DOM中的数据在本地执行,如果DOM中的数据没有经过严格确认,就会产生DOM XSS漏洞。(DOM型XSS只在前端,与后端毫无关系。)
直接输入一个script试试,但是发现输入框限制了长度。
这里我们有两种方法解决这个问题。
第一种是通过观察发现网页框的url里面有我们输入的信息,直接在这上面上修改。
输入,如图:
回车效果如下:
用快捷键f12,选中输入框,看到它的maxlength为20。
我们把它随意改个值,这里我改的是100。
JavaScript 可以使用 document.cookie 属性来创建 、读取、及删除 cookie。
我们这里输入
在留言板直接输入:
提交得到cookie值:
这里需要注意的是当我们点击其他关卡再次回到这个存储型xss关卡时它仍会出现弹窗,这说明存储型xss是存储在服务器的数据库中的,也就是说存储型XSS能危害所有访问受影响页面的用户。
我们像之前一样输入,点击提交发现出现一行小字,点击后出现403页面。
查看源代码,发现这里有个domxss函数。大概意思是我们输入的值作为str写入到了a标签里。
<a href='"+str+"'>what do you see?</a>
这里的写入时就失效了,因为a标签里面没有这种写法,所以我们要看看其他的用法,这里给出了两种方法。
根据提示a标签可以这么用:
<a href='' onclick="alert('xss')"></a>
所以我们直接输入str为
' οnclick="alert('xss')">
我们先闭合掉a标签,然后用img标签,语句如下:
'>xss')">
onmouseover事件:指鼠标移动都某个指点的HTML标签上,会出现什么效果。
既然还是DOM型,就直接查看网页源代码,发现跟上一关没啥区别。
唯一有一点不同的是,输入出现在了url中:
由于本关payload在url中,因此比第4关好利用很多
DOM型XSS只在前端,与后端毫无关系。DOM-X型危害更大,它能够像反射型一样在URL中体现,将URL发给了受害者就能进行攻击。
直接输入框输入
提交后发现没有反应
根据提示登录后台地址:/admin_login.php
再登录账号:admin密码:123456
看到后台得到的cookie值:
直接输入
提交后出现了一个’>’
发现页面有回显输入的内容,url中也有输入的内容,离开本页面再回来,页面就没有这个内容了,说明是反射型GET型XSS
说明这一题存在过滤,我们需要尝试他过滤了什么字符和如何绕过过滤。
猜测一下可能有:"<>'on/`() script img href src
把以上字符一起提交,发现<>‘on/’() script被过滤掉了
但是单独输入**<>‘on/’() ,发现没有被过滤掉:
说明过滤掉的语句可能是<.script*
那就不要用< script>标签了,尝试使用别的标签
输入Payload:
<a href="#" onclick="alert(document.cookie)">
点击之后得到cookie:
这里可以看一下php:
这里的preg_preplace()函数的用法如下:
pattern这部分为要匹配的内容,在匹配内容的开头和结尾必须要添加同样的标识,但是不能为数字和字母,所以这里前后出现了/:
'/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/'
htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。
预定义的字符是:
& (和号)成为 &
" (双引号)成为 "
’ (单引号)成为 ’
< (小于)成为 <
(大于)成为 >
它的语法如下: htmlspecialchars(string,flags,character-set,double_encode)
其中第二个参数flags需要重要注意,很多开发者就是因为没有注意到这个参数导致使用htmlspecialchars()函数过滤XSS时被绕过。因为flags参数对于引号的编码如下:
可用的引号类型:
ENT_COMPAT - 默认。仅编码双引号。
ENT_QUOTES - 编码双引号和单引号。
ENT_NOQUOTES -不编码任何引号。
输入**,发现没有效果。
查看源代码,发现有个a标签,它<>部分被html编码。此这关想闭合标签是不行了。仔细一看,又发现单引号居然没有被html编码,所以就利用一下标签吧。
输入#’ οnclick=‘alert(1)’>**,提交点击,发现成功弹窗。
先输入个试试,没有弹框
右键查看源代码,发现它过滤了<>:
试试#' onclick='alert(document.cookis)'
,发现还是没有弹窗,查看源代码,发现过过滤了’':
所以现在左右尖括号和单引号都被html编码了。
我们查看w3school,发现href 属性的值可以是任何有效文档的相对或绝对 URL,包括片段标识符和 JavaScript 代码段。
所以我们这里可以输入:
javascript:alert(document.cookie)
得到弹窗:
查看php文件,发现它用了ENT_QUOTES - 编码双引号和单引号。
先输入个试试,没有弹框,查看源代码:
发现输入的闭合掉了,介绍两种办法:
法一:直接可以输入,得到弹窗:
法二:
或者无中生有出一个js语句就好了,首先要用’;闭合掉当前的语句,然后插入新语句,然后再用//注释掉老语句遗留下来的’;
输入';alert(1);//
,得到弹窗
查看php,这里的关键是JS的输出点应该使用\对特殊字符进行转义:
总结:
1、在不知道它过滤了什么的情况下,可以用**"<>'on/`() script img href src**等字符
2、用htmlspecialchars进行过滤,默认情况下没有过滤单引号。
3、在a标签的href中可以利用JavaScript协议执行js语句。在有输入接口,并且将输入内容直接赋值给变量的,可以构造闭合来执行恶意js代码。