Como Joomla genera sus passwords

Hace un par de días realice un posts en donde unifico el sistema de autenticación de Joomla con otro sistema en PHP (ver posts), mientras realizaba y estudiaba el código del Joomla, note algunas cosas que aqui dejo para que no se me olviden y por a alguien más le sirve.

Joomla Divide el campo password en 2 partes.

Algo que caracteriza a joomla es que el campo password en 2 partes de forma encrypt’:’salt la segunda parte(salt) es una cadena generada de forma (seudo) aleatoria y es empleada en conjunto con una función dominante de la derivación (KDF) y la contraseña del usuario para generar  la primera parte encrypt como se muestra en la siguiente imagen.

Como joomla trata los passwords

Figura 1 . -Como joomla trata los passwords

Como se puede ver el password finalmente es la concatenación de la cadena salt y encrypt con el carácter ‘:‘ . El empleo de esta cadena salt es típica en los sistemas de cifrado y en seguridad informática la obtención de esta cadena salt un gran paso para la obtención de la contraseña(con un Dic. y FB).

Joomla emplea MD5 como mecanismo de cifrado.

Joomla al igual que la mayoría de los sistmas Web  cifra sus contraseñas con algún algoritmo de cifrado irreversible, Joomla emplea MD5 (al menos que se configure de forma contrario) , en la figura se ve como la cadena salt es obtenida mediante la función getSalt() dicha función se encuentra definida en las librerías del Joomla en la versión 1.5-1.6 se encuentra en:  JOOMLA1.6/libraries/joomla/user/helper.php (Descargar Joomla y cerciorarse )cuando es llamada con los parámetros por defecto lo que nos genera es:

$salt    = md5(mt_rand());

Como podemos observar emplea la función mt_rand, la cual nos devuelve un número pseudo aleatorio haciendo uso de la implementación de algoritmo Mersenne twister, esto es bueno ya que genera los números es un poco mas eficiente tanto en tiempo de ejecución como en el echo en que te garantiza que es el número generado es mas seudo aleatorio que el que se genera con el rand() que es como lo implementa típicamente lenguajes como C.

Por otra parte para obtener la cadena encrypt hace uso de la cadena salt generada previamente con los parametros por defecto toma el comportamiento como:

$crypt = md5($password.$salt);

Finalmente si quisiéramos hacer un sistema en donde se puedan registrar usuarios desde otra aplicación tendríamos que generar este comportamiento en nuestra aplicación, dejo aquí la función password que recibe una contraseña sin cifrar(tal como la recibe un formulario) y devuelve la contraseña como típicamente la generaría el joomla antes de guardar en su BD.

#genera un password en el formato como lo hace el joomla
#la El password lo genera en 2 partes P1:P2
#P1 Es el resultado del md5 de concatenación del password con P2
#P2 Es la cadena security salt generada con md5
#
#para mayor info respecto la cadena salt revisar la función getSalt
#definida en: JOOMLA1.6/libraries/joomla/user/helper.php
function password($password){
	$salt	= md5(mt_rand());
	$encrypt = md5($password.$salt);
	return $encrypt.':'.$salt;
}

#prueba con la contraseña admin
echo password('admin')."\n";

Código fuente disponible en:  http://gist.github.com/596732

No se recomienda tener más de un sistema de registro en un sistema ya que la duplicidad de funciones genera ambigüedades y por lo consiguiente inconsistencias (DIE), es por esto que si sólo la recomiendo en caso que bloquees los registros desde tu joomla.

Poniendo a prueba el sistema de generación de passwords.

Como se menciono previamente es una de las características del Joomla que genere una cadena salt por cada password, la pregunta seria ¿que tantan seguridad le brinda al sistema esta metodología de generación de passwords? y si ¿en lugar de md5 cambio la configuración por defecto para ocupar  otro mecanismo como sha1?.

Si cambiamos la función hash de md5 a sha1 para este mecanismo en lo personal considero que no mejora mucho ya que la cadena salt quedaría definida como sha1(mt_rand()) .A pesar que sha1 genera una cadena de 160bits a diferencia de md5 que genera una de 128bits ambas generarían la cadena hash del resultado obtenido por mt_rand(), algo análogo pasa con la cadena encrypt la cual seria  la cadena hash de la contraseña(en texto plano) concatenada con la cadena salt, algo similar a sh1(‘Contraseña’.$salt).

Por otra parte si observamos lo que cambia es que con md5 generamos 2 cadenas de 32 caracteres y el password final queda con 65caracteres  y con sha1 generamos 2 cadenas de 40 caracteres generando un password de 81caracteres, lo cual es un poco peligroso ya que si alguien llega a obtener el campo password de un usuario joomla automáticamente obtiene la cadena salt y encrypt y  al revisar la longitud de dichos campos sabe cual fue la funcion hash empleada para obtener la cadena crypt.

Por lo tanto la vulnerabilidad Seguridad de un campo password en joomla se encuentra delimitada por la prediccion de algoritmo Mersenne twister o de su implementacion en PHP mt_rand() , de los diccionarios disponibles para funciones hash (por ahí vi un Blog, vi un elegante  bot  que empleaba un diccionario cifrar MD5) y como siempre de la contraseña en texto plano de los usuarios….

24 respuestas a “Como Joomla genera sus passwords

  1. Hola sabes lei tu informacion y me ayudo mucho…pero quiero hacerte una consulta??… veras necesito yo agregar a los usuarios de mi sistema a la tabla de jos_users… pero he intentado ingresar manualmente desde la base de jommla pero no se me muestra esos usuarios…sino solo los que ingreso desde la parte grafica…no se enq otra tabla debo agregar algun atributo o tengo q galar un id…ayudame en eso sisisi estare muy agradecida

    • Tal vez estas utilizando distintas tablas, muchos sistemas usan la tabla users y joomla la tabla jos_users (con el prefijo jos_), tal vez los datos están en distintas tablas, revisa esto.

      Espero te sirva!, x cualquier cosa por aquí andamos :¬).

      • ya revise…. bueno mejor le explico de mejor manera…estoy queriendo mandar a insertar los datos la tabla jos_users de un formulario de php q me cree, ya tengo la conexion y funciona al pelo…sino q esos usuario q mando a guardar se almacenan correctamente en la base pero no se me visulizan en el GESTOR DE USUARIOS de mi joomla por ende con mis usuarios no me dejan logearme…. ayudeme si

      • tienes que registrarlo en jos_coore_acl_aro y jos_core_acl_groups_aro_map puedes mirar algunos registros para entender

  2. Hola, gracias por la información, pero he probado la función y he creado una contraseña, la he puesto en el campo jos_users.passwords pero no me deja loguearme, entonces le he vuelto a poner el password original y otra vez puedo loguearme, por lo que deduzco que la tu funcion y el sistema de joomla no es exactamente el mismo… o estoy haciendo algo mal?? Que puede ser?

    He probado con joomla 1.5.22

    • Revisa que no tengas configurado algún otro tipo de cifrado como por ejemplo SHA1.

      quizas la forma mas simple de revisar esto es revisando la longitud de las cadenas p.e. sha1 son de 40caracteres y md5 de 32.

      En caso que no te funcione revisa la definición original de la función en tu archivo JOOMLA1.5.X/libraries/joomla/user/helper.php.

      Saludos!.

  3. #genera un password en el formato como lo hace el joomla
    #la El password lo genera en 2 partes P1:P2
    #P1 Es el resultado del md5 de concatenación del password con P2
    #P2 Es la cadena security salt generada con md5
    #
    #para mayor info respecto la cadena salt revisar la función getSalt
    #definida en: JOOMLA1.6/libraries/joomla/user/helper.php
    function password($password){
    $salt = md5(mt_rand());
    $encrypt = md5($password.$salt);
    return $encrypt.’:’.$salt;
    }

    #prueba con la contraseña admin
    echo password(‘admin’).»\n»;

    esto es incorrecto genera contraseñas aleatorias y nunca «admin»

  4. Cómo haría un usuario para loguearse? cada vez q se refresca el formulario con el mismo valor de password, el valor encriptado cambia. Entonces como se conseguiría realizar la consulta?

    • Hola, No entiendo del todo tu pregunta, a mi entender seria «agregar la opción de recordar contraseña» esto típicamente se hace con una cookie de sesión cifrada en tu equipo.

  5. No, lo que Andres dice (creo) pero yo tengo la misma duda, dices que el password es guardado con un valor aleatorio, la pregunta es luego yo quiero verificar el login(un usuario que llega a mi web e intenta conectarse con el password correcto), y si es un random será diferente entonces al verificar si el password que ingresó el usuario es igual al que está almacenado ps será diferente y no habrá autentificación

    • Veras el campo password contiene un elemento aleatorio conocido en la jerga seguridad informática
      como el grano de sal(security salt), este elemento es generado por única ocasión al momento de guardarlo
      en la jerga de joomla lo llaman simplemente como salt, como lo intente explicar el proceso como joomla almacena su campo password es de la manera siguiente:

      Favor de verificar la imagen:

      1. Genera el salt de manera aleatoria.
      2. Genera la cadena encrypt(cadena cifrada) en función de salt y el password sin cifrar.
        El password guardado sera igual a la cadena
      3. cifrada(encrypt) unida por el carácter ‘:’ con la cadena salt
      4. .

      ¿Me preguntas como le harías para validar la contraseña?

      Si reflexionamos un poco nos damos cuenta que si bien salt es generada de manera aleatoria es también almacenada en la BD, por lo cual la no es necesario generarla posteriormente, para autenticar solo requieres hacer algo similar a:

      1. Rescatas tanto encrypt como salt del usuario que se intenta autenticar.
      2. Generas una cadena encrypt2 en función de salt y el password sin cifrar que vas a verificar(ocupando el mismo mecanismo de cifrado como se hizo cuando se registro típicamente MD5).
      3. Comparas encrypt con encrypt2 si son iguales entonces, la autenticación es correcta.
  6. aquí agrego una pequeña función para autenticarse, muy buenos sus comentarios me sirvieron de mucha ayuda.

    	 public function desencripta($passw){
    			list($encrypt,$salt)=explode(':',$model->password);
    			$encrypt2=md5($passw.$salt);
    			if ($encrypt!=$encrypt2){
    				return false;
    				} else{
    					return true;
    					}
    		}
  7. wow toda esta informacion esta muy buena, pero mi duda es … como se podria hacer para generar la sesion, ya tenemos como ingresar y verificar el usuario y contraseña pero la cookie de joomla como se crea ??

  8. pensaba que este codigo funcionaria pero lastimosamente no dice : «Fatal error: Call to protected method JApplication::_createSession() from context » »

    Codigo :

    initialise();

    $userid = 732;
    $username = ‘fer’;

    $user = JUser::getInstance($userid);
    $session = &JFactory::getSession();
    $session->fork();
    $mainframe->_createSession($session->getId());
    JPluginHelper::importPlugin(‘user’);
    $mainframe->triggerEvent(‘onLoginUser’, array(array(‘username’ => $username)));
    ?>

  9. Hola fitorec, este post es muy bueno!, gracias por tu aporte, mi pregunta sería, ¿cómo puedo hacer, si deseo ingresar datos a la tabla jos_user directamente?, sin tener que registrar los datos por la vista de registro de usuarios de Joomla, algo asi como con un insert into …alguna idea ? , gracias

    • Eso en teoría no se podría hacer, ese es el objetivo de los algoritmos de cifrado irreversible.

      Sin embargo si el hash proviene de un password muy común abra un diccionario de passwords en donde lo podrás encontrar, pero en el caso lo hace joomla no abría tal diccionario

Replica a fitorec Cancelar la respuesta