
Human-friendly Thrift encoder/decoder
Readable Thrift facilite le travail avec les messages binaires du protocole Thrift en les convertissant vers et depuis un format lisible par l'humain. Cela rend l'analyse manuelle et l'altération des messages Thrift au format binaire aussi simples que le travail avec des protocoles en clair comme HTTP.
La bibliothèque est implémentée en Java, ce qui permet son intégration dans des extensions pour les outils de test d'applications web populaires qui s'exécutent sur la JVM, tels que Burp et ZAP. Tout ce qu'il faut pour mettre en place un outil d'analyse ou d'altération est d'extraire les octets appropriés et de les passer au codec.
La bibliothèque readablethrift est un paquet Maven basé sur Gradle qui peut être
installé et inclus comme dépendance dans d'autres projets. Elle expose quatre méthodes
simples pour encoder et décoder, sous forme binaire brute ou encodée en Base64.
Remarque : Seul le format de protocole binaire standard est actuellement pris en charge. Les formats compact binaire et JSON (différent du JSON lisible produit par le codec) ne sont pas encore pris en charge.
ThriftCodec::decode crée une instance descriptive de org.json.JSONObject
directement à partir d'un tampon d'octets brut contenant un message Thrift binaire.ThriftCodec::decodeB64String décode une chaîne Base64
puis appelle decode sur celle-ci.ThriftCodec::encode convertit une instance descriptive de org.json.JSONObject en un tampon
d'octets brut contenant le message Thrift binaire équivalent.ThriftCodec::b64encodeJson convertit un objet JSON
au format binaire Thrift puis encode le résultat en Base64.La classe ThriftCodec est conçue pour être extensible afin de pouvoir gérer des
modifications ou extensions du format de protocole binaire Thrift, telles que des
en-têtes de format binaire supplémentaires ou de l'encapsulation.
Pour utiliser l'interface en ligne de commande interactive incluse dans la bibliothèque,
utilisez la tâche Gradle par défaut pour construire un JAR puis exécutez-le avec
java -jar :
$ ./gradlew
BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed
$ java -jar build/libs/readablethrift-1.0.0-all.jar
Enter Base64 encoded message or JSON object (or q to quit):
Pour montrer à quoi ressemble le JSON lisible par l'humain, prenons un exemple de blob binaire encodé en Base64 extrait d'un trafic applicatif :
$ base64 -D | hexdump
gAEAAQAAAAVsb2dpbgAAAAAMAAALAAAAAAAIY29vbHVzZXILAAEAAAALcGFzc3dvcmQxMjMAAA==
00000000: 8001 0001 0000 0005 6c6f 6769 6e00 0000 ........login...
00000010: 000c 0000 0b00 0000 0000 0863 6f6f 6c75 ...........coolu
00000020: 7365 720b 0001 0000 000b 7061 7373 776f ser.......passwo
00000030: 7264 3132 3300 00 rd123..
Les chaînes « login », nom d'utilisateur et mot de passe indiquent qu'il s'agit d'une requête d'authentification. Pour altérer ce message à la volée, il faudrait rechercher les détails internes du format de protocole binaire Thrift, déterminer la structure du message avec un éditeur hexadécimal, puis mettre à jour manuellement chaque champ. Dans le cas des chaînes de nom d'utilisateur et de mot de passe, il serait également nécessaire de mettre à jour les valeurs de longueur préfixées en plus des chaînes elles-mêmes. Ce serait un processus fastidieux, sujet aux erreurs, et chronophage. Readable Thrift simplifie ce processus ; voici le même message lorsqu'il lui est transmis :
Enter Base64 encoded message or JSON object (or q to quit): gAEAAQAAAAVsb2dpbgAAAAAMAAALAAAAAAAIY29vbHVzZXILAAEAAAALcGFzc3dvcmQxMjMAAA==
{"message": {
"name": "login",
"type": "call",
"fields": [{
"id": 0,
"type": "struct",
"value": [
{
"id": 0,
"type": "string",
"value": "cooluser"
},
{
"id": 1,
"type": "string",
"value": "password123"
}
]
}],
"seqid": 0
}}
Nous pouvons maintenant facilement vérifier que le message décrit un appel à la méthode « login », avec une structure
contenant deux valeurs de type chaîne comme argument. Mettre à jour les valeurs des chaînes est aussi simple que de modifier
les champs JSON value et de repasser le nouveau texte JSON au codec.
Tous les préfixes de longueur et autres détails du format binaire seront gérés automatiquement.
Il est également possible d'ajouter de nouveaux champs pour tester d'éventuels paramètres optionnels.
Peut-être y a-t-il un drapeau booléen admin ou debug ? Ou une liste d'identifiants de permissions ?
Décrivez un nouveau champ avec un id, un type et une value, puis ajoutez-le au
tableau fields :
Enter Base64 encoded message or JSON object (or q to quit): {"message": {
"name": "login",
"type": "call",
"fields": [{
"id": 0,
"type": "struct",
"value": [
{
"id": 0,
"type": "string",
"value": "differentuser"
},
{
"id": 1,
"type": "string",
"value": "differentpassword!"
}
]
},
{"id": 1, "type": "bool", "value": true},
{"id": 2, "type": "list", "value":
{
"elemType": "i32",
"list": [1, 2, 3]
}
},
{"id": 3, "type": "map", "value":
{
"keyType": "string",
"valueType": "string",
"map": {
"dog": "bark",
"cat": "meow"
}
}
}],
"seqid": 0
}}
gAEAAQAAAAVsb2dpbgAAAAAMAAALAAAAAAANZGlmZmVyZW50dXNlcgsAAQAAABJkaWZmZXJlbnRwYXNzd29yZCEAAgABAQ8AAggAAAADAAAAAQAAAAIAAAADDQADCwsAAAACAAAAA2NhdAAAAARtZW93AAAAA2RvZwAAAARiYXJrAA==
Ci-dessous se trouve le message mis à jour reconverti au protocole binaire Thrift :
$ base64 -D | hexdump
gAEAAQAAAAVsb2dpbgAAAAAMAAALAAAAAAANZGlmZmVyZW50dXNlcgsAAQAAABJkaWZmZXJlbnRwYXNzd29yZCEAAgABAQ8AAggAAAADAAAAAQAAAAIAAAADDQADCwsAAAACAAAAA2NhdAAAAARtZW93AAAAA2RvZwAAAARiYXJrAA==
00000000: 8001 0001 0000 0005 6c6f 6769 6e00 0000 ........login...
00000010: 000c 0000 0b00 0000 0000 0d64 6966 6665 ...........diffe
00000020: 7265 6e74 7573 6572 0b00 0100 0000 1264 rentuser.......d
00000030: 6966 6665 7265 6e74 7061 7373 776f 7264 ifferentpassword
00000040: 2100 0200 0101 0f00 0208 0000 0003 0000 !...............
00000050: 0001 0000 0002 0000 0003 0d00 030b 0b00 ................
00000060: 0000 0200 0000 0363 6174 0000 0004 6d65 .......cat....me
00000070: 6f77 0000 0003 646f 6700 0000 0462 6172 ow....dog....bar
00000080: 6b00