當前位置:
首頁 > 新聞 > 利用Python實現DGA域名檢測

利用Python實現DGA域名檢測


前段時間爆發的利用永恆之藍進行勒索及xshell等事件,各大廠家都站在不同的角度分析了相應的事件及程序,對於對逆向不了解看著的確很吃力。上段時間看到宮總及袁哥都在講DNS對於分析這種攻擊的可行性。



永恆之藍和xshell事件有如下的特徵:



1. 永恆之藍中黑客預留了一個沒有註冊的域名,用於防護事件不受控制時,啟用該域名可以抑制事件的擴大


2. Xshell事件中黑客通過DNS的txt欄位進行傳輸數據與指令


兩起事件都有一個共同特徵就是利用DNS來進行事件的抑制與數據與指令的下發,這樣的話,針對這種類型的黑客攻擊與安全事件,我們可以站在底層網路來分析這事件。


利用永恆之藍進行勒索事件中黑客預留的域名是DGA域名,在某些條件下探測該DGA域名是否可以正常解析,若解析成功則不進行加密,若解析成功則不加密。


DGA一般都是通過硬編碼寫入到程序中,在沒有能力對其逆向的情況下,我們可以分析網路流量來分析DNS請求的DGA域名。這樣就需要了解哪些域名是DGA域名,這裡面有多種方法與思路:



1. 利用開放平台里的DGA庫,目前個人所了解的國內360在開放相應的數據,這個也是個人首推的選擇

2. DGA域名有個特徵,很多DGA並沒有註冊,黑客前期會生成大量的DGA域名,但是在某些情況下,如傳輸數據與命令或抑制事件時,會選擇性的註冊少量域名,這樣的話可以對DNS解析不成功的域名進行記錄,並將這些域名進行進行,若其沒有註冊,且域名很隨機可以判斷為疑似DGA域名。這裡面有大牛介紹過 http://www.freebuf.com/geek/144459.html


3. 深度學習檢測DGA域名,可參考http://www.freebuf.com/articles/network/139697.html


由於上面的方法二和方法三都有人實現了,這裡面我主要介紹方法一的實現。這個思路是這樣:通過監測網路流量(有條件的同學可以在大網環境下測試下),分析DNS的請求,一旦請求的DNS和DGA庫中的匹配,輸出相應的IP、埠,當然後期也可以做相應的統計與告警。


DGA庫網上找了有一些,個人了解的國內推薦360的開放DGA的數據,100W+的DGA數據,並且每天都有更新。有需要的同學可直接下載,http://data.netlab.360.com/feeds/dga/dga.txt


DNS檢測DGA實現的代碼如下:



在代碼實現過程中,本個DGA正常解析成功的IP地址也記錄了下來,DGA都有問題,那麼解析的IP基本上也不正常。在大網環境下可以記錄下相應的IP地址,在做Passive DNS時可以利用這些數據完善相應的庫。

考慮到DGA的文件每天都會更新,可以進行定時下載該文件。



測試後,效果如下:




這樣的話就實現了監測異常DGA記錄,內網環境下可以分析機器被黑或者中馬,大網環境下可以通過DNS側重了解區域安全態勢。
完整實現的代碼如下:

#coding:utf-8

import time
from scapy.all import *
from requests import *

conf.iface="Intel(R) Dual Band Wireless-AC 8260"

list=[]
dgalist = open("dga.txt","r")
dgalist = (dgalist.readlines())[18:]
for dga in dgalist :
   list.append(dga.split(" ")[1])
data = set(list)

#Capture and Filter DGA
def capture(packet):
   if packet:
       i =0
       for p in packet:
           src = p[i][IP].src
           dst = p[i][IP].dst
           sport = p[i][UDP].sport
           dport = p[i][UDP].dport
           qr = str(p[i][DNS].qr)
           rcode = str(p[i][DNS].rcode)

           if "0" in qr:
               qr = "Query"
               qname = p[i][DNS].qd.qname
               if type(qname) == bytes:
                   qname = (qname.decode("utf-8"))[:-1]
               if qname in data:
                   print("[*] Found DGA Request:-->",src,sport,qr,qname)

           if "1" in qr:
               if "0" in rcode:
                   for j in range(10):
                       try:
                           qr = "Response"
                           rrname = p[j][DNS].an[j].rrname
                           rdata = p[j][DNS].an[j].rdata
                           if type(rrname) == bytes:
                               rrname = (rrname.decode("utf-8"))[:-1]
                               if type(rdata) == bytes:
                                   rdata = (rdata.decode("utf-8"))[:-1]
                           if rrname in data:
                               print ("[*] Found DGA Response:-->",src,dst,qr,rrname,rdata,"
")
                       except Exception as e:
                           pass

       i = i + 1

#update dgafile
def dgafileupdate():
   url = "http://data.netlab.360.com/feeds/dga/dga.txt"
   dgafile = get(url)
   with open("./dga.txt","w") as f:
       f.write(dgafile.text)
       print("Download DGAFile Finished")

if __name__ == "__main__":
   sniff(prn=capture,filter="udp port 53")
   while True:
       dgafileupdate()
       time.sleep(86400)

本文原創作者:feiniao,本文屬於 FreeBuf 原創獎勵計劃,未經許可禁止轉載


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 FreeBuf 的精彩文章:

利用忘記密碼功能繞過Windows auth & BitLocker
大疆的漏洞獎勵計劃來了,美國的「安全控訴」是不是可以歇會兒了?
特別企劃 | 銀行業木馬黑產報告
再見了,接碼平台:互動式語音驗證碼

TAG:FreeBuf |