المجتمع CRTP

PowerView ولا Active Directory Module؟ اقرأ نفس الحساب بطريقتين واعرف ليش النتائج أحيانًا تختلف

تشوف MemberOf في أداة، وتختفي من أداة ثانية، فتقول الأولى أقوى. لكن ممكن الفرق أن الخاصية ما طُلبت، أو عُرضت بصورة مختصرة، أو أن الاستعلامين وصلا إلى خادمين مختلفين. قوة أداة Enumeration ما تُقاس بطول الشاشة. في هذا المقال بنقرأ حساب مختبر واحد باستخدام Active Directory Module ونقارن المنطق مع PowerView بنسخة معروفة. بنركز على نوع الكائن والخصائص والفلتر والهوية وPipeline، وهي أشياء توفر وقتًا كثيرًا في تدريب CRTP. الأمثلة قراءة فقط داخل دليل تملكه أو مختبر مصرح، ولا تحتاج جمع كل المستخدمين أو البحث عن أسرار حتى تفهم الاختلاف.

حدد السؤال قبل اختيار الأداة

سؤال مثل أعطني معلومات المستخدم واسع جدًا. حدد ما تحتاجه: المعرف المستقر، موقع الكائن، عضوياته المباشرة، أو خاصية وظيفية معينة. إذا كان هدفك مقارنة النتائج، اختر خصائص قليلة ومعروفة لكلا الأداتين، وحساب مختبر لا يحتوي بيانات شخصية حقيقية.

خلنا نفترض مستخدمًا اسمه student01 داخل lab.example. نحتاج SamAccountName وDistinguishedName وMemberOf. الاختيار صغير عمدًا: تعرف الكائن الذي يفترض أن يعود، وتقدر تراجع الخصائص من مالك المختبر، وتفصل اختلاف طريقة عرض الأداة عن اختلاف الدليل.

بعدها سجل الخادم والهوية والإصدار والوقت. لا تقارن أمرًا يستخدم اعتماد الجلسة مع آخر يستخدم هوية أخرى ثم تنسب كل فرق إلى الأداة. كذلك لا تفترض أن الاسم القصير يعرف المستخدم عبر كل المجالات. إذا كان في المختبر أكثر من مجال، حدد السياق صراحة. بهذه البداية صار السؤال قابلًا للإجابة بدل تحول المقارنة إلى قائمة مميزات لا علاقة لها بالمهمة.

Get-ADUser يعيد مجموعة افتراضية، لا كل شيء

يوضح دليل Microsoft أن Get-ADUser يجلب مجموعة افتراضية من الخصائص، وأن Properties تطلب ما تحتاجه خارجها. لذلك غياب حقل من العرض الافتراضي لا يعني بالضرورة أنه فارغ في الدليل. استخدام Properties * على كل المستخدمين ليس أفضل خطوة أولى؛ اختر خصائص السؤال.

مثال قراءة محدود في مختبرك: $adUser = Get-ADUser -Identity 'student01' -Server 'dc01.lab.example' -Properties MemberOf . بعدها اعرض $adUser | Select-Object SamAccountName,DistinguishedName,MemberOf . أسماء المجال والخادم هنا تعليمية، وتستبدل بأسماء أصول مصرح بها.

راجع النتيجة من ناحيتين: هل الكائن هو المقصود؟ وهل الخاصية المطلوبة وصلت؟ الهوية يمكن تحديدها بمراجع يدعمها Cmdlet، لكن اختيار اسم غامض في سياق خاطئ يعيد خطأ أو كائنًا مختلفًا. ليس كل فشل Identity مشكلة صلاحيات. سجل الاسم المستقر أو DistinguishedName في الدليل قبل الانتقال للمقارنة، ولا تجعل تشابه DisplayName دليلًا أن الأداتين قرأتا الحساب نفسه.

PowerView اسم له نسخ ومشاريع مختلفة

PowerView في PowerSploit أداة PowerShell، وتوجد مشاريع أخرى تستخدم الاسم أو تعيد تقديم وظائف شبيهة بلغات أخرى. لا تنقل خيارات powerview.py إلى سكربت PowerView.ps1 ثم تتوقع أنها تعمل. المستودع الأصلي لـPowerSploit مؤرشف، وهذه معلومة مهمة عند تقييم التوافق والدعم.

في نسخة PowerShell المعروفة والمعتمدة داخل المختبر، ابدأ بـGet-Command Get-DomainUser -Syntax ثم Get-Help Get-DomainUser -Full. بهذه القراءة تتحقق من الوظيفة والمعاملات في النسخة الموجودة فعلًا. لا تحمل نسخة مجهولة لأن سطرًا في شرح قديم لم يتوافق مع النسخة التي يراجعها فريقك.

إذا كانت نسختك تعرض Identity وProperties وServer كما في النسخة التي تستخدمها، يمكن صياغة قراءة الحساب المحدد بهذا الشكل: $pvUser = Get-DomainUser -Identity 'student01' -Server 'dc01.lab.example' -Properties samaccountname,distinguishedname,memberof . راجع المساعدة قبل التنفيذ ولا تعتبر المثال صالحًا تلقائيًا لكل مشروع يحمل اسم PowerView. الفرق بين معرفة الأداة وحفظ اسمها يظهر في هذه الخطوة البسيطة.

نوع الكائن يشرح كثيرًا من الاختلاف

الأداة قد تعيد ADUser، أو كائنًا مخصصًا يحوي خصائص LDAP محولة، أو شكلًا خامًا من نتيجة بحث. الاسم المعروض لا يشرح النوع كاملًا. اقرأ $adUser | Get-Member و$pvUser | Get-Member على النتائج الموجودة عندك، ثم قارن أسماء الخصائص وأنواعها.

قد تكون قيمة في أداة سلسلة، وفي أخرى مجموعة قيم أو نوعًا خاصًا يعرض كنص. لا تفرض مقارنة مباشرة على حقول لا تعرف شكلها. ولو احتجت تحويلًا، اجعله معلنًا في تحليل النتيجة، واحتفظ بالنسخة الأصلية قبل التحويل. المقارنة الجيدة تعرف ما فقدته من معلومات حين بسّطت المخرج.

خلنا نفترض MemberOf تحتوي عدة DNs. ظهور {...} في جدول لا يعني أن هناك عضوية واحدة أو أن النص تالف. غالبًا أنت ترى عرضًا مختصرًا لمجموعة. اقرأ القيمة نفسها مثل $adUser.MemberOf، ثم راجع النوع والعدد داخل السياق. بهذه الطريقة تمنع خطأ شائعًا: تقرير يذكر نقص عضويات بينما الناقص هو عرض الشاشة فقط، وليس بيانات الاستعلام.

Select-Object يختار بيانات، وFormat يجهز عرضًا

Select-Object مفيد لاختيار الخصائص التي تريد الاحتفاظ بها في تحليل أو تصدير. أما Format-Table وFormat-List فيجهزان مخرجات للعرض. إذا أدخلت التنسيق مبكرًا ثم حاولت التعامل مع الناتج كأنه كائن المستخدم الأصلي، قد تحصل على خصائص تنسيق بدل الخصائص التي كنت تبحث عنها.

رتب العمل بهذا المنطق: اجمع النتيجة في متغير، حلل الكائنات، اختر الخصائص، ثم اعرض أو صدّر. مثال قراءة مريح: $adUser | Select-Object SamAccountName,DistinguishedName,MemberOf | Format-List . هنا التنسيق في النهاية لأن الهدف العرض. أما التحليل اللاحق فيستخدم $adUser أو نتيجة Select محفوظة، لا نتيجة Format.

المشكلة تظهر بوضوح في CSV: تمرير Format-Table إلى Export-Csv يمكن أن يصدر كائنات تنسيق. دليل Microsoft ينبه لهذا الفرق. لا تعتبر الملف صحيحًا لأنه امتداده csv؛ افتحه في مختبرك وتحقق من رؤوس الأعمدة وقيمة كائن معروف. اختبر صفًا واحدًا قبل تصدير نتائج أكبر، فذلك يكشف الخطأ بسرعة ويحمي وقتك وبياناتك.

الخاصية المتعددة تحتاج قرار تصدير واضحًا

CSV مناسب لحقول بسيطة، لكن قيمة مثل MemberOf ليست دائمًا خلية نصية واحدة بطبيعتها. لو حولتها إلى نص دون خطة، قد تحصل على تمثيل اسم نوع أو مجموعة يصعب تحليلها. حدد هل تحتاج صفًا لكل عضوية، أو قائمة نصية بفاصل معروف، أو صيغة تحفظ البنية مثل JSON وفق إجراء المختبر.

لملف مراجعة صغير، يمكن اختيار اسم المستخدم وDistinguishedName وعمود نصي تحوله أنت بوضوح من MemberOf. لكن لا تجعل النص المحول المصدر الوحيد؛ احتفظ بالمخرج الأصلي إذا كان نطاق الأدلة يسمح. الفاصل قد يظهر في قيم أخرى، ولا ينبغي أن يتحول الحقل إلى صيغة توهم القارئ أنها علاقة واحدة.

مثال منطقي دون افتراض مخرجات: مستخدم له ثلاث مجموعات مباشرة. في جدول عرض مختصر ترى جزءًا من القائمة، وفي ملف مسطح قد ترى سلسلة غير مفيدة إذا لم تنظمها. قبل اتخاذ قرار أمني قارن عدد القيم ومحتواها، وليس عدد الأسطر الظاهرة على الشاشة. تصميم التصدير جزء من صحة التحليل، وليس مجرد تحسين شكل التقرير.

الفارغ والمفقود والمرفوض ليست نتيجة واحدة

إذا لم تر خاصية، فهناك احتمالات: لم تطلبها، الكائن لا يملك قيمة لها، الأداة لم تعرضها، أو القراءة لم تحصل على المعلومة في هذا السياق. لا تقفز من الخانة الفارغة إلى ليس عنده عضوية أو لم ينطبق إعداد. تحتاج التأكد من الخصائص المطلوبة ومصدر الاستجابة والهوية.

في المختبر اقرأ حسابًا مرجعيًا معروف الإعداد بنفس الطريقة. إذا ظهرت الخاصية عليه، عندك دليل أن مسار القراءة قادر على إظهارها في هذه الظروف. بعدها تقارن الحساب الآخر ضمن نفس النطاق. لا تستخدم حسابًا أعلى دون تصريح فقط لتملأ خانة ناقصة؛ يمكن لمالك الدليل تأكيد الإعداد أو تنفيذ مراجعة مناسبة.

كذلك لا تساوي نتيجة لا يوجد كائن برفض وصول. قد تكون SearchBase غير مناسبة أو الخادم ليس في السياق الذي تقصده أو Identity تشير إلى قيمة قديمة. احتفظ برسالة الخطأ ولا تختصرها إلى Null. هذا التفريق يساعدك تختار بحثًا أضيق، ويحافظ على التقرير من بناء نتائج أمنية على خطأ استعلام أو اختلاف إعداد أداة.

Base وScope والفلتر يغيرون السؤال

في البحث عن عدة كائنات، SearchBase يحدد نقطة البداية وSearchScope يحدد مساحة البحث حولها، والفلتر يحدد من يطابق الشرط. أداة تبحث في OU المختبر وأخرى تبحث في المجال كله قد تعيدان قوائم مختلفة بصورة صحيحة تمامًا. المقارنة هنا ليست متكافئة حتى لو كانت الكلمة المستخدمة في الفلتر نفسها.

فرق أيضًا بين فلتر يجري على الخادم وWhere-Object يرشح نتائج وصلت إلى العميل. الثاني قد يكون مناسبًا لتحليل مجموعة صغيرة عندك، لكنه لا يضيق تلقائيًا البيانات التي طلبها الاستعلام الأول من الدليل. إذا كان نطاقك محدودًا، اضبط سؤال القراءة من المصدر بدل جمع واسع ثم حذف ما لا تحتاجه لاحقًا.

خلنا نفترض أنك تريد حسابًا واحدًا في OU=Lab. الأفضل تحديده وخصائصه أو بحثًا محدودًا مطابقًا للهدف، بدل جلب كل المستخدمين ثم اختيار الاسم من الشاشة. هذا يقلل الحمل والالتباس ويجعل النتيجة قابلة للتكرار. ولا تجعل عامل فلترة متشابه الاسم بين أداتين ضمانًا لتطابق بناء البحث؛ راجع المساعدة وسلوك النسخة.

العضوية المباشرة ليست التوكن الفعلي

MemberOf مفيدة لقراءة روابط العضوية التي تعرضها الخاصية، لكنها ليست وحدها جوابًا لكل صلاحيات المستخدم. العضوية المتداخلة وحالة الجلسة وقرارات الموارد تحتاج تحليلًا آخر، كما توجد تفاصيل مثل Primary Group لها تمثيل مختلف. لا تحول قائمة مباشرة إلى استنتاج أن المستخدم لا يستطيع المورد أو أنه مدير عليه.

في تمرين المقارنة اكتفِ بما تقيسه الخاصية: القيم التي أعادها الاستعلام المحدد للحساب. إذا احتجت العضوية المتداخلة، اطرح سؤالًا مستقلًا واختر طريقة قراءة موثقة، ثم حافظ على الفرق بين حالة الدليل وحالة جلسة قديمة. لا تضف مراحل إلى الاستعلام الأول وتخلط حدودها.

هذه نقطة مهمة لدارس CRTP: الأداة تعطي بيانات، وأنت تبني منها فرضية، ثم تتحقق من الفرضية بدليل مناسب. اسم مجموعة يوحي بإدارة لا يثبت حقوقها على كل جهاز، وغياب مجموعة مباشرة لا ينفي جميع المسارات. التفكير بهذه الطبقات يحول Enumeration من نسخ مخرجات إلى تحليل يفهم ما تقيسه كل خاصية وما الذي تتركه خارجها.

كيف تحقق اختلافًا بين الأداتين؟

ابدأ بالمعرف الثابت للكائن، ثم وحّد الخادم والهوية والخصائص المطلوبة والوقت قدر الإمكان. اقرأ النوع والقيم دون تنسيق مختصر. إذا بقي الفرق، راجع تحويلات كل أداة ومساعدتها ونسختها، وهل هناك تخزين نتيجة أو جلسة تحتفظ ببيانات سابقة. لا تفترض خللًا في الدليل قبل هذه المطابقة.

اختبار جيد يغير عاملًا واحدًا: نفس الحساب ونفس الخادم مع إضافة خاصية صريحة، أو نفس النتيجة بعرض كامل بدل جدول. سجل قبل وبعد وما تغير. إذا بدلت الأداة والخادم والهوية معًا، فقد تحصل على نتيجة مختلفة دون أن تعرف سببها. زيادة الأوامر لا تعوض جودة المقارنة.

إذا لم تستطع تفسير الفرق، اكتب حد المعرفة وأرفق مخرجًا منقحًا ومصدر الإعداد. يمكن لمالك المختبر مراجعة الكائن أو سياسة القراءة. لا تختر النتيجة الأطول باعتبارها الحقيقة، ولا تمسح النتيجة المخالفة من التقرير. اختلاف غير محلول نفسه معلومة عن موثوقية التحليل، لكن يحتاج وصفًا دقيقًا حتى لا يتحول إلى ادعاء أمني غير مثبت.

ورقة عمل صغيرة بدل قائمة أوامر طويلة

لكل قراءة، سجل السؤال والهوية والخادم والمعرف والخصائص والمخرج الأصلي والتفسير. أضف خانة ما الذي لا تثبته النتيجة. مثلًا: هذه قائمة عضويات مباشرة معادة، ولا تثبت عضوية التوكن الحالي أو صلاحية على خادم آخر. هذه الخانة تمنع انتقالًا غير مبرر إلى خطوة مؤثرة.

في المختبر استخدم حسابين معروفين بإعدادين مختلفين ضمن التصريح، وكرر القراءة المحدودة بكلتا الأداتين. هدف التمرين ليس جمع أكثر معلومات، بل معرفة كيف يظهر الفرق المتوقع وكيف تميز خطأ العرض من اختلاف البيانات. إذا ظهر تغير غير متوقع، ارجع إلى مصادره بدل إضافة فلاتر عشوائية.

احتفظ أيضًا بملاحظة الإصدار والمساعدة التي رجعت إليها. كثير من الشروحات القديمة تستخدم أسماء أو خيارات مختلفة، ولا يصح وصف فشل سطر قديم بأنه عجز في الأداة. بناء عادة قراءة Syntax ونوع الكائن والخصائص يوفر عليك وقتًا في أي مختبر عملي، ويجعلك قادرًا على شرح لماذا اخترت أداة معينة بدل الاعتماد على شهرتها بين المتدربين.

المراجع والموضوع الذي يكمل الفكرة

Get-ADUser وPowerView وسيلتان لقراءة أسئلة محددة، والنتيجة لا تُفهم إلا مع الهوية والسياق والخصائص ونوع الكائن. خذ البيانات أولًا، ثم حللها، ثم نسقها للعرض. لا تجعل جدولًا مختصرًا أو ملف CSV غير مراجع أساس قرار عن صلاحيات حساب.

دليل Get-ADUser: https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-aduser . مصدر PowerView الأصلي ووظائفه: https://github.com/PowerShellMafia/PowerSploit/tree/master/Recon . ودليل Export-Csv يوضح مشكلة تصدير كائنات التنسيق: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/export-csv . راجع النسخة الموجودة عندك بدل خلط PowerView PowerShell بمشروع Python مختلف.

بعد إتقان قراءة كائن واحد، انتقل إلى SharpHound: هناك حجم الجمع ونوعه وتغطيته يؤثرون في الرسم الذي يحلله BloodHound. نفس القاعدة تستمر: المخرج وسيلة لتوليد فرضية، وجودة الاستنتاج تعتمد فهم ما جُمع وكيف جُمع ومتى، لا عدد العلاقات الظاهرة في الشاشة.

لشرح سياق الجلسة راجع مقال PowerShell في الذاكرة: https://courses.cyberpts.com/community/174/tshghyl-powershell-fy-althakrh-wsh-ysyr-fala-wlysh-htha-ma-yany-an-aladah-sart-m . ومراجعة قدرات Endpoint في مقال JEA: https://courses.cyberpts.com/community/177/akhtbar-jea-fy-powershell-alhsab-mhdwd-lkn-wsh-tqdr-tswyh-aljlsh-balhwyh-ally-wr .