Compare commits

...

7 Commits

Author SHA1 Message Date
Carlos Polop
30586c064f Merge branch 'master' of github.com:peass-ng/PEASS-ng 2025-02-23 23:58:45 +01:00
Carlos Polop
b82fc9ac39 improve winpeas azure env detection 2025-02-23 23:58:41 +01:00
SirBroccoli
54818756e4 Update README.md 2025-02-23 23:47:47 +01:00
Carlos Polop
516aafff27 fix wget 2025-02-16 17:36:01 +01:00
Carlos Polop
2b64ffc803 a 2025-02-16 16:15:19 +01:00
Carlos Polop
9f8563c751 improve linpeas 2025-02-15 18:14:56 +01:00
Carlos Polop
573acee58c improve azure linpeas 2025-02-15 17:43:42 +01:00
12 changed files with 125 additions and 39 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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},"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -346,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} |
|---------------------------------------------------------------------------------|

View File

@@ -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

View File

@@ -12,10 +12,10 @@ 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>
{

View File

@@ -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} |
|---------------------------------------------------------------------------------|

View File

@@ -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", $"identity/oauth2/token?api-version={CONTAINER_API_VERSION}&resource=https://management.azure.com/", true),
new Tuple<string, string, bool>("Graph token", $"identity/oauth2/token?api-version={CONTAINER_API_VERSION}&resource=https://graph.microsoft.com/", true),
new Tuple<string, string, bool>("Vault token", $"identity/oauth2/token?api-version={CONTAINER_API_VERSION}&resource=https://vault.azure.net/", true),
new Tuple<string, string, bool>("Storage token", $"identity/oauth2/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;
}
}
}
}