绿盟科技应急响应中心安全研究员邓永凯:那些年,你怎么写总会出现的漏洞...
11月18號,2017看雪安全開發(fā)者峰會在北京悠唐皇冠假日酒店舉行。來自全國各地的開發(fā)人員、網(wǎng)絡安全愛好者及相應領域頂尖專家,在2017看雪安全開發(fā)者峰會匯聚一堂,只為這場“安全與開發(fā)”的技術盛宴。
源代碼作為軟件的最初原始形態(tài),其安全缺陷是導致軟件漏洞的直接根源。與之相對的是,解決代碼的完整性與安全性,實現(xiàn)安全編碼也成為減少漏洞的根本解決辦法。但讓人無奈的是,在編寫數(shù)量繁多且關系復雜的代碼過程中,難免會出現(xiàn)各種各樣的問題,即使是具有多年開發(fā)經(jīng)驗的老司機也是一樣。這些問題就像是高考英語易錯短語一樣,成為每個程序員編寫代碼的“必經(jīng)之路”。
本峰會上,綠盟科技應急響應中心安全研究員鄧永凱對開發(fā)者在開發(fā)編碼時最容易產(chǎn)生的漏洞以及意料之外的漏洞進行了分析,闡述其原因以及應該注意的地方。通過沒有防御到防御繞過、錯誤的防御姿勢、錯誤的使用方法、錯誤的修復方法、系統(tǒng)及語言自身特性、設計缺陷、二次漏洞、程序員的惰性導致的漏洞等方面進行實例講解。
綠盟科技應急響應中心安全研究員 鄧永凱
鄧永凱,Web安全研究員。綠盟科技從事安全工作6年,主要負責Web與系統(tǒng)漏洞掃描產(chǎn)品的開發(fā)及攻防代表、Web漏洞挖掘及分析、Web安全研究工作。 現(xiàn)于綠盟科技應急響應中心從事Web安全研究工作。擅長代碼審計、Web漏洞挖掘、安全自動化、滲透測試。曾創(chuàng)辦《安全參考》、《書安》等免費電子安全雜志,國內(nèi)多個漏洞提交平臺及SRC核心白帽子,SSC安全大會演講者。
以下為演講速記:
鄧永凱:大家下午好。很榮幸跟大家探討關于安全開發(fā)的問題。為什么取這個名字,《那些年,你怎么寫總會出現(xiàn)的漏洞》?今天是安全開發(fā)者大會,段總說在座各位基本上都是開發(fā)為主的,我們在開發(fā)的過程當中不僅僅要把功能完善好,也要注意在開發(fā)過程中的安全問題,是不是你就會在你的代碼里面埋下一些雷。
自我介紹一下,我之前也是一個程序員,主要負責綠盟科技的系統(tǒng)和web漏掃開發(fā)工作,并擔任攻防產(chǎn)品攻防代表,后來加入研究院做web和IoT安全研究的工作,之前基于愛好也辦過一些電子雜志《安全參考》、《書安》,現(xiàn)在由于某種原因已經(jīng)停辦了,大家網(wǎng)上可以找得到。
今天主要從這三個方面給大家展開來講,利用大量案例講解初級程序員、高級程序員以及瘋狂程序員,他們在開發(fā)編碼的過程當中是怎樣把漏洞寫出來的。為什么我加了防御、做了過濾、漏洞已經(jīng)修復還是不斷被黑客攻擊?
初級程序員開發(fā)的時候基本上不會考慮安全問題,因為他只要把任務完成了,功能開發(fā)OK了,上線運行OK就可以了,他不會考慮到安全漏洞,或者沒有安全開發(fā)的概念。很簡單,直接獲取參數(shù)進到數(shù)據(jù)庫操作里面,一個赤裸裸的注入。直接把參數(shù)拼接到系統(tǒng)命令里面,執(zhí)行命令里面,很暴力的命令注入。另外文件上傳,直接獲取文件上傳無任何判斷。這些簡單例子功能上來看沒有問題,我可以查閱數(shù)據(jù),可以執(zhí)行命令,可以上傳文件,但是有一個共同的缺陷就是,它獲取數(shù)據(jù)之后根本沒有考慮到用戶數(shù)據(jù)是正常數(shù)據(jù)還是惡意數(shù)據(jù),如果傳入惡意數(shù)據(jù)那么這些地方就會被黑客利用,那么你的業(yè)務功能也就會存在問題。初級開發(fā)者就會說:“我把東西只要寫完了,功能已經(jīng)OK,上線正常運行了,你現(xiàn)在跟我說安全開發(fā),什么是安全編碼?我只是個寫代碼的啊,你要我怎樣?”。
高級程序員經(jīng)驗非常豐富做過很多項目,有很多的經(jīng)驗。對用戶的數(shù)據(jù)進行一些處理,或者是加一些過濾,給業(yè)務里面加一些軟WAF等。但是,雖然做了這些安全措施,如果不到位或者是不完整或者是錯誤的方法,錯誤的修復或者是加過濾了,結(jié)果是一樣的仍然存在漏洞。比如獲取參數(shù)了,加入數(shù)據(jù)庫之前進行了處理,這個時候把用戶數(shù)據(jù)過濾了,但是在數(shù)據(jù)庫操作時這個ID沒有單雙引號的保護,這個過濾有什么用?過濾跟沒有過濾不是一個樣子嗎?一些經(jīng)驗的開發(fā)者在代碼全域入口加上軟WAF服務,通過一些請求包把獲得的參數(shù)統(tǒng)一過濾了,都可轉(zhuǎn)義了,而且變量的數(shù)據(jù)庫進到數(shù)據(jù)里面加上一些引號保護,也就是說想來注入,必須繞過我的單雙引號,這個時候就沒有辦法了,感覺很完美!別忘了獲取數(shù)據(jù)不僅僅通過GET、POST、COOKIE,通過別的方式也可以獲取,比如FILES、SERVER,前面就沒有考慮。上傳這個文件的考慮你的文件有單雙引號嗎,這樣就不受全局軟WAF的影響。通過count做一些信息帶到庫里面,雖然軟AWF服務,但是這個里面Select根本不受你的控制。
很多時候程序員在寫代碼的時候會經(jīng)過各種各樣的處理,在進行核心操作的時候比如說查詢數(shù)據(jù)庫或者進入數(shù)據(jù)庫的時候會給你一個反編碼,因為他害怕里面有一些他不想要的東西,比如說不合法的東西,他先給你反編碼一下,或者說他干脆給你一個反轉(zhuǎn)義,比如說反轉(zhuǎn)義,那么前面處理轉(zhuǎn)義已經(jīng)沒有用了,而且進入數(shù)據(jù)庫的時候跟他有一個反編碼、反轉(zhuǎn)義,那提交數(shù)據(jù)的時候編碼不就行了嗎,多來幾次編碼,編碼之后就沒有惡意數(shù)據(jù)了,提交數(shù)據(jù)后你再反轉(zhuǎn)義反編碼不照樣惡意數(shù)據(jù)就還原回去了。還有其他的案例,它想到了安全問題,你要逃逸單引號,我把你變成兩個單引號,單引號成對出現(xiàn)之后就沒有逃逸功能,就沒有辦法注入了。我輸入單引號你給我編兩個單一號,我輸入一個斜杠單引號,但是斜杠并沒有處理,斜杠是一個轉(zhuǎn)義的的功能。(如果數(shù)據(jù)庫用的是postgresql,就沒有辦法繞過了,因為它每個這個反斜線。不同的數(shù)據(jù)庫也有不同的效果。)
下面這個案例是一個意料之外的問題。這個都進入到那個prepare里面,把里面’%s’,”%s”統(tǒng)一替換為’%s’,要注入首先逃逸單引號,但是前面做了處理逃逸單引號是不可能的,所以是沒有問題的。這樣來看可能是沒有問題,他所有的東西都包括進來了,而且對方想要逃逸單雙引號是不可能,恰恰是格式化的時候就有一個問題,比如說這是一個合法格式化的東西,格式化的內(nèi)容。第一次進入prepare函數(shù)之后進行一個替換,變成下面的一個,這還是’%s’,再替換一下,有一些數(shù)據(jù)庫拼接起來,所以這個地方紅色標入的地方都有一個單引號。但是那個單引號最后被吃掉了,為什么中間單引號不見了,這就是格式化字串的東西。這個東西1就是代表了格式化第一個類型,后面那個單引號是干什么,是格式化時候的一個附加值用來做padding的,比如說單引號后面必須有一個字符,如果這個字符不夠會以單引號后面的另外一個字符附加進去。附加多少也是在后面一個數(shù)字,如果你不給數(shù)字的話就返回空,比如說這個里面單引號%S,就是不加任何東西反饋一個空,這個時候恰恰那個里面一個單引號就被當成Padding功能干掉了,這個時候就逃逸單引號進行注入了,這是一種繞過方法。另外一種繞過方法,可以傳入空格+%s+空格,第一次替換變成這樣,這樣會不會有問題?如果第一個%S被拒了是不是就直接執(zhí)行了?這個是合法,而且可以成功執(zhí)行。看起來是非常正常而且考慮很多功能的代碼,還是會產(chǎn)生很多的問題,也有很多辦法可以繞過。
做項目的時候有這樣一個案例,在前臺找到注入管理的帳號,但是管理員沒有辦法登陸,因為找不到后臺,前臺的功能有限,所以做滲透測試的時候拿不到shell都是耍流氓。你找不到后臺,前臺沒有辦法讓你登陸,你就只能看代碼。前臺限制登陸的時候,有這樣一個代碼。如果你登錄的用戶名是admin就直接退出了,前臺登不了,后臺也登不了,這樣寫大家看看是不是沒有問題,但是這里存在一個登錄繞過。
MySQL存儲數(shù)據(jù)的時候有格式,首先是字符集用什么語言存儲,哪種比對格式,Ci,大小寫不敏感。那么ADMIN前面判斷不等admin,但是查詢出來這個結(jié)果是一樣的。這樣ADMIN就繞過了。
第二種情況,剛剛前面也有一句話代碼set names utf8,這個功能是什么,將這個客戶端所有的字符集都變?yōu)閡tf8,服務端模擬為latin1,這字符集有差異,有差異的時候就會進行這個字符集的轉(zhuǎn)換,轉(zhuǎn)換的過程中就有這個錯誤的編碼字符。繼續(xù)繞過!
獲取一個用戶名,獲取一個密碼,密碼Md5加密,看你用戶名密碼對不對,這是很簡單的幾句話。剛剛開始看的時候我也沒發(fā)現(xiàn)有什么問題,但是你注意到這個MD5有兩個參數(shù),一個是字符串,一個輸出格式。第二個參數(shù)默認為False。如果為True就是以16位原始二進制字符返回,如果是False就是32位十六進制數(shù)。如果輸入129等等一大串之后,返回的內(nèi)容里面有一個單引號’Or’8其他字符,這個時候相當于一個萬能密碼。為什么呢,把后面那個密碼帶到那個密碼之后,’Or’8其他字符就相當于萬能密碼了,而且這個O單引號的后面必須是數(shù)字開頭,這個時候查詢出來的數(shù)據(jù)是OK的,相當于一個萬能密碼繞過。如果’Or’8其他字符后面是字母或者非數(shù)字的話就不行了,因為’Or’的字符是數(shù)字開頭則永遠返回True,這個時候就繞過了??梢詫懸粋€腳本爆破一下,只要有一個單引號數(shù)字開頭的就可以了,就可以繞過了。
前面都是各種數(shù)據(jù)傳輸過程中出現(xiàn)了缺陷,有一些比較聰明,把數(shù)據(jù)在傳輸過程中都簽名一下,簽名的過程中肯定有密鑰,密鑰拿不到,你沒有辦法偽造的簽名,你有問題也沒辦法利用。但是簽名并不是萬能的。萬一您的Key被泄露了怎么辦,或者你的Key直接可以破解。你的Key通過各種各樣的途徑被泄露,或者是被破解。這些例子具體就不講了,因為每一個例子都很多樣式,我們博客(http://blog.nsfocus.com )里面可以把這個東西搜索出來看一下,只要你的Key泄露之后就繼續(xù)偽造數(shù)據(jù)進行注入,進行漏洞利用。
二次漏洞利用,大家經(jīng)常聽到這樣的話“用戶一切輸入都是有害的”,這句話說得還不夠完整,應該是“進入核心操作的一切數(shù)據(jù)都是有害的”。因為數(shù)據(jù)在系統(tǒng)里面核心操作的時候,這些數(shù)據(jù)不一定是用戶直接傳進來的,也有可能是從其他地方查出來的,比如說另外一個系統(tǒng),另外一個存儲介質(zhì)或者另外一個數(shù)據(jù)庫或者配置文件里面取出來的,你取出來之后在某一天某一個時刻,通過另外一個地方又傳進去了,就是來回的處理的過程,這個里面會引發(fā)多次的漏洞利用。比如說用戶先輸入了一個數(shù)據(jù),插入這個數(shù)據(jù)庫里面了,或者插入到文件或者全局數(shù)組里面,跟蹤了一大堆但是他沒有利用這個數(shù)據(jù),但是存到存儲介質(zhì)里面,某一天某一個時刻他從這個存儲介質(zhì)里面取出來了,因為你在想你是從數(shù)據(jù)庫或者存儲介質(zhì)里面取出來東西,不是用戶直接傳給你,他就是安全的,你可以直接進行操作了。但是你取出來這個數(shù)據(jù),是有隱患的數(shù)據(jù),是不可信任的數(shù)據(jù)。比如說先插入一個用戶名,進行操作的時候轉(zhuǎn)義了。某一天取出來了,取出來了之后他想這是我取的東西,不是用戶輸給我的再進行一次操作,再繼續(xù)注入,這是很簡單的一個二次注入。
某知名攝像頭0day:前面有一個設置數(shù)據(jù)的地方,第一次先設置進去,第二次再取出來,取出來之后沒有進行處理直接命令執(zhí)行,這樣就可以利用。
還有把上面所有東西加起來一起用,有很多的方法來防御,我也有很多的方法繞過。
在文件上傳的時候我給你限制各種能執(zhí)行的后綴,但是有三種方法,第一個給bypass.php加一個X,這個x是%80-%99。第二個是在windows,小于號代表星號,星號可以代表任何字符,第一次傳一個空文件,然后在覆蓋之前的文件。第三種就是直接::$DASTA,就是這個數(shù)據(jù)流。另外一個通用方法就是直接在文件后面加/.,在打開這個文件先判斷這個文件是不是目錄,如果目錄就報錯,不是目錄就會打開。怎么判斷是不是目錄,就要以斜杠,不是斜杠就是打開。獲取最后打開文件長度的時候,把那個斜杠那個點去掉了,經(jīng)過一切處理,就直接打開了,就導致任意代碼寫入了。
還有GD庫的處理,雖然我們上傳的圖片被gd庫處理了,但是如果我們上傳一個特意構(gòu)造好的圖片,那么處理后,圖片里面存在php代碼,這個時候后綴可控那么就導致代碼執(zhí)行。
利用條件競爭,上傳文件了,處理之后我給你刪了,但是你在刪了之后,再處理的過程中有一個時間差,利用那個時間差可以生成另外一個文件。上傳了一個文件,有一堆處理,處理之后刪除,但是再刪除之前有一個時間差,利用這個時間差可以寫多線程角本,不停請求再生成另外一個就可以了。這是一個國外知名廠商的安全設備的一個0day漏洞。
命令執(zhí)行時使用easpaceshellarg和easpaceshellcmd,如果這兩個函數(shù)沒有用對的話,本來沒有漏洞就造出一個漏洞,就有這樣一個例子。你輸入一個引號他給你轉(zhuǎn)移,最后處理完了之后單引號不見了。
命令執(zhí)行的時候會限制你的字符,比如說這里限制你的輸入內(nèi)容必須是數(shù)字字母,我們可以用這兩個方法繞過。還有限制你的長度,根據(jù)輸出命令只能是七個字符或者五個字符,或者只能是四個字符,這個時候怎么執(zhí)行命令,拿不到shell?利用這種方法可以搞定,把你的命令分割了,切割之后創(chuàng)建成一個文件,再利用各種各樣的構(gòu)造,然后將命令輸入到一個文件,構(gòu)造完了之后再執(zhí)行那個文件,那個文件里面包含你所需要的命令。
說來說去無論就是Bypass,Bypass真的是一門藝術,不同的人,不同的漏洞,不同的場景,具有不同的方法。架構(gòu)層,資源層,規(guī)則層,人的層面都可以Bypass。你的代碼寫的再好,肯定也有薄弱的地方。只要你有薄弱的地方,我就可以繞過你。
程序員們“狠死你們這幫黑客”,我寫了那么多的東西,做了各種防御你還各種繞,繞了還給我報到漏洞平臺,我天天加班。
瘋狂程序員,一個重置密碼的功能就能有十幾種方法繞過,我想不通一個重置密碼功能這么多人開發(fā)出不同的邏輯,這些邏輯里面都有問題,都可以重置密碼。是不是很瘋狂?
這是某銀行的項目,修改A用戶信息時,可以添加一個字段,換成B用戶的手機號碼,正常情況下把A用戶信息修改了,有漏洞的情況下把B用戶信息修改了,它這兒不是,修改A用戶的時候A用戶信息被B用戶信息覆蓋了,而且把A用戶信息刪掉了,還進入到了B用戶,如果你把B用戶修成一個老板或者一個大BOSS,你瞬間進入到他的帳戶里面去了,你就很有錢了。
還有這樣一個項目只有一個登陸框,登陸不了什么也干不了,這是一個硬件設備。把這個固件下來,這里面也有一大堆的參數(shù),也沒有接口,訪問一下這個文件,構(gòu)造這個參數(shù)它真的可以訪問,而且直接進入到后臺了。想不通它這個是為什么,估計是傳說中的后門。
還有指哪修哪,永遠修不好,永遠修不完。第四次繞過,第八次繞過,最后程序員被開除了。這是真實的案例。當時我們也提了很多的漏洞,他說他們已經(jīng)把程序員開除了。
一切漏洞都來源于有缺陷的代碼,但是一切代碼都是可愛的程序員寫的,謝謝大家!
注:本文根據(jù)大會主辦方提供的速記整理而成,不代表CSDN觀點。
2017看雪安全開發(fā)者峰會更多精彩內(nèi)容:
- 2017看雪安全開發(fā)者峰會在京召開 共商網(wǎng)絡安全保障之策
- 中國信息安全測評中心總工程師王軍:用技術實現(xiàn)國家的網(wǎng)絡強國夢
- 興華永恒公司CSO仙果:Flash之殤—漏洞之王Flash Player的末路
- 中國婚博會PHP高級工程師、安全顧問湯青松:淺析Web安全編程
- 威脅獵人產(chǎn)品總監(jiān)彭巍:業(yè)務安全發(fā)展趨勢及對安全研發(fā)的挑戰(zhàn)
- 啟明星辰ADLab西南團隊負責人王東:智能化的安全——設備&應用&ICS
- 自由Android安全研究員陳愉鑫:移動App灰色產(chǎn)業(yè)案例分析與防范
- 騰訊反病毒實驗室安全研究員楊經(jīng)宇:開啟IoT設備的上帝模式
- 騰訊游戲安全高級工程師胡和君:定制化對抗——游戲反外掛的安全實踐
- 綠盟科技網(wǎng)絡安全攻防實驗室安全研究員廖新喜:Java JSON 反序列化之殤
- 阿里安全IoT安全研究團隊Leader謝君:如何黑掉無人機
總結(jié)
以上是生活随笔為你收集整理的绿盟科技应急响应中心安全研究员邓永凯:那些年,你怎么写总会出现的漏洞...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: new String[0]的作用
- 下一篇: 微型计算机的 I3 I5是,电脑i3和i