
OneDrive als verdeckter C2-Transport für Cobalt Strike
Ein benutzerdefinierter C2-Kanal (User-Defined C2) für Cobalt Strike, der OneDrive als Transportschicht verwendet.

Files.ReadWrite.All.Gehe im Azure-Portal zu App-Registrierungen und erstelle eine neue App:
Notiere die Mandanten-ID und die Client-ID von der Übersichtsseite.
Unter API-Berechtigungen:
Files.ReadWrite.All.Erstelle unter Zertifikate & Geheimnisse ein neues Geheimnis und kopiere dessen Wert.
Erstelle im OneDrive des Benutzers zwei Ordner, einen für den Posteingang und einen für den
Postausgang (z. B. c2inbox und c2outbox).
Öffne den Graph Explorer, melde dich als dieser Benutzer an und führe Folgendes aus:
GET https://graph.microsoft.com/v1.0/me/drive/root/children
Nimm die id jedes Ordners und die driveId aus einem beliebigen Eintrag der JSON-Antwort.
cp server/config.json.example server/config.json
Fülle server/config.json aus:
| Feld | Wert |
|---|---|
tenant_id | Microsoft Entra ID-Mandanten-ID |
client_id | Client-ID der Anwendung |
client_secret | Wert des Client-Geheimnisses |
drive_id | OneDrive-Laufwerk-ID |
inbox_folder_id | ID des Posteingangsordners |
outbox_folder_id | ID des Postausgangsordners |
Dann baue den Client:
make
Starte das Relay (verwende screen oder tmux, damit es weiterläuft, wenn dein Terminal die Verbindung trennt):
python3 server/relay.py --config server/config.json --ts-addr <teamserver-ip> --ts-port <udc2-port>
Erstelle in Cobalt Strike einen UDC2-Listener auf demselben Port und lade client/bof.o.
| Flag | Beschreibung |
|---|---|
--config | Pfad zu config.json (erforderlich) |
--ts-addr | Teamserver-IP |
--ts-port | Port des UDC2-Listeners |
--poll | Abfrageintervall in Sekunden (Standard 2.0) |
--state | Pfad zur Statusdatei (Standard: <config>.state.json) |
--debug | Debug-Logging aktivieren |
--clean | Statusdatei und Spool-Verzeichnis löschen, dann beenden |
Das Relay erstellt ein paar Dateien neben deiner Konfiguration, um den Überblick zwischen Neustarts zu behalten:
config.json.state.json) – verfolgt, welche Posteingangsdateien verarbeitet wurden, ausstehende Uploads und Beacon-Sitzungsinformationen. Lege mit --state einen benutzerdefinierten Pfad fest.config.json.state.json.spool/) – enthält Antwortdaten, die noch nicht zu OneDrive hochgeladen wurden. Wenn das Relay mitten im Upload abstürzt, bewahrt der Spool die Daten auf, damit sie beim nächsten Start erneut versucht werden können.config.json.state.json.lock) – verhindert, dass zwei Relay-Instanzen gegen denselben Status laufen. Wenn du Another relay holds the lock siehst und kein anderes Relay läuft, ist die Sperre von einem Absturz veraltet.Wenn der lokale Status des Relays beschädigt ist oder eine veraltete Sperre den Start blockiert, verwende --clean, um die Statusdatei und das Spool-Verzeichnis zu löschen, damit das Relay neu startet:
python3 server/relay.py --config server/config.json --clean
Die Sperrdatei bleibt erhalten. Das Relay bereinigt nicht, während eine andere Instanz läuft. Beim nächsten normalen Start initialisiert es sich neu und überspringt alle Posteingangsdateien, die älter als 30 Minuten sind.
Du kannst auch manuell zurücksetzen, indem du die Statusdatei und das Spool-Verzeichnis selbst löschst. Wenn die Sperrdatei veraltet ist (kein Relay läuft), lösche sie ebenfalls.
