Compare commits

..

15 Commits

Author SHA1 Message Date
Carlos Polop
1d4b748cbc Fix builder GTFOBins parsing and protections metadata 2026-01-16 18:07:04 +01:00
Carlos Polop
69371f825e Fix GTFOBins list fetch for linpeas builder 2026-01-16 18:01:40 +01:00
Carlos Polop
72dbd9ef28 Fix PR tests Go setup and update linpeas parts 2026-01-16 17:56:34 +01:00
SirBroccoli
32e9bf657a Merge pull request #537 from Apursuit/fix-busybox-su-false-positive
Fix `su` bruteforce false positives on BusyBox systems (bbsuid)
2026-01-16 17:47:57 +01:00
SirBroccoli
d6bd661460 Merge pull request #525 from peass-ng/update_PEASS-linpeas-HTB__Era___IDORs__PHP_ssh2_exec_Wrap_20251129_184039
[LINPEAS] Add privilege escalation check: HTB Era – IDORs, PHP ssh2.exec Wrapper R...
2026-01-16 17:38:44 +01:00
SirBroccoli
ed6263a4b3 Merge pull request #524 from peass-ng/update_PEASS-linpeas-Metasploit_Wrap-Up_11_28_2025_20251129_012934
[LINPEAS] Add privilege escalation check: Metasploit Wrap-Up 11/28/2025
2026-01-16 17:34:21 +01:00
SirBroccoli
93bb3e1a64 Merge pull request #523 from peass-ng/update_PEASS-winpeas-Metasploit_Wrap-Up_11_14_2025_20251127_132610
[WINPEAS] Add privilege escalation check: Metasploit Wrap-Up 11/14/2025
2026-01-16 17:33:05 +01:00
SirBroccoli
bf9d474cd3 Merge pull request #546 from JohannesLks/fix/ssh-key-regex-false-positive
fix: SSH key regex false positive with ImageMagick mime.xml
2026-01-16 17:31:28 +01:00
SirBroccoli
f856f0b588 Merge pull request #547 from JohannesLks/fix/rdcman-credentials-highlight
fix: Highlight stored credentials in RDCMan.settings
2026-01-14 16:57:35 +01:00
JohannesLks
9d35195c56 fix: Highlight stored credentials in RDCMan.settings
RDCMan.settings files can contain encrypted credentials in
credentialsProfiles sections. This change enables content
inspection to highlight:

- credentialsProfiles (indicates stored credentials)
- password (encrypted password value)
- encryptedPassword (alternative password field)

Previously, just_list_file only showed the file path without
inspecting contents, causing stored credentials to be missed.
2026-01-01 22:53:40 +01:00
JohannesLks
4abbf37cc0 fix: SSH key regex false positive with ImageMagick mime.xml
The regex '-----BEGIN .* PRIVATE KEY.*-----' was matching
'-----BEGIN PGP PRIVATE KEY BLOCK-----' in /etc/ImageMagick-6/mime.xml,
causing a false positive for SSH keys.

Fixed by removing the trailing .* before ----- so the regex now requires
the key header to end directly with -----, which excludes PGP key
definitions that have 'BLOCK-----' at the end.

Tested key types still detected:
- RSA PRIVATE KEY
- EC PRIVATE KEY
- OPENSSH PRIVATE KEY
- DSA PRIVATE KEY
2026-01-01 14:07:08 +01:00
npc
10b087febf Fix su bruteforce false positives on BusyBox systems (bbsuid)
Fix su bruteforce false positives on BusyBox systems (bbsuid)
2025-12-15 20:23:52 +08:00
HackTricks News Bot
b188ac34b6 Add linpeas privilege escalation checks from: HTB: Era – IDORs, PHP ssh2.exec Wrapper RCE, and Custom-Signed Binary Privilege 2025-11-29 18:48:21 +00:00
HackTricks News Bot
e99e64cddf Add linpeas privilege escalation checks from: Metasploit Wrap-Up 11/28/2025 2025-11-29 01:41:29 +00:00
HackTricks News Bot
dd220af544 Add winpeas privilege escalation checks from: Metasploit Wrap-Up 11/14/2025 2025-11-27 13:44:39 +00:00
14 changed files with 331 additions and 162 deletions

View File

@@ -110,10 +110,9 @@ jobs:
ref: ${{ github.head_ref }}
# Setup go
- uses: actions/setup-go@v2
- uses: actions/setup-go@v6
with:
go-version: 1.17.0-rc1
stable: false
go-version: '1.23'
- run: go version
# Build linpeas

View File

@@ -3546,7 +3546,7 @@ search:
- name: "RDCMan.settings"
value:
just_list_file: True
bad_regex: "credentialsProfiles|password|encryptedPassword"
type: f
search_in:
- common

View File

@@ -102,6 +102,9 @@ It uses **/bin/sh** syntax, so can run in anything supporting `sh` (and the bina
By default, **linpeas won't write anything to disk and won't try to login as any other user using `su`**.
LinPEAS keeps expanding vendor-specific coverage; as of 29-Nov-2025 it warns when IGEL OS appliances still ship the SUID `setup`/`date` helpers that allow NetworkManager/systemd configuration hijacking (Metasploit module `linux/local/igel_network_priv_esc`).
By default linpeas takes around **4 mins** to complete, but It could take from **5 to 10 minutes** to execute all the checks using **-a** parameter *(Recommended option for CTFs)*:
- From less than 1 min to 2 mins to make almost all the checks
- Almost 1 min to search for possible passwords inside all the accesible files of the system

View File

@@ -30,7 +30,7 @@
# Functions Used: echo_not_found, print_2title, print_list, warn_exec
# Global Variables:
# Initial Functions:
# Generated Global Variables: $ASLR, $hypervisorflag, $detectedvirt
# Generated Global Variables: $ASLR, $hypervisorflag, $detectedvirt, $unpriv_userns_clone, $perf_event_paranoid, $mmap_min_addr, $ptrace_scope, $dmesg_restrict, $kptr_restrict, $unpriv_bpf_disabled
# Fat linpeas: 0
# Small linpeas: 0
@@ -80,10 +80,86 @@ print_list "Seccomp enabled? ............... "$NC
print_list "User namespace? ................ "$NC
if [ "$(cat /proc/self/uid_map 2>/dev/null)" ]; then echo "enabled" | sed "s,enabled,${SED_GREEN},"; else echo "disabled" | sed "s,disabled,${SED_RED},"; fi
#-- SY) Unprivileged user namespaces
print_list "unpriv_userns_clone? ........... "$NC
unpriv_userns_clone=$(cat /proc/sys/kernel/unprivileged_userns_clone 2>/dev/null)
if [ -z "$unpriv_userns_clone" ]; then
echo_not_found "/proc/sys/kernel/unprivileged_userns_clone"
else
if [ "$unpriv_userns_clone" -eq 0 ]; then echo "0" | sed -${E} "s,0,${SED_GREEN},"; else echo "$unpriv_userns_clone" | sed -${E} "s,.*,${SED_RED},g"; fi
fi
#-- SY) Unprivileged eBPF
print_list "unpriv_bpf_disabled? ........... "$NC
unpriv_bpf_disabled=$(cat /proc/sys/kernel/unprivileged_bpf_disabled 2>/dev/null)
if [ -z "$unpriv_bpf_disabled" ]; then
echo_not_found "/proc/sys/kernel/unprivileged_bpf_disabled"
else
if [ "$unpriv_bpf_disabled" -eq 0 ]; then echo "0" | sed -${E} "s,0,${SED_RED},"; else echo "$unpriv_bpf_disabled" | sed -${E} "s,.*,${SED_GREEN},g"; fi
fi
#-- SY) cgroup2
print_list "Cgroup2 enabled? ............... "$NC
([ "$(grep cgroup2 /proc/filesystems 2>/dev/null)" ] && echo "enabled" || echo "disabled") | sed "s,disabled,${SED_RED}," | sed "s,enabled,${SED_GREEN},"
#-- SY) Kernel hardening sysctls
print_list "kptr_restrict? ................. "$NC
kptr_restrict=$(cat /proc/sys/kernel/kptr_restrict 2>/dev/null)
if [ -z "$kptr_restrict" ]; then
echo_not_found "/proc/sys/kernel/kptr_restrict"
else
if [ "$kptr_restrict" -eq 0 ]; then echo "0" | sed -${E} "s,0,${SED_RED},"; else echo "$kptr_restrict" | sed -${E} "s,.*,${SED_GREEN},g"; fi
fi
print_list "dmesg_restrict? ................ "$NC
dmesg_restrict=$(cat /proc/sys/kernel/dmesg_restrict 2>/dev/null)
if [ -z "$dmesg_restrict" ]; then
echo_not_found "/proc/sys/kernel/dmesg_restrict"
else
if [ "$dmesg_restrict" -eq 0 ]; then echo "0" | sed -${E} "s,0,${SED_RED},"; else echo "$dmesg_restrict" | sed -${E} "s,.*,${SED_GREEN},g"; fi
fi
print_list "ptrace_scope? .................. "$NC
ptrace_scope=$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null)
if [ -z "$ptrace_scope" ]; then
echo_not_found "/proc/sys/kernel/yama/ptrace_scope"
else
if [ "$ptrace_scope" -eq 0 ]; then echo "0" | sed -${E} "s,0,${SED_RED},"; else echo "$ptrace_scope" | sed -${E} "s,.*,${SED_GREEN},g"; fi
fi
print_list "perf_event_paranoid? ........... "$NC
perf_event_paranoid=$(cat /proc/sys/kernel/perf_event_paranoid 2>/dev/null)
if [ -z "$perf_event_paranoid" ]; then
echo_not_found "/proc/sys/kernel/perf_event_paranoid"
else
if [ "$perf_event_paranoid" -le 1 ]; then echo "$perf_event_paranoid" | sed -${E} "s,.*,${SED_RED},g"; else echo "$perf_event_paranoid" | sed -${E} "s,.*,${SED_GREEN},g"; fi
fi
print_list "mmap_min_addr? ................. "$NC
mmap_min_addr=$(cat /proc/sys/vm/mmap_min_addr 2>/dev/null)
if [ -z "$mmap_min_addr" ]; then
echo_not_found "/proc/sys/vm/mmap_min_addr"
else
if [ "$mmap_min_addr" -eq 0 ]; then echo "0" | sed -${E} "s,0,${SED_RED},"; else echo "$mmap_min_addr" | sed -${E} "s,.*,${SED_GREEN},g"; fi
fi
print_list "lockdown mode? ................. "$NC
if [ -f "/sys/kernel/security/lockdown" ]; then
cat /sys/kernel/security/lockdown 2>/dev/null | sed -${E} "s,none,${SED_RED},g; s,integrity|confidentiality,${SED_GREEN},g"
else
echo_not_found "/sys/kernel/security/lockdown"
fi
#-- SY) Kernel hardening config flags
print_list "Kernel hardening flags? ........ "$NC
if [ -f "/boot/config-$(uname -r)" ]; then
grep -E 'CONFIG_RANDOMIZE_BASE|CONFIG_STACKPROTECTOR|CONFIG_SLAB_FREELIST_|CONFIG_KASAN' /boot/config-$(uname -r) 2>/dev/null
elif [ -f "/proc/config.gz" ]; then
zcat /proc/config.gz 2>/dev/null | grep -E 'CONFIG_RANDOMIZE_BASE|CONFIG_STACKPROTECTOR|CONFIG_SLAB_FREELIST_|CONFIG_KASAN'
else
echo_not_found "kernel config"
fi
#-- SY) Gatekeeper
if [ "$MACPEAS" ]; then
print_list "Gatekeeper enabled? .......... "$NC
@@ -136,4 +212,4 @@ else
if [ "$hypervisorflag" ]; then printf $RED"Yes"$NC; else printf $GREEN"No"$NC; fi
fi
echo ""
echo ""

View File

@@ -58,5 +58,23 @@ else
echo_not_found "/proc/sys/kernel/modules_disabled"
fi
# Check for module signature enforcement
print_3title "Module signature enforcement? "
if [ -f "/proc/sys/kernel/module_sig_enforce" ]; then
if [ "$(cat /proc/sys/kernel/module_sig_enforce)" = "1" ]; then
echo "Enforced" | sed -${E} "s,.*,${SED_GREEN},g"
else
echo "Not enforced" | sed -${E} "s,.*,${SED_RED},g"
fi
elif [ -f "/sys/module/module/parameters/sig_enforce" ]; then
if [ "$(cat /sys/module/module/parameters/sig_enforce)" = "Y" ]; then
echo "Enforced" | sed -${E} "s,.*,${SED_GREEN},g"
else
echo "Not enforced" | sed -${E} "s,.*,${SED_RED},g"
fi
else
echo_not_found "module_sig_enforce"
fi
echo ""
echo ""

View File

@@ -1,126 +0,0 @@
# Title: System Information - CVE_2025_38236
# ID: SY_CVE_2025_38236
# Author: HT Bot
# Last Update: 17-12-2025
# Description: Detect Linux kernels exposed to CVE-2025-38236 (AF_UNIX MSG_OOB UAF) that allow local privilege escalation:
# - Vulnerable scope:
# * Linux kernels 6.9+ before commit 32ca245464e1479bfea8592b9db227fdc1641705
# * AF_UNIX stream sockets with MSG_OOB enabled (CONFIG_AF_UNIX_OOB or implicit support)
# - Exploitation summary:
# * send/recv MSG_OOB pattern leaves zero-length SKBs in the receive queue
# * manage_oob() skips cleanup, freeing the OOB SKB while u->oob_skb still points to it
# * Subsequent recv(MSG_OOB) dereferences the dangling pointer → kernel UAF → LPE
# - Mitigations:
# * Update to a kernel that includes commit 32ca245464e1479bfea8592b9db227fdc1641705 (or newer)
# * Disable CONFIG_AF_UNIX_OOB or block MSG_OOB in sandboxed processes
# * Backport vendor fixes or follow Chrome's MSG_OOB filtering approach
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info
# Global Variables: $MACPEAS, $SED_RED_YELLOW, $SED_GREEN, $E
# Initial Functions:
# Generated Global Variables: $cve38236_kernel_release, $cve38236_kernel_version, $cve38236_oob_line, $cve38236_unix_line, $cve38236_oob_status, $CVE38236_CONFIG_SOURCE, $cve38236_conf_file, $cve38236_config_key, $cve38236_release, $cve38236_cfg, $cve38236_config_line
# Fat linpeas: 0
# Small linpeas: 1
_cve38236_version_to_number() {
if [ -z "$1" ]; then
printf '0\n'
return
fi
echo "$1" | awk -F. '{
major=$1+0
if (NF>=2) minor=$2+0; else minor=0
if (NF>=3) patch=$3+0; else patch=0
printf "%d\n", (major*1000000)+(minor*1000)+patch
}'
}
_cve38236_version_ge() {
local v1 v2
v1=$(_cve38236_version_to_number "$1")
v2=$(_cve38236_version_to_number "$2")
[ "$v1" -ge "$v2" ]
}
_cve38236_cat_config_file() {
local cve38236_conf_file="$1"
if [ -z "$cve38236_conf_file" ] || ! [ -r "$cve38236_conf_file" ]; then
return 1
fi
if printf '%s' "$cve38236_conf_file" | grep -q '\\.gz$'; then
if command -v zcat >/dev/null 2>&1; then
zcat "$cve38236_conf_file" 2>/dev/null
elif command -v gzip >/dev/null 2>&1; then
gzip -dc "$cve38236_conf_file" 2>/dev/null
else
cat "$cve38236_conf_file" 2>/dev/null
fi
else
cat "$cve38236_conf_file" 2>/dev/null
fi
}
_cve38236_read_config_line() {
local cve38236_config_key="$1"
local cve38236_release cve38236_config_line cve38236_cfg
cve38236_release="$(uname -r 2>/dev/null)"
for cve38236_cfg in /proc/config.gz \
"/boot/config-${cve38236_release}" \
"/usr/lib/modules/${cve38236_release}/build/.config" \
"/lib/modules/${cve38236_release}/build/.config"; do
if [ -r "$cve38236_cfg" ]; then
cve38236_config_line=$(_cve38236_cat_config_file "$cve38236_cfg" | grep -E "^(${cve38236_config_key}=|# ${cve38236_config_key} is not set)" | head -n1)
if [ -n "$cve38236_config_line" ]; then
CVE38236_CONFIG_SOURCE="$cve38236_cfg"
printf '%s\n' "$cve38236_config_line"
return 0
fi
fi
done
return 1
}
if [ ! "$MACPEAS" ]; then
cve38236_kernel_release="$(uname -r 2>/dev/null)"
cve38236_kernel_version="$(printf '%s' "$cve38236_kernel_release" | sed 's/[^0-9.].*//')"
if [ -n "$cve38236_kernel_version" ] && _cve38236_version_ge "$cve38236_kernel_version" "6.9.0"; then
print_2title "CVE-2025-38236 - AF_UNIX MSG_OOB UAF"
cve38236_oob_line=$(_cve38236_read_config_line "CONFIG_AF_UNIX_OOB")
cve38236_oob_status="unknown"
if printf '%s' "$cve38236_oob_line" | grep -q '=y\|=m'; then
cve38236_oob_status="enabled"
elif printf '%s' "$cve38236_oob_line" | grep -q 'not set'; then
cve38236_oob_status="disabled"
fi
if [ "$cve38236_oob_status" = "unknown" ]; then
cve38236_unix_line=$(_cve38236_read_config_line "CONFIG_UNIX")
if printf '%s' "$cve38236_unix_line" | grep -q 'not set'; then
cve38236_oob_status="disabled"
elif printf '%s' "$cve38236_unix_line" | grep -q '=y\|=m'; then
cve38236_oob_status="enabled"
fi
fi
if [ "$cve38236_oob_status" = "disabled" ]; then
printf 'Kernel %s >= 6.9 but MSG_OOB support is disabled (%s).\n' "$cve38236_kernel_release" "${cve38236_oob_line:-CONFIG_AF_UNIX disabled}" | sed -${E} "s,.*,${SED_GREEN},"
print_info "CVE-2025-38236 requires AF_UNIX MSG_OOB; disabling CONFIG_AF_UNIX_OOB/CONFIG_UNIX mitigates it."
else
printf 'Kernel %s (parsed %s) may be vulnerable to CVE-2025-38236 - AF_UNIX MSG_OOB UAF.\n' "$cve38236_kernel_release" "$cve38236_kernel_version" | sed -${E} "s,.*,${SED_RED_YELLOW},"
[ -n "$cve38236_oob_line" ] && print_info "Config hint: $cve38236_oob_line"
if [ "$cve38236_oob_status" = "unknown" ]; then
print_info "Could not read CONFIG_AF_UNIX_OOB directly; AF_UNIX appears enabled, so assume MSG_OOB reachable."
fi
print_info "Exploit chain: crafted MSG_OOB send/recv frees the OOB SKB while u->oob_skb still points to it, enabling kernel UAF → arbitrary read/write primitives (Project Zero 2025/08)."
print_info "Mitigations: update to a kernel containing commit 32ca245464e1479bfea8592b9db227fdc1641705, disable CONFIG_AF_UNIX_OOB, or filter MSG_OOB in sandbox policies."
print_info "Heuristic detection: based solely on uname -r and kernel config; vendor kernels with backported fixes should be verified manually."
fi
echo ""
fi
fi

View File

@@ -33,17 +33,17 @@ grep "PermitRootLogin \|ChallengeResponseAuthentication \|PasswordAuthentication
if ! [ "$SEARCH_IN_FOLDER" ]; then
if [ "$TIMEOUT" ]; then
privatekeyfilesetc=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /etc 2>/dev/null)
privatekeyfileshome=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' $HOMESEARCH 2>/dev/null)
privatekeyfilesroot=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /root 2>/dev/null)
privatekeyfilesmnt=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /mnt 2>/dev/null)
privatekeyfilesetc=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY\-\-\-\-\-' /etc 2>/dev/null)
privatekeyfileshome=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY\-\-\-\-\-' $HOMESEARCH 2>/dev/null)
privatekeyfilesroot=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY\-\-\-\-\-' /root 2>/dev/null)
privatekeyfilesmnt=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY\-\-\-\-\-' /mnt 2>/dev/null)
else
privatekeyfilesetc=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /etc 2>/dev/null) #If there is tons of files linpeas gets frozen here without a timeout
privatekeyfileshome=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' $HOME/.ssh 2>/dev/null)
privatekeyfilesetc=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY\-\-\-\-\-' /etc 2>/dev/null) #If there is tons of files linpeas gets frozen here without a timeout
privatekeyfileshome=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY\-\-\-\-\-' $HOME/.ssh 2>/dev/null)
fi
else
# If $SEARCH_IN_FOLDER lets just search for private keys in the whole firmware
privatekeyfilesetc=$(timeout 120 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' "$ROOT_FOLDER" 2>/dev/null)
privatekeyfilesetc=$(timeout 120 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY\-\-\-\-\-' "$ROOT_FOLDER" 2>/dev/null)
fi
if [ "$privatekeyfilesetc" ] || [ "$privatekeyfileshome" ] || [ "$privatekeyfilesroot" ] || [ "$privatekeyfilesmnt" ] ; then

View File

@@ -17,7 +17,7 @@ if ! [ "$IAMROOT" ]; then
print_2title "Interesting writable files owned by me or writable by everyone (not in Home) (max 200)"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#writable-files"
#In the next file, you need to specify type "d" and "f" to avoid fake link files apparently writable by all
obmowbe=$(find $ROOT_FOLDER '(' -type f -or -type d ')' '(' '(' -user $USER ')' -or '(' -perm -o=w ')' ')' ! -path "/proc/*" ! -path "/sys/*" ! -path "$HOME/*" 2>/dev/null | grep -Ev "$notExtensions" | sort | uniq | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (act == pre){(cont += 1)} else {cont=0}; if (cont < 5){ print line_init; } if (cont == "5"){print "#)You_can_write_even_more_files_inside_last_directory\n"}; pre=act }' | head -n 200)
obmowbe=$(find $ROOT_FOLDER '(' -type f -or -type d ')' '(' '(' -user $USER ')' -or '(' -perm -o=w ')' ')' ! -path "/proc/*" ! -path "/sys/*" ! -path "/dev/*" ! -path "/snap/*" ! -path "$HOME/*" 2>/dev/null | grep -Ev "$notExtensions" | sort | uniq | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (act == pre){(cont += 1)} else {cont=0}; if (cont < 5){ print line_init; } if (cont == "5"){print "#)You_can_write_even_more_files_inside_last_directory\n"}; pre=act }' | head -n 200)
printf "%s\n" "$obmowbe" | while read l; do
if echo "$l" | grep -q "You_can_write_even_more_files_inside_last_directory"; then printf $ITALIC"$l\n"$NC;
elif echo "$l" | grep -qE "$writeVB"; then

View File

@@ -0,0 +1,80 @@
# Title: Interesting Permissions Files - IGEL OS SUID setup/date abuse
# ID: IP_IGEL_OS_SUID
# Author: HT Bot
# Last Update: 29-11-2025
# Description: Detect IGEL OS environments that expose the SUID-root `setup`/`date` binaries and highlight writable NetworkManager/systemd configs that enable the documented privilege escalation chain (Metasploit linux/local/igel_network_priv_esc).
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info
# Global Variables: $ITALIC, $NC, $SED_GREEN, $SED_RED, $SED_RED_YELLOW, $SUPERFAST
# Initial Functions:
# Generated Global Variables: $igel_markers, $igel_marker_sources, $marker, $igel_suid_hits, $candidate, $writable_nm, $writable_systemd, $unitdir, $tmp_units
# Fat linpeas: 0
# Small linpeas: 1
igel_markers=""
igel_marker_sources=""
if [ -f /etc/os-release ] && grep -qi "igel" /etc/os-release 2>/dev/null; then
igel_markers="Yes"
igel_marker_sources="/etc/os-release"
fi
if [ -f /etc/issue ] && grep -qi "igel" /etc/issue 2>/dev/null; then
igel_markers="Yes"
igel_marker_sources="${igel_marker_sources} /etc/issue"
fi
for marker in /etc/igel /wfs/igel /userhome/.igel /config/sessions/igel; do
if [ -e "$marker" ]; then
igel_markers="Yes"
igel_marker_sources="${igel_marker_sources} $marker"
fi
done
igel_suid_hits=""
for candidate in /usr/bin/setup /bin/setup /usr/sbin/setup /opt/igel/bin/setup /usr/bin/date /bin/date /usr/lib/igel/date; do
if [ -u "$candidate" ]; then
igel_suid_hits="${igel_suid_hits}$(ls -lah "$candidate" 2>/dev/null)\n"
fi
done
if [ -n "$igel_markers" ] || [ -n "$igel_suid_hits" ]; then
print_2title "IGEL OS SUID setup/date privilege escalation surface"
print_info "https://www.rapid7.com/blog/post/pt-metasploit-wrap-up-11-28-2025"
if [ -n "$igel_markers" ]; then
echo "Potential IGEL OS detected via: $igel_marker_sources" | sed -${E} "s,.*,${SED_GREEN},"
else
echo "IGEL-specific SUID helpers found but IGEL markers were not detected" | sed -${E} "s,.*,${SED_RED},"
fi
if [ -n "$igel_suid_hits" ]; then
echo "SUID-root helpers exposing configuration primitives:" | sed -${E} "s,.*,${SED_RED_YELLOW},"
printf "%b" "$igel_suid_hits"
else
echo "No SUID setup/date binaries were located (system may be patched)."
fi
writable_nm=""
writable_systemd=""
if ! [ "$SUPERFAST" ]; then
if [ -d /etc/NetworkManager ]; then
writable_nm=$(find /etc/NetworkManager -maxdepth 3 -type f -writable 2>/dev/null | head -n 25)
fi
for unitdir in /etc/systemd/system /lib/systemd/system /usr/lib/systemd/system; do
if [ -d "$unitdir" ]; then
tmp_units=$(find "$unitdir" -maxdepth 2 -type f -writable 2>/dev/null | head -n 15)
if [ -n "$tmp_units" ]; then
writable_systemd="${writable_systemd}${tmp_units}\n"
fi
fi
done
fi
if [ -n "$writable_nm" ]; then
echo "Writable NetworkManager profiles/hooks (swap Exec path to your payload):" | sed -${E} "s,.*,${SED_RED_YELLOW},"
echo "$writable_nm"
fi
if [ -n "$writable_systemd" ]; then
echo "Writable systemd unit files (edit ExecStart, then restart via setup/date):" | sed -${E} "s,.*,${SED_RED_YELLOW},"
printf "%b" "$writable_systemd"
fi
printf "$ITALIC Known exploitation chain: Use the SUID setup/date binaries to edit NetworkManager or systemd configs so ExecStart points to your payload, then trigger a service restart via the same helper to run as root (Metasploit linux/local/igel_network_priv_esc).$NC\n"
fi
echo ""

View File

@@ -0,0 +1,36 @@
# Title: Interesting Permissions Files - Writable root-owned executables
# ID: IP_Writable_root_execs
# Author: HT Bot
# Last Update: 29-11-2025
# Description: Locate root-owned executables outside home folders that the current user can modify
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info, echo_not_found
# Global Variables: $DEBUG, $IAMROOT, $ROOT_FOLDER, $HOME, $writeVB
# Initial Functions:
# Generated Global Variables: $writable_root_execs
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$IAMROOT" ]; then
print_2title "Writable root-owned executables I can modify (max 200)"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#writable-files"
writable_root_execs=$(
find "$ROOT_FOLDER" -type f -user root -perm -u=x \
\( -perm -g=w -o -perm -o=w \) \
! -path "/proc/*" ! -path "/sys/*" ! -path "/run/*" ! -path "/dev/*" ! -path "/snap/*" ! -path "$HOME/*" 2>/dev/null \
| while IFS= read -r f; do
if [ -w "$f" ]; then
ls -l "$f" 2>/dev/null
fi
done | head -n 200
)
if [ "$writable_root_execs" ] || [ "$DEBUG" ]; then
printf "%s\n" "$writable_root_execs" | sed -${E} "s,$writeVB,${SED_RED_YELLOW},"
else
echo_not_found "Writable root-owned executables"
fi
echo ""
fi

View File

@@ -1,7 +1,7 @@
# Title: LinPeasBase - su_try_pwd
# ID: su_try_pwd
# Author: Carlos Polop
# Last Update: 22-08-2023
# Last Update: 15-12-2025
# Description: Try to login as user using a password
# License: GNU GPL
# Version: 1.0
@@ -17,7 +17,7 @@ su_try_pwd(){
BFUSER=$1
PASSWORDTRY=$2
trysu=$(echo "$PASSWORDTRY" | timeout 1 su $BFUSER -c whoami 2>/dev/null)
if [ "$trysu" ]; then
if [ $? -eq 0 ]; then
echo " You can login as $BFUSER using password: $PASSWORDTRY" | sed -${E} "s,.*,${SED_RED_YELLOW},"
fi
}
}

View File

@@ -115,7 +115,7 @@ class LinpeasBuilder:
suidVB, sudoVB, capsVB = self.__get_gtfobins_lists()
assert len(suidVB) > 185, f"Len suidVB is {len(suidVB)}"
assert len(sudoVB) > 250, f"Len sudo is {len(sudoVB)}"
assert len(capsVB) > 10, f"Len suidVB is {len(capsVB)}"
assert len(capsVB) > 2, f"Len capsVB is {len(capsVB)}"
self.__replace_mark(SUIDVB1_MARKUP, suidVB[:int(len(suidVB)/2)], "|")
self.__replace_mark(SUIDVB2_MARKUP, suidVB[int(len(suidVB)/2):], "|")
@@ -348,8 +348,25 @@ class LinpeasBuilder:
return bin_b64
def __get_gtfobins_lists(self) -> tuple:
r = requests.get("https://github.com/GTFOBins/GTFOBins.github.io/tree/master/_gtfobins")
bins = re.findall(r'_gtfobins/([a-zA-Z0-9_ \-]+).md', r.text)
bins = []
api_url = "https://api.github.com/repos/GTFOBins/GTFOBins.github.io/contents/_gtfobins?per_page=100"
while api_url:
r = requests.get(api_url, timeout=10)
if not r.ok:
break
data = r.json()
for entry in data:
if entry.get("type") == "file" and entry.get("name"):
bins.append(entry["name"])
api_url = None
link = r.headers.get("Link", "")
for part in link.split(","):
if 'rel="next"' in part:
api_url = part.split(";")[0].strip().strip("<>")
break
if not bins:
r = requests.get("https://github.com/GTFOBins/GTFOBins.github.io/tree/master/_gtfobins", timeout=10)
bins = re.findall(r'_gtfobins/([a-zA-Z0-9_ \-]+)(?:\\.md)?', r.text)
sudoVB = []
suidVB = []
@@ -357,12 +374,12 @@ class LinpeasBuilder:
for b in bins:
try:
rb = requests.get(f"https://raw.githubusercontent.com/GTFOBins/GTFOBins.github.io/master/_gtfobins/{b}.md", timeout=5)
rb = requests.get(f"https://raw.githubusercontent.com/GTFOBins/GTFOBins.github.io/master/_gtfobins/{b}", timeout=5)
except:
try:
rb = requests.get(f"https://raw.githubusercontent.com/GTFOBins/GTFOBins.github.io/master/_gtfobins/{b}.md", timeout=5)
rb = requests.get(f"https://raw.githubusercontent.com/GTFOBins/GTFOBins.github.io/master/_gtfobins/{b}", timeout=5)
except:
rb = requests.get(f"https://raw.githubusercontent.com/GTFOBins/GTFOBins.github.io/master/_gtfobins/{b}.md", timeout=5)
rb = requests.get(f"https://raw.githubusercontent.com/GTFOBins/GTFOBins.github.io/master/_gtfobins/{b}", timeout=5)
if "sudo:" in rb.text:
if len(b) <= 3:
sudoVB.append("[^a-zA-Z0-9]"+b+"$") # Less false possitives applied to small names

View File

@@ -217,7 +217,7 @@ Once you have installed and activated it you need to:
- [x] SCCM
- [x] Security Package Credentials
- [x] AlwaysInstallElevated
- [x] WSUS
- [x] WSUS (HTTP downgrade + CVE-2025-59287 exposure)
- **Browser Information**
- [x] Firefox DBs

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
@@ -561,27 +562,66 @@ namespace winPEAS.Checks
{
Beaprint.MainPrint("Checking WSUS");
Beaprint.LinkPrint("https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#wsus");
string path = "Software\\Policies\\Microsoft\\Windows\\WindowsUpdate";
string path2 = "Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU";
string HKLM_WSUS = RegistryHelper.GetRegValue("HKLM", path, "WUServer");
string using_HKLM_WSUS = RegistryHelper.GetRegValue("HKLM", path2, "UseWUServer");
if (HKLM_WSUS.Contains("http://"))
string policyPath = "Software\\Policies\\Microsoft\\Windows\\WindowsUpdate";
string policyAUPath = "Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU";
string wsusPolicyValue = RegistryHelper.GetRegValue("HKLM", policyPath, "WUServer");
string useWUServerValue = RegistryHelper.GetRegValue("HKLM", policyAUPath, "UseWUServer");
if (!string.IsNullOrEmpty(wsusPolicyValue) && wsusPolicyValue.StartsWith("http://", StringComparison.OrdinalIgnoreCase))
{
Beaprint.BadPrint(" WSUS is using http: " + HKLM_WSUS);
Beaprint.BadPrint(" WSUS is using http: " + wsusPolicyValue);
Beaprint.InfoPrint("You can test https://github.com/pimps/wsuxploit to escalate privileges");
if (using_HKLM_WSUS == "1")
if (useWUServerValue == "1")
Beaprint.BadPrint(" And UseWUServer is equals to 1, so it is vulnerable!");
else if (using_HKLM_WSUS == "0")
else if (useWUServerValue == "0")
Beaprint.GoodPrint(" But UseWUServer is equals to 0, so it is not vulnerable!");
else
Console.WriteLine(" But UseWUServer is equals to " + using_HKLM_WSUS + ", so it may work or not");
Console.WriteLine(" But UseWUServer is equals to " + useWUServerValue + ", so it may work or not");
}
else
{
if (string.IsNullOrEmpty(HKLM_WSUS))
if (string.IsNullOrEmpty(wsusPolicyValue))
Beaprint.NotFoundPrint();
else
Beaprint.GoodPrint(" WSUS value: " + HKLM_WSUS);
Beaprint.GoodPrint(" WSUS value: " + wsusPolicyValue);
}
if (!string.IsNullOrEmpty(wsusPolicyValue))
{
bool clientsForced = useWUServerValue == "1";
if (clientsForced)
{
Beaprint.BadPrint(" CVE-2025-59287: Clients talk to WSUS at " + wsusPolicyValue + " (UseWUServer=1). Unpatched WSUS allows unauthenticated deserialization to SYSTEM.");
}
else
{
Beaprint.InfoPrint(" CVE-2025-59287: WSUS endpoint discovered at " + wsusPolicyValue + ". Confirm patch level before attempting exploitation.");
if (!string.IsNullOrEmpty(useWUServerValue))
Beaprint.InfoPrint(" UseWUServer is set to " + useWUServerValue + ", clients may still reach Microsoft Update.");
}
}
string wsusSetupPath = @"SOFTWARE\Microsoft\Update Services\Server\Setup";
string wsusVersion = RegistryHelper.GetRegValue("HKLM", wsusSetupPath, "VersionString");
string wsusInstallPath = RegistryHelper.GetRegValue("HKLM", wsusSetupPath, "InstallPath");
bool wsusRoleDetected = !string.IsNullOrEmpty(wsusVersion) || !string.IsNullOrEmpty(wsusInstallPath);
if (TryGetServiceStateAndAccount("WSUSService", out string wsusServiceState, out string wsusServiceAccount))
{
wsusRoleDetected = true;
string serviceMsg = " WSUSService status: " + wsusServiceState;
if (!string.IsNullOrEmpty(wsusServiceAccount))
serviceMsg += " (runs as " + wsusServiceAccount + ")";
Beaprint.BadPrint(serviceMsg);
}
if (wsusRoleDetected)
{
if (!string.IsNullOrEmpty(wsusVersion))
Beaprint.BadPrint(" WSUS Server version: " + wsusVersion + " (verify patch level for CVE-2025-59287).");
if (!string.IsNullOrEmpty(wsusInstallPath))
Beaprint.InfoPrint(" WSUS install path: " + wsusInstallPath);
Beaprint.BadPrint(" CVE-2025-59287: Local WSUS server exposes an unauthenticated deserialization surface reachable over HTTP(S). Patch or restrict access.");
}
}
catch (Exception ex)
@@ -590,6 +630,32 @@ namespace winPEAS.Checks
}
}
private static bool TryGetServiceStateAndAccount(string serviceName, out string state, out string account)
{
state = string.Empty;
account = string.Empty;
try
{
string query = $"SELECT Name, State, StartName FROM Win32_Service WHERE Name='{serviceName.Replace("'", "''")}'";
using (var searcher = new ManagementObjectSearcher(@"root\cimv2", query))
{
foreach (ManagementObject service in searcher.Get())
{
state = service["State"]?.ToString() ?? string.Empty;
account = service["StartName"]?.ToString() ?? string.Empty;
return true;
}
}
}
catch (Exception ex)
{
Beaprint.PrintException(ex.Message);
}
return false;
}
static void PrintKrbRelayUp()
{
try