0. Résumé exécutif
Jusqu’ici, nous séparions principalement :
PROTOCOLE
vs
POLITIQUE LOCALE
Il faut maintenant ajouter :
CONFIANCE DANS LES DONNÉES DISTANTES
Une valeur parfaitement conforme au protocole peut être mensongère.
Exemples :
Queue Rank
ModString
Client Version
pseudo
bits de capacité
état de parties
liste Source Exchange
Le paquet peut être syntaxiquement valide tout en portant une information choisie volontairement par un client modifié.
Le principe directeur proposé est :
Toute donnée contrôlée par un pair distant est une assertion non fiable tant qu’elle n’est pas vérifiée localement ou cryptographiquement.
Ce dossier montre également une nuance importante par rapport à l’intuition « un leecher envoie un faux rang pour passer premier dans notre upload ».
Dans l’eMule officiel :
- le score de notre propre Upload Queue est calculé localement ;
- un faux Remote Queue Rank ne permet donc pas directement au pair de s’attribuer un meilleur score chez nous ;
- en revanche, le Remote Queue Rank reçu est utilisé dans certaines décisions de notre Download Manager, notamment lors des choix A4AF / Source Exchange autour du seuil QR 50.
Il existe donc bien une surface de manipulation, mais elle n’est pas exactement celle que l’interface pourrait laisser penser.
1. Preuve historique : les clients mensongers ont réellement existé
Le corpus des Mods contient des fonctions explicitement offensives.
Applejuice
Le changelog annonce :
advanced undetectable Fake Rank
send Fake Rank to Clients on Queue
send Fake Rank instead of Full Queue
send Fake Rank to all Clients or only Leechers
manual enter send Fake Rank < x
Il annonce aussi :
Fake Tags
Clientversion Thief
Community Faker
Client Emulations
send arbitrary Clientversion
select sending Modstring
random Modstring
Ghost / no Modstring
Le même Mod comprend également :
Boost Clients depending on Remote Queue Rank
C’est une démonstration directe du problème de confiance :
A prend une décision locale selon un champ distant
B peut falsifier ce champ
→ B peut tenter d’influencer A
2. Les protections historiques confirment l’existence du problème
Le corpus mentionne notamment :
QR-Faker / Faked Ranks kicken
Anti-Fake-Rank
Anti-Nick-Thief
Anti-ModID Faker
Hash Thief Protection
Ghost Mod detection
Client Analyzer
Argos Anti-Leecher
DLP
SNAFU
Argos est documenté comme utilisant une détection multi-critères portant sur :
ModString
pseudonyme
logiciel
UserHash
opcode
Source Exchange
fast ask
tags invalides
violations de protocole
Ce corpus doit être étudié comme une base historique de menaces, pas comme un ensemble de règles à recopier.
4. Classification des données par niveau de confiance
Niveau L0 — Remote Claim
Le pair contrôle entièrement la valeur.
Exemples :
nickname
ModString
version
Remote Queue Rank
capabilities déclarées
part map
sources SX envoyées
affichage
optimisation faible
jamais privilège important seul
Niveau L1 — Cohérence locale
La valeur distante est cohérente avec d’autres observations.
Exemple :
le pair annonce SX4
et répond ensuite avec des paquets SX4 structurellement valides
Cela augmente la confiance dans cette capacité seulement.
Niveau L2 — Observation comportementale
Notre client observe directement un événement.
Exemples :
connexion réussie
octets reçus
latence
requêtes réellement faites
source SX réellement joignable
bloc reçu
Niveau L3 — Vérification cryptographique / intégrité
Exemples :
SecureIdent validé
bloc vérifié par hash
AICH cohérent
FileHash localement confirmé
Ces niveaux ne doivent pas devenir un « score universel ».
Ils doivent être appliqués au domaine concerné.
5. Remote Queue Rank : cas d’école
5.1 Réception
Dans DownloadClient.cpp eMule 0.72a :
ProcessEdonkeyQueueRank(...)
ProcessEmuleQueueRank(...)lisent directement le rang envoyé par le pair puis appellent :
SetRemoteQueueRank(rank, ...)Aucune preuve de la file distante n’est possible.
C’est logique : nous n’avons pas accès à sa waiting list.
5.2 Protection contre le flood
eMule ne fait toutefois pas confiance au rythme des messages.
CheckQueueRankFlood() :
- compte les QR non sollicités ;
- suit les mauvaises requêtes ;
- peut bannir avec la raison :
QR flood
Le contenu numérique du rang n’est pas vérifiable.
La fréquence d’envoi, elle, peut être vérifiée localement.
C’est exactement la distinction :
vérité distante : invérifiable
comportement protocolaire : observable
5.3 Utilisation du QR distant dans l’eMule officiel
Point important découvert dans la 0.72a.
SwapToRightFile() contient notamment des conditions :
GetRemoteQueueRank() <= 50et :
GetRemoteQueueRank() > 50dans des décisions liées au changement de fichier / Source Exchange.
Donc :
le Remote Queue Rank n’est pas purement décoratif dans le client officiel.
Un pair qui annonce volontairement un QR artificiel peut théoriquement influer sur cette branche de décision.
Cela ne signifie pas qu’il obtient directement un meilleur upload chez nous.
Cela signifie qu’une donnée invérifiable influence une heuristique locale de téléchargement.
6. Notre Upload Queue est mieux protégée contre le Fake Rank
Le dossier 04 a montré que notre propre score d’upload dépend de valeurs locales :
GetWaitStartTime()
Credits()->GetScoreRatio()
priorité locale du fichier
Un client distant ne fournit pas directement ces valeurs.
Il ne peut donc pas envoyer :
score=999999
dans un paquet standard pour devenir premier.
Les attaques sont plutôt indirectes
Exemples de domaines à surveiller :
identité clonée
multiplication d’instances/adresses
reconnexion/reask agressif
changement du fichier après attribution du slot
tentatives de contourner les règles de queue
Le détail de chacune doit être traité défensivement et mesuré.
7. Hello Tags : syntaxiquement valides ≠ vrais
BaseClient.cpp parse notamment :
CT_NAME
CT_VERSION
CT_PORT
CT_MOD_VERSION
CT_EMULE_UDPPORTS
CT_EMULE_BUDDYUDP
CT_EMULE_BUDDYIP
et les Info Packets contiennent notamment :
ET_COMPRESSION
ET_UDPPORT
ET_UDPVER
ET_SOURCEEXCHANGE
ET_COMMENTS
ET_EXTENDEDREQUEST
ET_COMPATIBLECLIENT
ET_FEATURES
ET_MOD_VERSION
Le parser vérifie les types.
Mais la valeur vient du client distant.
Exemple :
m_strModVersion = temptag.GetStr();Un Mod peut donc choisir la chaîne qu’il transmet.
8. ModString, version et nickname ne doivent pas accorder de privilège
Le corpus historique montre explicitement :
Clientversion Thief
Mod Thief
Nick Thief
Ghost Mod
Client Emulation
random Modstring
Par conséquent :
Mauvaise règle
si mod == "TrustedMod"
donner un bonus
Meilleure règle
Le ModString peut servir à :
diagnostic
compatibilité historique
statistiques
indice faible
mais pas à accorder seul :
crédits
slot prioritaire
bypass queue
confiance SX élevée
9. SecureIdent : exemple d’une donnée transformée en preuve
Le UserHash reçu dans le Hello est lui aussi choisi par le pair.
Pris seul :
UserHash = déclaration
Avec SecureIdent réussi :
UserHash + possession de la clé privée
= preuve cryptographique historique
L’eMule officiel utilise cette distinction dans plusieurs endroits.
Dans ClientList::AttachToAlreadyKnown() :
- si deux connexions présentent un même UserHash ;
- et que le client déjà connu possède une identité sécurisée validée ;
- le nouveau client contradictoire peut être banni pour UserHash invalide.
C’est une excellente philosophie à généraliser :
la déclaration n’est pas le problème ; le privilège n’est accordé qu’après preuve.
10. Source Exchange : surface de pollution naturelle
10.1 Ce que SX transporte
Selon la version :
IP/ID
port
serveur
UserHash
options de connexion
Toutes ces informations sont fournies par le pair SX.
10.2 Défenses déjà présentes
CPartFile::AddClientSources() 0.72a vérifie :
- version SX connue ;
- cohérence exacte taille / nombre d’entrées ;
- format de chaque version ;
- IP valides ;
- IPFilter ;
- clients bannis ;
- règles
CanAddSource(); - limite maximale de sources ;
- dédoublonnage ultérieur via
CheckAndAddSource().
Le commentaire SX1 dit explicitement que certaines vérifications réduisent le risque de :
wrong source data
wrong userhashes
duplicate sources
10.3 Limite fondamentale
Même après toutes ces vérifications :
IP syntaxiquement valide
ne prouve pas :
source en ligne
source possédant ce fichier
source répondant
source utile
11. Capability Trust : annoncer une fonction ne suffit pas
Exemple :
SX version = 4
CLAIMED_SX4
OBSERVED_VALID_SX4
OBSERVED_BROKEN_SX4
Réaction possible :
si un pair annonce une capacité mais produit plusieurs réponses invalides :
désactiver cette fonctionnalité pour ce pair
plutôt que :
bannir complètement le pair
Cela réduit les faux positifs et conserve la compatibilité.
12. Fast Reask / requêtes agressives
L’eMule officiel possède déjà une protection.
UploadClient.cpp::AddRequestCount()
Si le même fichier est redemandé avant :
MIN_REQUESTTIME = 10 minuteset que le pair n’a pas de Friend Slot :
badrequests++
À :
BADCLIENTBAN = 4le client peut être banni.
C’est un exemple de protection 100 % comportementale :
eMule ne cherche pas à savoir quel Mod est utilisé.
Il observe seulement :
ce client redemande trop vite
13. File Request Flood
BaseClient.cpp::CheckFailedFileIdReqs()
Les requêtes répétées portant sur des identifiants de fichiers invalides sont comptées.
Après répétitions et accumulation dans BadRequests, le client peut être banni avec :
FileReq flood
Encore une fois :
preuve locale du comportement
plutôt que :
liste noire de noms de Mods
14. Queue Rank Flood
Même logique :
QR reçus alors qu’ils n’étaient pas attendus
sont comptés.
Après répétitions :
Ban("QR flood")
Le rang lui-même peut mentir.
Le flood, lui, est objectivement observable.
15. Spam
L’eMule officiel possède aussi :
SetSpammer(true)
→ Ban("Identified as Spammer")Le dossier Trust devra plus tard examiner précisément les critères de classification comme spam afin de distinguer les règles robustes des heuristiques historiques.
16. Plusieurs clients depuis la même IP
UploadQueue.cpp contient déjà une limitation afin d’éviter qu’une même IP occupe trop d’entrées dans la waiting queue.
C’est une protection contre une forme simple de multiplication d’identités.
Limite :
elle ne protège pas contre des pairs utilisant réellement plusieurs IP
et ne doit pas être étendue naïvement à des environnements NAT où plusieurs utilisateurs légitimes partagent une adresse.
17. Données corrompues : une défense fondée sur les conséquences
L’eMule 0.72a possède :
CorruptionBlackBox
Le système enregistre les plages reçues et leurs expéditeurs.
Après vérification :
VerifiedData()
CorruptedData()
EvaluateData()
peuvent déterminer les clients ayant contribué aux zones corrompues.
Le code peut ensuite bannir un client lorsque la proportion de données corrompues attribuées dépasse la limite prévue.
Intérêt architectural
C’est probablement l’un des meilleurs exemples de défense historique :
pas besoin de croire le ModString
pas besoin de deviner l’intention
La sanction est liée à des octets réellement reçus et vérifiés comme mauvais.
18. Hashes : la donnée finale ne dépend pas de la parole du pair
Un client peut annoncer posséder une partie.
Il peut même envoyer des octets.
Mais la partie n’est considérée valide qu’après vérification :
ED2K / MD4
et éventuellement
AICH
Il s’agit d’un excellent exemple de design zéro-confiance avant l’heure :
recevoir
≠
accepter comme valide
19. Part Status : déclaration utile, preuve faible
La carte de parties du pair est nécessaire pour sélectionner les blocs.
Mais elle est contrôlée par le pair distant.
Remote Claim
La confiance augmente seulement lorsque :
le pair accepte effectivement les requêtes correspondantes
et fournit des données valides
À mesurer
parts advertised
requests attempted
requests fulfilled
valid payload
Un taux faible n’est toutefois pas automatiquement une triche :
fichier modifié
session interrompue
source obsolète
A4AF
changement d’état
La détection doit être statistique et prudente.
20. Pourquoi les vieilles blacklists sont insuffisantes
Argos, DLP et d’autres systèmes ont souvent utilisé :
modstrings connues
nick patterns
version patterns
hash patterns
bad opcodes
Ils étaient utiles dans le contexte de leur époque.
Mais une blacklist possède plusieurs défauts :
facile à contourner en changeant l’identifiant
vieillit rapidement
faux positifs
maintenance externe nécessaire
peut confondre client rare et client hostile
21. Ce que nous devons récupérer des anciens Anti-Leecher
À conserver conceptuellement
détection multi-critères
corrélation dans le temps
différents niveaux d’anomalies
historique par client
réactions graduées
protection anti-thief
protection fast-reask
analyse des incohérences protocole
À ne pas copier aveuglément
ban sur ModString seul
ban sur pseudo seul
ban permanent au premier signal
community favoritism
règles spécifiques à des Mods disparus
signatures non expliquées
23. Exemple
PeerTrustProfile
IdentityTrust
UserHash claimed
SecureIdent verified
result HIGH
ProtocolCompliance
malformed packets 0
file request floods 0
QR floods 0
result HIGH
QueueSignalTrust
remote QR unverifiable
suspicious changes 3
result UNKNOWN
SourceExchangeQuality
received 143
valid syntax 143
new 62
reachable 34
useful 19
result NORMAL
DataIntegrity
verified bytes 1.8 GiB
corrupt attributable 0
result HIGH
Ce profil n’a pas besoin d’être affiché tel quel à l’utilisateur normal.
Il sert au moteur et au diagnostic.
24. Provenance de chaque donnée
Proposition très importante :
LOCAL_MEASURED
REMOTE_CLAIM
CRYPTO_VERIFIED
HASH_VERIFIED
CROSS_CHECKED
HEURISTIC
Exemples :
RemoteQueueRank
value=17
origin=REMOTE_CLAIM
CreditDownloadedBytes
value=412 MiB
origin=LOCAL_MEASURED
SecureIdentity
state=VALID
origin=CRYPTO_VERIFIED
BlockIntegrity
state=GOOD
origin=HASH_VERIFIED
Cela permet de voir immédiatement dans le code si une décision forte dépend d’une donnée faible.
25. Trust Boundary Review
1. quelles entrées utilise-t-elle ?
2. qui contrôle ces entrées ?
3. peuvent-elles être vérifiées ?
4. quel avantage accordons-nous ?
5. que se passe-t-il si elles sont fausses ?
Exemple actuel :
SwapToRightFile()
entrée : RemoteQueueRank
contrôlé par : pair distant
preuve : aucune
effet : influence décision de swap
Statut :
AUDIT PRIORITAIRE
26. Réactions graduées
Proposition de niveaux :
R0 — Observer
aucune conséquence
log / métrique seulement
R1 — Ignorer la donnée
Exemple :
RemoteQR jugé incohérent
→ ne plus l’utiliser pour une optimisation
R2 — Désactiver la capacité
Exemple :
SX4 annoncé mais réponses répétées invalides
→ plus de SX avec ce pair pendant cette session
R3 — Cooldown
Exemple :
requêtes trop rapides
→ ignorer temporairement
R4 — Disconnect
Pour violation importante de session.
R5 — Temporary Ban
Réservé aux preuves fortes :
flood répété
usurpation SecureIdent établie
corruption attribuée au-delà du seuil
27. Le ban doit être explicable
Chaque sanction devrait avoir :
reason_code
evidence
timestamp
duration
scope
Exemple :
BAN
reason=QR_FLOOD
evidence=3 unsolicited QR + badrequest threshold
duration=historical default
Pas :
BAN
reason=leecher
Cette différence sera très importante pour le support et le développement.
28. Temporaire plutôt que définitif
Le réseau est dynamique.
Une IP peut plus tard appartenir à un autre utilisateur.
Un NAT peut représenter plusieurs utilisateurs.
Une erreur réseau peut imiter un comportement mauvais.
états à durée de vie limitée
dégradation progressive
réévaluation
sauf données persistantes cryptographiquement liées à une identité.
29. Pas de bonus fondé sur des données non vérifiables
Une Remote Claim ne doit jamais suffire seule à obtenir un privilège local significatif.
Exemples de privilèges :
slot immédiat
crédit artificiel
contournement de queue
bypass de limites
priorité spéciale
Cette règle aurait historiquement évité une partie des mécaniques exploitables par Fake Rank / Community Faker.
30. Attention aux mécanismes communautaires
Le corpus Applejuice comporte plusieurs fonctions :
Community
Community Faker
ignore hard limit for community
boost
special slots
Dès qu’un label distant ouvre un privilège local :
« je suis membre de la communauté »
il devient une cible naturelle de falsification.
31. Telemetry : mesurer les attaques réellement présentes en 2026
Beaucoup de protections historiques ciblent peut-être aujourd’hui des comportements disparus.
Nous ne devons pas supposer.
Proposition :
[TRUST_ANOMALY]
type=QR_UNSOLICITED
peer=anon-id
count=...
[TRUST_ANOMALY]
type=SX_INVALID_PACKET
version=4
expected=...
received=...
[TRUST_ANOMALY]
type=CAPABILITY_CONTRADICTION
claimed=SX4
observed=invalid_sx4
[TRUST_ANOMALY]
type=FILE_REASK_TOO_FAST
delta=...
Après plusieurs semaines :
quelles attaques existent réellement ?
quelles protections ne se déclenchent jamais ?
quels signaux créent des faux positifs ?
32. Confidentialité des logs
Un journal Trust ne doit pas devenir une base inutilement intrusive.
Par défaut :
pas de UserHash complet
pas d’IP persistée indéfiniment
identifiant pseudonymisé de session
durées de rétention courtes
Pour debug volontaire :
mode détaillé explicite
33. Patch immédiat 1 — annoter la confiance du Remote QR
Aucun changement protocolaire.
Première étape :
// Remote-provided, unverifiable queue position.
// Never treat as authoritative.
m_nRemoteQueueRank = nr;Puis créer des compteurs d’usage :
remote_qr_received
remote_qr_used_for_swap
remote_qr_threshold_le50
remote_qr_threshold_gt50
But :
savoir si la branche QR 50 est encore réellement importante.
34. Patch immédiat 2 — Decision Trace autour de SwapToRightFile
Ajouter uniquement du diagnostic.
Exemple :
[A4AF_SWAP_DECISION]
from=fileA
to=fileB
remoteQR=17
remoteQRTrust=UNVERIFIED
sxAllowedA=yes
sxAllowedB=no
decision=SWAP
reason=REMOTE_QR_LE_50
Cette trace nous permettra de mesurer exactement l’influence d’une donnée falsifiable.
35. Patch immédiat 3 — Source Exchange Quality Metrics
Ajouter à la provenance SX :
provider client
source announced
source accepted
source duplicate
source rejected-IP
source connected
source useful
Ne pas punir dans un premier temps.
Observation seulement.
36. Patch immédiat 4 — centraliser les anomalies protocole
Aujourd’hui, les protections sont dispersées :
CheckQueueRankFlood
CheckFailedFileIdReqs
AddRequestCount
CorruptionBlackBox
SecureIdent
same-IP queue logic
Créer à terme :
PeerProtocolMonitor
qui collecte les événements sans nécessairement remplacer les mécanismes existants.
Première phase :
miroir des événements
Aucun changement de comportement.
37. Patch immédiat 5 — le CSPRNG SecureIdent du dossier 03
Il s’intègre directement au Trust Model.
Le challenge SecureIdent est une preuve.
Il doit donc être généré avec une source d’aléa adaptée.
Remplacer :
rand()+139. Fuzzing défensif
Les parsers de paquets anciens sont un bon candidat au fuzzing local.
Objectif :
aucun crash
aucun dépassement
aucune allocation aberrante
aucun état impossible
Cibles prioritaires :
Hello / HelloAnswer
MuleInfo
SX1 / SX2
QueueRank
FileRequest
PartStatus
AICH
Le fuzzing concerne ici la robustesse de notre propre client.
Il ne nécessite aucune émission vers le réseau réel.
41. Matrice de confiance proposée
| Information | Source | Vérifiable ? | Utilisation recommandée |
|---|---|---|---|
| Nickname | pair | non | affichage |
| ModString | pair | non | diagnostic / indice faible |
| Client version | pair | partiellement par comportement | compatibilité prudente |
| Remote QR | pair | non | heuristique faible |
| UserHash | pair | oui via SecureIdent | identité après preuve |
| Octets transférés | local | oui | crédits / stats |
| Source SX | pair | seulement par essai | découverte avec filtrage |
| Part Status | pair | seulement par transfert | planification prudente |
| Bloc reçu | local | oui | provisoire jusqu’au hash |
| Bloc/part vérifié | hash | oui | forte confiance |
| Fréquence de requêtes | local | oui | anti-abus |
| Paquet malformé | local | oui | compliance |
| Corruption attribuée | local + hash | oui avec limites | forte anomalie |
42. Architecture proposée
PeerTrustProfile
Données par pair.
PeerEvidenceStore
Événements avec :
type
scope
strength
timestamp
expiration
PeerProtocolMonitor
Collecte :
flood
malformed packet
capability contradiction
rate violation
PeerQualityMonitor
Collecte :
SX yield
valid data
connection success
part claim success
PeerPolicy
Transforme les preuves en actions graduées.
43. Ne pas utiliser une moyenne magique
Exemple à éviter :
TrustScore = 72/100
Pourquoi ?
Parce qu’un client pourrait :
être excellent pour les données
mais mauvais pour SX
Une moyenne cacherait cette distinction.
Meilleure approche :
DataIntegrity = HIGH
SXQuality = LOW
QueueSignal = UNKNOWN
Identity = VERIFIED
Puis chaque sous-système n’utilise que la dimension qui le concerne.
44. Intégration à Source Discovery Manager
Dossier 01 :
Source Discovery Manager
peut maintenant utiliser :
SXQuality
mais pas :
ModStringTrust
Exemple :
deux pairs nous proposent 50 sources.
Pair A :
50 proposées
35 joignables historiquement
Pair B :
50 proposées
2 joignables historiquement
45. Intégration à Upload Intelligence
Dossier 04 :
l’Upload Queue doit utiliser seulement :
temps local
crédits locaux vérifiés
priorité locale
états localement observés
et jamais :
Remote Queue Rank
Remote ModString
Remote claimed ratio
pour accorder directement un slot.
46. Intégration à Connectivity Intelligence
Dossier 02 :
les capacités de callback annoncées peuvent être :
CLAIMED
puis évoluer vers :
OBSERVED_WORKING
si une tentative réussit.
47. Intégration à Identity Health
Dossier 03 :
SecureIdent devient la racine de confiance de l’identité historique.
Un ModString ne doit pas remplacer SecureIdent.
Un UserHash identique sans preuve cryptographique doit rester suspect lorsqu’il existe une identité sécurisée connue.
48. Ce que nous pouvons tirer d’Argos et Client Analyzer
L’idée la plus intéressante n’est pas la liste de Mods bannis.
C’est la corrélation multi-critères.
Argos documente :
modstring
pseudo
logiciel
hash
opcode
fast ask
SX exploit
tags invalides
violations protocole
plusieurs signaux indépendants
mais donner beaucoup plus de poids aux signaux :
objectivement observables
qu’aux simples chaînes de caractères.
49. Ordre de confiance suggéré
Du plus solide au plus faible :
hash / signature cryptographique
↓
mesure locale directe
↓
comportement répété cohérent
↓
corrélation de plusieurs déclarations
↓
déclaration distante isolée
↓
ModString / nickname / réputation statique
51. Conclusion
Le réseau eD2K/eMule a été conçu dans un environnement ouvert où les clients peuvent être modifiés.
Les anciens Leecher Mods démontrent que :
un paquet valide peut contenir une information mensongère
et les anciens Anti-Leecher démontrent que cette réalité était connue depuis longtemps.
Elle doit construire un modèle clair :
déclaration → observation → vérification → décision proportionnée
avec une règle centrale :
les avantages locaux doivent reposer autant que possible sur des faits mesurés par notre propre client.