Compare commits

...

42 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
SirBroccoli
b4a1382e8a Merge pull request #536 from DotNetRussell/patch-1
Fix wording in privilege escalation checklist
2025-12-15 09:52:13 +01:00
DNR
877b9b81ce Fix wording in privilege escalation checklist 2025-12-14 12:45:02 -05:00
carlospolop
0277e447f0 f 2025-12-12 16:25:36 +01:00
carlospolop
b09bd92116 f 2025-12-12 14:28:17 +01:00
SirBroccoli
8f017f98d3 Merge pull request #532 from compass-dexter/fix/ssh-AuthorizedKeysFile
[LINPEAS] fix(linPEAS): grep for AuthorizedKeysFile
2025-12-12 00:44:51 +01:00
SirBroccoli
17cfc6c56e Merge pull request #530 from Xyniath/master
[WINPEAS] Fix misspelling of SeDebugPrivilege in winPEAS output
2025-12-12 00:44:30 +01:00
compass-dexter
7e0f678f33 fix(linPEAS): grep for AuthorizedKeysFile
According to sshd_config(5) this is the correct setting
2025-12-10 16:58:13 +01:00
Matt
595e021864 fix: correct typo of SeDebugPrivilege 2025-12-08 00:27:02 +00:00
SirBroccoli
94e84dec91 Merge pull request #521 from peass-ng/update_PEASS-winpeas-HackTheBox_Mirage__Chaining_NFS_Leak_20251122_183905
[WINPEAS] Add privilege escalation check: HackTheBox Mirage Chaining NFS Leaks, Dy...
2025-12-07 13:23:17 +01:00
SirBroccoli
ac80ce3a9a Merge pull request #520 from peass-ng/update_PEASS-linpeas-SupaPwn__Hacking_Our_Way_into_Lovabl_20251119_184112
[LINPEAS] Add privilege escalation check: SupaPwn Hacking Our Way into Lovable’s O...
2025-12-07 13:22:12 +01:00
SirBroccoli
313fe6bef5 Update README.md 2025-12-07 13:21:52 +01: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
HackTricks News Bot
11c0d14561 Add winpeas privilege escalation checks from: HackTheBox Mirage: Chaining NFS Leaks, Dynamic DNS Abuse, NATS Credential Theft, 2025-11-22 18:54:22 +00:00
HackTricks News Bot
49db1df468 Add linpeas privilege escalation checks from: SupaPwn: Hacking Our Way into Lovable’s Office and Helping Secure Supabase 2025-11-19 18:59:41 +00:00
SirBroccoli
80318c5005 Merge pull request #514 from moscowchill/bat-pr
Fix ANSI escape codes displaying as literal text in winPEAS.bat
2025-11-15 15:45:38 +01:00
SirBroccoli
7af6c33d39 Merge pull request #513 from sttlr/patch-1
Fix: LinPEASS doesn't run via metasploit module
2025-11-15 15:44:50 +01:00
moscow chill
336c53a163 Fix ANSI escape codes displaying as literal text in winPEAS.bat
The script was setting E=0x1B[ as a literal string instead of the actual
ESC character (ASCII 27), causing color codes to display as text like
"0x1B[33m[+]0x1B[97m" instead of rendering as colors.

Changed the SetOnce subroutine to properly capture the ESC character using
the 'prompt $E' technique before building the ANSI escape sequence prefix.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 20:16:34 +01:00
Max K.
6877f39193 Fix: LinPEASS doesn't run via metasploit module
If you set "WINPEASS" to "false" - it's a string, and therefore "true". So it would run WinPEASS anyway.

The fix converts value of the variable to string before comparing it.
2025-10-28 13:19:03 +02:00
SirBroccoli
d75525ebbc Merge pull request #512 from moscowchill/pr-bat-fix
Fix winPEAS.bat compatibility with Windows 11 and modern Windows 10
2025-10-28 01:51:48 +01:00
moscow chill
29d8132d93 Fix winPEAS.bat compatibility with Windows 11 and modern Windows 10
WMIC has been deprecated since Windows 10 20H1 and removed in Windows 11.
The script was exiting early when WMIC commands failed instead of continuing.

Changes:
- Add proper WMIC existence checks using 'where wmic' before execution
- Implement PowerShell fallbacks for all WMIC commands
- Fix hotfix enumeration (Get-HotFix)
- Fix antivirus detection (Get-CimInstance)
- Fix mounted disk enumeration (Get-PSDrive)
- Fix running process checks (Get-Process)
- Fix service binary permission checks (Get-CimInstance Win32_Service)
- Add error suppression (2>nul) to conditional WMIC exploit checks

The script now properly detects WMIC availability and falls back to
PowerShell equivalents, ensuring full functionality on modern Windows
systems while maintaining backward compatibility with older systems.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 16:10:42 +01:00
carlospolop
c16c5de36f f 2025-10-18 00:59:40 +02:00
SirBroccoli
be3fe91da4 Merge pull request #507 from CravateRouge/master
Add ADCS ESC DC registry checks
2025-10-07 10:50:43 +02:00
CravateRouge
b8b4a0fc14 Fix InterfaceFlags syntax 2025-10-07 11:14:45 +08:00
CravateRouge
7042a182df Add ADCS ESC DC registry checks 2025-10-06 17:18:44 +02:00
SirBroccoli
c83eef9cd8 Merge pull request #502 from peass-ng/update_PEASS-linpeas-HTB_Planning__Grafana_CVE-2024-9264__20250913_182726
[LINPEAS] Add privilege escalation check: HTB Planning Grafana CVE-2024-9264 to Co...
2025-10-04 10:38:22 +02:00
SirBroccoli
e15a1f2e12 Update 16_Crontab_UI_misconfig.sh 2025-10-04 10:38:02 +02:00
SirBroccoli
ee83c23a74 Update 16_Crontab_UI_misconfig.sh 2025-10-04 10:34:04 +02:00
HackTricks News Bot
bdcebadde0 Add linpeas privilege escalation checks from: HTB Planning: Grafana CVE-2024-9264 to Container Root, Env-Creds Pivot, Crontab 2025-09-13 18:33:45 +00:00
22 changed files with 1073 additions and 100 deletions

View File

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

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
@@ -3954,3 +3954,24 @@ search:
type: f
search_in:
- common
- name: Crontab-UI
value:
config:
auto_check: True
files:
- name: "crontab.db"
value:
bad_regex: "-P[[:space:]]+\\S+|--password[[:space:]]+\\S+|[Pp]ass(word)?|[Tt]oken|[Ss]ecret"
only_bad_lines: True
type: f
search_in:
- common
- name: "crontab-ui.service"
value:
just_list_file: True
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

@@ -0,0 +1,126 @@
# Title: Processes & Cron & Services & Timers - Crontab UI (root) Misconfiguration
# ID: PR_Crontab_UI_misconfig
# Author: HT Bot
# Last Update: 2025-09-13
# Description: Detect Crontab UI service and risky configurations that can lead to privesc:
# - Root-run Crontab UI exposed on localhost
# - Basic-Auth credentials in systemd Environment= (BASIC_AUTH_USER/PWD)
# - Cron DB path (CRON_DB_PATH) and weak permissions / embedded secrets in jobs
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_info, print_list, echo_not_found
# Global Variables: $SEARCH_IN_FOLDER, $SED_RED, $SED_RED_YELLOW, $NC
# Initial Functions:
# Generated Global Variables: $svc, $state, $user, $envvals, $port, $dbpath, $dbfile, $candidates, $procs, $perms, $basic_user, $basic_pwd, $uprint, $pprint, $dir, $found
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Crontab UI (root) misconfiguration checks"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#scheduledcron-jobs"
# Collect candidate services referencing crontab-ui
candidates=""
if command -v systemctl >/dev/null 2>&1; then
candidates=$(systemctl list-units --type=service --all 2>/dev/null | awk '{print $1}' | grep -Ei '^crontab-ui\.service$' 2>/dev/null)
fi
# Fallback: grep service files for ExecStart containing crontab-ui
if [ -z "$candidates" ]; then
for dir in /etc/systemd/system /lib/systemd/system; do
[ -d "$dir" ] || continue
found=$(grep -RIl "^Exec(Start|StartPre|StartPost)=.*crontab-ui" "$dir" 2>/dev/null | xargs -r -I{} basename {} 2>/dev/null)
if [ -n "$found" ]; then
candidates=$(printf "%s\n%s" "$candidates" "$found" | sort -u)
fi
done
fi
# Also flag if the binary exists or a process seems to be running
if command -v crontab-ui >/dev/null 2>&1; then
print_list "crontab-ui binary found at: $(command -v crontab-ui)"$NC
else
echo_not_found "crontab-ui"
fi
procs=$(ps aux 2>/dev/null | grep -E "(crontab-ui|node .*crontab-ui)" | grep -v grep)
if [ -n "$procs" ]; then
print_list "Processes matching crontab-ui? ..................... "$NC
printf "%s\n" "$procs"
echo ""
fi
# If no candidates detected, exit quietly
if [ "$candidates" ]; then
# Iterate candidates and extract interesting data
printf "%s\n" "$candidates" | while read -r svc; do
[ -n "$svc" ] || continue
# Ensure suffix .service if missing
case "$svc" in
*.service) : ;;
*) svc="$svc.service" ;;
esac
state=""
user=""
if command -v systemctl >/dev/null 2>&1; then
state=$(systemctl is-active "$svc" 2>/dev/null)
user=$(systemctl show "$svc" -p User 2>/dev/null | cut -d= -f2)
fi
[ -z "$state" ] && state="unknown"
[ -z "$user" ] && user="unknown"
echo "Service: $svc (state: $state, User: $user)" | sed -${E} "s,root,${SED_RED},g"
# Read Environment from systemd (works even if file unreadable in many setups)
envvals=$(systemctl show "$svc" -p Environment 2>/dev/null | cut -d= -f2-)
if [ -n "$envvals" ]; then
basic_user=$(printf "%s\n" "$envvals" | tr ' ' '\n' | grep -E '^BASIC_AUTH_USER=' | head -n1 | cut -d= -f2-)
basic_pwd=$(printf "%s\n" "$envvals" | tr ' ' '\n' | grep -E '^BASIC_AUTH_PWD=' | head -n1 | cut -d= -f2-)
dbpath=$(printf "%s\n" "$envvals" | tr ' ' '\n' | grep -E '^CRON_DB_PATH=' | head -n1 | cut -d= -f2-)
port=$(printf "%s\n" "$envvals" | tr ' ' '\n' | grep -E '^PORT=' | head -n1 | cut -d= -f2-)
if [ -n "$basic_user" ] || [ -n "$basic_pwd" ]; then
uprint="$basic_user"
pprint="$basic_pwd"
[ -n "$basic_pwd" ] && pprint="$basic_pwd"
echo " └─ Basic-Auth credentials in Environment: user='${uprint}' pwd='${pprint}'" | sed -${E} "s,pwd='[^']*',${SED_RED_YELLOW},g"
fi
if [ -n "$dbpath" ]; then
echo " └─ CRON_DB_PATH: $dbpath"
fi
# Check listener bound to localhost
[ -z "$port" ] && port=8000
if command -v ss >/dev/null 2>&1; then
if ss -ltn 2>/dev/null | grep -qE "127\.0\.0\.1:${port}[[:space:]]"; then
echo " └─ Listener detected on 127.0.0.1:${port} (likely Crontab UI)."
fi
else
if netstat -tnl 2>/dev/null | grep -qE "127\.0\.0\.1:${port}[[:space:]]"; then
echo " └─ Listener detected on 127.0.0.1:${port} (likely Crontab UI)."
fi
fi
# If we know DB path, try to read crontab.db for obvious secrets and check perms
if [ -n "$dbpath" ] && [ -d "$dbpath" ] && [ -r "$dbpath" ]; then
dbfile="$dbpath/crontab.db"
if [ -f "$dbfile" ]; then
perms=$(ls -ld "$dbpath" 2>/dev/null | awk '{print $1, $3, $4}')
echo " └─ DB dir perms: $perms"
if [ -w "$dbpath" ] || [ -w "$dbfile" ]; then
echo " └─ Writable by current user -> potential job injection!" | sed -${E} "s,.*,${SED_RED},g"
fi
echo " └─ Inspecting $dbfile for embedded secrets in commands (zip -P / --password / pass/token/secret)..."
grep -E "-P[[:space:]]+\S+|--password[[:space:]]+\S+|[Pp]ass(word)?|[Tt]oken|[Ss]ecret" "$dbfile" 2>/dev/null | head -n 20 | sed -${E} "s,(${SED_RED_YELLOW}),\1,g"
fi
fi
fi
echo ""
done
fi
fi

View File

@@ -0,0 +1,72 @@
# Title: Software Information - PostgreSQL Event Triggers
# ID: SI_Postgresql_Event_Triggers
# Author: HT Bot
# Last Update: 19-11-2025
# Description: Detect unsafe PostgreSQL event triggers and postgres_fdw custom scripts that grant temporary SUPERUSER
# License: GNU GPL
# Version: 1.0
# Functions Used: echo_not_found, print_2title, print_info
# Global Variables: $DEBUG, $E, $SED_GREEN, $SED_RED, $SED_YELLOW, $TIMEOUT
# Initial Functions:
# Generated Global Variables: $psql_bin, $psql_evt_output, $psql_evt_status, $psql_evt_err_line, $postgres_fdw_dirs, $postgres_fdw_hits, $old_ifs, $evtname, $enabled, $owner, $owner_is_super, $func, $func_owner, $func_owner_is_super, $IFS
# Fat linpeas: 0
# Small linpeas: 1
if [ "$DEBUG" ] || { [ "$TIMEOUT" ] && [ "$(command -v psql 2>/dev/null || echo -n '')" ]; }; then
print_2title "PostgreSQL event trigger ownership & postgres_fdw hooks"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#postgresql-event-triggers"
psql_bin="$(command -v psql 2>/dev/null || echo -n '')"
if [ "$TIMEOUT" ] && [ "$psql_bin" ]; then
psql_evt_output="$($TIMEOUT 5 "$psql_bin" -w -X -q -A -t -d postgres -c "WITH evt AS ( SELECT e.evtname, e.evtenabled, pg_get_userbyid(e.evtowner) AS trig_owner, tr.rolsuper AS trig_owner_super, n.nspname || '.' || p.proname AS function_name, pg_get_userbyid(p.proowner) AS func_owner, fr.rolsuper AS func_owner_super FROM pg_event_trigger e JOIN pg_proc p ON e.evtfoid = p.oid JOIN pg_namespace n ON p.pronamespace = n.oid LEFT JOIN pg_roles tr ON tr.oid = e.evtowner LEFT JOIN pg_roles fr ON fr.oid = p.proowner ) SELECT evtname || '|' || evtenabled || '|' || COALESCE(trig_owner,'?') || '|' || COALESCE(CASE WHEN trig_owner_super THEN 'yes' ELSE 'no' END,'unknown') || '|' || function_name || '|' || COALESCE(func_owner,'?') || '|' || COALESCE(CASE WHEN func_owner_super THEN 'yes' ELSE 'no' END,'unknown') FROM evt WHERE COALESCE(trig_owner_super,false) = false OR COALESCE(func_owner_super,false) = false;" 2>&1)"
psql_evt_status=$?
if [ $psql_evt_status -eq 0 ]; then
if [ "$psql_evt_output" ]; then
echo "Non-superuser-owned event triggers were found (trigger|enabled?|owner|owner_is_super|function|function_owner|fn_owner_is_super):" | sed -${E} "s,.*,${SED_RED},"
printf "%s\n" "$psql_evt_output" | while IFS='|' read evtname enabled owner owner_is_super func func_owner func_owner_is_super; do
case "$enabled" in
O) enabled="enabled" ;;
D) enabled="disabled" ;;
*) enabled="status_$enabled" ;;
esac
echo " - $evtname ($enabled) uses $func owned by $func_owner (superuser:$func_owner_is_super); trigger owner: $owner (superuser:$owner_is_super)" | sed -${E} "s,superuser:no,${SED_RED},g"
done
else
echo "No event triggers owned by non-superusers were returned." | sed -${E} "s,.*,${SED_GREEN},"
fi
else
psql_evt_err_line=$(printf '%s\n' "$psql_evt_output" | head -n1)
echo "Could not query pg_event_trigger (psql exit $psql_evt_status): $psql_evt_err_line" | sed -${E} "s,.*,${SED_YELLOW},"
fi
else
if ! [ "$TIMEOUT" ]; then
echo_not_found "timeout"
fi
if ! [ "$psql_bin" ]; then
echo_not_found "psql"
fi
fi
postgres_fdw_dirs="/etc/postgresql /var/lib/postgresql /var/lib/postgres /usr/lib/postgresql /usr/local/lib/postgresql /opt/supabase /opt/postgres /srv/postgres"
postgres_fdw_hits=""
for d in $postgres_fdw_dirs; do
if [ -d "$d" ]; then
old_ifs="$IFS"
IFS="\n"
for f in $(find "$d" -maxdepth 5 -type f \( -name '*postgres_fdw*.sql' -o -name '*postgres_fdw*.psql' -o -name 'after-create.sql' \) 2>/dev/null); do
if [ -f "$f" ] && grep -qiE "alter[[:space:]]+role[[:space:]]+postgres[[:space:]]+superuser" "$f" 2>/dev/null; then
postgres_fdw_hits="$postgres_fdw_hits\n$f"
fi
done
IFS="$old_ifs"
fi
done
if [ "$postgres_fdw_hits" ]; then
echo "Detected postgres_fdw custom scripts granting postgres SUPERUSER (check for SupaPwn-style window):" | sed -${E} "s,.*,${SED_RED},"
printf "%s\n" "$postgres_fdw_hits" | sed "s,^, - ,"
fi
fi
echo ""

View File

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

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

@@ -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 "|"
GREPHOMESEARCH=$(echo "$HOMESEARCH" | sed 's/ *$//g' | tr " " "|") #Remove ending spaces before putting "|"

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

@@ -270,7 +270,7 @@ class MetasploitModule < Msf::Post
if datastore['CUSTOM_URL'] != ""
url_peass = datastore['CUSTOM_URL']
else
url_peass = datastore['WINPEASS'] ? "https://github.com/peass-ng/PEASS-ng/releases/latest/download/winPEASany_ofs.exe" : "https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh"
url_peass = datastore['WINPEASS'].to_s.strip.downcase == 'true' ? "https://github.com/peass-ng/PEASS-ng/releases/latest/download/winPEASany_ofs.exe" : "https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh"
end
# If URL is set, check if it is a valid URL or local file
if url_peass.include?("http://") || url_peass.include?("https://")

View File

@@ -69,57 +69,62 @@ ECHO.
CALL :T_Progress 2
:ListHotFixes
wmic qfe get Caption,Description,HotFixID,InstalledOn | more
where wmic >nul 2>&1
if %errorlevel% equ 0 (
wmic qfe get Caption,Description,HotFixID,InstalledOn | more
) else (
powershell -command "Get-HotFix | Format-Table -AutoSize"
)
set expl=no
for /f "tokens=3-9" %%a in ('systeminfo') do (ECHO."%%a %%b %%c %%d %%e %%f %%g" | findstr /i "2000 XP 2003 2008 vista" && set expl=yes) & (ECHO."%%a %%b %%c %%d %%e %%f %%g" | findstr /i /C:"windows 7" && set expl=yes)
IF "%expl%" == "yes" ECHO. [i] Possible exploits (https://github.com/codingo/OSCP-2/blob/master/Windows/WinPrivCheck.bat)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2592799" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2592799" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS11-080 patch is NOT installed! (Vulns: XP/SP3,2K3/SP3-afd.sys)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB3143141" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB3143141" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS16-032 patch is NOT installed! (Vulns: 2K8/SP1/2,Vista/SP2,7/SP1-secondary logon)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2393802" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2393802" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS11-011 patch is NOT installed! (Vulns: XP/SP2/3,2K3/SP2,2K8/SP2,Vista/SP1/2,7/SP0-WmiTraceMessageVa)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB982799" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB982799" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-59 patch is NOT installed! (Vulns: 2K8,Vista,7/SP0-Chimichurri)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB979683" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB979683" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-21 patch is NOT installed! (Vulns: 2K/SP4,XP/SP2/3,2K3/SP2,2K8/SP2,Vista/SP0/1/2,7/SP0-Win Kernel)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2305420" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2305420" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-092 patch is NOT installed! (Vulns: 2K8/SP0/1/2,Vista/SP1/2,7/SP0-Task Sched)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB981957" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB981957" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-073 patch is NOT installed! (Vulns: XP/SP2/3,2K3/SP2/2K8/SP2,Vista/SP1/2,7/SP0-Keyboard Layout)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB4013081" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB4013081" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS17-017 patch is NOT installed! (Vulns: 2K8/SP2,Vista/SP2,7/SP1-Registry Hive Loading)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB977165" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB977165" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-015 patch is NOT installed! (Vulns: 2K,XP,2K3,2K8,Vista,7-User Mode to Ring)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB941693" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB941693" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS08-025 patch is NOT installed! (Vulns: 2K/SP4,XP/SP2,2K3/SP1/2,2K8/SP0,Vista/SP0/1-win32k.sys)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB920958" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB920958" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS06-049 patch is NOT installed! (Vulns: 2K/SP4-ZwQuerySysInfo)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB914389" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB914389" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS06-030 patch is NOT installed! (Vulns: 2K,XP/SP2-Mrxsmb.sys)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB908523" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB908523" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS05-055 patch is NOT installed! (Vulns: 2K/SP4-APC Data-Free)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB890859" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB890859" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS05-018 patch is NOT installed! (Vulns: 2K/SP3/4,XP/SP1/2-CSRSS)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB842526" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB842526" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS04-019 patch is NOT installed! (Vulns: 2K/SP2/3/4-Utility Manager)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB835732" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB835732" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS04-011 patch is NOT installed! (Vulns: 2K/SP2/3/4,XP/SP0/1-LSASS service BoF)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB841872" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB841872" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS04-020 patch is NOT installed! (Vulns: 2K/SP4-POSIX)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2975684" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2975684" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS14-040 patch is NOT installed! (Vulns: 2K3/SP2,2K8/SP2,Vista/SP2,7/SP1-afd.sys Dangling Pointer)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB3136041" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB3136041" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS16-016 patch is NOT installed! (Vulns: 2K8/SP1/2,Vista/SP2,7/SP1-WebDAV to Address)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB3057191" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB3057191" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS15-051 patch is NOT installed! (Vulns: 2K3/SP2,2K8/SP2,Vista/SP2,7/SP1-win32k.sys)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2989935" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2989935" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS14-070 patch is NOT installed! (Vulns: 2K3/SP2-TCP/IP)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2778930" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2778930" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS13-005 patch is NOT installed! (Vulns: Vista,7,8,2008,2008R2,2012,RT-hwnd_broadcast)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2850851" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2850851" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS13-053 patch is NOT installed! (Vulns: 7SP0/SP1_x86-schlamperei)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2870008" 1>NUL
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2870008" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS13-081 patch is NOT installed! (Vulns: 7SP0/SP1_x86-track_popup_menu)
ECHO.
CALL :T_Progress 2
@@ -197,7 +202,12 @@ CALL :T_Progress 1
:AVSettings
CALL :ColorLine " %E%33m[+]%E%97m Registered Anti-Virus(AV)"
WMIC /Node:localhost /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct Get displayName /Format:List | more
where wmic >nul 2>&1
if %errorlevel% equ 0 (
WMIC /Node:localhost /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct Get displayName /Format:List | more
) else (
powershell -command "Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntiVirusProduct | Select-Object -ExpandProperty displayName"
)
ECHO.Checking for defender whitelisted PATHS
reg query "HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths" 2>nul
CALL :T_Progress 1
@@ -226,7 +236,12 @@ CALL :T_Progress 3
:MountedDisks
CALL :ColorLine " %E%33m[+]%E%97m MOUNTED DISKS"
ECHO. [i] Maybe you find something interesting
(wmic logicaldisk get caption 2>nul | more) || (fsutil fsinfo drives 2>nul)
where wmic >nul 2>&1
if %errorlevel% equ 0 (
wmic logicaldisk get caption | more
) else (
fsutil fsinfo drives
)
ECHO.
CALL :T_Progress 1
@@ -273,15 +288,29 @@ tasklist /SVC
ECHO.
CALL :T_Progress 2
ECHO. [i] Checking file permissions of running processes (File backdooring - maybe the same files start automatically when Administrator logs in)
for /f "tokens=2 delims='='" %%x in ('wmic process list full^|find /i "executablepath"^|find /i /v "system32"^|find ":"') do (
for /f eol^=^"^ delims^=^" %%z in ('ECHO.%%x') do (
icacls "%%z" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO.
where wmic >nul 2>&1
if %errorlevel% equ 0 (
for /f "tokens=2 delims='='" %%x in ('wmic process list full ^|find /i "executablepath"^|find /i /v "system32"^|find ":"') do (
for /f eol^=^"^ delims^=^" %%z in ('ECHO.%%x') do (
icacls "%%z" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO.
)
)
) else (
for /f "tokens=*" %%x in ('powershell -command "Get-Process | Where-Object {$_.Path -and $_.Path -notlike '*system32*'} | Select-Object -ExpandProperty Path -Unique"') do (
icacls "%%x" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO.
)
)
ECHO.
ECHO. [i] Checking directory permissions of running processes (DLL injection)
for /f "tokens=2 delims='='" %%x in ('wmic process list full^|find /i "executablepath"^|find /i /v "system32"^|find ":"') do for /f eol^=^"^ delims^=^" %%y in ('ECHO.%%x') do (
icacls "%%~dpy\" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO.
where wmic >nul 2>&1
if %errorlevel% equ 0 (
for /f "tokens=2 delims='='" %%x in ('wmic process list full ^|find /i "executablepath"^|find /i /v "system32"^|find ":"') do for /f eol^=^"^ delims^=^" %%y in ('ECHO.%%x') do (
icacls "%%~dpy\" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO.
)
) else (
for /f "tokens=*" %%x in ('powershell -command "Get-Process | Where-Object {$_.Path -and $_.Path -notlike '*system32*'} | Select-Object -ExpandProperty Path -Unique"') do (
for /f "delims=" %%d in ("%%~dpx") do icacls "%%d" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO.
)
)
ECHO.
CALL :T_Progress 3
@@ -376,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"
@@ -452,8 +481,19 @@ ECHO.
:ServiceBinaryPermissions
CALL :ColorLine " %E%33m[+]%E%97m SERVICE BINARY PERMISSIONS WITH WMIC and ICACLS"
ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#services
for /f "tokens=2 delims='='" %%a in ('cmd.exe /c wmic service list full ^| findstr /i "pathname" ^|findstr /i /v "system32"') do (
for /f eol^=^"^ delims^=^" %%b in ("%%a") do icacls "%%b" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos usuarios %username%" && ECHO.
where wmic >nul 2>&1
if %errorlevel% equ 0 (
for /f "tokens=2 delims='='" %%a in ('cmd.exe /c wmic service list full ^| findstr /i "pathname" ^|findstr /i /v "system32"') do (
for /f eol^=^"^ delims^=^" %%b in ("%%a") do icacls "%%b" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos usuarios %username%" && ECHO.
)
) else (
for /f "tokens=*" %%a in ('powershell -command "Get-CimInstance -ClassName Win32_Service | Where-Object {$_.PathName -and $_.PathName -notlike '*system32*'} | Select-Object -ExpandProperty PathName"') do (
for /f "tokens=1 delims= " %%b in ("%%a") do (
set "svcpath=%%b"
set "svcpath=!svcpath:~1,-1!"
if exist "!svcpath!" icacls "!svcpath!" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos usuarios %username%" && ECHO.
)
)
)
ECHO.
CALL :T_Progress 1
@@ -628,16 +668,29 @@ if "%long%" == "true" (
ECHO.
ECHO. [i] Iterating through the drives
ECHO.
for /f %%x in ('wmic logicaldisk get name^| more') do (
set tdrive=%%x
if "!tdrive:~1,2!" == ":" (
%%x
CALL :ColorLine " %E%33m[+]%E%97m FILES THAT CONTAINS THE WORD PASSWORD WITH EXTENSION: .xml .ini .txt *.cfg *.config"
findstr /s/n/m/i password *.xml *.ini *.txt *.cfg *.config 2>nul | findstr /v /i "\\AppData\\Local \\WinSxS ApnDatabase.xml \\UEV\\InboxTemplates \\Microsoft.Windows.Cloud \\Notepad\+\+\\ vmware cortana alphabet \\7-zip\\" 2>nul
ECHO.
CALL :ColorLine " %E%33m[+]%E%97m FILES WHOSE NAME CONTAINS THE WORD PASS CRED or .config not inside \Windows\"
dir /s/b *pass* == *cred* == *.config* == *.cfg 2>nul | findstr /v /i "\\windows\\"
ECHO.
where wmic >nul 2>&1
if !errorlevel! equ 0 (
for /f %%x in ('wmic logicaldisk get name ^| more') do (
set tdrive=%%x
if "!tdrive:~1,2!" == ":" (
%%x
CALL :ColorLine " %E%33m[+]%E%97m FILES THAT CONTAINS THE WORD PASSWORD WITH EXTENSION: .xml .ini .txt *.cfg *.config"
findstr /s/n/m/i password *.xml *.ini *.txt *.cfg *.config 2>nul | findstr /v /i "\\AppData\\Local \\WinSxS ApnDatabase.xml \\UEV\\InboxTemplates \\Microsoft.Windows.Cloud \\Notepad\+\+\\ vmware cortana alphabet \\7-zip\\" 2>nul
ECHO.
CALL :ColorLine " %E%33m[+]%E%97m FILES WHOSE NAME CONTAINS THE WORD PASS CRED or .config not inside \Windows\"
dir /s/b *pass* == *cred* == *.config* == *.cfg 2>nul | findstr /v /i "\\windows\\"
ECHO.
)
)
) else (
for /f %%x in ('powershell -command "Get-PSDrive -PSProvider FileSystem | Where-Object {$_.Root -match ':'} | Select-Object -ExpandProperty Name"') do (
%%x:
CALL :ColorLine " %E%33m[+]%E%97m FILES THAT CONTAINS THE WORD PASSWORD WITH EXTENSION: .xml .ini .txt *.cfg *.config"
findstr /s/n/m/i password *.xml *.ini *.txt *.cfg *.config 2>nul | findstr /v /i "\\AppData\\Local \\WinSxS ApnDatabase.xml \\UEV\\InboxTemplates \\Microsoft.Windows.Cloud \\Notepad\+\+\\ vmware cortana alphabet \\7-zip\\" 2>nul
ECHO.
CALL :ColorLine " %E%33m[+]%E%97m FILES WHOSE NAME CONTAINS THE WORD PASS CRED or .config not inside \Windows\"
dir /s/b *pass* == *cred* == *.config* == *.cfg 2>nul | findstr /v /i "\\windows\\"
ECHO.
)
)
CALL :T_Progress 2
@@ -654,7 +707,8 @@ EXIT /B
:SetOnce
REM :: ANSI escape character is set once below - for ColorLine Subroutine
SET "E=0x1B["
for /F %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"
SET "E=%ESC%["
SET "PercentageTrack=0"
EXIT /B
@@ -666,5 +720,5 @@ EXIT /B
:ColorLine
SET "CurrentLine=%~1"
FOR /F "delims=" %%A IN ('FORFILES.EXE /P %~dp0 /M %~nx0 /C "CMD /C ECHO.!CurrentLine!"') DO ECHO.%%A
ECHO.!CurrentLine!
EXIT /B

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

@@ -4,6 +4,8 @@ using System.DirectoryServices;
using System.Security.AccessControl;
using System.Security.Principal;
using winPEAS.Helpers;
using winPEAS.Helpers.Registry;
using winPEAS.Info.FilesInfo.Certificates;
namespace winPEAS.Checks
{
@@ -17,7 +19,7 @@ namespace winPEAS.Checks
new List<Action>
{
PrintGmsaReadableByCurrentPrincipal,
PrintAdcsEsc4LikeTemplates
PrintAdcsMisconfigurations
}.ForEach(action => CheckRunner.Run(action, isDebug));
}
@@ -152,22 +154,91 @@ namespace winPEAS.Checks
}
}
// Detect AD CS certificate templates where current principal has dangerous control rights (ESC4-style)
private void PrintAdcsEsc4LikeTemplates()
// Detect AD CS misconfigurations
private void PrintAdcsMisconfigurations()
{
try
{
Beaprint.MainPrint("AD CS templates with dangerous ACEs (ESC4)");
Beaprint.LinkPrint(
"https://book.hacktricks.wiki/en/windows-hardening/active-directory-methodology/ad-certificates.html#esc4",
"If you can modify a template (WriteDacl/WriteOwner/GenericAll), you can abuse ESC4");
Beaprint.MainPrint("AD CS misconfigurations for ESC");
Beaprint.LinkPrint("https://book.hacktricks.wiki/en/windows-hardening/active-directory-methodology/ad-certificates.html");
if (!Checks.IsPartOfDomain)
{
Beaprint.GrayPrint(" [-] Host is not domain-joined. Skipping.");
return;
}
Beaprint.InfoPrint("Check for ADCS misconfigurations in the local DC registry");
bool IsDomainController = RegistryHelper.GetReg("HKLM", @"SYSTEM\CurrentControlSet\Services\NTDS")?.ValueCount > 0;
if (IsDomainController)
{
// For StrongBinding and CertificateMapping, More details in KB014754 - Registry key information:
// https://support.microsoft.com/en-us/topic/kb5014754-certificate-based-authentication-changes-on-windows-domain-controllers-ad2c23b0-15d8-4340-a468-4d4f3b188f16
uint? strongBinding = RegistryHelper.GetDwordValue("HKLM", @"SYSTEM\CurrentControlSet\Services\Kdc", "StrongCertificateBindingEnforcement");
switch (strongBinding)
{
case 0:
Beaprint.BadPrint(" StrongCertificateBindingEnforcement: 0 — Weak mapping allowed, vulnerable to ESC9.");
break;
case 2:
Beaprint.GoodPrint(" StrongCertificateBindingEnforcement: 2 — Prevents weak UPN/DNS mappings even if SID extension missing, not vulnerable to ESC9.");
break;
// 1 is default behavior now I think?
case 1:
default:
Beaprint.NoColorPrint($" StrongCertificateBindingEnforcement: {strongBinding} — Allow weak mapping if SID extension missing, may be vulnerable to ESC9.");
break;
}
uint? certMapping = RegistryHelper.GetDwordValue("HKLM", @"SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL", "CertificateMappingMethods");
if (certMapping.HasValue && (certMapping & 0x4) != 0)
Beaprint.BadPrint($" CertificateMappingMethods: {certMapping} — Allow UPN-based mapping, vulnerable to ESC10.");
else if(certMapping.HasValue && ((certMapping & 0x1) != 0 || (certMapping & 0x2) != 0))
Beaprint.NoColorPrint($" CertificateMappingMethods: {certMapping} — Allow weak Subject/Issuer certificate mapping.");
// 0x18 (strong mapping) is default behavior if not the flags above I think?
else
Beaprint.GoodPrint($" CertificateMappingMethods: {certMapping} — Strong Certificate mapping enabled.");
// We take the Active CA, can they be several?
string caName = RegistryHelper.GetRegValue("HKLM", $@"SYSTEM\CurrentControlSet\Services\CertSvc\Configuration", "Active");
if (!string.IsNullOrWhiteSpace(caName))
{
// Obscure Source for InterfaceFlag Enum:
// https://www.sysadmins.lv/apidocs/pki/html/T_PKI_CertificateServices_Flags_InterfaceFlagEnum.htm
uint? interfaceFlags = RegistryHelper.GetDwordValue("HKLM", $@"SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\{caName}", "InterfaceFlags");
if (!interfaceFlags.HasValue || (interfaceFlags & 512) == 0)
Beaprint.BadPrint(" IF_ENFORCEENCRYPTICERTREQUEST not set in InterfaceFlags — vulnerable to ESC11.");
else
Beaprint.GoodPrint(" IF_ENFORCEENCRYPTICERTREQUEST set in InterfaceFlags — not vulnerable to ESC11.");
string policyModule = RegistryHelper.GetRegValue("HKLM", $@"SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\{caName}\PolicyModules", "Active");
if (!string.IsNullOrWhiteSpace(policyModule))
{
string disableExtensionList = RegistryHelper.GetRegValue("HKLM", $@"SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\{caName}\PolicyModules\{policyModule}", "DisableExtensionList");
// zOID_NTDS_CA_SECURITY_EXT (OID 1.3.6.1.4.1.311.25.2)
if (disableExtensionList?.Contains("1.3.6.1.4.1.311.25.2") == true)
Beaprint.BadPrint(" szOID_NTDS_CA_SECURITY_EXT disabled for the entire CA — vulnerable to ESC16.");
else
Beaprint.GoodPrint(" szOID_NTDS_CA_SECURITY_EXT not disabled for the CA — not vulnerable to ESC16.");
}
else
{
Beaprint.GrayPrint(" [-] Policy Module not found. Skipping.");
}
}
else
{
Beaprint.GrayPrint(" [-] Certificate Authority not found. Skipping.");
}
}
else
{
Beaprint.GrayPrint(" [-] Host is not a domain controller. Skipping ADCS Registry check");
}
// Detect AD CS certificate templates where current principal has dangerous control rights(ESC4 - style)
Beaprint.InfoPrint("\nIf you can modify a template (WriteDacl/WriteOwner/GenericAll), you can abuse ESC4");
var configNC = GetRootDseProp("configurationNamingContext");
if (string.IsNullOrEmpty(configNC))
{

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

View File

@@ -19,6 +19,14 @@ Download the **[latest releas from here](https://github.com/peass-ng/PEASS-ng/re
powershell "IEX(New-Object Net.WebClient).downloadString('https://raw.githubusercontent.com/peass-ng/PEASS-ng/master/winPEAS/winPEASps1/winPEAS.ps1')"
```
## Recent Updates
- Added Active Directory awareness checks to highlight Kerberos-only environments (NTLM restrictions) and time skew issues before attempting ticket-based attacks.
- winPEAS.ps1 now reviews AD-integrated DNS ACLs to flag zones where low-privileged users can register/modify records (dynamic DNS hijack risk).
- Enumerates high-value SPN accounts and weak gMSA password readers so you can immediately target Kerberoastable admins or abused service accounts.
- Surfaces Schannel certificate mapping settings to warn about ESC10-style certificate abuse opportunities when UPN mapping is enabled.
## Advisory
All the scripts/binaries of the PEAS Suite should be used for authorized penetration testing and/or educational purposes only. Any misuse of this software will not be the responsibility of the author or of any other collaborator. Use it at your own networks and/or with the network owner's permission.

View File

@@ -148,6 +148,244 @@ function Get-ClipBoardText {
}
}
function Get-DomainContext {
try {
return [System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain()
}
catch {
return $null
}
}
function Convert-SidToName {
param(
$SidInput
)
if ($null -eq $SidInput) { return $null }
try {
if ($SidInput -is [System.Security.Principal.SecurityIdentifier]) {
$sidObject = $SidInput
}
else {
$sidObject = New-Object System.Security.Principal.SecurityIdentifier($SidInput)
}
return $sidObject.Translate([System.Security.Principal.NTAccount]).Value
}
catch {
try { return $sidObject.Value }
catch { return [string]$SidInput }
}
}
function Get-WeakDnsUpdateFindings {
param(
[System.DirectoryServices.ActiveDirectory.Domain]$DomainContext
)
if (-not $DomainContext) { return @() }
$domainDN = $DomainContext.GetDirectoryEntry().distinguishedName
$forestDN = $DomainContext.Forest.RootDomain.GetDirectoryEntry().distinguishedName
$paths = @(
"LDAP://CN=MicrosoftDNS,DC=DomainDnsZones,$domainDN",
"LDAP://CN=MicrosoftDNS,DC=ForestDnsZones,$forestDN",
"LDAP://CN=MicrosoftDNS,$domainDN"
)
$weakPatterns = @(
"authenticated users",
"everyone",
"domain users"
)
$dangerousRights = @("GenericAll", "GenericWrite", "CreateChild", "WriteProperty", "WriteDacl", "WriteOwner")
$findings = @()
foreach ($path in $paths) {
try {
$container = New-Object System.DirectoryServices.DirectoryEntry($path)
$null = $container.NativeGuid
}
catch { continue }
$searcher = New-Object System.DirectoryServices.DirectorySearcher($container)
$searcher.Filter = "(objectClass=dnsZone)"
$searcher.PageSize = 500
$results = $searcher.FindAll()
foreach ($result in $results) {
try {
$zoneEntry = $result.GetDirectoryEntry()
$zoneEntry.Options.SecurityMasks = [System.DirectoryServices.SecurityMasks]::Dacl
$sd = $zoneEntry.ObjectSecurity
foreach ($ace in $sd.Access) {
if ($ace.AccessControlType -ne 'Allow') { continue }
$principal = Convert-SidToName $ace.IdentityReference
if (-not $principal) { continue }
$principalLower = $principal.ToLower()
if (-not ($weakPatterns | Where-Object { $principalLower -like "*${_}*" })) { continue }
$rights = $ace.ActiveDirectoryRights.ToString()
if (-not ($dangerousRights | Where-Object { $rights -like "*${_}*" })) { continue }
$findings += [pscustomobject]@{
Zone = $zoneEntry.Properties["name"].Value
Partition = $path.Split(',')[1]
Principal = $principal
Rights = $rights
}
}
}
catch { continue }
}
}
return ($findings | Sort-Object Zone, Principal -Unique)
}
function Get-GmsaReadersReport {
param(
[System.DirectoryServices.ActiveDirectory.Domain]$DomainContext
)
if (-not $DomainContext) { return @() }
$domainDN = $DomainContext.GetDirectoryEntry().distinguishedName
try {
$searcher = New-Object System.DirectoryServices.DirectorySearcher
$searcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$domainDN")
$searcher.Filter = "(&(objectClass=msDS-GroupManagedServiceAccount))"
$searcher.PageSize = 500
[void]$searcher.PropertiesToLoad.Add("sAMAccountName")
[void]$searcher.PropertiesToLoad.Add("msDS-GroupMSAMembership")
$results = $searcher.FindAll()
}
catch { return @() }
$report = @()
foreach ($result in $results) {
$name = $result.Properties["samaccountname"]
$blobs = $result.Properties["msds-groupmsamembership"]
if (-not $blobs) { continue }
$principals = @()
foreach ($blob in $blobs) {
try {
$raw = New-Object System.Security.AccessControl.RawSecurityDescriptor (, $blob)
foreach ($ace in $raw.DiscretionaryAcl) {
$sid = Convert-SidToName $ace.SecurityIdentifier
if ($sid) { $principals += $sid }
}
}
catch { continue }
}
if ($principals.Count -eq 0) { continue }
$principals = $principals | Sort-Object -Unique
$weak = $principals | Where-Object { $_ -match 'Domain Users|Authenticated Users|Everyone' }
$report += [pscustomobject]@{
Account = ($name | Select-Object -First 1)
Allowed = ($principals -join ", ")
WeakPrincipals = if ($weak) { $weak -join ", " } else { "" }
}
}
return $report
}
function Get-PrivilegedSpnTargets {
param(
[System.DirectoryServices.ActiveDirectory.Domain]$DomainContext
)
if (-not $DomainContext) { return @() }
$domainDN = $DomainContext.GetDirectoryEntry().distinguishedName
$keywords = @(
"Domain Admin",
"Enterprise Admin",
"Administrators",
"Exchange",
"IT_",
"Schema Admin",
"Account Operator",
"Server Operator",
"Backup Operator",
"DnsAdmin"
)
try {
$searcher = New-Object System.DirectoryServices.DirectorySearcher
$searcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$domainDN")
$searcher.Filter = "(&(objectClass=user)(servicePrincipalName=*))"
$searcher.PageSize = 500
[void]$searcher.PropertiesToLoad.Add("sAMAccountName")
[void]$searcher.PropertiesToLoad.Add("memberOf")
$results = $searcher.FindAll()
}
catch { return @() }
$findings = @()
foreach ($res in $results) {
$groups = $res.Properties["memberof"]
if (-not $groups) { continue }
$matchedGroups = @()
foreach ($group in $groups) {
$cn = ($group -split ',')[0] -replace '^CN=',''
if ($keywords | Where-Object { $cn -like "*${_}*" }) {
$matchedGroups += $cn
}
}
if ($matchedGroups.Count -gt 0) {
$findings += [pscustomobject]@{
User = ($res.Properties["samaccountname"] | Select-Object -First 1)
Groups = ($matchedGroups | Sort-Object -Unique) -join ', '
}
}
}
return ($findings | Sort-Object User | Select-Object -First 12)
}
function Get-NtlmPolicySummary {
try {
$msv = Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0' -ErrorAction Stop
}
catch { return $null }
$lsa = Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa' -ErrorAction SilentlyContinue
return [pscustomobject]@{
RestrictReceiving = $msv.RestrictReceivingNTLMTraffic
RestrictSending = $msv.RestrictSendingNTLMTraffic
LmCompatibility = if ($lsa) { $lsa.LmCompatibilityLevel } else { $null }
}
}
function Get-TimeSkewInfo {
param(
[System.DirectoryServices.ActiveDirectory.Domain]$DomainContext
)
if (-not $DomainContext) { return $null }
try {
$pdc = $DomainContext.PdcRoleOwner.Name
}
catch { return $null }
try {
$stripchart = w32tm /stripchart /computer:$pdc /dataonly /samples:3 2>$null
$sample = $stripchart | Where-Object { $_ -match ',' } | Select-Object -Last 1
if (-not $sample) { return $null }
$parts = $sample.Split(',')
if ($parts.Count -lt 2) { return $null }
$offsetString = $parts[1].Trim().TrimEnd('s')
[double]$offsetSeconds = 0
if (-not [double]::TryParse($offsetString, [ref]$offsetSeconds)) { return $null }
return [pscustomobject]@{
Source = $pdc
OffsetSeconds = $offsetSeconds
RawSample = $sample
}
}
catch {
return $null
}
}
function Get-AdcsSchannelInfo {
$info = [ordered]@{
MappingValue = $null
UpnMapping = $false
ServiceState = $null
}
try {
$schannel = Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL' -Name 'CertificateMappingMethods' -ErrorAction Stop
$info.MappingValue = $schannel.CertificateMappingMethods
if (($schannel.CertificateMappingMethods -band 0x4) -eq 0x4) { $info.UpnMapping = $true }
}
catch { }
$svc = Get-Service -Name certsrv -ErrorAction SilentlyContinue
if ($svc) { $info.ServiceState = $svc.Status }
return [pscustomobject]$info
}
function Search-Excel {
[cmdletbinding()]
Param (
@@ -1226,6 +1464,95 @@ Write-Host -ForegroundColor Blue "=========|| LISTENING PORTS"
Start-Process NETSTAT.EXE -ArgumentList "-ano" -Wait -NoNewWindow
######################## ACTIVE DIRECTORY / IDENTITY MISCONFIG CHECKS ########################
Write-Host ""
if ($TimeStamp) { TimeElapsed }
Write-Host -ForegroundColor Blue "=========|| ACTIVE DIRECTORY / IDENTITY MISCONFIG CHECKS"
$domainContext = Get-DomainContext
if (-not $domainContext) {
Write-Host "Host appears to be in a workgroup or the AD context could not be resolved. Skipping domain-specific checks." -ForegroundColor DarkGray
}
else {
$ntlmStatus = Get-NtlmPolicySummary
if ($ntlmStatus) {
$recvValue = if ($ntlmStatus.RestrictReceiving -ne $null) { [int]$ntlmStatus.RestrictReceiving } else { -1 }
$sendValue = if ($ntlmStatus.RestrictSending -ne $null) { [int]$ntlmStatus.RestrictSending } else { -1 }
$lmValue = if ($ntlmStatus.LmCompatibility -ne $null) { [int]$ntlmStatus.LmCompatibility } else { -1 }
$ntlmMsg = "Receiving:{0} Sending:{1} LMCompat:{2}" -f $recvValue, $sendValue, $lmValue
if ($recvValue -ge 1 -or $sendValue -ge 1 -or $lmValue -ge 5) {
Write-Host "[!] NTLM is restricted/disabled ($ntlmMsg). Expect Kerberos-only auth paths (sync time before Kerberoasting)." -ForegroundColor Yellow
}
else {
Write-Host "[i] NTLM restrictions appear relaxed ($ntlmMsg)."
}
}
$timeSkew = Get-TimeSkewInfo -DomainContext $domainContext
if ($timeSkew) {
$offsetAbs = [math]::Abs($timeSkew.OffsetSeconds)
$timeMsg = "Offset vs {0}: {1:N3}s (sample: {2})" -f $timeSkew.Source, $timeSkew.OffsetSeconds, $timeSkew.RawSample.Trim()
if ($offsetAbs -gt 5) {
Write-Host "[!] Significant Kerberos time skew detected - $timeMsg" -ForegroundColor Yellow
}
else {
Write-Host "[i] Kerberos time offset looks OK - $timeMsg"
}
}
$dnsFindings = @(Get-WeakDnsUpdateFindings -DomainContext $domainContext)
if ($dnsFindings.Count -gt 0) {
Write-Host "[!] AD-integrated DNS zones allow low-priv principals to write records (dynamic DNS hijack / service MITM risk)." -ForegroundColor Yellow
$dnsFindings | Format-Table Zone,Partition,Principal,Rights -AutoSize | Out-String | Write-Host
}
else {
Write-Host "[i] No obvious insecure dynamic DNS ACLs found with current privileges."
}
$spnFindings = @(Get-PrivilegedSpnTargets -DomainContext $domainContext)
if ($spnFindings.Count -gt 0) {
Write-Host "[!] High-value SPN accounts identified (prime Kerberoast targets):" -ForegroundColor Yellow
$spnFindings | Format-Table User,Groups -AutoSize | Out-String | Write-Host
}
else {
Write-Host "[i] No privileged SPN users detected via quick LDAP search."
}
$gmsaReport = @(Get-GmsaReadersReport -DomainContext $domainContext)
if ($gmsaReport.Count -gt 0) {
$weakGmsa = $gmsaReport | Where-Object { $_.WeakPrincipals -ne "" }
if ($weakGmsa) {
Write-Host "[!] gMSA passwords readable by low-priv groups/principals: " -ForegroundColor Yellow
$weakGmsa | Select-Object Account, WeakPrincipals | Format-Table -AutoSize | Out-String | Write-Host
}
else {
Write-Host "[i] gMSA accounts discovered (review allowed readers below)."
$gmsaReport | Select-Object Account, Allowed | Sort-Object Account | Select-Object -First 5 | Format-Table -Wrap | Out-String | Write-Host
}
}
else {
Write-Host "[i] No gMSA objects found via LDAP."
}
$adcsInfo = Get-AdcsSchannelInfo
if ($adcsInfo.MappingValue -ne $null) {
$hex = ('0x{0:X}' -f [int]$adcsInfo.MappingValue)
if ($adcsInfo.UpnMapping) {
Write-Host ("[!] Schannel CertificateMappingMethods={0} (UPN mapping allowed) - ESC10 certificate abuse possible if you can edit another user's UPN." -f $hex) -ForegroundColor Yellow
}
else {
Write-Host ("[i] Schannel CertificateMappingMethods={0} (UPN mapping flag not set)." -f $hex)
}
if ($adcsInfo.ServiceState) {
Write-Host ("[i] AD CS service state: {0}" -f $adcsInfo.ServiceState)
}
}
else {
Write-Host "[i] Could not read Schannel certificate mapping configuration." -ForegroundColor DarkGray
}
}
Write-Host ""
if ($TimeStamp) { TimeElapsed }
Write-Host -ForegroundColor Blue "=========|| ARP Table"
@@ -1323,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