mirror of
https://github.com/peass-ng/PEASS-ng.git
synced 2026-07-30 23:50:27 -07:00
Merge branch 'master' into update_PEASS-winpeas-The_Windows_Registry_Adventure__Part_20251217_014635
This commit is contained in:
@@ -110,10 +110,9 @@ jobs:
|
|||||||
ref: ${{ github.head_ref }}
|
ref: ${{ github.head_ref }}
|
||||||
|
|
||||||
# Setup go
|
# Setup go
|
||||||
- uses: actions/setup-go@v2
|
- uses: actions/setup-go@v6
|
||||||
with:
|
with:
|
||||||
go-version: 1.17.0-rc1
|
go-version: '1.23'
|
||||||
stable: false
|
|
||||||
- run: go version
|
- run: go version
|
||||||
|
|
||||||
# Build linpeas
|
# Build linpeas
|
||||||
|
|||||||
@@ -3546,7 +3546,7 @@ search:
|
|||||||
|
|
||||||
- name: "RDCMan.settings"
|
- name: "RDCMan.settings"
|
||||||
value:
|
value:
|
||||||
just_list_file: True
|
bad_regex: "credentialsProfiles|password|encryptedPassword"
|
||||||
type: f
|
type: f
|
||||||
search_in:
|
search_in:
|
||||||
- common
|
- common
|
||||||
|
|||||||
@@ -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`**.
|
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)*:
|
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
|
- 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
|
- Almost 1 min to search for possible passwords inside all the accesible files of the system
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
# Functions Used: echo_not_found, print_2title, print_list, warn_exec
|
# Functions Used: echo_not_found, print_2title, print_list, warn_exec
|
||||||
# Global Variables:
|
# Global Variables:
|
||||||
# Initial Functions:
|
# 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
|
# Fat linpeas: 0
|
||||||
# Small linpeas: 0
|
# Small linpeas: 0
|
||||||
|
|
||||||
@@ -80,10 +80,86 @@ print_list "Seccomp enabled? ............... "$NC
|
|||||||
print_list "User namespace? ................ "$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
|
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
|
#-- SY) cgroup2
|
||||||
print_list "Cgroup2 enabled? ............... "$NC
|
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},"
|
([ "$(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
|
#-- SY) Gatekeeper
|
||||||
if [ "$MACPEAS" ]; then
|
if [ "$MACPEAS" ]; then
|
||||||
print_list "Gatekeeper enabled? .......... "$NC
|
print_list "Gatekeeper enabled? .......... "$NC
|
||||||
@@ -136,4 +212,4 @@ else
|
|||||||
if [ "$hypervisorflag" ]; then printf $RED"Yes"$NC; else printf $GREEN"No"$NC; fi
|
if [ "$hypervisorflag" ]; then printf $RED"Yes"$NC; else printf $GREEN"No"$NC; fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
@@ -58,5 +58,23 @@ else
|
|||||||
echo_not_found "/proc/sys/kernel/modules_disabled"
|
echo_not_found "/proc/sys/kernel/modules_disabled"
|
||||||
fi
|
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 ""
|
||||||
|
|||||||
@@ -33,17 +33,17 @@ grep "PermitRootLogin \|ChallengeResponseAuthentication \|PasswordAuthentication
|
|||||||
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
if [ "$TIMEOUT" ]; then
|
if [ "$TIMEOUT" ]; then
|
||||||
privatekeyfilesetc=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /etc 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)
|
privatekeyfileshome=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY\-\-\-\-\-' $HOMESEARCH 2>/dev/null)
|
||||||
privatekeyfilesroot=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /root 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)
|
privatekeyfilesmnt=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY\-\-\-\-\-' /mnt 2>/dev/null)
|
||||||
else
|
else
|
||||||
privatekeyfilesetc=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /etc 2>/dev/null) #If there is tons of files linpeas gets frozen here without a timeout
|
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)
|
privatekeyfileshome=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY\-\-\-\-\-' $HOME/.ssh 2>/dev/null)
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# If $SEARCH_IN_FOLDER lets just search for private keys in the whole firmware
|
# 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
|
fi
|
||||||
|
|
||||||
if [ "$privatekeyfilesetc" ] || [ "$privatekeyfileshome" ] || [ "$privatekeyfilesroot" ] || [ "$privatekeyfilesmnt" ] ; then
|
if [ "$privatekeyfilesetc" ] || [ "$privatekeyfileshome" ] || [ "$privatekeyfilesroot" ] || [ "$privatekeyfilesmnt" ] ; then
|
||||||
|
|||||||
+1
-1
@@ -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_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"
|
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
|
#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
|
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;
|
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
|
elif echo "$l" | grep -qE "$writeVB"; then
|
||||||
|
|||||||
@@ -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 ""
|
||||||
@@ -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
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
# Title: LinPeasBase - su_try_pwd
|
# Title: LinPeasBase - su_try_pwd
|
||||||
# ID: su_try_pwd
|
# ID: su_try_pwd
|
||||||
# Author: Carlos Polop
|
# Author: Carlos Polop
|
||||||
# Last Update: 22-08-2023
|
# Last Update: 15-12-2025
|
||||||
# Description: Try to login as user using a password
|
# Description: Try to login as user using a password
|
||||||
# License: GNU GPL
|
# License: GNU GPL
|
||||||
# Version: 1.0
|
# Version: 1.0
|
||||||
@@ -17,7 +17,7 @@ su_try_pwd(){
|
|||||||
BFUSER=$1
|
BFUSER=$1
|
||||||
PASSWORDTRY=$2
|
PASSWORDTRY=$2
|
||||||
trysu=$(echo "$PASSWORDTRY" | timeout 1 su $BFUSER -c whoami 2>/dev/null)
|
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},"
|
echo " You can login as $BFUSER using password: $PASSWORDTRY" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ class LinpeasBuilder:
|
|||||||
suidVB, sudoVB, capsVB = self.__get_gtfobins_lists()
|
suidVB, sudoVB, capsVB = self.__get_gtfobins_lists()
|
||||||
assert len(suidVB) > 185, f"Len suidVB is {len(suidVB)}"
|
assert len(suidVB) > 185, f"Len suidVB is {len(suidVB)}"
|
||||||
assert len(sudoVB) > 250, f"Len sudo is {len(sudoVB)}"
|
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(SUIDVB1_MARKUP, suidVB[:int(len(suidVB)/2)], "|")
|
||||||
self.__replace_mark(SUIDVB2_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
|
return bin_b64
|
||||||
|
|
||||||
def __get_gtfobins_lists(self) -> tuple:
|
def __get_gtfobins_lists(self) -> tuple:
|
||||||
r = requests.get("https://github.com/GTFOBins/GTFOBins.github.io/tree/master/_gtfobins")
|
bins = []
|
||||||
bins = re.findall(r'_gtfobins/([a-zA-Z0-9_ \-]+).md', r.text)
|
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 = []
|
sudoVB = []
|
||||||
suidVB = []
|
suidVB = []
|
||||||
@@ -357,12 +374,12 @@ class LinpeasBuilder:
|
|||||||
|
|
||||||
for b in bins:
|
for b in bins:
|
||||||
try:
|
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:
|
except:
|
||||||
try:
|
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:
|
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 "sudo:" in rb.text:
|
||||||
if len(b) <= 3:
|
if len(b) <= 3:
|
||||||
sudoVB.append("[^a-zA-Z0-9]"+b+"$") # Less false possitives applied to small names
|
sudoVB.append("[^a-zA-Z0-9]"+b+"$") # Less false possitives applied to small names
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ Once you have installed and activated it you need to:
|
|||||||
- [x] SCCM
|
- [x] SCCM
|
||||||
- [x] Security Package Credentials
|
- [x] Security Package Credentials
|
||||||
- [x] AlwaysInstallElevated
|
- [x] AlwaysInstallElevated
|
||||||
- [x] WSUS
|
- [x] WSUS (HTTP downgrade + CVE-2025-59287 exposure)
|
||||||
|
|
||||||
- **Browser Information**
|
- **Browser Information**
|
||||||
- [x] Firefox DBs
|
- [x] Firefox DBs
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Management;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
@@ -561,27 +562,66 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Checking WSUS");
|
Beaprint.MainPrint("Checking WSUS");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#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 policyPath = "Software\\Policies\\Microsoft\\Windows\\WindowsUpdate";
|
||||||
string path2 = "Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU";
|
string policyAUPath = "Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU";
|
||||||
string HKLM_WSUS = RegistryHelper.GetRegValue("HKLM", path, "WUServer");
|
string wsusPolicyValue = RegistryHelper.GetRegValue("HKLM", policyPath, "WUServer");
|
||||||
string using_HKLM_WSUS = RegistryHelper.GetRegValue("HKLM", path2, "UseWUServer");
|
string useWUServerValue = RegistryHelper.GetRegValue("HKLM", policyAUPath, "UseWUServer");
|
||||||
if (HKLM_WSUS.Contains("http://"))
|
|
||||||
|
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");
|
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!");
|
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!");
|
Beaprint.GoodPrint(" But UseWUServer is equals to 0, so it is not vulnerable!");
|
||||||
else
|
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
|
else
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(HKLM_WSUS))
|
if (string.IsNullOrEmpty(wsusPolicyValue))
|
||||||
Beaprint.NotFoundPrint();
|
Beaprint.NotFoundPrint();
|
||||||
else
|
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)
|
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()
|
static void PrintKrbRelayUp()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
Reference in New Issue
Block a user