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…^^

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.