DOS攻擊可能的原因和分析與預(yù)防
關(guān)于安全的三個(gè)最核心的元素CIA,也就是:
Confidentiality(保密性):信息只能被授權(quán)的人查閱。
Integrity(完整性):信息沒(méi)有被意外地修改。
Availability(有效性):信息或者資源在需要的時(shí)候,總是可以使用的。
不同的產(chǎn)品對(duì)有效性的要求是不一樣的,有的要求三個(gè)9,有的要求4個(gè)9。一個(gè)產(chǎn)品的可用性對(duì)客戶的影響非常大,如果服務(wù)經(jīng)常不可以使用,客戶將可能選擇其它產(chǎn)品。可用性對(duì)一個(gè)系統(tǒng)來(lái)說(shuō)是十分關(guān)鍵的,如果一個(gè)系統(tǒng)經(jīng)常不可用,就像12306那樣,你會(huì)覺(jué)得很郁悶,客戶也會(huì)覺(jué)得很郁悶。本片文章著重分析和總結(jié)了幾種導(dǎo)致DOS的原因,作為參考。
DOS產(chǎn)生的主要原因有以下幾種:
1)系統(tǒng)存在耗資源的操作,包括內(nèi)存和CPU以及帶寬
當(dāng)一個(gè)操作需要消耗大量的CPU或者內(nèi)存的時(shí)候,首先需要想的是:是否有其他不需要耗費(fèi)這么多資源的方法可以實(shí)現(xiàn)?如果有則是最好的啦。如果沒(méi)有,需要注意這個(gè)操作是那些角色可以操作?是內(nèi)部接口還是外部接口?誰(shuí)可以觸發(fā)這個(gè)操作?如何避免被一般用戶出發(fā)這個(gè)操作?
舉個(gè)例子:一個(gè)搜索的頁(yè)面,對(duì)于用戶來(lái)說(shuō),可以設(shè)置每個(gè)頁(yè)面顯示多少條記錄。某些別有用心的用戶可能會(huì)嘗試修改一個(gè)頁(yè)面顯示的最大記錄數(shù)為一個(gè)很大的值,例如:10000。如果在服務(wù)器端沒(méi)有控制好,通過(guò)了驗(yàn)證,而且系統(tǒng)確實(shí)有大量的數(shù)據(jù),這樣的查詢是非常耗資源的。也許你會(huì)認(rèn)為10000條記錄沒(méi)什么,那么,如果修改為1000,000呢?
2)使用共享資源的操作,容易導(dǎo)致死鎖
現(xiàn)在的系統(tǒng)都是并發(fā)量很大的系統(tǒng),而一個(gè)系統(tǒng)又難免會(huì)有一些資源是共享的,如果系統(tǒng)存在一個(gè)線程需要使用兩個(gè)共享的資源,在其他線程也需要使用這些資源,就有可能導(dǎo)致死鎖,進(jìn)而使得系統(tǒng)停止工作。而且,這樣的問(wèn)題還非常難以調(diào)查具體的原因,貌似程序運(yùn)行的很好,其實(shí),很多功能都已經(jīng)停止工作。監(jiān)控程序也可能漏掉這樣的監(jiān)控。所以,其危害比較大。
因此,在使用共享資源時(shí),應(yīng)該盡量減少保持的時(shí)間,用完快速釋放。必須要同時(shí)使用多個(gè)資源時(shí),必須保證以同樣的順序使用,最好是能夠封裝在一個(gè)API之內(nèi),統(tǒng)一處理。另外,一些系統(tǒng)的API也有可能會(huì)導(dǎo)致阻塞,在調(diào)用可能導(dǎo)致阻塞的API之前,必須保證不上鎖任何資源。例如:訪問(wèn)數(shù)據(jù)庫(kù)有可能會(huì)因?yàn)閿?shù)據(jù)庫(kù)服務(wù)器的原因?qū)е伦枞?,這時(shí),就可以采用先訪問(wèn)數(shù)據(jù)庫(kù),得到數(shù)據(jù)之后,再使用共享資源進(jìn)行下一步操作。當(dāng)然,最好的方法還是通過(guò)設(shè)計(jì)盡量避免在同一個(gè)線程里同時(shí)訪問(wèn)多個(gè)共享資源。
3)緩沖區(qū)溢出
緩沖區(qū)溢出是一個(gè)眾所周知的導(dǎo)致程序不可用的原因。其危害性,不用說(shuō),可能大多說(shuō)的C/C++c程序員也都知道,也都對(duì)峙耿耿于懷。其避免方法也很簡(jiǎn)單,通過(guò)有效的inputvalidation避免其發(fā)生,這一點(diǎn)很難做到。不過(guò),還有另外一個(gè)比較好的方法就是:使用安全的庫(kù)是最好的方法,例如:STL,Safe C。
4)內(nèi)存泄漏
使用C/C++語(yǔ)言編程時(shí),需要使用malloc/free和new/delete分配和釋放內(nèi)存。很容易犯的錯(cuò)誤就是:
分配和釋放不匹配:例如使用new分配,使用free釋放,
這樣會(huì)導(dǎo)致內(nèi)存泄漏。
重復(fù)釋放 :例如new 分配一塊內(nèi)存之后,delete兩次,這樣會(huì)導(dǎo)致程序crash。
不正確地釋放: 使用new[]分配內(nèi)存,使用delete釋放,
這樣會(huì)導(dǎo)致內(nèi)存泄漏。
對(duì)于一些客戶端程序來(lái)說(shuō),一點(diǎn)內(nèi)存泄漏可能結(jié)果不是很嚴(yán)重。但是,對(duì)于后臺(tái)程序來(lái)說(shuō),一點(diǎn)點(diǎn)的內(nèi)存泄漏,都可能導(dǎo)致嚴(yán)重的Crash。因?yàn)?,后臺(tái)程序是常年累月地在運(yùn)行,泄漏的內(nèi)存會(huì)越來(lái)越多(這個(gè)根據(jù)泄漏內(nèi)存的操作的頻度有關(guān)),進(jìn)而導(dǎo)致程序的內(nèi)存不足。所以,嚴(yán)格按照語(yǔ)言設(shè)計(jì)的理念,正確地使用接口很重要。
5)不正確的緩存機(jī)制
a)不常用的對(duì)象就不要緩存
如果對(duì)象不經(jīng)常使用而被緩存,則意味著經(jīng)常使用的對(duì)象可能會(huì)因?yàn)閮?nèi)存的原因被從緩存中清除,這樣當(dāng)再次被使用時(shí),有需要再次導(dǎo)入到內(nèi)存。這樣會(huì)消耗很多CPU資源和內(nèi)存資源。使得整個(gè)系統(tǒng)的效率變得很低。所以,在決定需要緩存那些對(duì)象時(shí),最好先調(diào)查對(duì)象使用頻率。根據(jù)緩存的大小和使用頻率決定緩存那些對(duì)象。
b)不需要記錄的日志,就不要記錄
首先,關(guān)于保存日志的文件,最好單獨(dú)保存在一個(gè)單獨(dú)的分區(qū),使得系統(tǒng)不會(huì)因?yàn)槿罩咎嗾紳M磁盤而影響程序的正常工作。
其次,記錄日志要選擇性記錄,對(duì)于沒(méi)有用的日志,盡量不要記錄,否則,可能因?yàn)闊o(wú)用的日志太多,導(dǎo)致有用的日志被覆蓋,影響程序bug的分析和審計(jì)。
可見(jiàn),日志雖然不像具體的業(yè)務(wù)邏輯模塊那么重要,但是,正確地實(shí)現(xiàn)日志功能,可以對(duì)bug分析和審計(jì)提供很大的輔助作用。
6)服務(wù)使用的工具或者系統(tǒng)的配置不當(dāng)
Web服務(wù)器的配置對(duì)于系統(tǒng)的穩(wěn)定也至關(guān)重要,如果配置不當(dāng),也很容易導(dǎo)致系統(tǒng)被DOS攻擊,例如:TOMCAT如果配置成開發(fā)模式,很容易導(dǎo)致內(nèi)存耗盡;Oracle 如果連續(xù)插入兩個(gè)同樣的主鍵的值可能導(dǎo)致死鎖等。另外,像建立連接的Timeout時(shí)間設(shè)置不當(dāng),也可能導(dǎo)致連接被使用完而不能提供服務(wù)。
關(guān)于Web服務(wù)器和數(shù)據(jù)庫(kù)等第三方軟件的配置最重要的莫過(guò)于默認(rèn)的用戶名和密碼,這些用戶名和密碼是公開的,一些攻擊者也會(huì)首先嘗試這些用戶名和密碼。如果服務(wù)器上沒(méi)有修改,攻擊者可以通過(guò)這些用戶名和密碼控制系統(tǒng)。當(dāng)然,控制系統(tǒng)之后,DOS攻擊也就非常簡(jiǎn)單。
所以,關(guān)于使用第三方工具時(shí),關(guān)于配置方面的每一個(gè)配置項(xiàng),都要搞清楚,以免有漏網(wǎng)之魚損害系統(tǒng)。
7)沒(méi)有備份,一旦主系統(tǒng)掛掉,沒(méi)有備份的系統(tǒng)無(wú)縫接替
如果系統(tǒng)沒(méi)有很好的備份機(jī)制,一旦系統(tǒng)出問(wèn)題就會(huì)是一個(gè)很麻煩的事情。當(dāng)然,是否需要備份需要根據(jù)系統(tǒng)提供服務(wù)來(lái)定。至于是備份整個(gè)系統(tǒng)還是備份整個(gè)系統(tǒng)的數(shù)據(jù),這個(gè)需要根據(jù)系統(tǒng)和備份的成本和收益率來(lái)權(quán)衡。只要做一個(gè)在線服務(wù)的系統(tǒng),備份是必須考慮的。
8)存在注入問(wèn)題,如SQL注入,命令行注入等,一旦被利用,很容易使得攻擊者控制系統(tǒng),當(dāng)然DOS就更不在話下
一個(gè)最典型的SQL注入字符串如下:
aaaa’ or ‘1’=’1’--
這樣的注入相對(duì)來(lái)說(shuō)還是比較友善一些的。
如果一個(gè)非常惡意的攻擊者,注入的代碼如下:
aaaa’ or ‘1’=’1’;drop tableuser;--
結(jié)果會(huì)怎么樣?
關(guān)于SQL Server數(shù)據(jù)庫(kù),由于可以執(zhí)行一些系統(tǒng)的命令,如果注入系統(tǒng)的命令,可以使攻擊者控制系統(tǒng),啟動(dòng)一些服務(wù)等操作,危害也非常嚴(yán)重。
對(duì)于一些輸入作為腳本語(yǔ)言或者解釋語(yǔ)言的一部分時(shí),一定要謹(jǐn)記,要做好輸入驗(yàn)證和特殊字符轉(zhuǎn)義。
9)數(shù)據(jù)庫(kù)連接配置不當(dāng)
一個(gè)數(shù)據(jù)庫(kù)請(qǐng)求要有合適的超時(shí)配置,否則,可能導(dǎo)致阻塞。
在一般的產(chǎn)品線上,數(shù)據(jù)庫(kù)是非常關(guān)鍵的組件,一切應(yīng)用皆需要數(shù)據(jù)。如果數(shù)據(jù)庫(kù)配置不當(dāng),超時(shí)沒(méi)有設(shè)置為合適的值,在網(wǎng)絡(luò)不是很好或者數(shù)據(jù)庫(kù)系統(tǒng)有些小問(wèn)題的時(shí)候,很有可能導(dǎo)致,數(shù)據(jù)庫(kù)操作阻塞。如果阻塞的時(shí)間比較長(zhǎng),就可能導(dǎo)致很多請(qǐng)求被堆積在服務(wù)端。不但,占用大量?jī)?nèi)存,還使得請(qǐng)求不能及時(shí)得到響應(yīng),而導(dǎo)致DOS。
10)訪問(wèn)控制做的不好,也可以讓攻擊者提升權(quán)限控制系統(tǒng),進(jìn)而發(fā)動(dòng)DOS攻擊
訪問(wèn)控制做的不好的最嚴(yán)重的例子,就是管理員訪問(wèn)的一些操作控制不當(dāng)。可能有些人認(rèn)為將管理員的入口,從頁(yè)面上隱藏或者刪除,就可以有效地控制,防止一般人員可以訪問(wèn)這些操作。但是,總是有些好事者,喜歡琢磨一些事情,他們會(huì)很有耐心地琢磨出管理員可能的訪問(wèn)的接口。通過(guò)組裝這些接口,嘗試直接訪問(wèn)并且查看效果。如果你只是隱藏或者不顯示,這很容易導(dǎo)致問(wèn)題的出現(xiàn)。一旦攻擊者可以進(jìn)行管理員的操作,后果可想而知。所以,訪問(wèn)控制不能依靠隱藏,而是靠具有嚴(yán)格的、合適粒度的訪問(wèn)控制,保證每一個(gè)訪問(wèn)接口都被正確地控制。
11)實(shí)現(xiàn)邏輯導(dǎo)致的DOS攻擊
舉個(gè)最典型的例子就是:登錄幾次失敗之后,鎖住用戶(目前國(guó)內(nèi)仍然有不少網(wǎng)站使用這個(gè)策略)。這很有可能導(dǎo)致的后果就是,使用自動(dòng)發(fā)送請(qǐng)求的工具,針對(duì)一個(gè)網(wǎng)站很多用戶發(fā)送登錄請(qǐng)求,就會(huì)導(dǎo)致很多用戶被鎖住。當(dāng)真正的用戶登錄的時(shí)候,反而,因?yàn)橛脩舯绘i住而不能登錄。當(dāng)然,使用Captcha是一個(gè)很好的解決方案。
12)協(xié)議級(jí)別的攻擊
針對(duì)協(xié)議的攻擊有很多,例如,TCP SYN flood攻擊,針對(duì)ICMP協(xié)議的攻擊, 這些攻擊都有一些特征,可以通過(guò)防火墻定制規(guī)則過(guò)濾這些包。也有一些是通過(guò)防火墻不能處理的,例如:SSL Beast攻擊,是利用低版本的SSL和TLS的實(shí)現(xiàn)上的缺陷發(fā)動(dòng)的攻擊,這就需要升級(jí)使用最新版的協(xié)議;還有就是是利用SSL/TLS協(xié)議的再協(xié)商漏洞,可以使用單機(jī)就可以發(fā)送DOS攻擊,這樣的攻擊就需要修改服務(wù)器配置,禁止使用再協(xié)商機(jī)制才可以避免。
總之,導(dǎo)致DOS的原因有很多,必須在編程過(guò)程中時(shí)刻牢記一些容易導(dǎo)致DOS攻擊的原因,在設(shè)計(jì)和編碼的初始階段就注意預(yù)防,才是最有效的方法。希望本文能夠?qū)ψx者關(guān)于DOS攻擊的預(yù)防有所幫助。