Compare commits

...

35 Commits

Author SHA1 Message Date
carlospolop
ea9b930fdb fix capabilities module 2025-05-18 14:33:02 +02:00
SirBroccoli
dae0f7a533 Merge pull request #468 from ThatTotallyRealMyth/ThatTotallyRealMyth-4_capEdit-1
Update 4_Capabilities.sh: Fix capability decoding to prevent shell breaking output from shell/process capabiltiy checking.
2025-05-18 14:19:28 +02:00
carlospolop
3a317cc5c4 fix ec2 2025-05-18 14:17:15 +02:00
ThatTotallyRealMyth
01bf3a4ef8 Update 4_Capabilities.sh: Fix capability decoding to prevent sequence number output
Testing confirmed that certain capability values (specifically ffffffffffffffff) cause memory allocation errors in capsh:
"xrealloc: cannot allocate 716488832 bytes (57344 bytes allocated)"

These memory errors were being propagated into the output, causing the long sequence of numbers. The fix prevents these errors from affecting the script's output.
2025-05-18 16:05:01 +10:00
carlospolop
ef28ef7a33 fix linpeas not getting EC2 metadata 2025-05-18 04:58:22 +02:00
carlospolop
58c107df40 fix kill? 2025-05-18 04:46:19 +02:00
carlospolop
63c090059b kill frozen external binaries 2025-05-18 01:20:32 +02:00
carlospolop
4c16f72ae2 fix 2025-05-17 16:09:36 +02:00
carlospolop
85684b39ad add timeout 120 when executing external binary 2025-05-17 16:06:35 +02:00
SirBroccoli
c0b171a5c1 Update peass.rb 2025-05-16 22:25:10 +02:00
SirBroccoli
ddc2d95cb4 Update peass.rb 2025-05-16 15:53:43 +02:00
Carlos Polop
97ae1d2e3b Merge branch 'master' of github.com:peass-ng/PEASS-ng 2025-04-24 04:20:22 +02:00
Carlos Polop
3b6f0a5bdc f 2025-04-24 04:20:19 +02:00
SirBroccoli
7008652029 Merge pull request #462 from jahway603/jahway603-patch-1
Minor URL fix
2025-03-30 19:18:52 +02:00
SirBroccoli
e5239f8c58 Merge pull request #461 from Signum21/master
Handle path access denied
2025-03-30 19:18:34 +02:00
SirBroccoli
b2c03246d2 Merge pull request #459 from gildasio/master
Set grep to show filename that contains passwords
2025-03-30 19:18:13 +02:00
SirBroccoli
f0686d491b Merge pull request #464 from spkal01/master
Rework PEASS url logic for the metasploit module
2025-03-29 21:56:35 +01:00
spkal01
99e8eb7813 Rework PEASS url logic for the metasploit module 2025-03-29 21:45:58 +02:00
Carlos Polop
46193aa0d5 fix 2025-03-20 05:13:54 +01:00
Carlos Polop
62022abc47 impr winpeas 2025-03-20 05:02:34 +01:00
jahway603
d63e737b63 Minor URL fix 2025-03-18 12:33:50 -04:00
Signum21
0b041ad694 Handle path access denied
The program crashes when trying to access a path that is not allowed.
An exampe of this can be found on the latest HackTheBox machine (TheFrizz) where the starting user can't access the path C:\Users
2025-03-16 05:43:48 +01:00
Gildasio Junior
8ea67f3cc2 Set grep to show filename that contains passwords
This way one can identify which file contains the relevant information,
eg:

/var/log/responder/Poisoners-Session.log:2025-02-09 21:12:12,701 - [*] Skipping previously captured cleartext password for donald
/var/log/responder/Responder-Session.log:11/02/2025 12:33:11 PM - [HTTP] Basic Password : bambam
/var/log/responder/Responder-Session.log:11/02/2025 12:36:12 PM - [HTTP] Basic Password : estrella
2025-02-28 19:54:44 -03:00
Carlos Polop
ce5cb1ad9c fix 2025-02-24 00:21:09 +01:00
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
SirBroccoli
41e00d5618 Merge pull request #458 from DidierA/macos_echo
Fix echo -n on macOS
2025-02-02 13:49:16 +01:00
SirBroccoli
536913e7f0 Merge pull request #457 from gcorrall/fix_28_files_with_passwords
Fix 28_Files_with_passwords.sh
2025-02-02 13:48:14 +01:00
DidierA
4d771fb1f6 Fix echo -n on macOS 2025-01-31 16:45:24 +01:00
Gary Corrall
4964033d44 Fix 28_Files_with_passwords.sh 2025-01-29 16:33:54 +00:00
23 changed files with 318 additions and 91 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

@@ -8,7 +8,7 @@
# Functions Used: check_aws_ec2, exec_with_jq, print_2title, print_3title
# Global Variables: $is_aws_ec2
# Initial Functions: check_aws_ec2
# Generated Global Variables: $aws_req, $HEADER, $URL, $mac, $role
# Generated Global Variables: $aws_req, $HEADER, $URL, $mac, $role, $TOKEN, $TOKEN_HEADER, $TOKEN_TTL
# Fat linpeas: 0
# Small linpeas: 1
@@ -16,14 +16,20 @@
if [ "$is_aws_ec2" = "Yes" ]; then
print_2title "AWS EC2 Enumeration"
HEADER="X-aws-ec2-metadata-token: "
TOKEN=""
TOKEN_HEADER="X-aws-ec2-metadata-token"
TOKEN_TTL="X-aws-ec2-metadata-token-ttl-seconds: 21600"
URL="http://169.254.169.254/latest/meta-data"
aws_req=""
if [ "$(command -v curl || echo -n '')" ]; then
aws_req="curl -s -f -L -H '$HEADER'"
# Get token for IMDSv2
TOKEN=$(curl -s -f -X PUT "http://169.254.169.254/latest/api/token" -H "$TOKEN_TTL" 2>/dev/null)
aws_req="curl -s -f -L -H '$TOKEN_HEADER: $TOKEN'"
elif [ "$(command -v wget || echo -n '')" ]; then
aws_req="wget -q -O - -H '$HEADER'"
# Get token for IMDSv2
TOKEN=$(wget -q -O - --method=PUT --header="$TOKEN_TTL" "http://169.254.169.254/latest/api/token" 2>/dev/null)
aws_req="wget -q -O - --header '$TOKEN_HEADER: $TOKEN'"
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

@@ -17,27 +17,55 @@ if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Capabilities"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#capabilities"
if [ "$(command -v capsh || echo -n '')" ]; then
print_3title "Current shell capabilities"
cat "/proc/$$/status" | grep Cap | while read -r cap_line; do
cap_name=$(echo "$cap_line" | awk '{print $1}')
cap_value=$(echo "$cap_line" | awk '{print $2}')
if [ "$cap_name" = "CapEff:" ]; then
echo "$cap_name $(capsh --decode=0x"$cap_value" | sed -${E} "s,$capsB,${SED_RED_YELLOW},")"
# Add validation check for cap_value
# For more POSIX-compliant formatting, the following could be used instead:
# if echo "$cap_value" | grep -E '^[0-9a-fA-F]+$' > /dev/null 2>&1; then
if [[ "$cap_value" =~ ^[0-9a-fA-F]+$ ]]; then
# Memory errors can occur with certain values (e.g., ffffffffffffffff)
# so we redirect stderr to prevent error propagation
echo "$cap_name $(capsh --decode=0x"$cap_value" 2>/dev/null | sed -${E} "s,$capsB,${SED_RED_YELLOW},")"
else
echo "$cap_name [Invalid capability format]"
fi
else
echo "$cap_name $(capsh --decode=0x"$cap_value" | sed -${E} "s,$capsB,${SED_RED},")"
# Add validation check for cap_value
if [[ "$cap_value" =~ ^[0-9a-fA-F]+$ ]]; then
# Memory errors can occur with certain values (e.g., ffffffffffffffff)
# so we redirect stderr to prevent error propagation
echo "$cap_name $(capsh --decode=0x"$cap_value" 2>/dev/null | sed -${E} "s,$capsB,${SED_RED},")"
else
echo "$cap_name [Invalid capability format]"
fi
fi
done
echo ""
print_info "Parent process capabilities"
cat "/proc/$PPID/status" | grep Cap | while read -r cap_line; do
cap_name=$(echo "$cap_line" | awk '{print $1}')
cap_value=$(echo "$cap_line" | awk '{print $2}')
if [ "$cap_name" = "CapEff:" ]; then
echo "$cap_name $(capsh --decode=0x"$cap_value" | sed -${E} "s,$capsB,${SED_RED_YELLOW},")"
# Add validation check for cap_value
if [[ "$cap_value" =~ ^[0-9a-fA-F]+$ ]]; then
# Memory errors can occur with certain values (e.g., ffffffffffffffff)
# so we redirect stderr to prevent error propagation
echo "$cap_name $(capsh --decode=0x"$cap_value" 2>/dev/null | sed -${E} "s,$capsB,${SED_RED_YELLOW},")"
else
echo "$cap_name [Invalid capability format]"
fi
else
echo "$cap_name $(capsh --decode=0x"$cap_value" | sed -${E} "s,$capsB,${SED_RED},")"
# Add validation check for cap_value
if [[ "$cap_value" =~ ^[0-9a-fA-F]+$ ]]; then
# Memory errors can occur with certain values (e.g., ffffffffffffffff)
# so we redirect stderr to prevent error propagation
echo "$cap_name $(capsh --decode=0x"$cap_value" 2>/dev/null | sed -${E} "s,$capsB,${SED_RED},")"
else
echo "$cap_name [Invalid capability format]"
fi
fi
done
echo ""
@@ -69,10 +97,9 @@ if ! [ "$SEARCH_IN_FOLDER" ]; then
if ! [ "$capsVB_vuln" ]; then
echo "$cb" | sed -${E} "s,$capsB,${SED_RED},"
fi
if ! [ "$IAMROOT" ] && [ -w "$(echo $cb | cut -d" " -f1)" ]; then
echo "$cb is writable" | sed -${E} "s,.*,${SED_RED},"
fi
done
echo ""
fi
fi

View File

@@ -15,6 +15,6 @@
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Searching passwords inside logs (limit 70)"
(find /var/log/ /var/logs/ /private/var/log -type f -exec grep -R -i "pwd\|passw" "{}" \;) 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | grep -v "File does not exist:\|modules-config/config-set-passwords\|config-set-passwords already ran\|script not found or unable to stat:\|\"GET /.*\" 404" | head -n 70 | sed -${E} "s,pwd|passw,${SED_RED},"
(find /var/log/ /var/logs/ /private/var/log -type f -exec grep -R -H -i "pwd\|passw" "{}" \;) 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | grep -v "File does not exist:\|modules-config/config-set-passwords\|config-set-passwords already ran\|script not found or unable to stat:\|\"GET /.*\" 404" | head -n 70 | sed -${E} "s,pwd|passw,${SED_RED},"
echo ""
fi
fi

View File

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

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

@@ -2,30 +2,53 @@
# ID: execBin
# Author: Carlos Polop
# Last Update: 22-08-2023
# Description: Write and exected an embedded binary
# Description: Write and execute an embedded binary
# License: GNU GPL
# Version: 1.0
# Functions Used: print_3title, print_info
# Global Variables: $Wfolder
# Initial Functions:
# Generated Global Variables: $TOOL_NAME, $TOOL_LINK, $B64_BIN, $PARAMS
# Generated Global Variables: $TOOL_NAME, $TOOL_LINK, $B64_BIN, $PARAMS, $TMP_BIN, $cmdpid, $watcher, $rc
# Fat linpeas: 0
# Small linpeas: 1
execBin(){
TOOL_NAME=$1
TOOL_LINK=$2
B64_BIN=$3
PARAMS=$4
if [ "$B64_BIN" ]; then
echo ""
print_3title "Running $TOOL_NAME"
print_info "$TOOL_LINK"
echo "$B64_BIN" | base64 -d > $Wfolder/bin
chmod +x $Wfolder/bin
eval "$Wfolder/bin $PARAMS"
rm -f $Wfolder/bin
echo ""
execBin() {
TOOL_NAME=$1 # Display name
TOOL_LINK=$2 # Reference URL
B64_BIN=$3 # base64encoded executable
PARAMS=$4 # Arguments to the tool
[ -z "$B64_BIN" ] && return 0 # nothing to do
echo
print_3title "Running $TOOL_NAME"
print_info "$TOOL_LINK"
TMP_BIN=$(mktemp "${Wfolder:-/tmp}/bin.XXXXXX") || { echo "mktemp failed"; return 1; }
printf '%s' "$B64_BIN" | base64 -d > "$TMP_BIN" || { echo "decode failed"; rm -f "$TMP_BIN"; return 1; }
chmod +x "$TMP_BIN"
# ---------------- 120second wallclock timeout ----------------
if command -v timeout >/dev/null 2>&1; then # GNU/BSD timeout
timeout --preserve-status -s 9 120 "$TMP_BIN" $PARAMS
elif command -v gtimeout >/dev/null 2>&1; then # Homebrew coreutils (macOS)
gtimeout --preserve-status -s 9 120 "$TMP_BIN" $PARAMS
else # POSIX fallback
(
"$TMP_BIN" $PARAMS & # run in background
cmdpid=$!
( sleep 120 && kill -9 "$cmdpid" 2>/dev/null) &
watcher=$!
wait "$cmdpid"
rc=$?
kill -9 "$watcher" 2>/dev/null
exit $rc
)
fi
rc=$?
rm -f "$TMP_BIN"
echo
return $rc
}

View File

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

File diff suppressed because one or more lines are too long

View File

@@ -37,9 +37,10 @@ Basic options:
---- --------------- -------- -----------
PARAMETERS no Parameters to pass to the script
PASSWORD um1xipfws17nkw1bi1ma3bh7tzt4mo3e no Password to encrypt and obfuscate the script (randomly generated). The length must be 32B. If no password is set, only base64 will be used
.
PEASS_URL https://raw.githubusercontent.com/peass-ng/PEASS-ng/master/winPEAS/wi yes Path to the PEASS script. Accepted: http(s):// URL or absolute local path. Linpeas: https://raw.githubusercontent.com/peass-ng/PEASS-ng
nPEASexe/binaries/Obfuscated%20Releases/winPEASany.exe /master/linPEAS/linpeas.sh
WINPEASS true yes Use PEASS for Windows or PEASS for linux. Default is windows change to false for linux.
CUSTOM_URL no Path to the PEASS script. Accepted: http(s):// URL or absolute local path.
SESSION yes The session to run this module on.
SRVHOST no Set your metasploit instance IP if you want to download the PEASS script from here via http(s) instead of uploading it.
SRVPORT 443 no Port to download the PEASS script from using http(s) (only used if SRVHOST)

View File

@@ -1,3 +1,30 @@
# Copyright (c) 2025, PEASS-ng owners
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of PEASS-ng owners nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
@@ -37,7 +64,8 @@ class MetasploitModule < Msf::Post
))
register_options(
[
OptString.new('PEASS_URL', [true, 'Path to the PEASS script. Accepted: http(s):// URL or absolute local path. Linpeas: https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh', "https://github.com/peass-ng/PEASS-ng/releases/latest/download/winPEASany_ofs.exe"]),
OptString.new('WINPEASS', [true, 'Which PEASS script to use. Use True for WinPeass and false for LinPEASS', true]),
OptString.new('CUSTOM_URL', [false, 'URL to download the PEASS script from (if not using the default one). Accepts http(s) or absolute path. Overrides the WINPEASS variable', '']),
OptString.new('PASSWORD', [false, 'Password to encrypt and obfuscate the script (randomly generated). The length must be 32B. If no password is set, only base64 will be used.', rand(36**32).to_s(36)]),
OptString.new('TEMP_DIR', [false, 'Path to upload the obfuscated PEASS script inside the compromised machine. By default "C:\Windows\System32\spool\drivers\color" is used in Windows and "/tmp" in Unix.', '']),
OptString.new('PARAMETERS', [false, 'Parameters to pass to the script', nil]),
@@ -237,8 +265,14 @@ class MetasploitModule < Msf::Post
def load_peass
# Load the PEASS script from a local file or from Internet
peass_script = ""
url_peass = datastore['PEASS_URL']
url_peass = ""
# If no URL is set, use the default one
if datastore['CUSTOM_URL'] != ""
url_peass = datastore['CUSTOM_URL']
else
url_peass = datastore['WINPEASS'] ? "https://github.com/peass-ng/PEASS-ng/releases/latest/download/winPEASany_ofs.exe" : "https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh"
end
# If URL is set, check if it is a valid URL or local file
if url_peass.include?("http://") || url_peass.include?("https://")
target = URI.parse url_peass
raise 'Invalid URL' unless target.scheme =~ /https?/

0
parsers/__init__.py Normal file
View File

View File

@@ -144,7 +144,12 @@ def parse_line(line: str):
})
def main():
def parse_peass(outputpath: str, jsonpath: str = ""):
global OUTPUT_PATH, JSON_PATH
OUTPUT_PATH = outputpath
JSON_PATH = jsonpath
for line in open(OUTPUT_PATH, 'r', encoding="utf8").readlines():
line = line.strip()
if not line or not clean_colors(line): #Remove empty lines or lines just with colors hex
@@ -152,17 +157,21 @@ def main():
parse_line(line)
with open(JSON_PATH, "w") as f:
json.dump(FINAL_JSON, f)
if JSON_PATH:
with open(JSON_PATH, "w") as f:
json.dump(FINAL_JSON, f)
else:
return FINAL_JSON
# Start execution
if __name__ == "__main__":
try:
OUTPUT_PATH = sys.argv[1]
JSON_PATH = sys.argv[2]
outputpath = sys.argv[1]
jsonpath = sys.argv[2]
parse_peass(outputpath, jsonpath)
except IndexError as err:
print("Error: Please pass the peas.out file and the path to save the json\npeas2json.py <output_file> <json_file.json>")
sys.exit(1)
main()

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

@@ -594,7 +594,7 @@ namespace winPEAS.Checks
try
{
Beaprint.MainPrint("Checking KrbRelayUp");
Beaprint.LinkPrint("https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#krbrelayupp");
Beaprint.LinkPrint("https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#krbrelayup");
if (Checks.CurrentAdDomainName.Length > 0)
{

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

@@ -184,9 +184,17 @@ namespace winPEAS.Helpers
//////////////////////
public static List<string> ListFolder(String path)
{
string root = @Path.GetPathRoot(Environment.SystemDirectory) + path;
var dirs = from dir in Directory.EnumerateDirectories(root) select dir;
return dirs.ToList();
try
{
string root = @Path.GetPathRoot(Environment.SystemDirectory) + path;
var dirs = from dir in Directory.EnumerateDirectories(root) select dir;
return dirs.ToList();
}
catch(Exception ex)
{
//Path can't be accessed
return new List<string>();
}
}
internal static byte[] CombineArrays(byte[] first, byte[] second)

View File

@@ -1,20 +1,53 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System;
using System.Diagnostics;
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";
public static bool DoesProcessExist(string processName)
{
// Return false if the process name is null or empty
if (string.IsNullOrEmpty(processName))
{
return false;
}
// Retrieve all processes matching the specified name
Process[] processes = Process.GetProcessesByName(processName);
return processes.Length > 0;
}
// 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 +58,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 +97,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()
{
@@ -70,10 +137,27 @@ namespace winPEAS.Info.CloudInfo
}
}
string hwsRun = DoesProcessExist("HybridWorkerService") ? "Yes" : "No";
_endpointDataList.Add(new EndpointData()
{
EndpointName = "HybridWorkerService.exe Running",
Data = hwsRun,
IsAttackVector = true
});
string OSRun = DoesProcessExist("Orchestrator.Sandbox") ? "Yes" : "No";
_endpointDataList.Add(new EndpointData()
{
EndpointName = "Orchestrator.Sandbox.exe Running",
Data = OSRun,
IsAttackVector = true
});
_endpointData.Add("General", _endpointDataList);
}
catch (Exception ex)
{
// **Exception handling (e.g., logging) can be added here**
}
}
@@ -82,7 +166,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;
}
}
}
}