Hace poco, decidí preparar una presentación sobre vulnerabilidades web, en concreto sobre ataques XSS. Para ello debía estudiar cómo funcionan los sistemas de filtrado.
Escogí el sitio de redes sociales más popular en Rusia, VKontakte.ru, para hacer mis pruebas. Algo que me llamó la atención fue el nuevo sistema de estados del usuario.
Abajo puedes ver el código HTML en la parte de la página donde los usuarios editan sus mensajes de estado:
Como puedes ver, la función infoCheck () realiza el filtrado. El estado en sí está ubicado en esta cadena de códigos:
Lo que tenemos aquí es un filtrado de dos pasos. El primer paso es cuando el usuario escribe el mensaje con su nuevo estado. El segundo paso ocurre al convertir el mensaje del estado a texto y devolverlo a la página para que otros también puedan verlo.
El segundo paso funciona bien y sería imposible convertirlo a XSS activo, pero las cosas no se ven tan bien en el primer paso, así que vamos a analizarlo con más detalle.
Como era de esperar, el simple <script>alert()</script> no funcionaba y el estado seguía vacío. Otros intentos “similares al script” tampoco funcionaron, parece que esta cadena en particular está explícitamente filtrada.
Sin embargo, la etiqueta <script> no es esencial para que se ejecute un script. La primera vulnerabilidad se introduce al equipo del usuario usando la etiqueta <img>: Al ingresar la cadena <img src=1.gif onerror=some_function> como estado del usuario, podemos hacer que se ejecute esa función. Por ejemplo, podemos llamar la función profile.infoSave(), que tiene como nombre un parámetro vacío para vaciar el estado, pero usamos un parámetro que hayamos escogido. Por lo tanto, si escribimos <img src=1.gif onerror=profile.infoSave(‘XSS’)>, la cadena “XSS” aparece como nuestro mensaje de estado:
Otra vulnerabilidad interesante asociada con el filtrado es que la etiqueta <A> no se filtra. Si escribimos <A HREF=”//www.google.com/”>XSS</A> en nuestro estado, aparece… un hipervínculo que abre una ventana de edición de estados cuando se pulsa en él y, un rato después, abre Google.com.
Como todos sabemos, XSS = Cross site scripting, así que estudié la próxima vulnerabilidad desde un sitio web externo con un script incluido. Además de las etiquetas sin filtrar que mencioné arriba, la etiqueta <iframe> también pasó el filtro con éxito. Por lo tanto, al escribir <iframe src=”yoursite.com” width=”100%” height=”300″> en la línea del estado se produce un iframe que ejecutará el script que mencioné arriba cargado en la página. Abajo pueden ver un ejemplo de cómo puede verse el iframe:
Esta vulnerabilidad es más seria que las otras dos. Una forma de explotarla es creando una URL para cambiar el estado del usuario y enviarla a la víctima con la esperanza de que pulse en ella. El script se ejecutará en la página del usuario incluso antes de que aparezca el mensaje de estado. Este es un ejemplo clásico de XSS pasivo.
Estas vulnerabilidades existen desde el 01 de agosto de 2010, cuando se estrenó el nuevo sistema de actualización de estados de los usuarios. Contactamos a la administración de VKontakte el 01 de marzo de 2011, y las vulnerabilidades se parcharon el 03 de marzo.
Vulnerabilidades XSS en el sitio de redes sociales ruso “VKontakte”