Halo

A magic place for coding

0%

浅淡DDos攻击

Introduction

  今天我们来谈谈一种非常经典的网络攻击——DDos(Distributed Denial-of-service)。这种攻击是一种很常见的攻击,它可以发生在网络模型的每一层,在这篇博客我将和大家分享一下DDos攻击的基本原理,以及我们目前有什么手段能够防御。

What is DDos?

  DDos Attack,分布式拒绝服攻击,意思是攻击者通过一定的手段或技术,对指定的服务器发起攻击,使得在某段时间内该服务无法响应正常的请求。一般通过这种攻击,攻击者可以向被攻击方索取赎金等获得利益。

  Dos攻击(注意这里是Dos,而不是DDos)的原理有两种:

  1. Dos Bug: 通过处罚系统的逻辑漏洞,使得服务器崩溃。例如某个网页的某个操作实现逻辑有问题,每次都会造成数据库崩溃,那么攻击者只需要触发这个操作1次,就能达到Dos的效果。;
  2. Dos Flood:通过控制一个botnet生成大量的请求。

  这篇博客我将focus在第二种,因为第一种更多的是程序逻辑的问题,而第二种才是和网络息息相关的攻击。

  DDos最大的特点是通过发送小size的网络包,造成服务器崩溃,这就是放大效果(Amplification)。举个例子,DNS放大攻击是一个非常典型的DDos,攻击者向DNS服务器发起请求(约60bytes),但是伪造了source ip。DNS服务器收到请求后,返回了EDNS(约3000bytes)给source ip,因此source ip上的机器实际上就被攻击了。从网络包的大小看,攻击者仅仅使用了60bytes就换取了3000bytes,这是一个很明显的放大。

Different Types of DDos

TCP SYN Flood I

Problem

  我们知道在TCP三次握手的第一次握手,客户端向服务端发起SYN请求,服务端收到后就需要ACK,最关键的是服务器在这里会存下来客户端网络包的Sequence Number(SNc)和自己返回包的Sequence Number(SNs)。这里的存储就是问题所在,因为任意一个客户端都可以发起这个SYN请求(攻击者不需要再ACK一次,即不需要完成TCP握手过程),而对于任意一个请求,服务器都要消耗一定的存储资源,如果对方来势汹汹,是用一个botnet进行攻击,那么服务器就会在短时间内耗光存储,无法继续服务后面的请求。

Solution

  对于这类攻击,关键在于服务器不能不加限制地使用存储资源,服务器应该只给合法用户的连接分配资源,因此有人提出了sync cookie。它的作用在于,在第一次握手时,服务器并不需要马上分配内存资源,而是把需要存储的内容放到cookie中(在网络包中携带),等到用户真的完成了TCP三次握手,才真正分配资源去存储。

  大致细节为:

  1. 服务器在返回SYN-ACK时,Sequence Number(SNs) = (T + mss + L),其中T是5位随机数(通过时间计数器生成),L = MAC(SAddr, SPort, DAddr, DPort, SNc, T)。
  2. 客户端如果确认连接,会发送ACK给服务端,此时AN = SNs + 1,SN = SNc + 1;
  3. 服务端拿到AN和SN后,首先用AN - 1得到SNs(sync cookie),然后根据当前时间对比T来判断是否过期,然后重新计算L来确认cookie是否有效

  因此这种方式能够保证服务器只分配资源给真正有需要完成TCP连接的用户,一定程度上防止了上述的攻击。

TCP Connection Flood

Problem

  上面提到的sync cookie确实能够防止只发起SYN请求的攻击,但是如果攻击者把TCP三次握手都完成了呢?好像就没有办法区分了。

  的确,这个就是现状。很多时候我们无法分清大量的TCP连接,到底是来自于恶意攻击,还是用户的真实行为。试想一下,当双十一开抢的时候,TCP的连接数绝对爆炸增长,但这并不是一种恶意攻击,所以不能够滥杀。因此我们到底有没有一种方案能够在安全和便利中取得平衡呢?

Solution

  从特点看,如果攻击者建立了大量的TCP连接,那么它必须使用固定的IP地址,因为在协议中已经拿到,我们可以根据这些IP去反查到位置。如果我们部署了proxy或者网关,就可以针对这些IP进行block或者rate limit。

Route Hijacking

  Route Hijacking是一种非常有意思的Dos,它并不是通过产生大量的请求去实现的,而是通过修改某个AS的路由,所有有关的请求从一个AS路由到另一个AS,这样位于原来AS的服务就无法收到正常的请求,对于用户来说就是无法服务了。

  这种劫持一般都是网络运营商配置错误导致的,所以,还是要守规矩。

SSL/TLS handsahke

  回顾第一种攻击,是通过消耗服务器的存储资源达到Dos的效果,那么我们能否通过消耗服务器的计算资源达到相同的效果呢?答案是可以的,在SSL/TLS中,当客户端发起请求后,服务端会通过证书的形式把公钥发送给客户端,然后客户端用公钥把自己随机生成的key加密发送给服务端,此时服务端就需要解密去获得这个key。

  问题的关键就在于key的加密是非对称加密,如果使用RSA算法,客户端用公钥加密非常快,但是服务端用私钥解密非常慢,此时攻击者就可以利用这个特点,大量发起HTTPS请求,导致服务端的计算资源都耗费在RSA的解密上,无法响应正常的请求。

How to deal with DDos

  上面看了几个Dos的例子,虽然对于每一个例子都有一些特定的解决方法,但是有没有一些针对Dos更加普遍的应对措施呢?

Client Puzzles

  防范Dos的核心在于防范放大效应,即不允许客户端以较低的代价去耗费服务端大量的资源。意思是如果客户端想要与服务端建立连接,那么它也需要付出一定的代价。

  这就是Client Puzzles的思想,当客户端想要建立连接时,服务端返回一个puzzle给客户端,需要客户端把这个puzzle解出来才能继续往后走。这个puzzle是:$LSB_n(SHA-1(C || X)) == 0^n$,客户端需要找到这个$X$。这个puzzle的特点是不容易计算但是很容易验证,而且难度随着n的增大而增加。所以服务端可以根据当前的请求量灵活调整n,当当前的请求量正常时,就不需要puzzle,当当前的请求量异常(可能是Dos攻击)时,则发放puzzle,需要客户端耗费一定的计算时间才能继续往下走。

  虽然这个方法很巧妙地解决了双方资源消耗不对等的问题,但是它并不是一个好的解决方案,因为它需要客户端和服务器都具备client puzzle的功能,同时,这种方法会伤害到一些合法的用户。例如在请求量异常时,合法用户请求也会需要client puzzle,对于性能较差的移动设备,可能实际效果和Dos没什么区别。

CAPTCHA

  CAPTCHA(Completely Automated Public Turing test to tell Computers and Humans Apart),这个名字太长了,简单来说就是验证码。这个手段是目前最常用的手段,它的核心就是区分出人和机器的操作。因为人的操作频率是有限的,一般来说攻击都是机器完成,所以只要区分出人和机器,就能很大程度上区分出攻击。

Source Identification

  这是一种更加精细化的思路,既然网络中网络包是路由过来的,那么能不能把源头控制住,把问题扼杀在摇篮中。

  那这个摇篮就是ISP了,如果ISP能够把一些攻击的IP识别出来做成一个列表,然后source ip属于这个列表就把网络包丢掉,这样攻击的packet就不要流入到网络中了。

  但是理想很丰满,现实很骨感,这个策略需要所有的ISP都实现才有用。根据统计只要10%的ISP没有实现就等于没有防护(甚至有案例是只通过3个ISP就实现了攻击),但是大家都不积极,大家都在等别人先做。

Traceback

  靠ISP之间去完成估计是等不及了,只能还是从服务端入手。我们能不能通过在网络包中带上路由的信息,去找到攻击包的完整路径,这样就容易识别出来了。这个思路基于几个assumption:

  1. 大多数的router还是安全的,没有被入侵;
  2. 攻击者会向被攻击者发送大量packet;
  3. 从攻击者到被攻击者的packet的路径是相对稳定的

  这种方法也非常直观,每个路由都把自己的地址写入到路径中,到服务器的时候就能得到一条完整的path。但是这里也有很大的问题,比如说网络包中还要找一个地方去存放这类信息,如果路径很长的话,还会占很大的空间。

Edge Sampling

  针对上面Traceback路径过长的问题,有人提出了采样的思路,我们不需要把整条路经精准地记录下来,既然有大量的攻击packet,采样一些得到的数据也会相对准确,所以存储的信息就是startenddistance

  每到一个router时,有两种操作,每种操作各50%机率:

  1. 把自己的地址写入start;把0写入到distance;
  2. 如果distance为0,则把自己的地址写入到end;distance增加1

  这样服务器就能通过这三个字段去重构网络图,每个包提供的三元组都是一条路径。

Summary

  总的来说,DDos是一种很经典但是又很多变的网络攻击,它可以发生在任意一层。网络在设计之初就没有对这类型的攻击有很好的防护,因此就需要后面添加各种手段去防范,而且这个防范也不是100%的。希望通过这篇博客,大家能够简单了解Dos的一些知识,并且在设计、开发系统时,对这类问题有一个简单的防范。

Welcome to my other publishing channels