據(jù)統(tǒng)計,在所有黑客攻擊事件中,SYN攻擊是最常見又最容易被利用的一種攻擊手法。相信很多人還記得2000年YAHOO網(wǎng)站遭受的攻擊事例,當(dāng)時黑客利用的就是簡單而有效的SYN攻擊,有些網(wǎng)絡(luò)蠕蟲病毒配合SYN攻擊造成更大的破壞。本文介紹SYN攻擊的基本原理、工具及檢測方法,并全面探討SYN攻擊防范技術(shù)。
據(jù)統(tǒng)計,在所有黑客攻擊事件中,SYN攻擊是最常見又最容易被利用的一種攻擊手法。相信很多人還記得2000年YAHOO網(wǎng)站遭受的攻擊事例,當(dāng)時黑客利用的就是簡單而有效的SYN攻擊,有些網(wǎng)絡(luò)蠕蟲病毒配合SYN攻擊造成更大的破壞。本文介紹SYN攻擊的基本原理、工具及檢測方法,并全面探討SYN攻擊防范技術(shù)。
一、TCP握手協(xié)議
在TCP/IP協(xié)議中,TCP協(xié)議提供可靠的連接服務(wù),采用三次握手建立一個連接。
第一次握手:建立連接時,客戶端發(fā)送syn包(syn=j)到服務(wù)器,并進入SYN_SEND狀態(tài),等待服務(wù)器確認(rèn);
第二次握手:服務(wù)器收到syn包,必須確認(rèn)客戶的SYN(ack=j+1),同時自己也發(fā)送一個SYN包(syn=k),即SYN+ACK包,此時服務(wù)器進入SYN_RECV狀態(tài);
第三次握手:客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=k+1),此包發(fā)送完畢,客戶端和服務(wù)器進入ESTABLISHED狀態(tài),完成三次握手。
完成三次握手,客戶端與服務(wù)器開始傳送數(shù)據(jù),在上述過程中,還有一些重要的概念:
未連接隊列:在三次握手協(xié)議中,服務(wù)器維護一個未連接隊列,該隊列為每個客戶端的SYN包(syn=j)開設(shè)一個條目,該條目表明服務(wù)器已收到SYN包,并向客戶發(fā)出確認(rèn),正在等待客戶的確認(rèn)包。這些條目所標(biāo)識的連接在服務(wù)器處于Syn_RECV狀態(tài),當(dāng)服務(wù)器收到客戶的確認(rèn)包時,刪除該條目,服務(wù)器進入ESTABLISHED狀態(tài)。
Backlog參數(shù):表示未連接隊列的最大容納數(shù)目。
SYN-ACK 重傳次數(shù) 服務(wù)器發(fā)送完SYN-ACK包,如果未收到客戶確認(rèn)包,服務(wù)器進行首次重傳,等待一段時間仍未收到客戶確認(rèn)包,進行第二次重傳,如果重傳次數(shù)超過系統(tǒng)規(guī)定的最大重傳次數(shù),系統(tǒng)將該連接信息從半連接隊列中刪除。注意,每次重傳等待的時間不一定相同。
半連接存活時間:是指半連接隊列的條目存活的最長時間,也即服務(wù)從收到SYN包到確認(rèn)這個報文無效的最長時間,該時間值是所有重傳請求包的最長等待時間總和。有時我們也稱半連接存活時間為Timeout時間、SYN_RECV存活時間。
二、SYN攻擊原理
SYN攻擊屬于DOS攻擊的一種,它利用TCP協(xié)議缺陷,通過發(fā)送大量的半連接請求,耗費CPU和內(nèi)存資源。SYN攻擊除了能影響主機外,還可以危害路由器、防火墻等網(wǎng)絡(luò)系統(tǒng),事實上SYN攻擊并不管目標(biāo)是什么系統(tǒng),只要這些系統(tǒng)打開TCP服務(wù)就可以實施。從上圖可看到,服務(wù)器接收到連接請求(syn=j),將此信息加入未連接隊列,并發(fā)送請求包給客戶(syn=k,ack=j+1),此時進入SYN_RECV狀態(tài)。當(dāng)服務(wù)器未收到客戶端的確認(rèn)包時,重發(fā)請求包,一直到超時,才將此條目從未連接隊列刪除。配合IP欺騙,SYN攻擊能達到很好的效果,通常,客戶端在短時間內(nèi)偽造大量不存在的IP地址,向服務(wù)器不斷地發(fā)送syn包,服務(wù)器回復(fù)確認(rèn)包,并等待客戶的確認(rèn),由于源地址是不存在的,服務(wù)器需要不斷的重發(fā)直至超時,這些偽造的SYN包將長時間占用未連接隊列,正常的SYN請求被丟棄,目標(biāo)系統(tǒng)運行緩慢,嚴(yán)重者引起網(wǎng)絡(luò)堵塞甚至系統(tǒng)癱瘓。
三、SYN攻擊工具
SYN攻擊實現(xiàn)起來非常的簡單,互聯(lián)網(wǎng)上有大量現(xiàn)成的SYN攻擊工具。
1、Windows系統(tǒng)下的SYN工具
以synkill.exe為例,運行工具,選擇隨機的源地址和源端囗,并填寫目標(biāo)機器地址和TCP端囗,激活運行,很快就會發(fā)現(xiàn)目標(biāo)系統(tǒng)運行緩慢。如果攻擊效果不明顯,可能是目標(biāo)機器并未開啟所填寫的TCP端囗或者防火墻拒絕訪問該端囗,此時可選擇允許訪問的TCP端囗,通常,windows系統(tǒng)開放tcp139端囗,UNIX系統(tǒng)開放tcp7、21、23等端囗。
四、檢測SYN攻擊
檢測SYN攻擊非常的方便,當(dāng)你在服務(wù)器上看到大量的半連接狀態(tài)時,特別是源IP地址是隨機的,基本上可以斷定這是一次SYN攻擊。我們使用系統(tǒng)自帶的netstat 工具來檢測SYN攻擊:
# netstat -n -p TCP |
上面是在LINUX系統(tǒng)中看到的,很多連接處于SYN_RECV狀態(tài)(在WINDOWS系統(tǒng)中是SYN_RECEIVED狀態(tài)),源IP地址都是隨機的,表明這是一種帶有IP欺騙的SYN攻擊。
我們也可以通過下面的命令直接查看在LINUX環(huán)境下某個端囗的未連接隊列的條目數(shù):
#netstat -n -p TCP grep SYN_RECV grep :22 wc -l 324
顯示TCP端囗22的未連接數(shù)有324個,雖然還遠(yuǎn)達不到系統(tǒng)極限,但應(yīng)該引起管理員的注意。
五、SYN攻擊防范技術(shù)
關(guān)于SYN攻擊防范技術(shù),人們研究得比較早。歸納起來,主要有兩大類,一類是通過防火墻、路由器等過濾網(wǎng)關(guān)防護,另一類是通過加固TCP/IP協(xié)議棧防范.但必須清楚的是,SYN攻擊不能完全被阻止,我們所做的是盡可能的減輕SYN攻擊的危害,除非將TCP協(xié)議重新設(shè)計。
1、過濾網(wǎng)關(guān)防護
這里,過濾網(wǎng)關(guān)主要指明防火墻,當(dāng)然路由器也能成為過濾網(wǎng)關(guān)。防火墻部署在不同網(wǎng)絡(luò)之間,防范外來非法攻擊和防止保密信息外泄,它處于客戶端和服務(wù)器之間,利用它來防護SYN攻擊能起到很好的效果。過濾網(wǎng)關(guān)防護主要包括超時設(shè)置,SYN網(wǎng)關(guān)和SYN代理三種。
■網(wǎng)關(guān)超時設(shè)置:
防火墻設(shè)置SYN轉(zhuǎn)發(fā)超時參數(shù)(狀態(tài)檢測的防火墻可在狀態(tài)表里面設(shè)置),該參數(shù)遠(yuǎn)小于服務(wù)器的timeout時間。當(dāng)客戶端發(fā)送完SYN包,服務(wù)端發(fā)送確認(rèn)包后(SYN+ACK),防火墻如果在計數(shù)器到期時還未收到客戶端的確認(rèn)包(ACK),則往服務(wù)器發(fā)送RST包,以使服務(wù)器從隊列中刪去該半連接。值得注意的是,網(wǎng)關(guān)超時參數(shù)設(shè)置不宜過小也不宜過大,超時參數(shù)設(shè)置過小會影響正常的通訊,設(shè)置太大,又會影響防范SYN攻擊的效果,必須根據(jù)所處的網(wǎng)絡(luò)應(yīng)用環(huán)境來設(shè)置此參數(shù)。
■SYN網(wǎng)關(guān):
SYN網(wǎng)關(guān)收到客戶端的SYN包時,直接轉(zhuǎn)發(fā)給服務(wù)器;SYN網(wǎng)關(guān)收到服務(wù)器的SYN/ACK包后,將該包轉(zhuǎn)發(fā)給客戶端,同時以客戶端的名義給服務(wù)器發(fā)ACK確認(rèn)包。此時服務(wù)器由半連接狀態(tài)進入連接狀態(tài)。當(dāng)客戶端確認(rèn)包到達時,如果有數(shù)據(jù)則轉(zhuǎn)發(fā),否則丟棄。事實上,服務(wù)器除了維持半連接隊列外,還要有一個連接隊列,如果發(fā)生SYN攻擊時,將使連接隊列數(shù)目增加,但一般服務(wù)器所能承受的連接數(shù)量比半連接數(shù)量大得多,所以這種方法能有效地減輕對服務(wù)器的攻擊。
■SYN代理:
當(dāng)客戶端SYN包到達過濾網(wǎng)關(guān)時,SYN代理并不轉(zhuǎn)發(fā)SYN包,而是以服務(wù)器的名義主動回復(fù)SYN/ACK包給客戶,如果收到客戶的ACK包,表明這是正常的訪問,此時防火墻向服務(wù)器發(fā)送ACK包并完成三次握手。SYN代理事實上代替了服務(wù)器去處理SYN攻擊,此時要求過濾網(wǎng)關(guān)自身具有很強的防范SYN攻擊能力。
2、加固tcp/ip協(xié)議棧
防范SYN攻擊的另一項主要技術(shù)是調(diào)整tcp/ip協(xié)議棧,修改tcp協(xié)議實現(xiàn)。主要方法有SynAttackProtect保護機制、SYN cookies技術(shù)、增加最大半連接和縮短超時時間等。tcp/ip協(xié)議棧的調(diào)整可能會引起某些功能的受限,管理員應(yīng)該在進行充分了解和測試的前提下進行此項工作。
■SynAttackProtect機制
為防范SYN攻擊,win2000系統(tǒng)的tcp/ip協(xié)議棧內(nèi)嵌了SynAttackProtect機制,Win2003系統(tǒng)也采用此機制。SynAttackProtect機制是通過關(guān)閉某些socket選項,增加額外的連接指示和減少超時時間,使系統(tǒng)能處理更多的SYN連接,以達到防范SYN攻擊的目的。默認(rèn)情況下,Win2000操作系統(tǒng)并不支持SynAttackProtect保護機制,需要在注冊表以下位置增加SynAttackProtect鍵值:
HKLMSYSTEMCurrentControlSetServicesTcpipParameters
當(dāng)SynAttackProtect值(如無特別說明,本文提到的注冊表鍵值都為十六進制)為0或不設(shè)置時,系統(tǒng)不受SynAttackProtect保護。
當(dāng)SynAttackProtect值為1時,系統(tǒng)通過減少重傳次數(shù)和延遲未連接時路由緩沖項(route cache entry)防范SYN攻擊。
當(dāng)SynAttackProtect值為2時(Microsoft推薦使用此值),系統(tǒng)不僅使用backlog隊列,還使用附加的半連接指示,以此來處理更多的SYN連接,使用此鍵值時,tcp/ip的TCPInitialRTT、window size和可滑動窗囗將被禁止。
我們應(yīng)該知道,平時,系統(tǒng)是不啟用SynAttackProtect機制的,僅在檢測到SYN攻擊時,才啟用,并調(diào)整tcp/ip協(xié)議棧。那么系統(tǒng)是如何檢測SYN攻擊發(fā)生的呢?事實上,系統(tǒng)根據(jù)TcpMaxHalfOpen,TcpMaxHalfOpenRetried 和TcpMaxPortsExhausted三個參數(shù)判斷是否遭受SYN攻擊。
TcpMaxHalfOpen 表示能同時處理的最大半連接數(shù),如果超過此值,系統(tǒng)認(rèn)為正處于SYN攻擊中。Win2000 server默認(rèn)值為100,Win2000 Advanced server為500。
TcpMaxHalfOpenRetried定義了保存在backlog隊列且重傳過的半連接數(shù),如果超過此值,系統(tǒng)自動啟動SynAttackProtect機制。Win2000 server默認(rèn)值為80,Win2000 Advanced server為400。
TcpMaxPortsExhausted 是指系統(tǒng)拒絕的SYN請求包的數(shù)量,默認(rèn)是5。
如果想調(diào)整以上參數(shù)的默認(rèn)值,可以在注冊表里修改(位置與SynAttackProtect相同)
■ SYN cookies技術(shù)
我們知道,TCP協(xié)議開辟了一個比較大的內(nèi)存空間backlog隊列來存儲半連接條目,當(dāng)SYN請求不斷增加,并這個空間,致使系統(tǒng)丟棄SYN連接。為使半連接隊列被塞滿的情況下,服務(wù)器仍能處理新到的SYN請求,SYN cookies技術(shù)被設(shè)計出來。
SYN cookies應(yīng)用于linux、FreeBSD等操作系統(tǒng),當(dāng)半連接隊列滿時,SYNcookies并不丟棄SYN請求,而是通過加密技術(shù)來標(biāo)識半連接狀態(tài)。
在TCP實現(xiàn)中,當(dāng)收到客戶端的SYN請求時,服務(wù)器需要回復(fù)SYN+ACK包給客戶端,客戶端也要發(fā)送確認(rèn)包給服務(wù)器。通常,服務(wù)器的初始序列號由服務(wù)器按照一定的規(guī)律計算得到或采用隨機數(shù),但在SYN cookies中,服務(wù)器的初始序列號是通過對客戶端IP地址、客戶端端囗、服務(wù)器IP地址和服務(wù)器端囗以及其他一些安全數(shù)值等要素進行hash運算,加密得到的,稱之為cookie。當(dāng)服務(wù)器遭受SYN攻擊使得backlog隊列滿時,服務(wù)器并不拒絕新的SYN請求,而是回復(fù)cookie(回復(fù)包的SYN序列號)給客戶端, 如果收到客戶端的ACK包,服務(wù)器將客戶端的ACK序列號減去1得到cookie比較值,并將上述要素進行一次hash運算,看看是否等于此cookie。如果相等,直接完成三次握手(注意:此時并不用查看此連接是否屬于backlog隊列)。
在RedHat linux中,啟用SYN cookies是通過在啟動環(huán)境中設(shè)置以下命令來完成:
# echo 1 ?? /proc/sys/net/ipv4/tcp_syncookies
■ 增加最大半連接數(shù)
大量的SYN請求導(dǎo)致未連接隊列被塞滿,使正常的TCP連接無法順利完成三次握手,通過增大未連接隊列空間可以緩解這種壓力。當(dāng)然backlog隊列需要占用大量的內(nèi)存資源,不能被無限的擴大。
WIN2000:除了上面介紹的TcpMaxHalfOpen, TcpMaxHalfOpenRetried參數(shù)外,WIN2000操作系統(tǒng)可以通過設(shè)置動態(tài)backlog(dynamic backlog)來增大系統(tǒng)所能容納的最大半連接數(shù),配置動態(tài)backlog由AFD.SYS驅(qū)動完成,AFD.SYS是一種內(nèi)核級的驅(qū)動,用于支持基于window socket的應(yīng)用程序,比如ftp、telnet等。AFD.SYS在注冊表的位置:
HKLMSystemCurrentControlSetServicesAFDParametersEnableDynamicBacklog值為1時,表示啟用動態(tài)backlog,可以修改最大半連接數(shù)。
MinimumDynamicBacklog表示半連接隊列為單個TCP端囗分配的最小空閑連接數(shù),當(dāng)該TCP端囗在backlog隊列的空閑連接小于此臨界值時,系統(tǒng)為此端囗自動啟用擴展的空閑連接(DynamicBacklogGrowthDelta),Microsoft推薦該值為20。
MaximumDynamicBacklog是當(dāng)前活動的半連接和空閑連接的和,當(dāng)此和超過某個臨界值時,系統(tǒng)拒絕SYN包,Microsoft推薦MaximumDynamicBacklog值不得超過2000。
DynamicBacklogGrowthDelta值是指擴展的空閑連接數(shù),此連接數(shù)并不計算在MaximumDynamicBacklog內(nèi),當(dāng)半連接隊列為某個TCP端囗分配的空閑連接小于MinimumDynamicBacklog時,系統(tǒng)自動分配DynamicBacklogGrowthDelta所定義的空閑連接空間,以使該TCP端囗能處理更多的半連接。Microsoft推薦該值為10。
LINUX:Linux用變量tcp_max_syn_backlog定義backlog隊列容納的最大半連接數(shù)。在Redhat 7.3中,該變量的值默認(rèn)為256,這個值是遠(yuǎn)遠(yuǎn)不夠的,一次強度不大的SYN攻擊就能使半連接隊列占滿。我們可以通過以下命令修改此變量的值:
# sysctl -w net.ipv4.tcp_max_syn_backlog=`2048`
Sun Solaris Sun Solaris用變量tcp_conn_req_max_q0來定義最大半連接數(shù),在Sun Solaris 8中,該值默認(rèn)為1024,可以通過add命令改變這個值:
# ndd -set /dev/tcp tcp_conn_req_max_q0 2048
HP-UX:HP-UX用變量tcp_syn_rcvd_max來定義最大半連接數(shù),在HP-UX 11.00中,該值默認(rèn)為500,可以通過ndd命令改變默認(rèn)值:
#ndd -set /dev/tcp tcp_syn_rcvd_max 2048
■縮短超時時間
上文提到,通過增大backlog隊列能防范SYN攻擊;另外減少超時時間也使系統(tǒng)能處理更多的SYN請求。我們知道,timeout超時時間,也即半連接存活時間,是系統(tǒng)所有重傳次數(shù)等待的超時時間總和,這個值越大,半連接數(shù)占用backlog隊列的時間就越長,系統(tǒng)能處理的SYN請求就越少。為縮短超時時間,可以通過縮短重傳超時時間(一般是第一次重傳超時時間)和減少重傳次數(shù)來實現(xiàn)。
Win2000第一次重傳之前等待時間默認(rèn)為3秒,為改變此默認(rèn)值,可以通過修改網(wǎng)絡(luò)接囗在注冊表里的TcpInitialRtt注冊值來完成。重傳次數(shù)由TcpMaxConnectResponseRetransmissions 來定義,注冊表的位置是:HKLMSYSTEMCurrentControlSetServicesTcpipParameters registry key。
當(dāng)然我們也可以把重傳次數(shù)設(shè)置為0次,這樣服務(wù)器如果在3秒內(nèi)還未收到ack確認(rèn)包就自動從backlog隊列中刪除該連接條目。
LINUX:Redhat使用變量tcp_synack_retries定義重傳次數(shù),其默認(rèn)值是5次,總超時時間需要3分鐘。
Sun Solaris Solaris 默認(rèn)的重傳次數(shù)是3次,總超時時間為3分鐘,可以通過ndd命令修改這些默認(rèn)值。