点击劫持,也称UI覆盖攻击
黑客创建一个网页,用iframe包含了目标网站,并且把它隐藏起来。做一个伪装的页面或图片盖上去,且按钮与目标网站一致,诱导用户去点击。伪装的按钮背后可能就会执行了危险操作。
<!DOCTYPE html><html><meta http-equiv="Content-Type" content="text/html;charset=utf-8"><head> <title>点击劫持 POC</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>美女图片</button><img src="http://pic1.win4000.com/wallpaper/2018-03-19/5aaf2bf0122d2.jpg"><iframe src="http://i.youku.com/u/UMjA0NTg4Njcy" scrolling="no"></iframe></body></html>
防护方案:
使用一个HTTP头-X-Frame-Options。它可以设置frame的加载权限。它有三个可选的值:
nginx配置:
add_header X-Frame-Options SAMEORIGIN;
图片覆盖攻击,攻击者使用一张或多张图片,利用图片的style或者能够控制的CSS,将图片覆盖在网页上,形成点击劫持。
<a href="http://tieba.baidu.com/f?kw=%C3%C0%C5%AE"> <img src="XXXXXX" /></a>
你以为你点了图片,其实你点了其他的链接。
防护方案:
在防御图片覆盖攻击时,需要检查用户提交的HTML代码中,img标签的style属性是否可能导致浮出。
URL跳转漏洞(URL重定向漏洞),跳转漏洞一般用于钓鱼攻击
攻击原理:
URL跳转漏洞本质上是利用Web应用中带有重定向功能的业务,将用户从一个网站重定向到另一个网站。
示例:http://www.
aaa.com?returnUrl=http://www.evil.com,www.aaa.com 有一个功能会取到returnUrl后的路径,然后跳转。这种功能就会被黑客利用,跳转到他想跳转的其他页面上去。
一般容易出现的漏洞的点:
URL跳转漏洞校验绕过
//获取参数String url = request.getParameter("returnUrl");//判断是否包含域名if (url.indexOf("www.abc.com ") !=-1){ response.sendRedirect(url);}
黑客可以注册一个包含abc.com的域名来绕过,如:
http://www.abc.com?returnUrl=http://www.abc.com.evil.com
2. 利用URL的各种特性符号
http://www.aaa.com?returnUrl=http://www.evil.com?www.aaa.comhttp://www.aaa.com?returnUrl=http://www.evil.comwww.aaa.comhttp://www.aaa.com?returnUrl=http://www.aaa.com@www.evil.comhttp://www.aaa.com?returnUrl=http://www.evil.com#www.aaa.com
防护方案
通过窃取用户SessionId,使用SessionId登录进目标账户的攻击方法。如果SessionId是保存在Cookie中的,则这种攻击可以称为Cookie劫持。
攻击原理:
获取SessionId的方式有多种:
防御方法:
response.setHeader("SET-HEADER","user="+request.getParameter("cookie")+";HttpOnly;Secure");
会话固定是让用户使用黑客预先设置的sessionID进行登录,这样同样黑客能拿到用户SessionId。
攻击步骤:
攻击者如果让目标使用黑客的Session ID呢?如果是保存在Cookie中是比较难做的,但如果是SessionID保存在URL中,则攻击者只要诱导用户打开这个URL即可。
防御方法:
// 会话失效session.invalidate();// 会话重建session=request.getSession(true);
一般情况下,Session是有生命周期的,当用户长时间未活动,或者用户点击退出后,服务器将销毁Session。但如果攻击者拿到了一个用户的Session,它可以通过不停的发起访问请求,让Session一直存活。
<script> //要保持session的url var url ="http://bbs.yuanjing.com/wap/index.php?/sid=LOXSAJH4M"; //定时任务 window.setInterval("keeyId()",6000); function keepsid(){ document.getElementById("iframe1").src=url+"&time"+Math.random();}</script><iframe id="iframe1" src=""/></iframe>
攻击者设置可以为Session Cookie增加一个Expire事件,使得原本浏览器关闭就会失效的Cookie持久化地保存在本地。
防护方案:
注入攻击是Web安全领域中一种最常见的攻击方式。XSS本质上也是一种针对HTML的注入攻击。注入攻击的本质,是把用户输入的数据当做了代码执行。这里有两个关键条件,第一个是用户能控制输入,第二个是原本程序要执行的代码拼接了用户输入的数据。解决注入攻击的核心思想:数据与代码分离原则
本应该输入正常的数据,而黑客却输入一些sql语句。如果应用程序比较脆弱的话,则可能应用程序会被攻击。
最简单的示例就是一个:查询某个用户
String query = "select * from accounts where name ='"+request.getParameter("name")+"';
用户如果输张三李四是没问题的,如果输入 李四 or 1=1 那么它会查到所有用户数据。
容易导致SQL注入的弱点:
攻击步骤:
所谓盲注,就是在服务器没有返回错误信息的情况下完成的注入攻击。最常见的盲注验证方法是构造简单的条件语句,根据返回的页面是否变化来判断是否存在漏洞。
示例:下面是一个根据userId查询用户的功能:
1) 我先输入
1 ' and 1=1 #
发现能查询到数据
2)再输入
1 ' and 1=2 # 发现查不出数据,证明注入成功。
3)继续输入利用order by猜列数
1' order by 1 #
成功,然后输入 1' order by 2 # ,依次递增,直到提示
Unknown column '3' in 'order clause'
成功得到该表的列数。
4)知道列数之后,使用union select 联合查询获取更多的信息,union 查询的使用前提是关联查询的两个查询列数要一致
1 ' union select database(),user() #
查询到数据库名和当前查询的用户名
5)继续查询当前数据库版本、操作系统
1 ' union select version(),@@version_compile_os#
6)根据数据库名,查询里面的表
1 ' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa' #
7)猜users表的字段,根据经验试试是不是user和password
1' union select user,password from users#
成功爆出了某网站的用户名和密码
1) Mybatis:${}:单纯替代,纯粹的将参数传进去,没有做任何的转义操作和预编译。
#{}: Mybatis会通过预编译机制生成PreparedStatement参数,然后再安全的给参数赋值
${}是存在注入风险的。
2) Hibernate
usernameString//前台输入的用户名passwordString//前台输入的密码//hql语句String queryString = "from User t where t.username= " +usernameString + " and t.password="+ passwordString;//执行查询List result = session.createQuery(queryString).list();
通过hql拼接的方式不安全。建议用参数绑定:
usernameString//前台输入的用户名passwordString//前台输入的密码//hql语句String queryString = "from User t where t.username:usernameString and t.password: passwordString";//执行查询List result = session.createQuery(queryString) .setString("usernameString ",usernameString ) .setString("passwordString",passwordString) .list();
3)JDBC:使用预处理执行SQL语句,对所有传入SQL语句中的变量做绑定,这样用户拼接进来的变量无论内容是什么,都会被当做替代符号"?"所替代的值。
示例:
String sql = "select * from users where userid = " + userid;
如果用户输入userid是"1;delete users;"会被编译成2条sql,那么users表会被非法删除。
但是如果是预编译的方式,那么会编译成一条sql,查询userid为'"1;delete users;"的用户,查询结果会是不存在,不会存在危险。
XML注入是将用户录入的信息作为XML节点。
示例:
//userData是准备保存的XML数据,接受了name和email两个用户提交的数据String userData = "<USER >"+ "<name>"+ request.getParameter("name")+ "</name>"+ "<email>"+ request.getParameter("email")+ "</email>" "</USER>"//保存XML数据userDao.save(userData);
如果用户输入的时候name输入张三,email输入:
user1@lagou.com</email></USER><USER><name>user2</name><email>user2@lagou.com
这样就恶意构造了一个xml,拼接起来一次保存了两条数据。
防护方案:
对xml数据进行转义:
String userData = "<USER>"+ "<name>"+StringUtil.xmlEncode(request.getParameter("name"))+"</name>"+ "<email>"+StringUtil.xmlEncode(request.getParameter("email"))+"</email>"+ "</USER>";
web应用程序中如果有允许接收用户输入一段代码并执行。那么用户可以根据这个功能写一个远程控制木马,进行恶意攻击。代码注入往往是由一些不安全的函数或者方法引起的,其中的典型代表就是eval()
public static void main(String[] args) { //在Java中也可以实施代码注入,比如利用Java的脚本引擎。 ScriptEngineManager manager = newScriptEngineManager(); //获得JS引擎对象 ScriptEngine engine =manager.getEngineByName("JavaScript"); try { //用户录入 String param = "hello"; String command = "print('"+param+"')"; //调用JS中的eval方法 engine.eval(command); } catch (ScriptException e) { e.printStackTrace(); } }
攻击示例:
hello'); var fImport = new JavaImporter(java.io.File);with(fImport) { var f = new File('new'); f.createNewFile(); }
防护方案:
对抗代码注入,需要禁止eval()等可以执行命令的函数,如果一定要用,则需要对用户输入的数据进行处理。如只能由开发人员定义代码内容,用户只能提交对应的id”1、2、3“等参数。
OS命令注入(操作系统命令注入),仅当Web应用程序代码包括操作系统调用,并且使用了用户的输入内容。
示例:
应用程序开发人员希望用户能够在Web应用程序中查看Ping命令的输出。用户正常输入ip,那还好。
如果输入:
127.0.0.1 && whoami
或者
127.0.0.1 && ps -ef
就能够执行一些危险的操作。
防护方案:
最有效的方法就是不要再应用程序代码中调用OS命令。如果非要这么搞,那么还是一样需要对用户输入进行严格的验证。
互联网当中,我们经常用到文件上传功能,传excel、传图片、传视频等等。文件上传后,服务器的处理逻辑如果做的不够安全,就会导致漏洞的产生。
文件上传后导致的常见安全问题一般有:
防护方案:
文件下载和目录浏览漏洞是属于程序设计和编码上的不严谨导致的。处理用户请求下载文件时,用户提交文件路径,就把服务器上对应的文件发送给用户,这就造成了任意文件下载危险。如果用户提交目录,就把目录下的文件列表发给用户,会造成目录遍历安全威胁。良好的设计应该是:不允许用户提交任意文件路径进行下载,而是用户单机下载按钮默认传递ID到后台程序。
防护方案:
功能权限漏洞是指Web应用没有做权限控制,或仅仅在菜单上做了权限控制,导致恶意用户只要猜到了其他页面的URL地址,就可以访问到他权限外的页面和数据。
防护方案:
针对任何URL,每次用户访问,都要判断用户是否有访问此URL的权限。
这种问题出现在未对用户与数据级别之间建立关系,如用户A和用户B都有查询订单的权限,但是A只能查询A的订单,B只能查B的订单。如果只校验用户是否有某个功能的权限,不校验时候有这个数据的权限,就会出现越权问题。
防护方案:
根据用户的ID做好数据级权限控制,比如针对CRUD操作进行身份验证,且对用户访问的数据进行数据权限校验,防止通过修改ID的方式查看别人的数据。
DDOS(Distributed Denial of Service)又称为分布式拒绝服务,DDOS是利用合理的请求造成资源过载,导致服务不可用。常见的DDOS攻击有SYN flood、UDP flood、ICMP flood等。其中SYN flood是一种最为经典的DDOS攻击,其发现于1996年,至今仍然保持着非常强大的生命力。SYN flood如此猖獗是因为它利用了TCP协议设计中的缺陷,而TCP/IP是整个互联网的基础,想要修复这样的缺陷机不是不可能的事情。
SYN flood攻击原理:
SYN flood攻击是根据TCP协议的三次握手过程进行的攻击。在TCP服务器收到SYN请求包时,在发送ACK包回去之前,TCP服务器需要先分配一个数据区专门服务于这个快形成的TCP连接。
在常见的SYN flood攻击中,攻击者短时间内发送大量的SYN包给受害者服务器,服务器需要为每个TCP SYN包分配一个数据区,只要这些SYN包具有不同的源地址。这将给受害者服务器造成很大的系统负担,最终导致系统不能正常工作。
SYN flood防护方案:
syn cookie:
syn cookie是通过修改TCP三次握手协议,来专门防御DDOS的一种手段。服务器收到客户端的SYN包,并且返回一个ACK+SYN包时,不专门分配一个数据区,而是根据这个包计算出一个cookie值。然后再收到ACK包时,服务器根据这个cookie值检查这个ACK包是否合法。如果合法,再分配专门的数据区进行处理未来的TCP连接。
CC攻击是DDOS攻击的一种,可以看作是应用层面的DDOS攻击。攻击原理是:针对一些耗费资源较大的应用页面不断发起请求,以达到消耗服务器资源的目的。
防护方案:
IP黑白名单的开发
可以使用OpenResty+Lua脚本实现。也可以使用KONG