Chiffrement des mots de passe dans mRemoteNG

Bonjour à tous, aujourd’hui on va se pencher rapidement sur le chiffrement des mots de passe dans mRemoteNG. Y’a pas longtemps, j’avais pommé un mot de passe qui visiblement ne s’était pas bien sauvegardé dans mon password Manager (problème d’interface chaise clavier probable), bonne nouvel il était toujours dans ma conf mRemoteNg.

mRemoteNG ?

mRemoteNG est un gestionnaire de connexions à distance (un peu comme PuTTY) pour Windows qui gère une pelleté de protocol et qui a le bon goût d’être Open Source. Jusqu’ici tout va bien.

Les exports de configuration dans mRemoteNG

Donc par rapport à mon soucis je commence par exporter ma conf et du coup ni une ni deux, bouton droit :

Et je me jette dans le XML ainsi généré :

<Node Name="Serveur.tld.fq.dn" Type="Connection" Descr="" Icon="mRemoteNG" Panel="General" Username="user@geekeries.org" Domain="" Password="Ni1es1Kzm##########KJNibkcvcveRfEYV#######DOAcvcvTYUtQB+#####jlcvcvEpkex5A+wE=" Hostname="Serveur.tld.fq.dn" Protocol="RDP" PuttySession="Default Settings" Port="3389"

Donc là, je me dis nickel un base64 (mais aussi quelle bande de nazes chez mRemoteNG… :’-D)

Bref, un coup de base 64 decode et…

[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("Ni1es1Kzm##########KJNibkcvcveRfEYV#######DOAcvcvTYUtQB+#####jlcvcvEpkex5A+wE="))
6-^�R��GTD�l����M��%쇑|D��|�)`�v�TGP�m�/c���JyU{@�

Nada, je récupère du bon gros bruit quel que soit l’encodage demandé.

(Dé)Chiffrement des mots de passe dans mRemoteNG

Bon un coup de let me google that for you plus tard, et on apprend (ici, ) que mRemoteNG « chiffre » les mots de passes dans les exports en AES (ouh samy, j’ai peur) et que le mot de passe par défaut est, suspense :

"mR3m"

Voilà voilà, je vous ai déjà parlé de comment on stocke un mot de passe non (spoiler alert : pas comme ça) ? Bref, en grattant un peu je suis même tombé (ici, source d’origine du code ci-dessous) sur un module PowerShell qui fait le taf ici (et pas besoin d’installer Python \o/), alors le module semble plus maintenu et foire à l’import mais le code de déchiffrement des mots passe lui fonctionne bien :

Add-Type -Path 'C:\Program Files (x86)\mRemoteNG\BouncyCastle.Crypto.dll'

function ConvertFrom-MRNGSecurePassword {

    param(

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]
        $EncryptedMessage,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [securestring]
        $EncryptionKey

    )

    $Password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto( [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR( $EncryptionKey ) )
    $EncryptedMessageBytes = [convert]::FromBase64String( $EncryptedMessage )

    $Engine = [Org.BouncyCastle.Crypto.Engines.AesEngine]::new()
    $Cipher = [Org.BouncyCastle.Crypto.Modes.GcmBlockCipher]::new($Engine)
    $Encoding = [System.Text.Encoding]::UTF8
    $SecureRandom = [Org.BouncyCastle.Security.SecureRandom]::new()
    
    $NonceBitSize = 128
    $MacBitSize   = 128
    $KeyBitSize   = 256
    $SaltBitSize  = 128
    $KeyDerivationIterations = 1000
    $MinPasswordLength = 1

    $Salt = New-Object byte[] ( $SaltBitSize/8 )
    [array]::Copy( $EncryptedMessageBytes, 0, $Salt,  0, $Salt.Length )

    Write-Verbose ( "Salt: {0}" -f ($Salt -join ',') ) -Verbose

    $PasswordInBytes = [Org.BouncyCastle.Crypto.PbeParametersGenerator]::Pkcs5PasswordToBytes( $Password.ToCharArray() )
    $KeyGenerator = [Org.BouncyCastle.Crypto.Generators.Pkcs5S2ParametersGenerator]::new()
    $KeyGenerator.Init( $PasswordInBytes, $Salt, $KeyDerivationIterations )
    $KeyParameter = $KeyGenerator.GenerateDerivedMacParameters($KeyBitSize)
    $KeyBytes = $KeyParameter.GetKey()

    $CipherStream = New-Object System.IO.MemoryStream (, $EncryptedMessageBytes )
    $CipherReader = New-Object System.IO.BinaryReader ( $CipherStream )

    $Payload = $CipherReader.ReadBytes( $Salt.Length )

    $Nonce = $CipherReader.ReadBytes( $NonceBitSize / 8 )

    Write-Verbose ( 'Nonce: {0}' -f ( $Nonce -join ',' ) ) -Verbose
    
    $Parameters = [Org.BouncyCastle.Crypto.Parameters.AeadParameters]::new( $KeyParameter, $MacBitSize, $Nonce, $Payload )

    $Cipher.Init( $false, $Parameters )

    $CipherTextBytes = $CipherReader.ReadBytes( $EncryptedMessageBytes.Length - $Nonce.Length )

    $PlainText = New-Object byte[] ( $Cipher.GetOutputSize( $CipherTextBytes.Length ) )

    $Len = $Cipher.ProcessBytes( $CipherTextBytes, 0, $CipherTextBytes.Length, $PlainText, 0 )
    $Cipher.DoFinal( $PlainText, $Len ) > $null

    $Encoding.GetString( $PlainText )

}


$EncyptionKey = ConvertTo-SecureString -String "mR3m" -AsPlainText -Force
$Password = 'Ni1es1Kzm##########KJNibkcvcveRfEYV#######DOAcvcvTYUtQB+#####jlcvcvEpkex5A+wE='
ConvertFrom-MRNGSecurePassword -EncryptedMessage $Password -EncryptionKey $EncyptionKey

Bon voilà, c’est franchement un peu à vomir en 2021 surtout qu’au moment de l’export mRemoteNG ne signale, ni ne propose, de modifier cette clé au moment de l’export, et je l’ai pas vu dans les paramètres… Le produit étant open souce vous pouvez toujours retrouver là ou est calée cette clé pour la modifier, mais bon…

Chiffrement des mots de passe dans mRemoteNG
D’ailleurs, ne vous y trompez pas : y’a marqué crypter !

Ah et si vous vous imaginiez que le problème n’est que lors de l’export et qu’il suffit de faire gaffe à ces derniers, ne rêver pas : le fichier de conf du logiciel est stocké là %userprofile%\AppData\Roaming\mRemoteNG\confCons.xml avec les mêmes informations bien sûr, sinon c’est pas drôle hein ;-). Bref, dans ce bas monde, point de magie, illustration :

Conclusion – it’s not a bug it’s a feature…

Voilà voilà, c’est beau le chiffrement des mots de passe dans mRemoteNG en 2021, non ??? J’espère que ça vous aura intérressé, ma conclusion : ayez une confiance « très relative » dans la sécurité de vos mots de passe enregistrés dans mRemoteNG. Ce qui me fait marrer c’est que j’imagine toutes les sécurités que mettent les admins sur les mots de passe par GPO dans votre SI, (bloquer le copier-coller, blinder le RDP et le chiffrement, expiration de session, etc.) pour se retrouver avec des clients qui laisse leurs mots de passe presque qu’en clair sur le poste (sans en avoir conscience). Ça vaut le coup de faire votre inventaire sur le parc et de changer de client de gestionnaire de connexion (voir en conseiller un correct pour vos utilisateurs…), amusez vous bien…^^

5 commentaires on “Chiffrement des mots de passe dans mRemoteNG

  1. Le mot de passe demandé pour ouvrir le fichier ne sert-il pas à crypter les mots de passe ?
    Sinon, pour plus de sécurité, je suggère de stocker le fichier dans un coffre fort avec cryptomator.

  2. Merci pour la réponse, en effet les bonnes pratiques sont toujours plus secure… J’ai exporté la conf et regardé dans tous les fichiers de Mremote y compris le fichiers de config et pas de trace de ces données de logs par défaut c’est donc à mon sens positif mais valable que pour un domaine donc pas applicable à n’importe qui…
    La base de RoyalTS chiffré par un mot de passe, cela m’a l’air mieux mais peut être un leurre à creuser je l’utilisais il y longtemps, quand à Remote Desktop Connection Manager les mot de passe sont stocké dans rdp…

  3. Bonjour,
    Merci pour votre article très instructif quoiqu’un peu trop technique sur certains points mais l’essentiel est compris, je voulais tester ce logiciel mais cela me rebute inévitablement après cette lecture.
    Dans les options il y a la possibilité de paramétrer des crédentials par défaut en cas de champs vide dans l’entrée de connexion.
    Pensez/savez vous si cette information peut également être récupéré dabs le fichier de conf;xml ?
    Existe il un gestionnaire de connexion réellement sécurisé ?

    • Hello Adrien,
      il faut pas être rebuté, il faut juste le savoir…^^ la bonne pratique en conlcusion serait au moins de recompiler le client depuis les source en changeant la clé du coup.
      Après, je ne sais pas pour les paramètres par défaut, mais… ce n’est pas difficile à tester du coup ? En mettre un exporter, regarder 😉 .
      Il existe d’autres gestionnaires RDP/SSH (exemple : RoyalTS ou Remote Desktop Connection Manager). Mais je n’ai aucune idée de leur niveau de sécurité pour autant, à creuser.
      La vrai règle sécu, c’est surtout de ne pas laisser ses mots de passes trainer n’importe où :-)… Un mot de passe ça va dans un Password Manager (KeePass, Bitwarden, etc) et pas dans un gestionnaire de conf.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.