XUT_ / COURSES / PENETRATION TESTER

Exploitation - Denial of Service

Denegación de Servicio

Prototype pollution, una vulnerabilidad crítica en aplicaciones JavaScript, puede llevar a DoS, entre otras consecuencias. Esto ocurre cuando un atacante manipula el prototipo de un objeto ampliamente utilizado, causando que la aplicación se comporte inesperadamente o que incluso crashee. En JavaScript, los objetos heredan propiedades y métodos de los prototipos, y alterar estos prototipos afecta directamente a los objetos.

Por ejemplo, si un atacante contamina el método Object.prototype.toString, cada llamada posterior a este método por parte de cualquier objeto ejecutará el comportamiento alterado. En una aplicación compleja donde toString es frecuentemente usada, esto puede llevar a resultados inesperados, potencialmente causando que la aplicación funcione mal. El método toString es usado universalmente en JavaScript.

Si el método contaminado lleva a un procesamiento ineficiente o a un bucle infinito, puede agotar los recursos del sistema causando un DoS. Además, puede interferir con la lógica de negocio.


Ejemplo Práctico

  • De nuevo, visitaremos http://IP:5000 y veremos si podemos crashear el servidor. Como ya hemos hablado, tenemos el método Object.prototype.toString.
  • Visitamos la página del perfil de cualquier amigo y podemos ver que así es como se comporta el cliente:
html
<form action="/clone-album/1" method="post" class="mb-4">
	<h2 class="mb-3">Clone Album of Josh</h2>
	<div class="form-group">
		<label for="selectedAlbum">Select an Album to Clone:</label>
		<select class="form-control" name="selectedAlbum" id="selectedAlbum">
				<option value="Trip to US">
					Trip to US
				</option>
		</select>
	</div>
	<div class="form-group">
		<label for="newAlbumName">New Album Name:</label>
		<input type="text" class="form-control" name="newAlbumName" id="newAlbumName"
			placeholder="Enter new album name">
	</div>
	<button type="submit" class="btn btn-primary">Clone Album</button>
</form>
  • Vemos que esta función lama a la función merge. ¿Qué pasa si intentamos mandar un payload que sobrescriba una función existente como toString() y luego la llamamos desde un objeto?
  • Para preparar el payload tomaremos un simple JSON:
javascript
{"__proto__": {"toString": "Just crash the server"}}
  • Vamos al perfil e introducimos el payload en lugar del nombre del álbum. Exploitation - Denial of Service
  • Decodearemos el payload una vez que app.js reciba la petición, parsee el JSON y asigne el valor de la función toString en la propiedad __proto__ del objeto friend.
  • Esto crea un comportamiento abrupto ya que toString es ampliamente utilizada por diferentes objetos. Podemos hacer click en clonar el álbum y pasa lo siguiente: Exploitation - Denial of Service
  • El TypeError que obtenemos es Object.prototype.toString.call is not a function, ya que hemos sobrescrito la función usando PP.
  • Puedes sobrescribir muchas otras funciones incrustadas como toJSON, valueOf, constructor, etc, pero la aplicación no crasheará siempre. Depende de cuánto se use la función que sobrescribes.