
نص PowerShell للمساعدة في العثور على الإعدادات الضعيفة في نهج المجموعة لـ Active Directory. (مهمل، استخدم Grouper2 بدلاً من ذلك!)
لا تستخدم GROUPER بعد الآن. استخدم GROUPER2! https://github.com/l0ss/Grouper2
برنامج PowerShell للمساعدة في العثور على الإعدادات الضعيفة في نهج المجموعة (Group Policy) في Active Directory.

Grouper هي وحدة PowerShell مصممة لمختبري الاختراق وفرق الاختراق الأحمر (على الرغم من أنها قد تكون مفيدة أيضًا لمسؤولي الأنظمة) تقوم بغربلة مخرجات XML (الكثير من الضوضاء عادةً) من أمر Get-GPOReport cmdlet (جزء من وحدة نهج المجموعة من Microsoft) وتحديد جميع الإعدادات المحددة في كائنات نهج المجموعة (GPOs) التي قد تكون مفيدة لشخص يحاول فعل شيء ممتع/شرير.
أمثلة على أنواع الأشياء التي تجدها في GPOs:
نعم إنها خشنة بعض الشيء، لكنها توفر علي قدرًا هائلاً من الوقت في قراءة تقارير GPO HTML الرهيبة بحجم 150 ميجابايت، وإذا كانت تعمل معي فقد تعمل معك.
ملاحظة: على الرغم من أن بعض أسماء الوظائف قد تتضمن كلمة "تدقيق" (audit)، فإن Groper ليس المقصود منه بأي حال أن يكون تدقيقًا شاملاً للتكوينات الأفضل الممارسات إلخ. إذا كنت تريد ذلك، يجب عليك استخدام Microsoft SCT و LGPO.exe أو شيء من هذا القبيل.
قم بإنشاء تقرير GPO على جهاز Windows مثبتة عليه أوامر نهج المجموعة cmdlets. هذه الأوامر مثبتة افتراضيًا على وحدات التحكم بالمجال (Domain Controllers)، ويمكن تثبيتها على عملاء Windows باستخدام RSAT، أو تمكينها من خلال معالج "إضافة ميزة" على خوادم Windows.
Get-GPOReport -All -ReportType xml -Path C:\temp\gporeport.xml
قم باستيراد وحدة Grouper.
Import-Module .\grouper.psm1
قم بتشغيل Grouper.
Invoke-AuditGPOReport -Path C:\temp\gporeport.xml
هناك أيضًا بعض المعاملات التي يمكنك العبث بها لتغيير إعدادات النهج التي سيظهرها Grouper:
-showDisabled
افتراضيًا، سيعرض Grouper فقط GPOs الممكّنة حاليًا والمرتبطة بوحدة تنظيمية (OU) في AD. هذا يبدل هذا السلوك.
-Online
افتراضيًا، يعمل Grouper فقط مع مخرجات XML الفعلية من Get-GPOReport، ولا يقوم بأي اتصالات شبكة على الإطلاق، مما يجعله "آمنًا من حيث العمليات (opsec safe)"، رغم أنني أكره هذا المصطلح.
إذا قمت بتشغيله مع -Online، سيقوم Grouper بتفعيل الفحوصات التي تتطلب التحدث إلى (على الأقل) مجال AD الذي تم إنشاء التقرير منه، ولكنها ستتضمن أيضًا التحدث إلى خوادم الملفات مثلًا. سيسمح هذا لـ Grouper بالقيام بأشياء مفيدة مثل الإبلاغ عن ACLs على الملفات المستهدفة بواسطة GPOs، والتحقق مما إذا كان المستخدم الحالي يستطيع الكتابة إلى الملف المعني.
-Level
Grouper لديه 3 مستويات من التصفية يمكنك تطبيقها على مخرجاته.
الاستخدام بسيط. -Level 3، -Level 2، إلخ.
يعمل Get-GPOReport بشكل جيد على الأجهزة غير المرتبطة بالمجال عبر runas /netonly. ستحتاج إلى بعض بيانات الاعتماد منخفضة الصلاحية، لكن هذا متوقع.
افعل مثل هذا:
runas /netonly /user:domain\user powershell.exe
على جهاز غير مرتبط بالمجال يمكنه الاتصال بوحدة تحكم بالمجال.
ثم في جلسة PowerShell الناتجة، افعل مثل هذا:
Get-GpoReport -Domain example.com -All -ReportType xml -Path C:\temp\gporeport.xml
سهل.
كل ما يحتاجه Grouper للعمل هو PowerShell 2.0 وملف xml الناتج من Get-GPOReport. يمكنك تشغيله على VM بدون كرت شبكة إذا كنت قلقًا وسيظل يعمل بشكل جيد.
ومع ذلك، إنه كود بسيط إلى حد ما لذا لا ينبغي أن يكون من الصعب رؤية أنه لا يفعل أي شيء مريب عن بعد.
إجابة قصيرة: نعم.
إجابة طويلة: نعم، فعل أحد هذه الأشياء سيكون أفضل، لكن هناك شيئين منعوني من فعلها حتى الآن.
من الناحية المثالية، أود تحليل ملفات النهج مباشرة من SYSVOL، لكنها مخزنة بمجموعة من تنسيقات الملفات المختلفة، بعضها مملوك، وهي حقًا مزعجة في القراءة، وليس لدي الوقت ولا الرغبة في كتابة مجموعة من المحللات (parsers) لها من الصفر عندما توفر Microsoft بالفعل cmdlets تقوم بالمهمة بشكل جيد.
في المستقبل غير البعيد، أود دمج Get-GPOReport من Microsoft داخل Grouper، حتى لا تحتاج إلى RSAT على الإطلاق، لكني بحاجة لمعرفة ما إذا كان ذلك سيشكل انتهاكًا لحقوق النشر. أحتاج أيضًا لمعرفة كيفية فعل ذلك الشيء الذي قلته للتو.
Grouper ليس ماسحًا للثغرات. Grouper يقوم فقط بتصفية الكم الهائل من الحشو والضوضاء في تقارير نهج المجموعة لإظهار فقط إعدادات النهج التي يمكن تكوينها بطرق قابلة للاستغلال.
بقدر الإمكان، أعمل على كل فئة من فئات الفحوصات لإضافة تصفية إضافية لإزالة التكوينات غير الضعيفة بشكل واضح وتقليل مستويات الضوضاء أكثر، لكن نهج المجموعة مرن للغاية ومن الصعب توقع كل خطأ محتمل قد يفعله المسؤول.
رائع، لقد وجدت طريقة لتحسين Grouper! قم بالتمرير لأسفل وسترى حيث قدمت دليلًا صغيرًا لإضافة فحوصات جديدة إلى Grouper.
أنا معك يا صديقي. يوجد ملف test_report.xml في المستودع يمكنك تجربته. يحتوي على مجموعة من الإعدادات السيئة حتى ترى كيف يبدو ذلك.
ستحتاج إلى تشغيله مع العلم -showDisabled لأنه مليء بتكوينات سيئة لدرجة أنني لم أرغب حتى في تمكين GPO في بيئة مختبر.
حسنًا.

إجابة قصيرة: PowerView ستقوم بعمل جيد في هذا.
إجابة أطول: سأحاول إضافة هذه الوظيفة في وقت ما، لكن في الوقت الحالي، اصمت واستخدم PowerView.
رائع، سهل الإصلاح.
افتح grouper.ps1، ابحث عن مصفوفة "$polchecks" وقم فقط بتعليق السطر الذي يتم فيه إضافة هذا الفحص إلى المصفوفة.
تم.
بالتأكيد، يبدو جيدًا.
احصل على بعض مخرجات XML لتقرير GPO التي تتضمن نوع النهج/الإعداد الذي تريد أن يتمكن Grouper من العثور عليه. قد يتطلب هذا إنشاء نهج مناسب في بيئة مختبر.
ابحث عن كائن XML <GPO> الذي يطابق النهج المستهدف.
ابحث عن القسم الفرعي من XML الذي يطابق المعلومات التي تريد استخراجها من النهج. إعدادات النهج مقسمة إما إلى نهج المستخدم (User) أو نهج الكمبيوتر (Computer)، لذا سيكون هذا عادةً في أحد:
GPO.Computer.ExtensionData.Extension
or
GPO.User.ExtensionData.Extension
الآن الجزء المزعج - سبب كون هذا الكود فوضويًا هو أن كل قسم من إعدادات النهج منظم بشكل مختلف ويستخدم اصطلاحات تسمية مختلفة جدًا، لذا ستحتاج لمعرفة كيفية تنظيم النهج المستهدف. حظًا سعيدًا؟
إليك هيكل دالة فحص يمكنك استخدامه للبدء. تأكد من أنها إما لا تعود بشيء على الإطلاق أو تعود بقيمة $null إذا لم يتم العثور على شيء مثير للاهتمام.
Function Get-GPOThing {
[cmdletbinding()]
Param (
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()] [System.Xml.XmlElement]$polXML,
[Parameter(Mandatory=$true)][ValidateSet(1,2,3)][int]$level
)
######
# الوصف: يتحقق من الأشياء.
# ضعيف: وصف لما يظهره إذا كان Level -eq 3
# مثير للاهتمام: وصف لما يظهره إذا كان Level -eq 2
# ممل: جميع الأشياء.
######
$settingsThings = ($polXml.Thing.ExtensionData.Extension.Thing | Sort-Object GPOSettingOrder)
if ($settingsThings) {
foreach ($setting in $settingsThings) {
if ($level -eq 1) {
$output = @{}
$output.Add("Name", $setting.Name)
if ($setting.SettingBoolean) {
$output.Add("SettingBoolean", $setting.SettingBoolean)
}
if ($setting.SettingNumber) {
$output.Add("SettingNumber", $setting.SettingNumber)
}
$output.Add("Type", $setting.Type.InnerText)
Write-Output $output
""
}
}
}
}
شكر جزيل لكل من:
بالحديث عن الكود السيئ، نعم أعرف أن هذه فوضى. حاولت جعلها معيارية قدر الإمكان حتى يتمكن الآخرون من إضافة فحوصات إضافية دون عناء كبير، لكنها لا تزال بحاجة إلى الكثير من الحب. إذا رأيت خطأً ارتكبته ويحتاج بشكل عاجل إلى الإصلاح، فيرجى إخباري.
استخدم Ctrl-f للوصول إلى "$polchecks" وأضفه إلى مصفوفة الفحوصات مع البقية.
اختبره.
إذا كان يعمل، قدم طلب سحب (pull request)!
إذا علقت، تواصل معي. سأحاول المساعدة إذا تمكنت من توفير بضع دقائق.