前段时间爆发的利用永恒之蓝进行勒索及xshell等事件,各大厂家都站在不同的角度分析了相应的事件及程序,对于对逆向不了解看着的确很吃力。上段时间看到宫总及袁哥都在讲DNS对于分析这种攻击的可行性。

\r\n

\"点击查看原图\"

\r\n

\"点击查看原图\"

\r\n

永恒之蓝和xshell事件有如下的特征:

\r\n

1.  永恒之蓝中黑客预留了一个没有注册的域名,用于防护事件不受控制时,启用该域名可以抑制事件的扩大。

\r\n

2.  Xshell事件中黑客通过DNStxt字段进行传输数据与指令

\r\n

两起事件都有一个共同特征就是利用DNS来进行事件的抑制与数据与指令的下发,这样的话,针对这种类型的黑客攻击与安全事件,我们可以站在底层网络来分析这事件。

\r\n

利用永恒之蓝进行勒索事件中黑客预留的域名是DGA域名,在某些条件下探测该DGA域名是否可以正常解析,若解析成功则不进行加密,若解析成功则不加密。

\r\n

DGA一般都是通过硬编码写入到程序中,在没有能力对其逆向的情况下,我们可以分析网络流量来分析DNS请求的DGA域名。这样就需要了解哪些域名是DGA域名,这里面有多种方法与思路:

\r\n

1.  利用开放平台里的DGA库,目前个人所了解的国内360在开放相应的数据,这个也是个人首推的选择

\r\n

2.  DGA域名有个特征,很多DGA并没有注册,黑客前期会生成大量的DGA域名,但是在某些情况下,如传输数据与命令或抑制事件时,会选择性的注册少量域名,这样的话可以对DNS解析不成功的域名进行记录,并将这些域名进行进行,若其没有注册,且域名很随机可以判断为疑似DGA域名。这里面有大牛介绍过http://www.freebuf.com/geek/144459.html

\r\n

3.  深度学习检测DGA域名,可参考http://www.freebuf.com/articles/network/139697.html

\r\n

\r\n

由于上面的方法二和方法三都有人实现了,这里面我主要介绍方法一的实现。这个思路是这样:通过监测网络流量(有条件的同学可以在大网环境下测试下),分析DNS的请求,一旦请求的DNSDGA库中的匹配,输出相应的IP、端口,当然后期也可以做相应的统计与告警。

\r\n

DGA库网上找了有一些,个人了解的国内推荐360的开放DGA的数据,100W+DGA数据,并且每天都有更新。有需要的同学可直接下载,http://data.netlab.360.com/feeds/dga/dga.txt

\r\n

 \"点击查看原图\"

\r\n

DNS检测DGA实现的代码如下:

\r\n

\r\n
#coding:utf-8\r\n\r\nimport time\r\nfrom scapy.all import *\r\nfrom requests import *\r\n\r\nconf.iface=\'Intel(R) Dual Band Wireless-AC 8260\'\r\n\r\nlist=[]\r\ndgalist = open(\'dga.txt\',\'r\')\r\ndgalist = (dgalist.readlines())[18:]\r\nfor dga in dgalist :\r\n	list.append(dga.split(\'\\t\')[1])\r\ndata = set(list)\r\n\r\nf = open(\"./aa.txt\",\'w+\')\r\n\r\n#Capture and Filter DGA\r\ndef capture(packet):\r\n	if packet:\r\n		i =0\r\n		for p in packet:\r\n			src = p[i][IP].src\r\n			dst = p[i][IP].dst\r\n			sport = p[i][UDP].sport\r\n			dport = p[i][UDP].dport\r\n			qr = str(p[i][DNS].qr)\r\n			rcode = str(p[i][DNS].rcode)\r\n\r\n			if \'0\' in qr:\r\n				try:\r\n					qr = \'Query\'\r\n					qname = p[i][DNS].qd.qname\r\n					if type(qname) == bytes:\r\n						qname = (qname.decode(\'utf-8\'))[:-1]\r\n					if qname in data:\r\n						print(\"[*] Found DGA Request:-->\",src,sport,qr,qname)\r\n						print(src,sport,qr,qname,file=f)\r\n				except Exception as e:\r\n					pass\r\n\r\n\r\n			if \'1\' in qr:\r\n				if \'0\' in rcode:\r\n					for j in range(10):\r\n						try:\r\n							qr = \'Response\'\r\n							rrname = p[j][DNS].an[j].rrname\r\n							rdata = p[j][DNS].an[j].rdata\r\n							if type(rrname) == bytes:\r\n								rrname = (rrname.decode(\'utf-8\'))[:-1]\r\n								if type(rdata) == bytes:\r\n									rdata = (rdata.decode(\'utf-8\'))[:-1]\r\n							if rrname in data:\r\n								print (\"[*] Found DGA Response:-->\",src,dst,qr,rrname,rdata,\'\\n\')\r\n								print (src,dst,qr,rrname,rdata,file=f)\r\n						except Exception as e:\r\n							pass\r\n\r\n		i = i + 1\r\n		\r\n#update dgafile\r\ndef dgafileupdate():\r\n	url = \'http://data.netlab.360.com/feeds/dga/dga.txt\'\r\n	dgafile = get(url)\r\n	with open(\'./dga.txt\',\'w\') as f:\r\n		f.write(dgafile.text)\r\n		print(\'Download DGAFile Finished\')\r\n\r\nif __name__ == \'__main__\':\r\n	sniff(prn=capture,filter=\'udp port 53\')\r\n	while True:\r\n		dgafileupdate()\r\n		time.sleep(86400)

\r\n

\r\n

\"点击查看原图\"

\r\n

    在代码实现过程中,本个DGA正常解析成功的IP地址也记录了下来,DGA都有问题,那么解析的IP基本上也不正常。在大网环境下可以记录下相应的IP地址,在做Passive DNS时可以利用这些数据完善相应的库。

\r\n

    考虑到DGA的文件每天都会更新,可以进行定时下载该文件。

\r\n

\"点击查看原图\"

\r\n

测试后,效果如下:

\r\n

\"点击查看原图\"
\r\n