跨站脚本攻击XSS(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS(x也意味着未知)。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页面时,嵌入Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。XSS攻击针对的是用户层面的攻击!
XSS分为:存储型 、反射型 、DOM型XSS
一.反射型XSS
非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面。反射型XSS大多数是用来盗取用户的Cookie信息。
目录
在第一个框输入<script>alert(1)</script>
我们看到有弹窗。
我们再对第二个框进行测试时,看到有显示successful,猜它和后台的交互了。
然后用XSS Platform (xsscom.com)http://xsscom.com//index.php?do=login获得它与后端的信息。
先将第一句复制到第一个框,send之后,
再把url复制下来,放到第二个框,send后,再回去查看获得的信息。
2.DVWA-low
看了一下源码好像没有什么限制,直接输入<script>alert(123456)</script>
看到了弹窗。
3.DVWA—Medium
先看一下源码,
看到有一个 $name = str_replace( '<script>', '', $_GET[ 'name' ] );
这个函数将字符“<script>”换为NULL,那么由于函数只执行一次,有多种方法可以绕过。比如将这个标签双写绕过,但是只能过滤一次,就达成了我们的目的。
这个我就熟悉了,在学文件上传时就了解过了不少绕过技巧,利用的原理都是一样的。
这次我们用双写绕过,如下:
<sc<script>ript>alert(123456)</script>
成功回显。
或者我们可以用大小写绕过
<Script>alert(123456)</script>
也是有回显的。
4.DVWA—High
先看看源码
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
明显采用了正则表达式来过滤了,那就根据我做文件上传的思路来看应该要换个标签。
所以我们去了解了一下果然是这样子做的,
那么我们就采用其中一种吧,如下:
<svg οnlοad="alert(1)">
成功回显。
5.Impossible
$name = htmlspecialchars( $_GET[ 'name' ] );
查查看htmlspecialchars是什么意思
htmlspecialchars:把预定义的字符 "<" (小于)和 ">" (大于)转换为 HTML 实体
按这样的话,我们不能构造出标签来对其进行攻击了。
无能为力,问问别人吧。
二.储存型XSS
持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,插入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie。
1.low
首先我们看到对name栏输入的数字进行了一个限制,因为name一栏的最长限制为10,所以如果我们想要在name处攻击,那么就需要更改前端。
然后我找了大半天才发现是在这里
修改完后,检查一遍没其他限制后直接输入
<script>alert(123456)</script>
又或者我们可以在message中直接输入<script>alert(1)</script>
ps.如果再进行第一种后有进行第二种会先弹出123456然后再弹出1。这是因为它已经保存在数据库中了,这时我们clear一下就好了。这也正是存储型xss的魅力所在。
2.Medium
我们看看源码先,再看看有什么函数是我们不认识的积累一下。
trim() 函数移除字符串两侧的空白字符或其他预定义字符。
addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
预定义字符是:
- 单引号(')
- 双引号(")
- 反斜杠(\)
- NULL
stripslashes() 函数删除由 addslashes() 函数添加的反斜杠
mysqli_real_escape_string() 函数转义在 SQL 语句中使用的字符串中的特殊字符
简单看一眼就能知道其对message过滤的严格程度比name要高很多,所以我们选择对name进行xss。因为对message进行了HTML实体转义,而对name只是替换<script>(这是比较粗糙的过滤)以及转义SQL语句中使用的特殊字符,可以使用别的html标签对$name参数的防护进行绕过。
看看能不能大写绕过
ps.此时name还是有字数限制,记得修改。
看到这个是可以的。
也可以采用一下两种标签。
<body οnlοad=alert('xss')>
<a href='' οnclick=alert('xss')>click</a>
3.High
可以看到相比较medium而言,high对$name参数通过正则匹配对<script>严格的过滤,没有对别的标签做过滤,但可以通过别的html标签来进行绕过。
以下仍然可用:
<body οnlοad=alert('xss')>
<a href='' οnclick=alert('xss')>click</a>
搞定了。
4. Impossible
都进行了html实体转义,那就没办法了。
三.DOM型XSS
不经过后端,DOM-XSS漏洞是基于文档对象模型(Document Objeet Model,DOM)的一种漏洞,DOM-XSS是通过url传入参数去控制触发的,其实也属于反射型XSS。 DOM的详解:DOM文档对象模型
1.low
直接在url上构造<script>alert(/hack/)</script>
直接有回显,没有限制。
2.medium
查看源码我们知道其对script标签进行了一个过滤
也就是这个stripos() 函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)。
那就没办法用大小写绕过了。
我们尝试用其他的标签来看一下。
结果还是不行,这时我们发现payload语句插入到了value标签属性内。而且底下还有一个select标签。
所以我们要闭合option标签和select标签。
?default=English</option></select><img src=1 οnerrοr=alert(/xss/)>
有回显了。
3.high
传入的参数如果不是French、English、German、Spanlish这四种字符串的话,就会直接跳到
?default=English
白名单只允许传的default值为French English German Spanish其中一个。
我们可以使用#定位符,#号后面的字符不会提交给PHP服务器。
看到#的用法我想中级是不是也可以用这种办法呢?不提交给服务器就不会进入value里面了。尝试一下果然可以。
4.Impossible
不需要做任何处理,在客户端处理,在url直接注入,发现没有弹窗。