search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

利用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('\t')[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,"\n") 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)



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦