淺談HTTP響應(yīng)拆分攻擊
譯文【51CTO.com 獨(dú)家特稿】在本文中,我們將探討何謂HTTP響應(yīng)拆分以及攻擊行為是怎樣進(jìn)行的。一旦徹底理解了其發(fā)生原理(該原理往往被人所誤解),我們就可以探究如何利用響應(yīng)拆分執(zhí)行跨站點(diǎn)腳本(簡(jiǎn)稱XSS)。接下來(lái)自然就是討論如果目標(biāo)網(wǎng)站存在響應(yīng)拆分漏洞,我們要如何利用這一機(jī)會(huì)組織CSRF(即跨站點(diǎn)偽造請(qǐng)求)攻擊。最后,我們一起來(lái)看看哪些預(yù)防措施能夠抵御這些攻擊行為。如果大家對(duì)這個(gè)話題感興趣,不妨繼續(xù)讀下去。
什么是HTTP響應(yīng)拆分?
首先讓我們?cè)O(shè)想一下某個(gè)具備多種語(yǔ)言選項(xiàng)的頁(yè)面。該頁(yè)面的默認(rèn)語(yǔ)言為英語(yǔ),但其中同時(shí)具備一個(gè)下拉菜單,允許我們?cè)谶x定其中對(duì)應(yīng)的其它語(yǔ)種后,整個(gè)頁(yè)面的語(yǔ)言也同時(shí)發(fā)生切換。比方說(shuō)根據(jù)初始頁(yè)面的配置,302重新指向的結(jié)果為http://www.abc.com/index.php?lang=en。但對(duì)于來(lái)自德國(guó)的用戶而言,當(dāng)然希望頁(yè)面內(nèi)容以德語(yǔ)呈現(xiàn),這時(shí)他們就可以從下拉菜單的備用語(yǔ)言中進(jìn)行選擇。這使得302重新指向?qū)⒈话l(fā)往服務(wù)器上的德語(yǔ)頁(yè)面——http://www.abc.com/index.php?lang=german。用戶的瀏覽器會(huì)遵循重新指向的引導(dǎo),并將德語(yǔ)頁(yè)面正常呈現(xiàn)出來(lái)。
現(xiàn)在讓我們思考一下HTTP 302重新指向響應(yīng)的主體內(nèi)容。內(nèi)容大體如下:
- HTTP/1.1 302 Moved Temporarily
- Location: http://www.abc.com/index.php?lang=en
或者是:
- HTTP/1.1 302 Moved Temporarily
- Location: http://www.abc.com/index.php?lang=german
大家可能已經(jīng)發(fā)現(xiàn)了,惟一產(chǎn)生變化的只有l(wèi)ang參數(shù)的值。也就是說(shuō),這個(gè)值是由用戶所控制,我們可以將該值設(shè)置為任何想要的內(nèi)容。正是這種特性導(dǎo)致了HTTP響應(yīng)拆分攻擊的發(fā)生。
此時(shí)我們不再把參數(shù)值設(shè)定為"german",而是按照下列內(nèi)容進(jìn)行設(shè)定:
- a) The value 'german'
- b) CR/LF - %0d%0a
- c) A response with Content Length 0 [這里之所以設(shè)長(zhǎng)度為0,是因?yàn)檫@一段其實(shí)無(wú)關(guān)緊要]
- d) CR/LF - %0d%0a
- e) A response which contains malicious content [舉例來(lái)說(shuō),可以設(shè)定JavaScript會(huì)在頁(yè)面被訪問(wèn)時(shí)自動(dòng)下載惡意軟件]
先來(lái)看看c)的內(nèi)容--這也是首個(gè)響應(yīng)。HTTP協(xié)議的工作方式是一個(gè)請(qǐng)求對(duì)應(yīng)一個(gè)響應(yīng),因此針對(duì)該請(qǐng)求——即http://www.abc.com/index.php?lang=german的響應(yīng)是經(jīng)過(guò)精心設(shè)計(jì)的。其實(shí)我們并不關(guān)心這個(gè)響應(yīng)本身及其內(nèi)容,我們想要的只是將Content-Length: 0設(shè)為其響應(yīng)頭。
CR/LF(即回車換行符)是響應(yīng)之間的分界符。所以只要我們?nèi)鏳)中所示加入CR/LF內(nèi)容,那么第二輪響應(yīng)即會(huì)啟動(dòng),且根據(jù)HTTP協(xié)議的規(guī)定這是完全正常的。在新一輪響應(yīng)中我們可以添加大量信息。舉例來(lái)說(shuō),如果我們打算顯示一條"Hello, you have been phished"(意為'你好,你已然中招了')的消息,此時(shí)面前已經(jīng)完全沒有任何阻礙了。只需輸入如下所示的內(nèi)容,即可輕松實(shí)現(xiàn):
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 41
Hello, you have been phished
還是覺得有點(diǎn)迷糊?讓我們?cè)倏偨Y(jié)一次。攻擊者控制參數(shù)并發(fā)送一個(gè)將產(chǎn)生兩次響應(yīng)的請(qǐng)求;這兩次響應(yīng)都由攻擊者組織,并以服務(wù)器為目標(biāo)。首個(gè)響應(yīng)旨在回應(yīng)將頁(yè)面轉(zhuǎn)化為德語(yǔ)的請(qǐng)求,而第二個(gè)響應(yīng)(到目前為止)還未經(jīng)解釋,它只是暫時(shí)掛起--因?yàn)樵擁憫?yīng)還沒有能夠映射的對(duì)應(yīng)請(qǐng)求。請(qǐng)記住,HTTP需要響應(yīng)(無(wú)論內(nèi)容代碼是什么),但它需要的是一個(gè)能對(duì)應(yīng)所有請(qǐng)求的響應(yīng)。因此掛起中的HTTP響應(yīng)是無(wú)法工作的。
現(xiàn)在請(qǐng)仔細(xì)閱讀…因?yàn)檫@部分正是大多數(shù)人(連我自己在很長(zhǎng)一段時(shí)間內(nèi)也是如此)沒有搞清楚的內(nèi)容。為了處理第二個(gè)掛起中的響應(yīng),攻擊者會(huì)迅速對(duì)服務(wù)器上的頁(yè)面發(fā)送一條有效的公開訪問(wèn)(通常是這樣)請(qǐng)求,比如說(shuō)branches.html。
這里假設(shè)他發(fā)送的請(qǐng)求為:
GET /branches.html HTTP/1.1
Host: www.abc.com
就在發(fā)出首個(gè)包含"可完全自定內(nèi)容"參數(shù)的請(qǐng)求之后,他會(huì)旋即發(fā)出上述第二條請(qǐng)求,而這也正是"Hello, you have been phished"字段的映射對(duì)象。兩條請(qǐng)求對(duì)應(yīng)兩次響應(yīng),大家明白了嗎?
哈哈,恐怕各位還是有些困惑。盡管大家可能已經(jīng)了解整個(gè)映射的發(fā)生過(guò)程,但仍然沒鬧明白這種攻擊是如何影響其他人的。畢竟,攻擊者的這一切行動(dòng)都發(fā)生在他自己的計(jì)算機(jī)上,所修改的請(qǐng)求也只限于他個(gè)人…也就是說(shuō),會(huì)受影響的只有他自己。說(shuō)實(shí)話,為什么攻擊者要對(duì)自身展開攻勢(shì)?這似乎毫無(wú)道理可言啊。不過(guò)我要指出的是,這對(duì)位于中間幀及緩存中的代理服務(wù)器或者某些設(shè)備而言,可以說(shuō)是接納請(qǐng)求及響應(yīng)的關(guān)鍵性一環(huán)。
攻擊者必須躲在代理服務(wù)器之后,并借助代理將他的請(qǐng)求發(fā)送到互聯(lián)網(wǎng)上的目標(biāo)服務(wù)器處。如果他想感染其它用戶,這些被害用戶也必須處于同樣的代理服務(wù)器之后。因此,讓我們?cè)賮?lái)總結(jié)一次(請(qǐng)保持耐性…)
a)攻擊者發(fā)送一條包含一個(gè)值及兩次響應(yīng)的請(qǐng)求,使用%0d%0a進(jìn)行分隔。在本文的例子中,請(qǐng)求的內(nèi)容如下:
http://www.abc.com/index.php?lang=german%0d%0aContent- Length:%200%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2041%0d%0aHello, you have been phished
b)該請(qǐng)求的發(fā)送目的地為www.abc.com…不過(guò)重要的是,它是通過(guò)中間代理服務(wù)器進(jìn)行傳遞的。因此現(xiàn)在在代理服務(wù)器上,第一個(gè)請(qǐng)求被映射在第一次響應(yīng)上,而第二次響應(yīng)則由于沒有能夠匹配的請(qǐng)求而處于掛起狀態(tài)。
c)在首個(gè)請(qǐng)求發(fā)出后,攻擊者會(huì)立即向目標(biāo)網(wǎng)站(同樣通過(guò)代理服務(wù)器)發(fā)出新請(qǐng)求(第二個(gè)請(qǐng)求),內(nèi)容如下:
GET /branches.html HTTP/1.1
Host: www.abc.com
d)代理服務(wù)器會(huì)在收到branches.html后,第一時(shí)間將其映射至第二次響應(yīng)中(即'You have been phished ')。因此接下來(lái)發(fā)往branches.html的請(qǐng)求將不再顯示銀行的分支機(jī)構(gòu)名單,而是指向惡意網(wǎng)頁(yè)。沒錯(cuò),對(duì)于每位訪問(wèn)者畢竟是如此,而不僅僅針對(duì)攻擊者。為什么會(huì)這樣?因?yàn)檫@正是緩存代理服務(wù)器的處理方式…常發(fā)請(qǐng)求緩存響應(yīng)。也就是說(shuō),如果某個(gè)發(fā)往branches.html的請(qǐng)求始終產(chǎn)生同一份關(guān)于銀行支行信息的靜態(tài)列表,那么代理服務(wù)器幾乎肯定會(huì)調(diào)用緩存對(duì)該請(qǐng)求進(jìn)行響應(yīng)。換言之,下一次指向branches.html的請(qǐng)求將自動(dòng)返回來(lái)自緩存的響應(yīng)。而在攻擊者的安排下,代理服務(wù)器的緩存內(nèi)容遭受感染,并被迫返回惡意響應(yīng)而非原本的靜態(tài)列表……這種狀況將持續(xù)下去直到緩存過(guò)期。
希望經(jīng)過(guò)上面的詳細(xì)介紹,大家會(huì)對(duì)HTTP響應(yīng)拆分有一個(gè)明確的概念。這里是文章的重中之重,所以不妨多讀幾遍。關(guān)鍵在于,攻擊者發(fā)出的第二條請(qǐng)求會(huì)迫使代理服務(wù)器遵從第二條請(qǐng)求對(duì)應(yīng)第二次響應(yīng)的映射模式。一旦理解了這一點(diǎn),整個(gè)概念應(yīng)該就比較清晰了。#p#
通過(guò)響應(yīng)拆分實(shí)現(xiàn)跨站點(diǎn)腳本
在這里需要指出,我并不打算詳細(xì)解釋跨站點(diǎn)腳本及其具體類型。網(wǎng)上可以輕易找到大量討論這方面話題的文章(我會(huì)在結(jié)尾處提供一些參考鏈接),通過(guò)閱讀大家完全能夠透徹理解這一概念。
現(xiàn)在我們已經(jīng)對(duì)響應(yīng)拆分相當(dāng)熟悉,那么接下來(lái)該從攻擊者的視角出發(fā),以獲得進(jìn)一步的收獲。我們能夠通過(guò)響應(yīng)拆分在目標(biāo)計(jì)算機(jī)上運(yùn)行JavaScript,并嘗試且最終獲取對(duì)其瀏覽器的完全控制權(quán)嗎?答案是肯定的,只要對(duì)我們此前所給出的例子進(jìn)行些許擴(kuò)展,這一目標(biāo)就可以順利實(shí)現(xiàn)。
大家應(yīng)該還記得,我們?cè)谇拔闹兴O(shè)計(jì)的第二輪惡意響應(yīng)只是利用簡(jiǎn)單的頁(yè)面告知用戶"你已然中招了"。而要實(shí)現(xiàn)更邪惡的目的,我們要編寫一些JavaScript代碼來(lái)代替原本的簡(jiǎn)單頁(yè)面。與僅僅能夠?qū)崿F(xiàn)顯示功能的頁(yè)面不同,JavaScript能夠切實(shí)運(yùn)行于用戶的瀏覽器之中。而攻擊者對(duì)于目標(biāo)用戶瀏覽器的控制能力完全取決于JavaScript代碼的內(nèi)容。因此,如果要對(duì)前文中所設(shè)計(jì)的例子加以擴(kuò)展,攻擊者會(huì)設(shè)計(jì)出如下的URL:
http://www.abc.com/index.php?lang=german%0d%0aContent- Length:%200%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent- Length:%20%0d%0aalert('在你的計(jì)算機(jī)上運(yùn)行JavaScript')
然后他會(huì)像以前那樣向branches.html發(fā)送請(qǐng)求,該包含惡意JavaScript內(nèi)容的請(qǐng)求自然會(huì)被映射至第二輪響應(yīng)中。代理緩存將同原先一樣受到感染,而使用著同一款代理服務(wù)器的其他用戶在訪問(wèn)branches.html時(shí),該JavaScript代碼就會(huì)侵入他的計(jì)算機(jī)。
如果目標(biāo)站點(diǎn)在XSS方面存在漏洞,那么我們完全可以用同樣的邏輯對(duì)其展開攻擊。只是在這種情況下,漏洞參數(shù)才是腳本的主體,因此我們需要利用其替換掉前一個(gè)例子中的JavaScript部分。
在我所舉的例子中,JavaScript內(nèi)容非常直觀,結(jié)果也只是彈出一個(gè)小小的警告框。事實(shí)上JavaScript完全可以編寫得更為復(fù)雜,并使攻擊者獲得可以完全掌控目標(biāo)用戶瀏覽器并最終控制計(jì)算機(jī)的能力。一款名為BeeF的開發(fā)框架能夠?yàn)楣粽邘蜕洗竺?,只需編寫一小段JavaScript再將其導(dǎo)入BeeF控制器,受害者的計(jì)算機(jī)就在劫難逃了。
通過(guò)響應(yīng)拆分實(shí)現(xiàn)跨站點(diǎn)請(qǐng)求偽造
與前面一樣,我不打算在這里詳述CSRF攻擊的來(lái)龍去脈。大家還是從文末的參考資料匯總那里去獲得相關(guān)的細(xì)節(jié)信息吧。簡(jiǎn)單來(lái)說(shuō),CSRF攻擊的受害者會(huì)在不知情的狀態(tài)下執(zhí)行某些"隱性"操作。需要強(qiáng)調(diào)的是,這些操作基本上都是受害者打死也不想去執(zhí)行的類型。
作為CSRF攻擊發(fā)生的先決條件,受害人需要首先登錄到操作執(zhí)行的站點(diǎn)上。因此如果攻擊者打算誘導(dǎo)受害者執(zhí)行的操作是"刪除我的谷歌個(gè)人資料",那么用戶必須要先登錄到相應(yīng)的谷歌系統(tǒng)中,操作才能順利執(zhí)行。另外,攻擊者必須能夠?qū)Π▍?shù)值在內(nèi)的確切結(jié)構(gòu)進(jìn)行預(yù)測(cè)。以銀行轉(zhuǎn)賬操作為例,具體數(shù)額必須準(zhǔn)確有效,如:GET /transfer/php?acc1=1000&acc2=2000&amt=900。這樣只要用戶在登錄至www.abc.com之后發(fā)出類似的GET指令,由acc1指向acc2的轉(zhuǎn)賬行為將自動(dòng)執(zhí)行。
在CSRF攻擊當(dāng)中,攻擊者總會(huì)使出某種花招誘導(dǎo)用戶點(diǎn)擊鏈接,或是采取社交角度的心理戰(zhàn)術(shù)、或是讓用戶訪問(wèn)某個(gè)處于攻擊者控制之下的頁(yè)面;總之盡管理論上用戶是自主發(fā)出的請(qǐng)求,但實(shí)際上后臺(tái)到底執(zhí)行了什么內(nèi)容受害者并不知情。
現(xiàn)在,讓我們回到響應(yīng)拆分這一話題。大家應(yīng)該還記得攻擊者借助響應(yīng)拆分特性感染branches.html頁(yè)面,并向其中注入JavaScript惡意內(nèi)容以嘗試在用戶的瀏覽器上運(yùn)行腳本的做法吧。而在CSRF攻擊中,我們需要確保行為(例如前面提到的轉(zhuǎn)賬操作URL)在用戶訪問(wèn)被感染頁(yè)面時(shí)能夠自動(dòng)執(zhí)行。換句話說(shuō),branches.html中會(huì)包含一個(gè)小型鏡像,并隨同該頁(yè)面一同被載入。該鏡像的<IMG SRC>標(biāo)簽將向www.abc.com網(wǎng)站的服務(wù)器發(fā)送內(nèi)容為/transfer/php?acc1=1000&acc2=2000&amt=900的請(qǐng)求。
因此在執(zhí)行響應(yīng)拆分攻擊時(shí),整個(gè)惡意URL的內(nèi)容如下所示:
http://www.abc.com/index.php?lang=german%0d%0aContent- Length:%200%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent- Length:%20%0d%0a< / body>< / html>
最終的結(jié)果是,每當(dāng)用戶通過(guò)代理訪問(wèn)受感染的頁(yè)面(即branches.html),且在另一個(gè)瀏覽器選項(xiàng)卡中登錄了www.abc.com站點(diǎn),那么后臺(tái)即會(huì)順利地將款項(xiàng)轉(zhuǎn)匯至攻擊者指定的賬戶中。
示例代碼:
現(xiàn)在讓我們快速瀏覽一遍PHP中那些存在響應(yīng)拆分漏洞的代碼類型。對(duì)于初學(xué)者來(lái)說(shuō),我們以一個(gè)小型HTML文件為例(名稱為respsplit1.html),其中包含了允許用戶選擇語(yǔ)言種類的下拉菜單。具體內(nèi)容如下:
- <HTML>
- <BODY>
- <FORM NAME="form" action="respsplit1.php" method="GET">
- <select name="lang">
- <option value="EN">English</option>
- <option value="GER">German</option>
- </select>
- <INPUT TYPE="submit" name="Submit" value=Submit></INPUT>
- </FORM>
- </BODY>
- </HTML>
選擇想要的語(yǔ)言類型后,大家當(dāng)然會(huì)點(diǎn)擊提交按鈕,而這一輸入行為將被提交至名為respsplit1.php的PHP文件處。上述所有代碼的功能是截獲我們的輸入內(nèi)容,并利用其建立一個(gè)用于重新指向的URL,再將其發(fā)送至302重新指向響應(yīng)處。Respsplit1.php文件的內(nèi)容如下所示:
- <?php
- $lang = $_GET['lang']
- header("Location: http://localhost/respsplit2.php?lang=$lang");
- ?>
在瀏覽器中打開該HTML文件并將其置于Burp或是任何其它類型的代理編輯器中。這時(shí)請(qǐng)留意我們?cè)陬^一個(gè)頁(yè)面點(diǎn)擊提交后所產(chǎn)生的響應(yīng)。大家會(huì)清楚地發(fā)現(xiàn),自己在下拉菜單中選擇的項(xiàng)目實(shí)際上是本機(jī)302響應(yīng)中的響應(yīng)頭。因此如果各位想對(duì)此進(jìn)行修改,那就必須得在請(qǐng)求到達(dá)服務(wù)器端之前,對(duì)lang參數(shù)的值利用惡意字符串進(jìn)行編輯(也就是達(dá)到我們前面所說(shuō)的一項(xiàng)請(qǐng)求兩次響應(yīng))。
respsplit2.php所做的僅僅是將大家所選擇的語(yǔ)言種類顯示出來(lái),除此無(wú)它。
- <?php
- $a=$_GET['lang'];
- if (strcmp($a,'EN') == 0)
- echo "Language selected is English";
- elseif (strcmp($a,'GER') == 0)
- echo "Language selected is German";
- else
- echo "No valid language selected ";
- ?>
現(xiàn)在當(dāng)我打算進(jìn)行上試測(cè)試時(shí),我自己的PHP框架會(huì)從響應(yīng)頭中把%0d%0a字符串除去,這種默認(rèn)設(shè)置實(shí)際上起到了保護(hù)作用。不過(guò)如果大家所使用的是版本較老的框架,那么默認(rèn)設(shè)置將不會(huì)實(shí)施保護(hù),進(jìn)而導(dǎo)致代碼極易在CRLF處發(fā)生問(wèn)題。這里所提到的過(guò)濾功能如下圖所示:
- <?php
- $pattern1 = "/\%0d/";
- $pattern2 = "/\%0a/";
- $lang = $_GET['lang'];
- $r = preg_match($pattern1 , $lang);
- $s = preg_match($pattern2 , $lang);
- if (($r > 0) || ($s > 0)){
- echo 'Carriage Return found in user input';
- echo "<BR>";
- }
- else {
- header("Location: http://localhost/respsplit2.php?lang=$lang");
- }
- ?>
我們可以自主編寫更為高效的過(guò)濾器,例如將內(nèi)容只包含字母及數(shù)字的項(xiàng)目列入白名單,并直接屏蔽掉其它一切類型;但這僅僅是防御性代碼的一種使用范例。如果大家忘記編寫這類過(guò)濾器,那么就等于將自己的命運(yùn)完全交付給所使用的框架本身。如果各位與我使用的框架相似(Ubuntu 10.04內(nèi)的APT庫(kù))還好,因?yàn)槠渲袃?nèi)置了保護(hù)機(jī)制…否則就等著為此而付出慘重代價(jià)吧。
目前已經(jīng)被發(fā)現(xiàn)了為數(shù)不少的響應(yīng)拆分類漏洞。我在文末的參考鏈接中提供了詳細(xì)的清單。#p#
應(yīng)對(duì)措施:
◆響應(yīng)拆分攻擊:使用服務(wù)器端驗(yàn)證機(jī)制,并禁止全部用戶在任何與響應(yīng)頭有關(guān)的輸入請(qǐng)求中使用回車換行符(即CRLF)。
◆XSS攻擊:引入白名單、黑名單過(guò)濾機(jī)制(輸入驗(yàn)證)以及Escape HTML(輸出驗(yàn)證)。
◆CSRF攻擊:使用AntiCsrf語(yǔ)言符號(hào),這樣攻擊者就無(wú)法準(zhǔn)確預(yù)測(cè)目標(biāo)結(jié)構(gòu),自然也不能對(duì)其加以偽造了。
結(jié)論:
響應(yīng)拆分式攻擊只能在多個(gè)用戶使用相同代理服務(wù)器連接不同網(wǎng)站時(shí)奏效。代理服務(wù)器的緩存一旦受到感染,用戶就會(huì)在從代理服務(wù)器緩存中讀取該頁(yè)面時(shí)遭到攻擊。不過(guò)請(qǐng)注意,并非所有代理服務(wù)器都在響應(yīng)拆分方面存在漏洞,雖然這算是句題外話。如果大家有興趣進(jìn)一步了解這種攻擊,我強(qiáng)烈建議大家閱讀由Amit Klein撰寫的精彩論文(詳見參考文獻(xiàn)1)。
參考文獻(xiàn):
◆響應(yīng)拆分攻擊- http://packetstormsecurity.org/papers/general/whitepaper_httpresponse.pdf
◆XSS攻擊 - http://www.technicalinfo.net/papers/CSS.html
◆XSS攻擊應(yīng)對(duì)措施-https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet
◆CSRF攻擊 - https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29
◆CSRF攻擊應(yīng)對(duì)措施- https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet
◆B瀏覽器開發(fā)框架 - http://beefproject.com/
◆學(xué)習(xí)PHP(教程)- http://www.w3schools.com/php/
◆PHP函數(shù) - http://php.net/quickref.php
◆已曝光的響應(yīng)拆分漏洞匯總清單- http://cwe.mitre.org/data/definitions/113.html
原文鏈接:http://resources.infosecinstitute.com/http-response-splitting-attack/
【51CTO.com獨(dú)家特稿,非經(jīng)授權(quán)謝絕轉(zhuǎn)載!合作媒體轉(zhuǎn)載請(qǐng)注明原文出處及出處!】