Geek++ · Dossier 13 / 25

Audit de l’obfuscation du protocole

Étude technique publique · 1,167 mots · ≈ 6 min de lecture attentive

Étude intégraleSans réflexion CODEXSources & constantes conservées
Obfuscation
TCP/UDP
payload
RC4 · padding · magic
PAIR

Ce dossier distingue volontairement la fonction historique d’obfuscation de toute promesse de sécurité moderne. Les pistes de travail sont des mesures et tests, pas une annonce de nouveau protocole.

1. Sources auditées

EncryptedStreamSocket.cpp
EncryptedStreamSocket.h
EncryptedDatagramSocket.cpp
EncryptedDatagramSocket.h
BaseClient.cpp
ServerConnect.cpp
UDPSocket.cpp
ClientUDPSocket.cpp
Preferences.cpp
Opcodes.h

2. Terminologie

Le code mélange historiquement :

Crypt Layer
Encryption Layer
Protocol Obfuscation
Basic Obfuscation

Pour notre documentation :

« obfuscation »

doit rester le terme principal lorsqu’on parle de l’objectif de sécurité.

3. But déclaré par le source

Le commentaire de EncryptedStreamSocket.cpp décrit explicitement :

random looking stream
very limited protection against passive eavesdropping single connections

Donc le but documenté est :

réduire l'identification triviale du protocole

pas fournir un canal moderne authentifié.

4. Conséquence éditoriale

Éviter les formulations :

eMule chiffre de façon sécurisée les transferts
connexion protégée comme HTTPS

Préférer :

le flux est obfusqué au moyen d'un chiffrement de flux historique

5. Client ↔︎ client : matière de clé

Le handshake client-client utilise notamment :

remote UserHash
RandomKeyPart 4 octets
magic directionnelle

pour dériver des clés via MD5.

Le UserHash doit donc être connu avant de pouvoir employer ce mode.

6. Direction des clés

Des valeurs différentes sont utilisées pour :

send
receive

afin de séparer les deux keystreams.

Vérifier le détail exact dans chaque branche avant de publier une spécification wire complète.

7. RandomKeyPart

Le commentaire source explique sa fonction :

sans variation, plusieurs connexions entre les mêmes clients dériveraient les mêmes clés et RC4 produirait les mêmes sorties initiales.

Le RandomKeyPart introduit une variation par connexion.

8. RNG moderne

La branche actuelle possède :

CryptoPP::AutoSeededRandomPool cryptRandomGen

pour la génération liée à cette couche.

C’est mieux que l’utilisation d’un PRNG faible pour le matériau aléatoire de handshake.

9. RC4

Le transform utilisé reste :

RC4

avec discard des :

1024 premiers octets

du keystream.

10. Pourquoi le discard

RC4 possède des biais connus dans les premiers octets.

Le discard est une mitigation historique.

Il ne répare pas l’ensemble des faiblesses structurelles de RC4 et ne doit pas être vendu comme modernisation cryptographique.

11. Magic sync

Constante observée :

MAGICVALUE_SYNC = 0x835E6FC4

Le handshake vérifie cette valeur après transformation pour confirmer que les clés correspondent.

12. Negotiation state machine

CEncryptedStreamSocket maintient plusieurs états :

ECS_UNKNOWN
ECS_NONE
ECS_ENCRYPTING
...

et des sous-états de négociation.

La robustesse de cette machine est plus importante qu’une micro-optimisation du RC4.

13. Client-client handshake

Structure commentée dans le source :

SemiRandom marker
RandomKeyPart
MagicValue
EncryptionMethodsSupported
EncryptionMethodPreferred
PaddingLen
RandomBytes

puis réponse avec méthode sélectionnée et padding.

14. Taille du padding

Le padding est variable et contribue à changer la signature initiale de la connexion.

Le parser doit imposer des bornes strictes au champ de longueur.

15. Overhead client-client

Commentaire source :

18–48 octets
~33 moyenne
+ en-têtes IP/TCP

Ce chiffre concerne le handshake d’obfuscation, pas tout le coût de la connexion.

16. Client ↔︎ serveur

Le client ne dispose pas d’un UserHash serveur partagé.

Le mode serveur utilise donc un accord DH historique afin de dériver un secret S.

17. Paramètres DH observés

p = groupe 768 bits embarqué
g = 2
private exponent = historique, 128 bits

Ne pas présenter 768-bit DH comme un paramètre moderne recommandé.

18. Dérivation serveur

Direction client sortante :

SendKey    = MD5(S || magic 34)
ReceiveKey = MD5(S || magic 203)

Le serveur inverse naturellement les directions.

19. Discard serveur

Comme côté client-client :

1024 bytes RC4 discarded

avant le handshake chiffré utile.

20. Handshake serveur

Structure commentée :

Client:
  random marker
  G^A
  padding

Server:
  G^B
  Magic
  methods
  padding

Client:
  Magic
  selected method
  padding

La réponse finale peut être différée jusqu’au premier payload pour économiser une frame.

21. Overhead serveur

Commentaire source :

206–251 octets
~229 moyenne

plus les en-têtes.

22. Pourquoi DH n’apporte pas d’authentification

Le propre commentaire explique qu’un DH non authentifié n’ajoute pas une protection substantielle contre l’écoute active/man-in-the-middle.

Cela confirme la finalité d’obfuscation.

23. Security boundary

Ce que l’obfuscation cache partiellement

marqueurs wire
contenu applicatif à un observateur trivial
signature de début fixe

Ce qu’elle ne cache pas

IP
port
timing
volume
durée
pattern de trafic

24. Négociation dans BaseClient::Connect

Condition actuelle :

HasValidHash
AND SupportsCryptLayer(remote)
AND local enabled
AND (remote requests OR local prefers)

Alors :

SetConnectionEncryption(true, remote UserHash)

Sinon false.

25. Required state

L’état RequiresCryptLayer est également utilisé dans le filtrage des sources.

Cela crée un impact en amont du transport :

découverte
→ admission
→ connexion

26. Cas D10 : serveur UDP

Crypt Required empêche le Global UDP GetSources historique parce que les sources reçues ne fournissent pas de UserHash utilisable pour cette exigence.

À mesurer sur réseau actuel.

27. Cas Source Exchange

SX moderne peut transporter UserHash/options dans certaines versions/conditions.

Vérifier si cela améliore la compatibilité avec Crypt Required selon provenance de la source.

28. UDP client

EncryptedDatagramSocket possède un mode spécifique pour des datagrammes client.

Il faut distinguer :

obfuscation client UDP
Kad UDP
server UDP

Les clés et formats ne sont pas interchangeables.

29. Kad UDP

Kad utilise des clés UDP dérivées/associées aux contacts et à l’IP.

Les objectifs incluent :

obfuscation
validation d'origine plus robuste que paquet totalement anonyme

mais pas une identité forte équivalente à SecureIdent.

30. Server UDP

Les serveurs peuvent annoncer :

UDP obfuscation support
server UDP key
obfuscated UDP port

Le client mémorise ces données dans CServer.

38. Détection protocolaire

Ne pas lancer de tests visant à contourner activement les politiques d’un FAI.

Une étude locale/offline peut simplement comparer :

entropie apparente
marqueurs fixes
signature initiale

entre plain et obfusqué.

39. RC4 : dette technique vs interop

Le fait que RC4 soit obsolète cryptographiquement ne signifie pas qu’on peut le remplacer localement.

Compatibilité réseau :

les deux côtés doivent implémenter le même wire protocol

40. Nouvelle crypto éventuelle : changement de protocole

Une vraie évolution demanderait au minimum :

nouvelle capability
nouveau handshake
algorithme authentifié
versioning
fallback
interop multi-client
protection downgrade
tests

C’est un projet séparé.

41. Ne pas bricoler un « AES à la place de RC4 »

Changer seulement la primitive casserait le protocole et ne résoudrait pas :

authentification
négociation
downgrade
gestion des clés
compatibilité

42. Question stratégique future

Si une nouvelle couche devait être conçue, son but devrait être défini avant l’algorithme :

obfuscation DPI ?
confidentialité ?
authentification ?
les trois ?

Sans but clair, aucune modernisation n’est sérieuse.

43. Fingerprinting résiduel

Même avec contenu pseudo-aléatoire, un observateur peut utiliser :

ports
durées
burst sizes
patterns de connexion
réseau de pairs

Une nouvelle crypto ne rendrait pas automatiquement eMule anonyme.

44. Compatibilité serveurs

Une extension future ne peut pas supposer que les serveurs eD2K actuels seront mis à jour.

C’est une contrainte différente de client-client, où un nouveau protocole peut éventuellement être négocié entre deux clients modernes.

46. Conclusion

La couche actuelle est un mécanisme historique cohérent avec son objectif :

rendre eMule moins trivialement identifiable

Elle ne correspond pas aux objectifs d’un protocole moderne de confidentialité authentifiée.

Le travail utile immédiat consiste à vérifier sa robustesse et son impact réel sur la compatibilité, pas à annoncer sa substitution.

================================================================================================


Dossier 13 terminé

Audit de l’obfuscation du protocole

← Dossier 12Dossier 14 →