
ملاحظات الهندسة العكسية، والمصدر بعد إزالة التشويش، ومؤشرات الاختراق، وقواعد YARA الخاصة ببرمجية Tourmaline ClickFix Python RAT، والتي تغطي نفق DNS الخاص بها وC2 القائم على blockchain dead-drop.
عثرت مؤخرًا على قطعة من البرمجيات الخبيثة المصممة بذكاء والتي تطلق على نفسها اسم "Torumaline".
تمت كتابة هذا الملف التعريفي (README) بلطف شديد من قبل Claude لأنني كنت مشغولًا جدًا بالامتحانات في وقت إنشاء هذا المستودع.
استغلال وفك تشفير هذه البرمجية الخبيثة استهلك جزءًا كبيرًا من وقتي المخصص للتحضير للرياضيات!
اقرأ منشور المدونة!
لأغراض تعليمية وبحثية فقط
جميع العينات مقدمة لتحليل البرمجيات الخبيثة والبحث الدفاعي. لا تقم بتشغيلها خارج بيئة معزولة ومعزولة عن الشبكة.
Tourmaline (Tourmaline.exe) هي برمجية خبيثة متقدمة متعددة المراحل لنظام Windows من نوع سرقة المعلومات/الباب الخلفي، يتم توزيعها عبر حملة ClickFix - وهي نافذة منبثقة مزيفة من Cloudflare "تحقق من أنك إنسان" في المتصفح تخدع المستخدمين لتشغيل أمر أو مثبّت خبيث يدويًا.
الملف الثنائي هو مثبّت Inno Setup 6.7.0 (المراجعة 2، إزاحات 64-بت) مخصص البناء، يحتوي على بيئة تشغيل Python 3.11 كاملة ومرحلتين من حمولة Python المشوّشة. ينشئ بابًا خلفيًا دائمًا مع:
microsoft.com)tourmaline/
├── README.md # This file
├── LICENSE # Research use license
├── .gitignore
│
├── src/ # Extracted & deobfuscated source code
│ ├── stage1_loader.py # Stage 1: Original obfuscated XOR time-lock loader (main.py)
│ ├── stage2_backdoor.py # Stage 2: Deobfuscated core backdoor (from QGBdu.dxf)
│ └── decrypt_payload.py # Utility: O(1) payload key recovery & decryption
│
├── iocs/ # Indicators of Compromise
│ ├── indicators.json # Structured IOC data (IPs, hashes, domains, registry)
│ ├── indicators.csv # Flat CSV for SIEM import
│ └── rules.yar # YARA detection rules
│
└── samples/ # Malware samples (password-protected)
├── README.md # Sample archive instructions
├── Tourmaline_sample.zip # Password: infected - contains Tourmaline.exe
└── QGBdu.dxf # Raw encrypted Stage 2 payload blob
يتم توزيع البرمجية الخبيثة عبر ClickFix - وهي تقنية هندسة اجتماعية حيث يقوم موقع مخترق أو يتحكم به المهاجم بتركيب طبقة فوقية لـ CAPTCHA مزيف من Cloudflare أو صفحة تحقق من المتصفح. تُوجّه الطبقة الفوقية الضحية للقيام بما يلي:
Win+Rيقوم الأمر الملصق بتنزيل Tourmaline.exe وتنفيذه بصمت. يعمل المثبّت بالأمر /VERYSILENT /SUPPRESSMSGBOXES /NORESTART.
ملاحظة: لا يمكن لأداة
innoextract 1.9القياسية استخراج هذا الملف الثنائي — فهي تدعم المراجعة 1 فقط. تستخدم المراجعة 2 إزاحات 64-بت وتتطلب تحليلًا مخصصًا (انظرsrc/decrypt_payload.py).
Tourmaline.exe
│
├─ Inno Setup installer runs silently
│ ├─ Extracts Python 3.11 runtime to %APPDATA%\Tourmaline\
│ ├─ Extracts main.py (Stage 1 loader)
│ ├─ Extracts QGBdu.dxf (encrypted Stage 2 blob)
│ ├─ Kills any existing pythonw.exe instances
│ └─ Registers persistence (Task Scheduler / registry)
│ └─ Name: "TourmalineUpdate" / "Hardware monitoring service"
│
├─ Stage 1: main.py (XOR Time-Lock Loader)
│ ├─ Counts _n from 99,999,999 → 0 (anti-sandbox delay ~hours on slow VMs)
│ ├─ At each _n, constructs 33-byte XOR key: struct.pack('>I', _n) + hardcoded_suffix
│ ├─ Tests key against known plaintext header of QGBdu.dxf
│ └─ On match: decrypts QGBdu.dxf entirely and exec()s the result
│ └─ O(1) bypass: known-plaintext attack on first 4 bytes (see below)
│
└─ Stage 2: QGBdu.dxf → Python backdoor
├─ Reads MachineGuid from HKLM\SOFTWARE\Microsoft\Cryptography
├─ Derives mutex Global\Tourmaline_<hash>
├─ Resolves C2 IP via Ethereum dead-drop (Sepolia testnet)
├─ Establishes DNS tunnel to C2
└─ Poll-execute loop: fetches tasks, exec()s Python, returns output
يستخدم المُحمّل (main.py) عدًا تنازليًا من 99,999,999 للعثور على مفتاح فك التشفير XOR. على جهاز حقيقي يكتمل هذا في ثوانٍ (لأن _n يبدأ مرتفعًا والقيمة الحقيقية قريبة من 14,511,188). في بيئة معزولة بحد زمني قصير، لا تكتمل الحلقة أبدًا.
بنية المفتاح:
full_key = struct.pack('>I', _n) + bytes.fromhex('2b0cffe07b06ac25793b3f00cfaa2dd5881c2d6378165247539dbbdaeb')
بما أننا نعرف أول 16 بايت من النص الأصلي (g1 = lambda l6, )، يمكننا استعادة _n فورًا عبر هجوم XOR بالنص الأصلي المعروف:
key_prefix = bytes(ciphertext[i] ^ known_plaintext[i] for i in range(4))
# Result: key_prefix = 00dd6c54 → _n = 14,511,188
استخدم src/decrypt_payload.py لإعادة إنتاج هذا.
تستدعي البرمجية الخبيثة عقدًا ذكيًا على Ethereum في شبكة Sepolia التجريبية لاسترداد عنوان IP النشط للـ C2. هذا يعني أن المهاجم يمكنه تغيير عنوان IP الخاص بالـ C2 في أي وقت عبر تحديث العقد — مما يجعل تعطيل C2 التقليدي القائم على قوائم حظر عناوين IP غير فعال.
Contract : 0x2d7a04cca0c34005f58393f30ac725e25f19e5f5
Selector : 0xeb9fd6fe
Network : Ethereum Sepolia (chainId 11155111)
RPC : https://ethereum-sepolia-rpc.publicnode.com
Result : ChaCha20-encrypted blob containing current C2 IP
يتم فك تشفير البيانات المُعادة باستخدام مفتاح ChaCha20 المضمّن للكشف عن عنوان C2 الحي. في وقت التحليل، تم حل هذا إلى 158.94.211.185 (تم التحقق عبر استدعاء RPC مباشر).
يتم إرسال جميع حركة C2 كـ استعلامات UDP DNS خام مباشرة إلى عنوان IP الخاص بالـ C2 على المنفذ 53. تُبنى الاستعلامات على شكل <encoded_data>.microsoft.com، متجاوزةً التصفية القائمة على DNS وتظهر كبيانات قياس عن بُعد شرعية من Windows.
socket.getaddrinfo الخاص بـ Python أو أي مكتبة DNSينفذ الباب الخلفي محرك exec() عشوائي لـ Python. المهام هي:
exec() في مساحة أسماء دائمة مع التقاط المخرجاتأنواع المهام المدعومة: تنفيذ Python، رفع/تنزيل ملفات، أمر shell، تحديث ذاتي.
| الملف | SHA256 |
|---|---|
Tourmaline.exe | c9b390b3b7148f549df86503858d52e030b2b5e78fed0bc525ded5927f9265d6 |
Tourmaline.exe (MD5) | b74ac808dea2de31caf024310694ef0c |
انظر iocs/rules.yar لقواعد الكشف التي تغطي:
إذا تم تنفيذ هذه البرمجية الخبيثة على جهاز:
taskkill /F /IM pythonw.exe%APPDATA%\Tourmaline\ أو %COMMONAPPDATA%\Tourmaline\TourmalineUpdateHKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run بحثًا عن Tourmaline أو SystemService158.94.211.185:53/UDP؛ احظر جميع حركة UDP/53 الصادرة غير المتوقعةethereum-sepolia-rpc.publicnode.compip install pyOpenSSL cryptography
# From the repo root:
python3 src/decrypt_payload.py samples/QGBdu.dxf decrypted_stage2.py
7z x -pinfected samples/Tourmaline_sample.zip
انظر LICENSE. هذا المستودع لأغراض تعليمية وبحثية دفاعية فقط.
| الخاصية | القيمة |
|---|
| اسم الملف | Tourmaline.exe |
| الحجم | 11,341,339 بايت (~10.8 ميجابايت) |
| MD5 | b74ac808dea2de31caf024310694ef0c |
| SHA256 | c9b390b3b7148f549df86503858d52e030b2b5e78fed0bc525ded5927f9265d6 |
| التنسيق | Inno Setup 6.7.0 Unicode (المراجعة 2، إزاحات 64-بت) |
| نوع PE | PE 32-بت، 11 قسمًا |
| حجم الطبقة الفوقية | 10,447,387 بايت |
| إزاحة سحر Inno | 0xD9864 (890,148 بايت) |
| اسم التطبيق | Tourmaline |
| إصدار التطبيق | 2.63.519 |
| GUID التطبيق | {2C25872D-85FC-44C7-9B16-844E39E50A44} |
| مسار التثبيت | {commonappdata}\Tourmaline |
| بيئة التشغيل المضمنة | Python 3.11 (مضمن كامل) |
| ملفات الحمولة | 36 ملفًا في تدفق LZMA2 صلب |
| المعامل | القيمة |
|---|
| عنوان IP للـ C2 | 158.94.211.185 |
| منفذ C2 | 53 (UDP) |
| البروتوكول | نفق DNS-over-UDP مخصص |
| النطاق المنتحل | microsoft.com |
| مفتاح ChaCha20 | 36f555c87f71581f57d83576c88193fdc00a0173f741a3e198e2d7abdc9cda59 |
| عقد البلوكشين | 0x2d7a04cca0c34005f58393f30ac725e25f19e5f5 (Sepolia) |
| المفتاح العام ECDSA | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEt17l3rGHHR9sYdHEvV8S+JRRCUHQQveSadlGk04xM/8WClDf/67Tyritt2+T18SY8n0xv1TKKl0AgnNFuboEEQ== |
| اسم الخدمة | SystemService / TourmalineUpdate |
| Mutex | Global\Tourmaline_<MachineGuid-hash> |
| النوع | القيمة |
|---|
| عنوان IP للـ C2 | 158.94.211.185 |
| منفذ C2 | 53/UDP |
| النطاق المنتحل | *.microsoft.com (UDP مخصص، ليس DNS حقيقي) |
| Ethereum RPC | https://ethereum-sepolia-rpc.publicnode.com |
| العقد الذكي | 0x2d7a04cca0c34005f58393f30ac725e25f19e5f5 |
| المفتاح | القيمة |
|---|
HKLM\SOFTWARE\Microsoft\Cryptography\MachineGuid | يُقرأ لبصمة الضحية |
%APPDATA%\Tourmaline\ | دليل التثبيت |
| Task Scheduler | TourmalineUpdate |
| اسم عرض الخدمة | Hardware monitoring service |
| Mutex | Global\Tourmaline_<hash> |
| الحقل | القيمة |
|---|
| تاريخ الاكتشاف | سبتمبر 2026 |
| الباحث | Vihaan Pundir (v-pun215) |
| ناقل التوزيع | ClickFix fake Cloudflare CAPTCHA |
| التصنيف | Backdoor / DNS Tunnel C2 / Blockchain Dead-Drop |
| المنصة | Windows (64-bit) |