Acceder a SMF con contraseña hasheada ¿es realmente posible?

Iniciado por Xyzed, 11 Mayo 2021, 08:08 AM

0 Miembros y 1 Visitante están viendo este tema.

Xyzed

Hola.

Hace años que utilizó SMF, hoy me cruce en el foro con un post interesante:

Inicio de sesión SMF a través de hash de contraseña

En resumen se argumenta que es posible acceder a SMF mediante una contraseña hasheada (haciendo referencia a que gracias a esto, no sirve de nada el hash ante un posible robo de la base de datos).
Esto ya que mediante el método POST que utiliza el formulario de login lo que se hace es enviar la contraseña cifrada + la sesión ID.

Es decir:
Código (html4strict) [Seleccionar]

SHA1(hash + session_id)


Código (html4strict) [Seleccionar]

<form action="https://tuforo.ejemplo/index.php?action=login2" name="frmLogin" id="frmLogin" method="post" accept-charset="UTF-8" onsubmit="hashLoginPassword(this, 'add5f76205f957b650bb0a5aa71e6ccd');">
<!-- Viendo esto en el onsubmit-->


¿Es realmente es esto posible o entendí mal? Supuestamente está "solucionado" en 2.1.

Edit:
Código (javascript) [Seleccionar]

//Función mencionada encargada del hash que viene por defecto en SMF.
function hashLoginPassword(doForm, cur_session_id)
{
// Compatibility.
if (cur_session_id == null)
cur_session_id = smf_session_id;

if (typeof(hex_sha1) == 'undefined')
return;
// Are they using an email address?
if (doForm.user.value.indexOf('@') != -1)
return;

// Unless the browser is Opera, the password will not save properly.
if (!('opera' in window))
doForm.passwrd.autocomplete = 'off';

doForm.hash_passwrd.value = hex_sha1(hex_sha1(doForm.user.value.php_to8bit().php_strtolower() + doForm.passwrd.value.php_to8bit()) + cur_session_id);

// It looks nicer to fill it with asterisks, but Firefox will try to save that.
if (is_ff != -1)
doForm.passwrd.value = '';
else
doForm.passwrd.value = doForm.passwrd.value.replace(/./g, '*');
}




Saludos.
...

MinusFour

Pues si, no se que estaban pensando con esto... La única forma sería implementar algo como RSA y un protocolo para intercambio de llaves. Todo esto ya lo hace SSL, así que no tiene caso hacer esto del lado del cliente.

Danielㅤ

Hola, hasta donde tengo conocimientos eso no es así...

SMF 2.0 utiliza éste método para cifrar las contraseñas de los usuarios:

Código (php) [Seleccionar]
$hash = sha1(strtolower($username) . $password);

Las contraseñas utilizan un salt y ese salt es el nombre de usuario, entonces se cifra el usuario + la contraseña.

Y no, no es posible acceder como piensas aunque tengas la contraseña hasheada ya que al intentar iniciar sesión el foro vuelve a hashear la contraseña y aunque esté hasheada la va a volver a cifrar igual a otra distinta, por lo que obviamente no será la misma porque no van a coincidir.

De todas maneras en SMF 2.1 se mejora el método de cifrado utilizando lo más seguro hasta ahora que es bcrypt.


Saludos
¡Regresando como cual Fenix! ~
Bomber Code © 2021 https://www.bombercode.net/foro/

Ayudas - Aportes - Tutoriales - Y mucho mas!!!

MinusFour

Cita de: [D]aniel en 11 Mayo 2021, 16:21 PM
Hola, hasta donde tengo conocimientos eso no es así...

SMF 2.0 utiliza éste método para cifrar las contraseñas de los usuarios:

Código (php) [Seleccionar]
$hash = sha1(strtolower($username) . $password);

Las contraseñas utilizan un salt y ese salt es el nombre de usuario, entonces se cifra el usuario + la contraseña.

Y no, no es posible acceder como piensas aunque tengas la contraseña hasheada ya que al intentar iniciar sesión el foro vuelve a hashear la contraseña y aunque esté hasheada la va a volver a cifrar igual a otra distinta, por lo que obviamente no será la misma porque no van a coincidir.

De todas maneras en SMF 2.1 se mejora el método de cifrado utilizando lo más seguro hasta ahora que es bcrypt.


Saludos

El salt lo único que está haciendo es que no puedas usar dumps de otros sistemas que no usen este salt.

En teoría, si tu tienes el hash (el hash usuario+password) tu puedes iniciar sesión con ese usuario. Por ejemplo, si encuentras una vulnerabilidad que imprima el hash de un usuario podrías iniciar sesión con ese usuario. En cambio, si no se hiciera esto del lado del cliente, el atacante no podría usar este hash.

Incluso los desarrolladores de SMF confirmaron que era posible y que por eso lo han cambiado en el 2.1, lo dicen justo ahi en el link del mensaje principal.

Xyzed

Cita de: [D]aniel en 11 Mayo 2021, 16:21 PM
Hola, hasta donde tengo conocimientos eso no es así...

SMF 2.0 utiliza éste método para cifrar las contraseñas de los usuarios:

Código (php) [Seleccionar]
$hash = sha1(strtolower($username) . $password);

Las contraseñas utilizan un salt y ese salt es el nombre de usuario, entonces se cifra el usuario + la contraseña.

Y no, no es posible acceder como piensas aunque tengas la contraseña hasheada ya que al intentar iniciar sesión el foro vuelve a hashear la contraseña y aunque esté hasheada la va a volver a cifrar igual a otra distinta, por lo que obviamente no será la misma porque no van a coincidir.

De todas maneras en SMF 2.1 se mejora el método de cifrado utilizando lo más seguro hasta ahora que es bcrypt.


Saludos
Hola.

Fijate el post que compartí de SMF, ahí se especifica bien todo y se menciona lo que dijiste, en SMF 2.1 está "solucionado".




Cita de: MinusFour en 11 Mayo 2021, 18:12 PM
En teoría, si tu tienes el hash (el hash usuario+password) tu puedes iniciar sesión con ese usuario. Por ejemplo, si encuentras una vulnerabilidad que imprima el hash de un usuario podrías iniciar sesión con ese usuario. En cambio, si no se hiciera esto del lado del cliente, el atacante no podría usar este hash.

Claro, comprendo el error pero no como es posible "explotarlo".
¿Con qué parámetros finales accedería el usuario?
...

Danielㅤ

Ya, ahora entiendo, pero para que eso sea posible tiene que estar vulnerable la base de datos y/o el foro.

Ahora recuerdo que una programadora de SMF comento en su momento que mejorar el sistema de cifrado sería sobreescribir parte del código de SMF e incluso hasta se había pensado en crear un mod para esto que no recuerdo si al final se lo creó o no, también se comento que para que éste mod funcione deberían restablecer su contraseña todos los usuarios, es decir que les llegaría un email pidiéndoles que generen su nueva clave.


Saludos
¡Regresando como cual Fenix! ~
Bomber Code © 2021 https://www.bombercode.net/foro/

Ayudas - Aportes - Tutoriales - Y mucho mas!!!

Xyzed

Cita de: [D]aniel en 12 Mayo 2021, 04:12 AM
Ya, ahora entiendo, pero para que eso sea posible tiene que estar vulnerable la base de datos y/o el foro.
Exactamente.
Yo intentaba probar en localhost con SMF 2.0.16/17 el acceso mediante los parámetros cifrados, pero no logré entender al 100% como acceder teniendo la contraseña hasheada.

Cita de: [D]aniel en 12 Mayo 2021, 04:12 AM
Ahora recuerdo que una programadora de SMF comento en su momento que mejorar el sistema de cifrado sería sobreescribir parte del código de SMF e incluso hasta se había pensado en crear un mod para esto que no recuerdo si al final se lo creó o no, también se comento que para que éste mod funcione deberían restablecer su contraseña todos los usuarios, es decir que les llegaría un email pidiéndoles que generen su nueva clave.

Ayer antes de realizar el posteo revise por arriba como funcionaba el sistema del hash en el formulario y es mediante la función, que puede ser modificada a gusto.
Ya después utilizar sha1 u otro cifrado en lo que vendría a ser el foro completo es algo distinto y que cambiarlo si sería mucho más complejo, pero no imposible.

Si no me equivoco ya existen los mods que nombras.

Saludos.

...

#!drvy

Toda la idea de hashear las contraseñas es prevenir que un atacante pueda ver y/o utilizar dichas contraseñas si se diese el caso de un compromiso en la base de datos.

Este fallo, basicamente permite que tu, habiendo conseguido acceso a la base de datos, puedas loguear con cualquier cuenta sin tener que averiguar el hash o hacer brute force.

Eso es basicamente el fallo y es absurdo que hayan hecho esto.. un claro ejemplo de More Complex = Less Secure.


Saludos

MinusFour

Cita de: Xyzed en 12 Mayo 2021, 03:33 AM
Hola.

Fijate el post que compartí de SMF, ahí se especifica bien todo y se menciona lo que dijiste, en SMF 2.1 está "solucionado".




Claro, comprendo el error pero no como es posible "explotarlo".
¿Con qué parámetros finales accedería el usuario?

No estoy muy seguro de que otros campos se envían o se necesitan del lado del cliente. Pero ahí está enviando un nuevo campo hash_passwrd que es básicamente:

Código (php) [Seleccionar]
sha1(hashUserDb + $session_id)

Los otros campos probablemente son enviados normalmente (excepto passwrd que se remplaza por un string vacío o por asteriscos).

El identificador de sesión esta en una cookie pero también lo imprimen en el formulario:

Código (javascript) [Seleccionar]

hashLoginPassword(this, 'add5f76205f957b650bb0a5aa71e6ccd');


Sería bastante sencillo modificar el script de JS para que tome el hash en lugar del password:

Código (javascript) [Seleccionar]

//Función mencionada encargada del hash que viene por defecto en SMF.
function hashLoginPassword(doForm, cur_session_id)
{
// Compatibility.
if (cur_session_id == null)
cur_session_id = smf_session_id;

if (typeof(hex_sha1) == 'undefined')
return;
// Are they using an email address?
if (doForm.user.value.indexOf('@') != -1)
return;

// Unless the browser is Opera, the password will not save properly.
if (!('opera' in window))
doForm.passwrd.autocomplete = 'off';

doForm.hash_passwrd.value = hex_sha1(doForm.passwrd.value + cur_session_id);

// It looks nicer to fill it with asterisks, but Firefox will try to save that.
if (is_ff != -1)
doForm.passwrd.value = '';
else
doForm.passwrd.value = doForm.passwrd.value.replace(/./g, '*');
}


Y como usa el scope global, solo tienes que copiar y pegar en la consola. Y listo, ahora solo usas los hashes tal cual aparecen en la BD.

Cita de: [D]aniel en 12 Mayo 2021, 04:12 AM
Ya, ahora entiendo, pero para que eso sea posible tiene que estar vulnerable la base de datos y/o el foro.

No necesariamente, el hash es salteado con el usuario y contraseña. En teoría, dado lo común que es que los usuarios reúsen credenciales... es perfectamente posible encontrar una BD de otro foro que use este mismo esquema. Por eso, el salt tiene que ser random.

Y por si no fuera poco, enviar el hash de la contraseña  en texto plano no ofrece ninguna ventaja sobre usar una contraseña normal. Esa cuenta puede ser fácilmente comprometida monitoreando la red si va por texto plano. La contraseña es simplemente el hash y si va por texto plano, yo lo puedo leer.

Así que, esto hace absolutamente nada (fuera de que oculta la verdadera contraseña, que podría ser usada en otros sitios...).

Xyzed

Perfecto, muchas gracias a todos por sus aportes, ya logré entender el asunto.

Una función similar se utiliza para iniciar al panel de administración index.php?action=admin: hashAdminPassword que se encuentra en scripts.js al igual que hashLoginPassword.

El cambió que habría que hacer en esa función para loguear con el hash es el siguiente, lo dejo por si a alguien le sirve:
Código (javascript) [Seleccionar]

function hashAdminPassword(doForm, username, cur_session_id)
{
    // Compatibility.
    if (cur_session_id == null)
        cur_session_id = smf_session_id;

    if (typeof(hex_sha1) == 'undefined')
        return;

    doForm.admin_hash_pass.value = hex_sha1(doForm.admin_pass.value + cur_session_id); //En esta linea se realiza el cambio.
    doForm.admin_pass.value = doForm.admin_pass.value.replace(/./g, '*');


}



Saludos.
...