Hardening consulting

Support de la reconnection en RDP

Et oui encore un article sur du RDP ! J'ai fait quelques expériences avec la reconnection automatique et je profite de cet article pour en parler un peu.


La reconnection automatique

La reconnection automatique permet au client RDP de se reconnecter à un serveur quand il y a eu un coupure, et ceci sans ressaisir les logins / mots de passe. La coupure peut être due à une coupure réseau ou même un crash serveur. L'exemple typique consiste à rabattre l'écran de son portable avec une connection RDP en cours, et quand on réouvre le client se reconnecte tout seul.


Niveau protocole

La reconnection automatique est décrite dans la spécification:

  • une fois le client authentifié, le serveur envoie un cookie de reconnection et un id de session dans un Save Session Info PDU. Le client est censé le stocker et s'en servir au moment de la reconnection;
  • après la coupure, quand le client veut se reconnecter, il va utiliser l'identifiant de session et le cookie qu'il va mettre dans le client info PDU. Il ne s'agit pas du cookie lui-même mais d'un dérivé qui est calculé comme suit:
toSend = hmac_md5(cookie, clientRandom);

Le cookie est utilisé comme clé d'un HMAC-MD5 et pour le contenu qui est hashé: quand il s'agit d'une connexion avec la sécurité RDP, clientRandom est le secret échangé durant la phase de "sécurisation" de la connexion (sécurisation entre guillemets car la sécurité RDP n'est pas sécurisée du tout). Quand le transport est fait au dessus de TLS (sécurité TLS ou NLA), ce sont simplement 32 octets à 0 qui sont utilisés;

  • A la réception le serveur effectue le même calcul pour vérifier que le cookie est légitime, et le cas échéant reconnecter automatiquement à la session en cours;

On notera que la spécification dit que le cookie est censé être regénéré et renvoyé toutes les heures par le serveur.

Conclusion

Une fonctionnalité intéressante et facile à implémenter, FreeRDP avait quand même le soucis qu'il ne stockait pas le clientRandom coté serveur, mais depuis ce patch c'est fait.