
ShellcodeFluctuation PoC, портированный на Nim
Nim-порт оригинального репозитория: https://github.com/mgeeky/ShellcodeFluctuation Все комментарии были скопированы как есть из оригинального репозитория, так как они действительно помогли мне понять технику. Для получения дополнительной информации о самой технике я настоятельно рекомендую ознакомиться с README оригинального репозитория!
Установка зависимостей:
nimble install winim ptr_math
Я полностью осознаю, что эта техника шифрования памяти не является лучшей с точки зрения OpSec. Она шифрует только те области, которые были для неё заданы. Например, для C2-импланта все адреса памяти недавно исполняемых модулей не будут зашифрованы во время Sleep. Для обнаружений, основанных на куче (например, для конфигурации Cobalt Strike), вам всё равно потребуется добавить сюда шифрование кучи.
Но тем не менее, технику шифрования памяти можно совершенно спокойно использовать для обхода автоматических детектов сканеров памяти во время Sleep для основного C2-импланта. Я успешно протестировал PoC с Covenant и кастомизированным бесстадийным пейлоадом как этот.
Ключ шифрования/дешифрования, адрес шеллкода и другие значения, такие как защита (RW), должны быть заданы вручную в этом порте. В оригинальном репозитории адрес вызова шеллкода (Shellcode Caller-Adress) получался автоматически.
Файл Example.nim содержит всё, что нужно для начала работы. Конечно, при использовании C2-шеллкода вам не нужно вызывать Sleep самостоятельно (это нужно только для запуска всего в рамках PoC), это должен делать ваш C2. На данный момент это совместимо только с C2-фреймворками, которые используют функцию Win32 Sleep, но если вы модифицируете хук для другой функции, это будет работать точно так же.
import winim
import Fluctuation
echo "Trying to hook Sleep"
if (hookSleep()):
echo "Hooked Sleep successfully!"
type
PocArray = array[12, byte]
let names: PocArray = [byte 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA]
g_fluctuationData.shellcodeAddr = unsafeAddr names[0]
echo "Shellcode address:"
echo repr(g_fluctuationData.shellcodeAddr)
g_fluctuationData.shellcodeSize = size_t(len(names))
echo "Shellcode Size:"
echo repr(g_fluctuationData.shellcodeSize)
when defined(amd64):
g_fluctuationData.encodeKey = 0xDEADB33f
when defined(i386):
g_fluctuationData.encodeKey = 0xDEAD
g_fluctuationData.currentlyEncrypted = false
g_fluctuationData.protect = PAGE_READWRITE
g_fluctuate = FluctuateToRW
echo "Calling Sleep"
Sleep(2500)
echo "Everything went fine and as expected"
else:
echo "Failed to hook Sleep"
quit(1)
Протестировать PoC шифрования можно, например, так:
nim c --debuginfo --linedir:on Example.nim
Запустите с помощью отладчика:
gdb Example.exe
Установите точки останова до и после Sleep:
# Before encryption
break Example.nim:31
# After encryption
break Fluctuation.nim:98
# Original value restored
break Example.nim:33
Затем проверьте значение адреса шеллкода для каждой точки останова следующим образом:

Флуктуация в NA пока не работает: в моём тесте векторный обработчик исключений (Vectored Exception Handler) так и не сработал, и приложение упало. В будущем надо будет провести дополнительные тесты/отладку. Не стесняйтесь проверить сами! :-)