安全涉及的领域很广泛,有 web 安全、DDoS 攻防、用户隐私、加密解密、数据安全、授权和认证等等,很多。

可以逐一学习。

今天我们主要讲一下 web 安全 顺带了解一下 DDoS 防范。(因为这个比较好找资料,准备的有些仓促。

web 安全

XSS(Cross Site Scripting) 攻击

通过对网页注入可执行代码且成功地被浏览器执行,达到攻击的目的。

成功的条件

  1. 需要向web页面注入恶意代码
  2. 恶意代码被浏览器执行

分类

依据攻击效果可以分为两类,

  • 反射性攻击

恶意代码并没有保存在目标网站,通过引诱用户点击一个链接到目标网站的恶意链接来实施攻击的。

比如:

xssreflect

  • 存储型攻击

恶意代码被保存到目标网站的服务器中,这种攻击具有较强的稳定性和持久性。

例如 bbs 发帖,中插入了脚本,查看这个帖子就可能执行恶意脚本。

1
2
3
4
5
6
7
<div>
<img src="https://www.baidu.com/img/bd_logo1.png?where=super&id="/>
</div>
<div>
<!-- id= imageid"/><script>alert(/xss/)</script><br x=" -->
<img src="https://www.baidu.com/img/bd_logo1.png?where=super&id=" /><script>alert(/xsst2/)</script><br x="" />
</div>

XSS 防范方法

  1. 针对反射性攻击,可以在表单提交或者 url 传递参数之前,对参数进行过滤。

  2. 针对存储型攻击,控制用户输入的输出,可以采用白名单的方法使用合法的标签显示,过滤掉非法的字符。

CSRF (Cross—Site Request Forgery)

既跨站点请求伪造,也被叫做 XSRF,和 XSS 一样也是一种比较常见的 web 攻击。CSRF攻击者会过过构造的第三方页面诱导受害者完成加载或者点击,利用受害者的权限,以其身份向合法网站发起恶意请求,通常用户发生状态改变的请求,比如虚拟货币的转账,账号信息修改,恶意发邮件等等,由于具有一定的隐蔽性,所以比较难以防范。

原理

csrf

例如,转账的请求为:

1
get http://xxxbank.com/transfer.do?from=rommel&to=alice&amount=100 HTTP/1.1

CSRF 的攻击过程过程图上图所示:

  1. CSRF 攻击有一个前提条件,是用户具有某个正常访问的访问权限。一般网站的访问权限都具备一定的有效期,比如1天过期,或者几个小时过期,在此期间权限信息会保留在用户浏览器的 cookie 中,例子中假设用户C刚刚登录了网站A,权限还没有过期。
  2. 攻击者利用正常网站 A 的 CSFR 漏洞,构造页面一个恶意网页 B,在页面中包含对发往正常网站 A 的请求,在用户 C 加载页面 B(或者点击某些元素时触发)时,会触发攻击请求,目的是为了实现虚拟币的转账,请求可能隐藏得很深,用户并不一定能发现,伪造的请求如下:
1
2
3

<img widht=0 height=0 src="http://xxxbank.com/transfer.do?from=rommel&to=attacker&amount=100" />

CSRF 防范方法

  1. 添加 Referer 域名白名单:HTTP 的 Referer 头记录了当前请求的来源页面的URL,如果用户是通过浏览器打开的网页一般都会带有这个信息。可以验证 URL 的域名是否在网站允许的白名单内,如果不在则拒绝请求。这种方式实现比较简单,而且可以在 web 服务器层统一配置,减少了后端开发成本,但是 Referer 域可以伪造,用户浏览器的可靠性也不能完全信赖,判断 Referer 可以做为一种辅助手段,但不能根治 CSRF。
  2. 令牌 (Token) 验证:令牌验证的方式,这是目前方法CSRF的一种普遍方法,其原理是在用户正式提交数据更新之前,给用户生成一个 token,一方面 token 保存在服务端,比如 Session 或者缓存中,一方面用户提交请求时连同 token 一同提交,服务获得接收到请求之后再做 token 验证,token 不存在、或者token不一致,或者失效都算作验证失败。token 的生成具有一定的随机性,攻击者往往很难伪造。token 一般作为一个 post 字段提交,或者作为 ajax 请求的 header 信息提交。
  3. 二次验证:对于一些敏感操作,比如对涉及到交易操作的控制更加严格一些。在用户提交时可以让用户输入验证码,或者再次输入交易密码,确保是用户的真实操作,而不是机器触发的。
  4. SameSite Cookie 属性 Http cookie

SQL 注入

利用后端程序的漏洞,针对数据库进行攻击。

1
2

SELECT * FROM users WHERE username = "$username" AND password = "$password";

如果攻击者设定了一个 password = anywords” OR 1=1 的密码,那么执行的 sql 就变成了

1
2
3

SELECT * FROM users WHERE username = "xxx" AND password = "anywords" OR 1=1

如果 构造密码为 password anywords” OR 1=1;DROP TABLE users ,那么 users 表都会被删除。

'上古'时代,网络上流传的搞笑图片

sql 注入防范

  • 预编译sql

预编译 sql 的原理:

  1. 基本解析:包括SQL语句的语法、语义解析,以及对应的表和列是否存在等等。
  2. 编译:将 SQL 语句编译成机器理解客理解的中间代码格式。
  3. 查询优化:编译器在所有的执行方案中选择一个最优的。
  4. 缓存:缓存优化后的执行方案。
  5. 执行阶段:执行最终查询方案并返回给用户数据。

预编译语句指的是在缓存之后,在执行阶段的之前的编译后的语句,通过占位符来替代查询查询参数。同样的SQL,如果参数不同普通的SQL语句每次请求都会进行编译,而预编译语句只会编译一次,在执行阶段会从缓存中取出预编译语句并将占位符替换成查询参数数据,而在这个阶段SQL 语句已经是编译后的语句,参数数据只能最为纯数据使用,不能作为SQL语句的一部分,通过SQL字符串的拼装已经不起作用,所以可以避免SQL注入。

1
2
3
4
5
6

String query = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = connection.prepareStatement( query );
pstmt.setString( 1, username);
pstmt.setString( 2, password);
ResultSet results = pstmt.executeQuery( );
  • 交给 ORM 框架

hash DoS (Denial of Service)

我们都知道,哈希表 是一个 O(1) 的数据结构,对于其中的任意元素=可以在一个与哈希表长度无关的时间内计算出一个哈希值(key),然后在常量时间内定位到一个bucket,找到改元素。

这是理想的情况,但是存在不同的数据项,具有相同的 hash 值,这是就会发生 hash 碰撞。

哈希表的实现需要解决碰撞问题,碰撞解决大体有两种思路,第一种是根据某种原则将被碰撞数据定为到其它桶,例如线性探测——如果数据在插入时发生了碰撞,则顺序查找这个桶后面的桶,将其放入第一个没有被使用的桶;第二种策略是每个桶不是一个只能容纳单个数据项的位置,而是一个可容纳多个数据的数据结构(例如链表或红黑树),所有碰撞的数据以某种数据结构的形式组织起来。

不论使用了哪种碰撞解决策略,都导致插入和查找操作的时间复杂度不再是 O(1)。以查找为例,不能通过key定位到桶就结束,必须还要比较原始key(即未做哈希之前的key)是否相等,如果不相等,则要使用与插入相同的算法继续查找,直到找到匹配的值或确认数据不在哈希表中。

哈希表碰撞攻击就是通过精心构造数据,使得所有数据全部碰撞,人为将哈希表变成一个退化的单链表,此时哈希表各种操作的时间均提升了一个数量级,因此会消耗大量CPU资源,导致系统无法快速响应请求,从而达到拒绝服务攻击(DoS)的目的。

web 应用 大多会使用json作为数据传递的方式,在服务端拿到 json 字符串后,都会将 json 字符串转换成 json 对象,json 对象大多都是基于 hashmap 或者 hashtable 做的,因此只要能够导致 hash 碰撞,然后结合一个较大的 json 对象,就能将 hashmap 的性能降低到极致,拖垮cpu,从而达到 DoS 的目的。

DDoS

DDoS的概念和发展

拒绝服务

其实可以简单理解为:让一个公开网站无法访问。要达到这个目的的方法也很简单:不断地提出服务请求,让合法用户的请求无法及时处理。

分布式

其实随着网络发展,很多大型企业具备较强的服务提供能力,所以应付单个请求的攻击已经不是问题。道高一尺,魔高一丈,于是乎攻击者就组织很多同伙,同时提出服务请求,直到服务无法访问,这就叫“分布式”。但是在现实中,一般的攻击者无法组织各地伙伴协同“作战”,所以会使用“僵尸网络”来控制N多计算机进行攻击。

僵尸网络 肉鸡

就是数量庞大的僵尸程序(Bot)通过一定方式组合,出于恶意目的,采用一对多的方式进行控制的大型网络,也可以说是一种复合性攻击方式。因为僵尸主机的数量很大而且分布广泛,所以危害程度和防御难度都很大。

僵尸网络具备高可控性,控制者可以在发布指令之后,就断开与僵尸网络的连接,而控制指令会自动在僵尸程序间传播执行。

这就像个生态系统一样,对于安全研究人员来说,通过捕获一个节点可以发现此僵尸网络的许多僵尸主机,但很难窥其全貌,而且即便封杀一些僵尸主机,也不会影响整个僵尸网络的生存。

DDoS的攻击方式

分布式拒绝服务攻击的精髓是:利用分布式的客户端,向目标发起大量看上去合法的请求,消耗或者占用大量资源,从而达到拒绝服务的目的。

其主要攻击方法有4种:

  • 攻击带宽

当网络数据包的数量达到或者超过上限的时候,会出现网络拥堵、响应缓慢的情况。DDoS就是利用这个原理,发送大量网络数据包,占满被攻击目标的全部带宽,从而造成正常请求失效,达到拒绝服务的目的。

攻击者可以使用ICM泛洪(即发送大量ICMP相关报文)、或者UDP泛洪(即发送用户数据报协议的大包或小包),使用伪造源IP地址方式进行隐匿,并对网络造成拥堵和服务器响应速度变慢等影响。

但是这种直接方式通常依靠受控主机本身的网络性能,所以效果不是很好,还容易被查到攻击源头。于是反射攻击就出现,攻击者使用特殊的数据包,也就是IP地址指向作为反射器的服务器,源IP地址被伪造成攻击目标的IP,反射器接收到数据包的时候就被骗了,会将响应数据发送给被攻击目标,然后就会耗尽目标网络的带宽资源。

  • 攻击系统

创建TCP连接需要客户端与服务器进行三次交互,也就是常说的“三次握手”。这个信息通常被保存在连接表结构中,但是表的大小有限,所以当超过了存储量,服务器就无法创建新的TCP连接了。

攻击者就是利用这一点,用受控主机建立大量恶意的TCP连接,占满被攻击目标的连接表,使其无法接受新的TCP连接请求。如果攻击者发送了大量的TCP SYN报文,使服务器在短时间内产生大量的半开连接,连接表也会被很快占满,导致无法建立新的TCP连接,这个方式是SYN洪水攻击,很多攻击者都比较常用。

  • 攻击应用

由于DNS和Web服务的广泛性和重要性,这两种服务就成为了消耗应用资源的分布式拒绝服务攻击的主要目标。

比如向DNS服务器发送大量查询请求,从而达到拒绝服务的效果,如果每一个DNS解析请求所查询的域名都是不同的,那么就有效避开服务器缓存的解析记录,达到更好的资源消耗效果。当DNS服务的可用性受到威胁,互联网上大量的设备都会受到影响而无法正常使用。

近些年,Web技术发展非常迅速,如果攻击者利用大量的受控主机不断地向Web服务器恶意发送大量HTTP请求,要求Web服务器处理,就会完全占用服务器资源,让正常用户的Web访问请求得不到处理,导致拒绝服务。一旦Web服务受到这种攻击,就会对其承载的业务造成致命的影响。

  • 混合攻击

在实际的生活中,乖哦概念记者并不关心自己使用的哪种攻击方法管用,只要能够达到目的,一般就会发动其所有的攻击手段,尽其所能的展开攻势。对于被攻击目标来说,需要面对不同的协议、不同资源的分布式拒绝服务攻击,分析、响应和处理的成本就会大大增加。

随着僵尸网络向着小型化的趋势发展,为降低攻击成本,有效隐藏攻击源,躲避安全设备,同时保证攻击效果,针对应用层的小流量慢速攻击已经逐步发展壮大起来。因此,从另一个角度来说,DDoS攻击方面目前主要是两个方面:UDP及反射式大流量高速攻击、和多协议小流量及慢速攻击。

DDoS防范

  1. 高性能设备
  2. 提高带宽
  3. 异常流量清洗
  4. 分布式防御