diff --git a/.github/workflows/CI-master_tests.yml b/.github/workflows/CI-master_tests.yml index 62219c9..842ef3c 100644 --- a/.github/workflows/CI-master_tests.yml +++ b/.github/workflows/CI-master_tests.yml @@ -212,15 +212,14 @@ jobs: steps: # Download repo - - uses: actions/checkout@v2 + - uses: actions/checkout@v5 with: 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 diff --git a/.github/workflows/PR-tests.yml b/.github/workflows/PR-tests.yml index 1536b85..5a58e73 100644 --- a/.github/workflows/PR-tests.yml +++ b/.github/workflows/PR-tests.yml @@ -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 diff --git a/build_lists/sensitive_files.yaml b/build_lists/sensitive_files.yaml index 0310714..5380830 100644 --- a/build_lists/sensitive_files.yaml +++ b/build_lists/sensitive_files.yaml @@ -3546,7 +3546,7 @@ search: - name: "RDCMan.settings" value: - just_list_file: True + bad_regex: "credentialsProfiles|password|encryptedPassword" type: f search_in: - common diff --git a/linPEAS/README.md b/linPEAS/README.md index 620608d..5ade213 100755 --- a/linPEAS/README.md +++ b/linPEAS/README.md @@ -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 diff --git a/linPEAS/builder/linpeas_parts/1_system_information/16_Protections.sh b/linPEAS/builder/linpeas_parts/1_system_information/16_Protections.sh index 50901c9..95a91b5 100644 --- a/linPEAS/builder/linpeas_parts/1_system_information/16_Protections.sh +++ b/linPEAS/builder/linpeas_parts/1_system_information/16_Protections.sh @@ -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 "" \ No newline at end of file +echo "" diff --git a/linPEAS/builder/linpeas_parts/1_system_information/17_Kernel_Modules.sh b/linPEAS/builder/linpeas_parts/1_system_information/17_Kernel_Modules.sh index 41490d6..9beb7e0 100644 --- a/linPEAS/builder/linpeas_parts/1_system_information/17_Kernel_Modules.sh +++ b/linPEAS/builder/linpeas_parts/1_system_information/17_Kernel_Modules.sh @@ -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 "" \ No newline at end of file + +echo "" diff --git a/linPEAS/builder/linpeas_parts/7_software_information/Ssh.sh b/linPEAS/builder/linpeas_parts/7_software_information/Ssh.sh index f456964..65947a0 100644 --- a/linPEAS/builder/linpeas_parts/7_software_information/Ssh.sh +++ b/linPEAS/builder/linpeas_parts/7_software_information/Ssh.sh @@ -29,21 +29,21 @@ fi peass{SSH} -grep "PermitRootLogin \|ChallengeResponseAuthentication \|PasswordAuthentication \|UsePAM \|Port\|PermitEmptyPasswords\|PubkeyAuthentication\|ListenAddress\|ForwardAgent\|AllowAgentForwarding\|AuthorizedKeysFiles" /etc/ssh/sshd_config 2>/dev/null | grep -v "#" | sed -${E} "s,PermitRootLogin.*es|PermitEmptyPasswords.*es|ChallengeResponseAuthentication.*es|FordwardAgent.*es,${SED_RED}," +grep "PermitRootLogin \|ChallengeResponseAuthentication \|PasswordAuthentication \|UsePAM \|Port\|PermitEmptyPasswords\|PubkeyAuthentication\|ListenAddress\|ForwardAgent\|AllowAgentForwarding\|AuthorizedKeysFile" /etc/ssh/sshd_config 2>/dev/null | grep -v "#" | sed -${E} "s,PermitRootLogin.*es|PermitEmptyPasswords.*es|ChallengeResponseAuthentication.*es|FordwardAgent.*es,${SED_RED}," 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 diff --git a/linPEAS/builder/linpeas_parts/8_interesting_perms_files/14_Writable_files_owner_all.sh b/linPEAS/builder/linpeas_parts/8_interesting_perms_files/14_Writable_files_owner_all.sh index 894d5bf..a6c0918 100644 --- a/linPEAS/builder/linpeas_parts/8_interesting_perms_files/14_Writable_files_owner_all.sh +++ b/linPEAS/builder/linpeas_parts/8_interesting_perms_files/14_Writable_files_owner_all.sh @@ -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 diff --git a/linPEAS/builder/linpeas_parts/8_interesting_perms_files/16_IGEL_OS_SUID.sh b/linPEAS/builder/linpeas_parts/8_interesting_perms_files/16_IGEL_OS_SUID.sh new file mode 100644 index 0000000..9a7d312 --- /dev/null +++ b/linPEAS/builder/linpeas_parts/8_interesting_perms_files/16_IGEL_OS_SUID.sh @@ -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 "" diff --git a/linPEAS/builder/linpeas_parts/8_interesting_perms_files/16_Writable_root_execs.sh b/linPEAS/builder/linpeas_parts/8_interesting_perms_files/16_Writable_root_execs.sh new file mode 100644 index 0000000..1f86216 --- /dev/null +++ b/linPEAS/builder/linpeas_parts/8_interesting_perms_files/16_Writable_root_execs.sh @@ -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 diff --git a/linPEAS/builder/linpeas_parts/functions/su_try_pwd.sh b/linPEAS/builder/linpeas_parts/functions/su_try_pwd.sh index 306e0f5..f7a868d 100644 --- a/linPEAS/builder/linpeas_parts/functions/su_try_pwd.sh +++ b/linPEAS/builder/linpeas_parts/functions/su_try_pwd.sh @@ -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 -} \ No newline at end of file +} diff --git a/linPEAS/builder/linpeas_parts/linpeas_base/0_variables_base.sh b/linPEAS/builder/linpeas_parts/linpeas_base/0_variables_base.sh index a79840f..c99df36 100644 --- a/linPEAS/builder/linpeas_parts/linpeas_base/0_variables_base.sh +++ b/linPEAS/builder/linpeas_parts/linpeas_base/0_variables_base.sh @@ -371,7 +371,7 @@ echo "" printf ${BLUE}"Linux Privesc Checklist: ${YELLOW}https://book.hacktricks.wiki/en/linux-hardening/linux-privilege-escalation-checklist.html\n"$NC echo " LEGEND:" | sed "s,LEGEND,${C}[1;4m&${C}[0m," echo " RED/YELLOW: 95% a PE vector" | sed "s,RED/YELLOW,${SED_RED_YELLOW}," -echo " RED: You should take a look to it" | sed "s,RED,${SED_RED}," +echo " RED: You should take a look into it" | sed "s,RED,${SED_RED}," echo " LightCyan: Users with console" | sed "s,LightCyan,${SED_LIGHT_CYAN}," echo " Blue: Users without console & mounted devs" | sed "s,Blue,${SED_BLUE}," echo " Green: Common things (users, groups, SUID/SGID, mounts, .sh scripts, cronjobs) " | sed "s,Green,${SED_GREEN}," @@ -514,4 +514,4 @@ else HOMESEARCH="$HOME $HOMESEARCH" fi fi -GREPHOMESEARCH=$(echo "$HOMESEARCH" | sed 's/ *$//g' | tr " " "|") #Remove ending spaces before putting "|" \ No newline at end of file +GREPHOMESEARCH=$(echo "$HOMESEARCH" | sed 's/ *$//g' | tr " " "|") #Remove ending spaces before putting "|" diff --git a/linPEAS/builder/src/linpeasBuilder.py b/linPEAS/builder/src/linpeasBuilder.py index 40c8b51..d53eec7 100644 --- a/linPEAS/builder/src/linpeasBuilder.py +++ b/linPEAS/builder/src/linpeasBuilder.py @@ -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 diff --git a/winPEAS/winPEASbat/winPEAS.bat b/winPEAS/winPEASbat/winPEAS.bat index fdf176d..c51ccf2 100755 --- a/winPEAS/winPEASbat/winPEAS.bat +++ b/winPEAS/winPEASbat/winPEAS.bat @@ -405,7 +405,7 @@ CALL :T_Progress 1 :BasicUserInfo CALL :ColorLine "%E%32m[*]%E%97m BASIC USER INFO -ECHO. [i] Check if you are inside the Administrators group or if you have enabled any token that can be use to escalate privileges like SeImpersonatePrivilege, SeAssignPrimaryPrivilege, SeTcbPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeCreateTokenPrivilege, SeLoadDriverPrivilege, SeTakeOwnershipPrivilege, SeDebbugPrivilege +ECHO. [i] Check if you are inside the Administrators group or if you have enabled any token that can be use to escalate privileges like SeImpersonatePrivilege, SeAssignPrimaryPrivilege, SeTcbPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeCreateTokenPrivilege, SeLoadDriverPrivilege, SeTakeOwnershipPrivilege, SeDebugPrivilege ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#users--groups ECHO. CALL :ColorLine " %E%33m[+]%E%97m CURRENT USER" diff --git a/winPEAS/winPEASexe/README.md b/winPEAS/winPEASexe/README.md index c29acf4..dc10847 100755 --- a/winPEAS/winPEASexe/README.md +++ b/winPEAS/winPEASexe/README.md @@ -218,7 +218,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 diff --git a/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs b/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs index b096a86..a15ad23 100644 --- a/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs +++ b/winPEAS/winPEASexe/winPEAS/Checks/SystemInfo.cs @@ -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; @@ -562,27 +563,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) @@ -591,6 +631,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 diff --git a/winPEAS/winPEASps1/winPEAS.ps1 b/winPEAS/winPEASps1/winPEAS.ps1 index c471666..efd3268 100644 --- a/winPEAS/winPEASps1/winPEAS.ps1 +++ b/winPEAS/winPEASps1/winPEAS.ps1 @@ -1650,7 +1650,7 @@ Write-Host -ForegroundColor Blue "=========|| WHOAMI INFO" Write-Host "" if ($TimeStamp) { TimeElapsed } Write-Host -ForegroundColor Blue "=========|| Check Token access here: https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/privilege-escalation-abusing-tokens.html#abusing-tokens" -ForegroundColor yellow -Write-Host -ForegroundColor Blue "=========|| Check if you are inside the Administrators group or if you have enabled any token that can be use to escalate privileges like SeImpersonatePrivilege, SeAssignPrimaryPrivilege, SeTcbPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeCreateTokenPrivilege, SeLoadDriverPrivilege, SeTakeOwnershipPrivilege, SeDebbugPrivilege" +Write-Host -ForegroundColor Blue "=========|| Check if you are inside the Administrators group or if you have enabled any token that can be use to escalate privileges like SeImpersonatePrivilege, SeAssignPrimaryPrivilege, SeTcbPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeCreateTokenPrivilege, SeLoadDriverPrivilege, SeTakeOwnershipPrivilege, SeDebugPrivilege" Write-Host "https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#users--groups" -ForegroundColor Yellow Start-Process whoami.exe -ArgumentList "/all" -Wait -NoNewWindow