mirror of
https://github.com/peass-ng/PEASS-ng.git
synced 2026-01-16 23:12:16 -08:00
Compare commits
15 Commits
update_PEA
...
20260116-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d4b748cbc | ||
|
|
69371f825e | ||
|
|
72dbd9ef28 | ||
|
|
32e9bf657a | ||
|
|
d6bd661460 | ||
|
|
ed6263a4b3 | ||
|
|
93bb3e1a64 | ||
|
|
bf9d474cd3 | ||
|
|
f856f0b588 | ||
|
|
9d35195c56 | ||
|
|
4abbf37cc0 | ||
|
|
10b087febf | ||
|
|
b188ac34b6 | ||
|
|
e99e64cddf | ||
|
|
dd220af544 |
5
.github/workflows/PR-tests.yml
vendored
5
.github/workflows/PR-tests.yml
vendored
@@ -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
|
||||
|
||||
@@ -3546,7 +3546,7 @@ search:
|
||||
|
||||
- name: "RDCMan.settings"
|
||||
value:
|
||||
just_list_file: True
|
||||
bad_regex: "credentialsProfiles|password|encryptedPassword"
|
||||
type: f
|
||||
search_in:
|
||||
- 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`**.
|
||||
|
||||
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
|
||||
|
||||
@@ -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 ""
|
||||
|
||||
@@ -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 ""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
# 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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user