
Human-friendly Thrift encoder/decoder
تُسهّل أداة Readable Thrift التعامل مع رسائل بروتوكول Thrift الثنائية من خلال تحويلها من وإلى تنسيق سهل للبشر. وهذا يجعل التحليل اليدوي لرسائل Thrift الثنائية والعبث بها بنفس سهولة التعامل مع البروتوكولات النصية الصريحة مثل HTTP.
المكتبة منفّذة بلغة Java، مما يتيح التكامل مع الإضافات الخاصة بأدوات اختبار تطبيقات الويب الشائعة التي تعمل على JVM، مثل Burp وZAP. كل ما يتطلبه الأمر لتشغيل أداة تحليل أو عبث هو استخراج البايتات المناسبة وتمريرها إلى المرمّز (codec).
مكتبة readablethrift هي حزمة Maven مبنية على Gradle ويمكن تثبيتها أو تضمينها كاعتماد (dependency) في مشاريع أخرى. وهي توفر أربع طرق بسيطة للترميز وفك الترميز، إما في صورة ثنائية خام أو بصيغة Base64.
ملاحظة: يُدعم حاليًا بروتوكول التنسيق الثنائي القياسي فقط. التنسيق الثنائي المضغوط (Compact binary) وJSON (المختلف عن JSON القابل للقراءة الذي ينتجه المرمّز) غير مدعومين بعد.
ThriftCodec::decode كائن org.json.JSONObject وصفيًا مباشرةً من مخزن بايتات خام يحتوي على رسالة Thrift ثنائية.ThriftCodec::decodeB64String بفك ترميز سلسلة Base64 ثم تستدعي decode عليها.ThriftCodec::encode كائن org.json.JSONObject وصفيًا إلى مخزن بايتات خام يحتوي على رسالة Thrift الثنائية المكافئة.ThriftCodec::b64encodeJson تحوّل كائن JSON إلى تنسيق Thrift الثنائي ثم ترمزه بترميز Base64.صُممت فئة ThriftCodec لتكون قابلة للتوسعة بحيث يمكنها التعامل مع التعديلات أو الإضافات على تنسيق بروتوكول Thrift الثنائي، مثل ترويسات التنسيق الثنائي الإضافية أو التغليف (encapsulation).
لاستخدام واجهة سطر الأوامر التفاعلية المضمنة في المكتبة، استخدم مهمة Gradle الافتراضية لبناء ملف JAR ثم قم بتشغيله باستخدام 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):
لتوضيح شكل JSON القابل للقراءة، لنأخذ مثالاً على كتلة ثنائية مشفرة بـ Base64 مستخرجة من بعض حركة مرور التطبيق:
$ 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..
السلاسل النصية "login" واسم المستخدم وكلمة المرور تشير إلى أن هذا طلب مصادقة. إذا أراد شخص العبث بهذه الرسالة أثناء تدفقها، فسيتعين عليه الاطلاع على التفاصيل الداخلية لمحلل تنسيق بروتوكول Thrift الثنائي، ومعرفة بنية الرسالة باستخدام محرر سداسي عشري، ثم تحديث كل حقل يدويًا. وفي حالة سلاسل اسم المستخدم وكلمة المرور، سيكون من الضروري أيضًا تحديث قيم الطول المسبوقة بالإضافة إلى السلاسل نفسها. وستكون هذه عملية شاقة وعرضة للأخطاء وتستغرق وقتًا طويلاً. تعمل أداة Readable Thrift على تبسيط هذه العملية؛ إليك نفس الرسالة عند تمريرها إليها:
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
}}
الآن يمكننا التحقق بسهولة من أن الرسالة تصف استدعاءً لطريقة "login"، مع بنية (struct) تحتوي على قيمتين نصيتين كوسيطة. تحديث القيم النصية ببساطة هو تعديل حقول value في JSON وإعادة تمرير نص JSON الجديد إلى المرمّز. سيتم التعامل تلقائيًا مع جميع بادئات الطول والتفاصيل الأخرى للتنسيق الثنائي.
من الممكن أيضًا إضافة حقول جديدة لاختبار المعاملات الاختيارية المحتملة. ربما توجد علامة منطقية (boolean) للإدارة أو التصحيح؟ أو قائمة بمعرفات الصلاحيات؟ صف حقلًا جديدًا باستخدام id وtype وvalue، ثم أضفه إلى مصفوفة 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==
فيما يلي الرسالة المحدّثة بعد تحويلها مرة أخرى إلى بروتوكول 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