譯:h4d35
預估稿費:120RMB
投稿方式:發送郵件至linwei#360.cn,或登陸網頁版在線投稿
前言
本篇文章主要介紹了在一次漏洞懸賞項目中如何利用配置錯誤挖到一個認證繞過漏洞。
從JS文件中發現認證繞過漏洞
本文內容源自一個私有漏洞賞金計劃。在這個漏洞計劃中,接受的漏洞范圍限于目標網站少數幾個公開的功能?;谇捌诎l現的問題(當我被邀請進這個計劃時,其他人一共提交了5個漏洞),似乎很難再挖到新的漏洞。同時,在賞金詳情中提到了這樣一句話:
如果你成功進入管理頁面,請立即報告,請勿在/admin中進行進一步的測試。
然而,目標網站中存在一個僅限于未認證和未經授權的用戶訪問的管理頁面。當我們訪問/login或/admin時會跳轉到https://bountysite.com/admin/dashboard?redirect=/。
對登錄頁面進行暴力破解也許是一個可行方案,但是我并不喜歡這種方式。看一下網頁源碼,沒什么有用的內容。于是我開始查看目標網站的結構。似乎目標網站的JS文件都放在少數幾個文件夾中,如/lib、/js、/application等。
有意思!
祭出神器BurpSuite,使用Intruder跑一下看能否在上述文件夾中找到任何可訪問的JS文件。將攻擊點設置為https://bountysite.com/admin/dashboard/js/*attack*.js。注意,不要忘記.js擴展名,這樣如果文件能夠訪問則返回200響應。確實有意思!因為我找到了一些可訪問的JS文件,其中一個文件是/login.js。
訪問這個JS文件https://bountysite.com/admin/dashboard/js/login.js,請求被重定向至管理頁面:) 。但是,我并沒有查看該文件的權限,只能看到部分接口信息。
但是我并沒有就此止步。這看起來很奇怪,為什么我訪問一個.js文件卻被作為HTML加載了呢?經過一番探查,終于發現,我能夠訪問管理頁面的原因在于*login*。是的,只要在請求路徑/dashboard/后的字符串中含有*login*(除了'login',這只會使我回到登錄頁面),請求就會跳轉到這個管理接口,但是卻沒有正確的授權。
我繼續對這個受限的管理接口進行了進一步的測試。再一次查看了頁面源碼,試著搞清楚網站結構。在這個管理接口中,有其他一些JS文件能夠幫助我理解管理員是如何執行操作的。一些管理操作需要一個有效的令牌。我試著使用從一個JS文件中泄露的令牌執行相關管理操作,然并卵。請求還是被重定向到了登錄頁面。我發現另外一個真實存在的路徑中也部署了一些內容,那就是/dashboard/controllers/*.php。
再一次祭出BurpSuite,使用Intruder檢查一下是否存在可以從此處訪問的其他任何路徑。第二次Intruder的結果是,我發現幾乎不存在其他無需授權即可訪問的路徑。這是基于服務器返回的500或者200響應得出的結論。
回到我在上一步偵察中了解到的網站結構中,我發現這些路徑是在/controllers中定義的,通過/dashboard/*here*/進行訪問。但是直接訪問這些路徑會跳轉到登錄頁面,似乎網站對Session檢查得還挺嚴格。此時我又累又困,幾乎都打算放棄了,但是我想最后再試一把。如果我利用與訪問管理頁面相同的方法去執行這些管理操作會怎么樣呢?很有趣,高潮來了:) 我能夠做到這一點。
通過訪問/dashboard/photography/loginx,請求跳轉到了Admin Photography頁面,并且擁有完整的權限!
從這里開始,我能夠執行和訪問/dashboard/*路徑下的所有操作和目錄,這些地方充滿了諸如SQL注入、XSS、文件上傳、公開重定向等漏洞。但是,我沒有繼續深入測試,因為這些都不在賞金計劃之內,根據計劃要求,一旦突破管理授權限制,應立即報告問題。此外,根據管理頁面顯示的調試錯誤信息可知,我之所以能夠訪問到管理頁面,是因為應用程序在/dashboard/controllers/*文件中存在錯誤配置。期望達到的效果是:只要請求鏈接中出現*login*,就重定向至主登錄頁面,然而,實際情況并不如人所愿。
后記
總之,這是有趣的一天!我拿到了這個漏洞賞金計劃最大金額的獎勵。
PHP中,要跳過HTTPS的驗證,可以使用cURL庫的CURLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST選項。這些選項允許你禁用對SSL證書的驗證。請注意,禁用SSL驗證可能會導致安全風險,因為它無法驗證服務器的身份。這種方法僅適用于測試環境或在你確信目標服務器是可信的情況下使用。
下面是一個示例代碼,展示了如何在PHP中模擬登錄時跳過HTTPS驗證:
<?php
// 登錄表單的URL
$login_url='https://example.com/login';
// 登錄后要抓取的頁面URL
$target_url='https://example.com/data';
// 登錄表單的用戶名和密碼
$username='your_username';
$password='your_password';
// 創建POST請求的數據
$post_data=array(
$username_field=> $username,
$password_field=> $password
);
// 初始化cURL會話
$ch=curl_init();
// 設置cURL選項
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 禁用SSL驗證
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// 發送登錄請求
$result=curl_exec($ch);
// 檢查是否登錄成功
if ($result !==false) {
// 登錄成功,繼續抓取登錄后的頁面數據
// 設置抓取目標頁面的URL
curl_setopt($ch, CURLOPT_URL, $target_url);
// 發送抓取請求
$data=curl_exec($ch);
// 處理抓取到的數據
if ($data !==false) {
// 在這里可以對抓取到的數據進行處理,例如解析HTML、提取信息等
echo $data;
} else {
// 抓取失敗
echo 'Failed to fetch data.';
}
} else {
// 登錄失敗
echo 'Login failed.';
}
// 關閉cURL會話
curl_close($ch);
?>
在代碼中,使用curl_setopt()函數來設置CURLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST選項為false,從而禁用了SSL驗證。
請注意,在實際生產環境中,強烈建議不要禁用SSL驗證,以確保通信的安全性。只有在開發和測試階段,或者在你確信目標服務器是可信的情況下,才應該考慮禁用SSL驗證.
讓我們看看如下這個web應用示例:
<html> <meta http?equiv="Content?Security?Policy" content="script?src 'nonce?...' 'unsafe?eval'"> <div id="template_target"></div> <script type="application/template" id="template"> Hello World! 1 + 1={{ 1 + 1 }} </script> Your search is <?php echo $_GET['q']; ?> <script nonce="..."> let template=document.getElementById('template'); template_target.innerHTML=template.innerText.replace(/{{(.?)}}/g,eval) </script> </html>
以上這段簡單的HTML代碼可能反映了現在滲透測試人員經常碰到的模板化Web應用。某些模板內容存儲在Web頁面中,然后再轉換為HTML代碼的一部分。上段代碼中含有id為template的HTML元素內容先被讀取,然后再執行{{}}括號內的內容,最后在某個單獨HTML元素中呈現出來。
Hello World! 1 + 1=2 Your search is ...........
其次,這段代碼應用程序會在頁面上打印URL中的參數值。這顯而易見是一個XSS漏洞,但由于CSP(內容安全策略)的存在,攻擊者并不能直接執行javascript。雖然直接運行javascript的路被堵死,但是我們可以找到其他繞過方法。
乍一看,貌似eval函數是一個可以利用的點,我們或許可以直接插入某些特制代碼,讓eval函數去執行。
為了實現這點,我們必須插入HTML元素中id為template的代碼。但在我們插入語句的前面已有id為template的HTML元素,而document.getElementById('template')只會去獲取第一個HTML元素,并不是我們所輸入的語句。
此刻,我們需要換個角度,看看瀏覽器是否能出現“意外”,以前就出現過很多瀏覽器的異常解析所導致的XSS攻擊。我把所有能使用的tag都收集起來進行測試,看看是否有驚喜。測試代碼如下:
<div id="template">First Tag</div> {% for tag in tag_list %} <{{tag}} id="template">{{tag}}</{{tag}}> {% endfor %} <script>console.log(document.getElementById('template'));</script>
當程序運行完畢時,我得到一個奇怪的結果:當輪到<html>時,頁面結構似乎發生了大變,此時已不再是<div>排在前面。讓我們看下當插入<html id="template">時的變化:
此時<html>已排在文檔頂部(在我所測試的所有瀏覽器中都是如此?。?,現在getElementById('template')將獲取<html>中的惡意數據,而不是<div>的內容。
只需簡單的?q=<html id="template">{{ alert("xss") }}</html>就可進行攻擊
最終,由于瀏覽器這個“莫名其妙”的特性,我們繞過了CSP成功進行了XSS攻擊!
本文由白帽匯整理并翻譯,不代表白帽匯任何觀點和立場
來源:https://nosec.org/home/detail/2860.html
原文:https://pagedout.institute/download/PagedOut_001_beta1.pdf(該PDF文檔的第62頁
白帽匯從事信息安全,專注于安全大數據、企業威脅情報。
公司產品:FOFA-網絡空間安全搜索引擎、FOEYE-網絡空間檢索系統、NOSEC-安全訊息平臺。
為您提供:網絡空間測繪、企業資產收集、企業威脅情報、應急響應服務。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。