Un sigiloso ataque en SII.cl
[This post is only available in Spanish because the target audience is in Chile]
En el último tiempo, han circulado diversos correos falsos en nombre del SII (Servicio de Impuesto Internos) en el marco de ataques de phishing y distribución de malware.
Analizando algunos de ellos, es notorio que se trata de correos falsos, dado que presentan:
- Faltas de ortografía.
- URLs en otros dominios.
- IPs externas.
- Descarga de ejecutables
.exe
.
Si no presentaran tales características, la probabilidad de infectar/engañar a la gente que recibe tales correos aumenta considerablemente. En este post revisaremos una vulnerabilidad de Cross-Site Scripting en el sitio SII.cl que puede ser explotada sigilosamente y que permite lograr acceso a la cuenta de la víctima. Esta falla de seguridad se encuentra parchada desde Septiembre de 2018.
El comienzo
Tras hacer una boleta en la página del Servicio de Impuestos Internos, me llamó la atención el formato de las URLs en el sitio. Por ejemplo, el formulario de ingreso se encuentra en la siguiente URL:
Esta URL contiene dos URLS separadas por ?
: la URL en el cuadro amarillo despliega la página actual, en este caso el formulario de ingreso, y la URL en el cuadro rojo es usada para redireccionar al usuario post-autenticación exitosa. Frente a este comportamiento, establecí la siguiente hipótesis:
Si la segunda URL (cuadro rojo) apunta a una página vulnerable a Cross-Site Scripting que puede ser explotable a través de parámetros que son parte de la URL, podría crear un escenario donde el usuario se autentica en la página del SII, es redireccionado a la página vulnerable y obtengo sus tokens de sesión. De esa forma, puedo lograr acceso a su cuenta sin que el usuario lo note.
Para lograr el objetivo, obtener los tokens de sesión implica que puedo leer las cookies desde Javascript, lo cual es posible ya que las cookies de sii.cl no tienen la opción HttpOnly habilitada.
Encontrando la página vulnerable
Probando una serie de endpoints en el sitio del SII, llegué a esta URL que es solo accesible para usuarios autenticados:
https://www1.sii.cl/cgi-bin/Portal001/mipeSelEmpresa.cgi?DESDE_DONDE_URL=OPCN%3D110%26TIPO%3D4
Esta página tiene la siguiente respuesta:
Como vemos, hay dos puntos de inyección.
- La URL es usada dentro del tag
script
en la asignaciónwindow.location.href
para redireccionar el navegador a la página de autenticación, tras mostrar unalert
(línea 14). - El parámetro
DESDE_DONDE_URL
es reflejado como parte del cuerpo de la página.
Dado el orden del código, el tag script
es lo primero que se ejecuta y realiza inmediatamente una redirección a otra página, entonces no es posible en primera instancia explotar el segundo punto de inyección.
Dado que el parámetro DESDE_DONDE_URL
se encuentra al final de la URL y nuestra inyección será en este punto, con el fin de ser más claro solo nos referiremos a su contenido y no a mostrar la URL completa cada vez.
Explotando la vulnerabilidad en <script>
Usaremos alert(1)
como payload en nuestra explotación para mostrar un mensaje de alerta que nos indique nuestra vulnerabilidad fue explotada exitosamente.
Tras incluir los caracteres '/;)
en el parámetro DESDE_DONDE_URL
, podemos asegurar que el parámetro DESDE_DONDE_URL
reflejado en el tag script
no escapa estos caracteres especiales y es posible una inyección de código Javascript.
Ahora viene una parte interesante: ¿cómo evitamos la redirección que está haciendo window.location.href
? En este post en StackExchange explican una técnica de reemplazar el string actual para evitar la redirección. Después de unos intentos, pude crear un payload válido para evitar la redirección.
DESDE_DONDE_URL=OPCN%3D110%26TIPO%3D4'.replace(/^.*$/,'%23');
El valor %23
corresponde al caracter #
y debe ser codificado, sino el navegador piensa que es el identificador de fragmento y no lo envía al servidor. Finalmente, el navegador evalua window.location.href='#'
, por lo que no realiza la redirección.
Luego de evitar la redirección, podemos inyectar nuestro payload y agregar //
al final para comentar los caracteres que siguen. Finalmente, nuestro parámetro luce así:
DESDE_DONDE_URL=OPCN%3D110%26TIPO%3D4'.replace(/^.*$/,'%23');alert(1);//
Como prueba de concepto, funciona. Sin embargo, en el mundo real, los navegadores aplican codificación URL sobre el caracter '
, por lo que nuestro vector falla al requerir imprescindiblemente de este caracter.
Retomando el segundo punto de inyección
Revisamos una vez más la situación inicial.
Tras incluir los caracteres =>()</|”
en el parámetro DESDE_DONDE_URL
, podemos asegurar que el parámetro DESDE_DONDE_URL
reflejado en el tag input
no escapa estos caracteres especiales y es posible una inyección de código HTML.
Ahora el punto es: ¿cómo llegamos a ejecutar nuestro vector si el tag script
se ejecutara antes y redireccionará a otra página? La solución es hacer ese redireccionamiento inválido debido a un error de sintaxis en Javascript.
Las variables que contienen strings en Javascript son declaradas como variable = 'value';
donde en este caso '
son los delimitadores del valor de la variable. En caso de que falte un delimitador, el interprete de Javascript lanzará una excepción relacionada con una falla de sintaxis.
En la página nos encontramos con el código window.location.href='...DESDE_DONDE_URL=OPCN%3D110%26TIPO%3D4';
y la parte final del string esta bajo nuestro control, por lo podríamos escapar el '
final con un \
para hacer la declaración inválida.
Finalmente, nuestro parámetro queda así:
DESDE_DONDE_URL=OPCN%3D110%26TIPO%3D4\
Y la redirección no es realizada por error de sintaxis en el tag script
.
Explotando la vulnerabilidad exitosamente
Como nuestro parámetro DESDE_DONDE_URL
debe terminar en backslash ( \
), nuestro payload para explotar la vulnerabilidad debería ir antes de este caracter. Ocupando como payload un tag SVG, el parámetro queda:
DESDE_DONDE_URL=OPCN%3D110%26TIPO%3D4"><svg%20onload=alert(1)//\
En la respuesta del servidor se puede ver que nuestro tag SVG
fue inyectado correctamente.
La explotación es exitosa, tanto desde BurpSuite como desde un navegador como Firefox.
Uniendo los hilos
Ahora el desafío es crear el flujo para que un usuario se autentique en el formulario de ingreso y sea redirigido a esta página vulnerable con el payload contenido en el parámetro DESDE_DONDE_URL
.
Para esto, construimos una nueva URL de ingreso:
https://zeusr.sii.cl//AUT2000/InicioAutenticacion/IngresoRutClave.html?https://www1.sii.cl/cgi-bin/Portal001/mipeSelEmpresa.cgi?DESDE_DONDE_URL=OPCN%3D110%26TIPO%3D4"><svg%20onload=alert(1)//\
Ingresamos los datos de usuario y contraseña, la autenticación es exitosa pero ocurre un error. El endpoint contra el que se realiza la autenticación ( CAutInicio.cgi
) hace una redirección en Javascript a nuestra URL vulnerable. El tema es que el \
que añadimos al final hace fallar la redirección porque escapa el apostrofe en este contexto.
Por lo tanto, debemos escaparlo para esta primera redirección, por lo tanto el payload queda:
DESDE_DONDE_URL=OPCN%3D110%26TIPO%3D4"><svg%20onload=alert(1)//\\
Lo interesante es que el navegador, al enviar los datos de autenticación mediante POST, aplica codificación URL sobre \\
, resultando en %5c%5c
. En el primer endpoint (CAutInicio.cgi
) es decodificado, mostrandose como \\
y permitiendo una correcta declaración de string en Javascript, y al ejecutar location.replace()
el navegador reemplaza \\
por \
. Gracias a este comportamiento, nuestra explotación es exitosa.
Impacto
Siguiendo con nuestra hipótesis inicial, tras lograr encontrar una página vulnerable explotable a través de parámetros GET
, ahora viene la parte de obtener las cookies. En este caso, usé una técnica con un tag <img>
que exfiltra las cookies presentes en document.cookie
a un servidor bajo mi control.
A continuación mostramos un video con la explotación de la vulnerabilidad. Unos puntos a tener en cuenta:
- El video comienza con el navegador y nuestra “URL maliciosa” ya cargada.
- Como ven, es la página real del SII y sus largas URLs hacen propicio el ataque, ya que nuestro payload no se muestra inicialmente en la barra de URL, levantando menos sospechas.
- La única interacción que realiza la víctima es autenticarse en el sitio real del SII, como normalmente uno lo hace.
- El video muestra una víctima no autenticada en el sitio del SII, pero víctimas autenticadas también eran vulnerables.
- El script
steal_cookie.py
levanta un servidor web bajo mi control que espera la petición realizada involuntariamente por la víctima post-autenticación. - En la terminal se muestra
REDACTED
en algunos valores de la cookie ya que es información sensible de mi cuenta. Sin embargo, esta información sensible es guardada encookie.txt
para posteriormente acceder a la cuenta.
Conclusiones
El impacto de esta vulnerabilidad es alto. Guillermo, co-founder de alertot, visualizo los siguientes escenarios:
- Generar documentos como boletas de honorarios.
- Acceder a información de impuestos y alterar documentos.
- Alterar información de la participacion en sociedades.
- Aceptar y rechazar facturas.
¿Recuerdan los escándalos en política relacionados con boletas falsas? No es necesario ir muy lejos para ver el potencial que tienen las vulnerabilidades en el sitio de impuestos de un país.
Esta vulnerabilidad fue reportada responsablemente en Septiembre de 2018. A pesar de no tener un conducto regularizado para reportar vulnerabilidades (logré el contacto a través de un amigo), una semana después el fallo estaba arreglado.