Ce document explique comment configurer le plugin Rubrik v1.0.0 avec le module Threat Exchange de la plateforme Cloud Exchange. Ce plugin permet de partager les IoCs de menaces de type MD5 et SHA256 vers la page Threat Hunt de Rubrik, et peut effectuer une action Start Threat Hunt.
Conditions préalables
Pour compléter la configuration du plugin, vous aurez besoin de :
- Un locataire Netskope (ou plusieurs, par exemple des instances de production et de développement/test).
- A Netskope Cloud Exchange tenant with the Tenant plugin and Threat Exchange plugin already configured.
- Connectivité à votre instance Rubrik Security Cloud (par exemple : <customername>.my.rubrik.com).
Support des plugins Rubrik
Le plugin permet de pousser SHA256 et MD5 vers Rubrik. Le plugin permet également d'exécuter l'action Start Threat Hunt sur les IoC partagés.
| Types d'indicateurs prédéfinis | Non pris en charge |
| Types d'indicateurs partagés | SHA256, MD5 |
Détails de l'API
Liste des API utilisées
| Cas d'utilisation | Méthode | Endpoint | Champ d'application de l'API |
|---|---|---|---|
| Obtenir un jeton d'authentification | PUBLIER | /api/client_token | Aucun |
| Obtenir les objectFids de la plateforme Rubrik | PUBLIER | /api/graphql | Chasse aux menaces (Lire) |
| Obtenez les clusters présents sur Rubrik | PUBLIER | /api/graphql | Chasse aux menaces
(Lire) |
| Lancez la chasse aux menaces sur Rubrik | PUBLIER | /api/graphql | Chasse aux menaces (Lire) |
Obtenir un jeton d'authentification
API Endpoint: /api/client_token
Method: PUBLIER
Headers
| Clé | Value |
|---|---|
| User-Agent | netskope-ce-5.0.1-cte-rubrik-v1.0.0 |
Payload
| Paramètres | Value |
|---|---|
| client_id | <Client ID> |
| client_secret | <Client Secret> |
Sample API Response
{
"access_token": "",
"expires_in": 43200,
"Client_id" : “”
}
API pour démarrer l'action de chasse à la menace
Obtenir des ObjectFids de Rubrik
API Endpoint: /api/graphql
Method: POST
Headers
| Clé | Value |
| User-Agent | netskope-ce-5.0.1-cte-rubrik-v1.0.0 |
| Authorization | Jeton porteur <Bearer Token> |
| Content-Type | application/json |
Payload
| Requête GraphQL | Variables |
|---|---|
query SnappableQuery($first: Int, $after: String, $typeFilter: [HierarchyObjectTypeEnum!], $filter: [Filter!], $sortBy: HierarchySortByField, $sortOrder: SortOrder) {
inventoryRoot {
descendantConnection(first: $first, after: $after, typeFilter: $typeFilter, filter: $filter, sortBy: $sortBy, sortOrder: $sortOrder) {
edges {
cursor
node {
id
... on WindowsFileset {
isPassThrough
__typename
}
... on ShareFileset {
isPassThrough
__typename
}
... on LinuxFileset {
isPassThrough
__typename
}
... on O365Onedrive {
userPrincipalName
__typename
}
...EffectiveSlaColumnFragment
...HierarchyObjectClusterColumnFragment
...HierarchyObjectLocationColumnFragment
...HierarchyObjectNameColumnFragment
...HierarchyObjectTypeFragment
... on AzureNativeVirtualMachine {
region
isAdeEnabled
resourceGroup {
subscription {
name
__typename
}
__typename
}
effectiveSlaDomain {
...ArchivalSpecFragment
__typename
}
__typename
}
... on AzureNativeManagedDisk {
region
isAdeEnabled
resourceGroup {
subscription {
name
__typename
}
__typename
}
effectiveSlaDomain {
...ArchivalSpecFragment
__typename
}
__typename
}
... on CloudDirectNasExport {
exportPath
__typename
}
__typename
}
__typename
}
pageInfo {
endCursor
hasNextPage
hasPreviousPage
__typename
}
__typename
}
__typename
}
}
fragment EffectiveSlaColumnFragment on HierarchyObject {
id
effectiveSlaDomain {
...EffectiveSlaDomainFragment
... on GlobalSlaReply {
description
__typename
}
__typename
}
... on CdmHierarchyObject {
pendingSla {
...SLADomainFragment
__typename
}
__typename
}
__typename
}
fragment EffectiveSlaDomainFragment on SlaDomain {
id
name
... on GlobalSlaReply {
isRetentionLockedSla
retentionLockMode
__typename
}
... on ClusterSlaDomain {
fid
cluster {
id
name
__typename
}
isRetentionLockedSla
retentionLockMode
__typename
}
__typename
}
fragment SLADomainFragment on SlaDomain {
id
name
... on ClusterSlaDomain {
fid
cluster {
id
name
__typename
}
__typename
}
__typename
}
fragment HierarchyObjectClusterColumnFragment on HierarchyObject {
...CdmClusterLabelFragment
... on CloudDirectHierarchyObject {
cluster {
id
name
__typename
}
__typename
}
__typename
}
fragment CdmClusterLabelFragment on CdmHierarchyObject {
cluster {
id
name
version
__typename
}
primaryClusterLocation {
id
__typename
}
__typename
}
fragment HierarchyObjectLocationColumnFragment on HierarchyObject {
logicalPath {
name
objectType
__typename
}
physicalPath {
name
objectType
__typename
}
__typename
}
fragment HierarchyObjectNameColumnFragment on HierarchyObject {
name
__typename
}
fragment HierarchyObjectTypeFragment on HierarchyObject {
objectType
__typename
}
fragment ArchivalSpecFragment on GlobalSlaReply {
archivalSpec {
storageSetting {
targetType
__typename
}
__typename
}
archivalSpecs {
storageSetting {
targetType
__typename
}
__typename
}
__typename
}
|
{
"first": 1,
"filter": [
{
"texts": [
"false"
],
"field": "IS_GHOST"
},
{
"texts": [
“”
],
"field": "CLUSTER_ID"
}
],
"sortBy": "NAME",
"sortOrder": "ASC",
"typeFilter": [
"LinuxFileset",
"ShareFileset",
"VmwareVirtualMachine",
"WindowsFileset",
"HypervVirtualMachine",
"NutanixVirtualMachine",
"NAS_FILESET"
],
"after":"Y3Vyc29yOmludDow"
}
|
Sample API Response
{
"data": {
"inventoryRoot": {
"descendantConnection": {
"edges": [
{
"cursor": "Y3Vyc29yOmludDox",
"node": {
"id": "",
"effectiveSlaDomain": {
"id": "",
"name": "MGMT-12H-30D-1Y-AWS-USW1",
"isRetentionLockedSla": false,
"retentionLockMode": "NO_MODE",
"__typename": "GlobalSlaReply",
"description": "Upgraded from Cluster_A"
},
"pendingSla": null,
"__typename": "NasFileset",
"cluster": {
"id": "",
"name": "Cluster_A",
"version": "8.1.3-p11-25483",
"__typename": "Cluster"
},
"primaryClusterLocation": {
"id": "",
"__typename": "DataLocation"
},
"logicalPath": [
{
"name": "/volume1/ISO: **",
"objectType": "FilesetTemplate",
"__typename": "PathNode"
},
{
"name": "/volume1/ISO",
"objectType": "NasShare",
"__typename": "PathNode"
},
{
"name": "domain.com",
"objectType": "NasSystem",
"__typename": "PathNode"
}
],
"physicalPath": [
{
"name": "/volume1/ISO: **",
"objectType": "FilesetTemplate",
"__typename": "PathNode"
},
{
"name": "/volume1/ISO",
"objectType": "NasShare",
"__typename": "PathNode"
},
{
"name": "domain.com",
"objectType": "NasSystem",
"__typename": "PathNode"
}
],
"name": "/volume1/ISO: **",
"objectType": "NAS_FILESET"
},
"__typename": "HierarchyObjectEdge"
}
],
"pageInfo": {
"endCursor": "Y3Vyc29yOmludDox",
"hasNextPage": true,
"hasPreviousPage": true,
"__typename": "PageInfo"
},
"__typename": "HierarchyObjectConnection"
},
"__typename": "InventoryRoot"
}
}
}
Présentez vos clusters sur Rubrik
API Endpoint: /api/graphql
Method: POST
Headers
| Clé | Value |
|---|---|
| User-Agent | netskope-ce-5.0.1-cte-rubrik-v1.0.0 |
| Authorization | Jeton porteur <Bearer Token> |
| Content-Type | application/json |
Payload
| Requête GraphQL | Variables |
|---|---|
query ClusterPickerQuery($first: Int, $after: String, $filter: ClusterFilterInput, $sortBy: ClusterSortByEnum, $sortOrder: SortOrder) {
clusterConnection(filter: $filter, sortBy: $sortBy, sortOrder: $sortOrder, first: $first, after: $after) {
edges {
cursor
node {
id
status
...ClusterIconNameFragment
...ClusterVersionColumnFragment
...ClusterTypeColumnFragment
...ClusterCapacityColumnFragment
...ClusterProtectedCountColumnFragment
...ClusterGeoLocationColumnFragment
...ClusterNameColumnFragment
__typename
}
__typename
}
pageInfo {
startCursor
endCursor
hasNextPage
hasPreviousPage
__typename
}
__typename
}
}
fragment ClusterIconNameFragment on Cluster {
id
name
status
pauseStatus
state {
clusterRemovalState
__typename
}
defaultAddress
passesConnectivityCheck
connectivityLastUpdated
...ClusterNodeConnectionFragment
globalManagerConnectivityStatus {
urls {
url
isReachable
__typename
}
__typename
}
systemStatus
ccprovisionInfo {
jobStatus
jobType
progress
vendor
__typename
}
__typename
}
fragment ClusterNodeConnectionFragment on Cluster {
clusterNodeConnection {
nodes {
id
status
ipAddress
__typename
}
__typename
}
__typename
}
fragment ClusterVersionColumnFragment on Cluster {
version
eosDate
eosStatus
__typename
}
fragment ClusterTypeColumnFragment on Cluster {
name
productType
type
clusterNodeConnection {
nodes {
id
__typename
}
__typename
}
__typename
}
fragment ClusterCapacityColumnFragment on Cluster {
metric {
usedCapacity
availableCapacity
totalCapacity
__typename
}
__typename
}
fragment ClusterProtectedCountColumnFragment on Cluster {
productType
noSqlWorkloadCount
...ClusterProtectedSnappablesFragment
__typename
}
fragment ClusterProtectedSnappablesFragment on Cluster {
protectedSnappables: snappableConnection(filter: {protectionStatus: Protected}) {
count
__typename
}
__typename
}
fragment ClusterGeoLocationColumnFragment on Cluster {
geoLocation {
address
__typename
}
__typename
}
fragment ClusterNameColumnFragment on Cluster {
name
__typename
}
|
{
"sortBy": "ClusterName",
"sortOrder": "ASC",
"filter": {
"type": [],
"name": [
""
]
},
"first": 1
}
|
Sample API Response
{
"data": {
"clusterConnection": {
"edges": [
{
"cursor": "Y3Vyc29yOmludDow",
"node": {
"id": "40fdb2a5-3591-40ee-a37a-50bce5240d62",
"status": "Connected",
"name": "Cluster_A",
"pauseStatus": "NOT_PAUSED",
"state": {
"clusterRemovalState": "REGISTERED",
"__typename": "clusterState"
},
"defaultAddress": "cluster-a.domain.com",
"passesConnectivityCheck": true,
"connectivityLastUpdated": "2024-08-05T10:16:10.000Z",
"clusterNodeConnection": {
"nodes": [
{
"id": "RVMHM223S002373",
"status": "OK",
"ipAddress": "10.8.107.107",
"__typename": "ClusterNode"
},
{
"id": "RVMHM223S002379",
"status": "OK",
"ipAddress": "10.8.107.106",
"__typename": "ClusterNode"
},
{
"id": "RVMHM223S002714",
"status": "OK",
"ipAddress": "10.8.107.104",
"__typename": "ClusterNode"
},
{
"id": "RVMHM223S002718",
"status": "OK",
"ipAddress": "10.8.107.105",
"__typename": "ClusterNode"
}
],
"__typename": "ClusterNodeConnection"
},
"__typename": "Cluster",
"globalManagerConnectivityStatus": {
"urls": [
{
"url": "https://mycustomername.my.rubrik.com",
"isReachable": true,
"__typename": "GlobalManagerUrl"
}
],
"__typename": "GlobalManagerConnectivity"
},
"systemStatus": "OK",
"ccprovisionInfo": {
"jobStatus": "INITIALIZING",
"jobType": "ADD_NODE",
"progress": 0,
"vendor": "VENDOR_UNKNOWN",
"__typename": "CcprovisionInfo"
},
"version": "8.1.3-p11-25483",
"eosDate": "2024-07-25",
"eosStatus": "EOS_STATUS_UNSUPPORTED",
"productType": "CDM",
"type": "OnPrem",
"metric": {
"usedCapacity": 7113709735936,
"availableCapacity": 54306599845888,
"totalCapacity": 61420309581824,
"__typename": "ClusterMetric"
},
"noSqlWorkloadCount": 0,
"protectedSnappables": {
"count": 148,
"__typename": "SnappableConnection"
},
"geoLocation": {
"address": "Santa Clara, CA, USA",
"__typename": "GeoLocation"
}
},
"__typename": "ClusterEdge"
}
],
"pageInfo": {
"startCursor": "Y3Vyc29yOmludDow",
"endCursor": "Y3Vyc29yOmludDow",
"hasNextPage": true,
"hasPreviousPage": false,
"__typename": "PageInfo"
},
"__typename": "ClusterConnection"
}
}
}
Lancez la chasse aux menaces sur Rubrik
API Endpoint: /api/graphql
Method: POST
Headers
| Clé | Value |
|---|---|
| User-Agent | netskope-ce-5.0.1-cte-rubrik-v1.0.0 |
| Authorization | Jeton porteur <Bearer Token> |
| Content-Type | application/json |
Payload
| Requête GraphQL | Variables |
|---|---|
mutation StartThreatHuntMutation($input: StartThreatHuntInput!)
{
startThreatHunt(input: $input)
{
huntId isSyncSuccessful __typename
}
}
|
{
"input": {
"clusterUuid": "40fdb2a5-3591-40ee-a37a-50bce5240d62",
"indicatorsOfCompromise": [
{
"iocKind": "IOC_HASH",
"iocValue": "sha256:a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e"
},
{
"iocKind": "IOC_HASH",
"iocValue": "sha256:a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146f"
}
],
"objectFids": [
“”
],
"fileScanCriteria": {
"fileSizeLimits": {
"maximumSizeInBytes": 1024,
"minimumSizeInBytes": 5
},
"pathFilter": {
"includes": [
"*.acm",
"*.ax",
"*.cpl",
"*.dll",
"*.drv",
"*.efi",
"*.exe",
"*.mui",
"*.ocx",
"*.scr",
"*.sys",
"*.tsp"
],
"excludes": [],
"exceptions": []
}
},
"maxMatchesPerSnapshot": 1,
"name": "Sample threat hunt",
"shouldTrustFilesystemTimeInfo": true,
"snapshotScanLimit": {
"maxSnapshotsPerObject": 1
}
}
}
|
Sample API Response
{
"data": {
"startThreatHunt": {
"huntId": "892caaf9-90d3-5c87-8297-5862e972a032",
"isSyncSuccessful": true,
"__typename": "StartThreatHuntReply"
}
}
}
Matrice de performance
Voici la lecture des performances réalisée en partageant 100K indicateurs à Rubrik sur une Large CE Stack avec ces spécifications.
| Détails de la pile | Taille : Grande RAM : 32 GB CPU : 16 cœurs |
| Indicateurs extraits de Rubrik | NA |
| Indicateurs partagés avec Rubrik | ~26K per minute |
Agent utilisateur
netskope-ce-5.0.1-cte-rubrik-v1.0-0
Workflow
- Obtenez votre numéro de client et votre secret de client.
- Configurez le plugin Rubrik.
- Configurez une règle de gestion Threat Exchange.
- Configurez le partage de Threat Exchange.
- Validez le plugin Rubrik.
Cliquez sur "play" pour regarder une vidéo :
Obtenez vos paramètres de configuration
Suivez les étapes de ce document pour générer l'identifiant et le secret du client :
https://docs.rubrik.com/en-us/saas/saas/adding_a_service_account.html?hl=adding%2Cservice%2Caccount
Configurer le plugin Rubrik
- Connectez-vous à Cloud Exchange et accédez à Settings > Plugins.
- Recherchez et sélectionnez la boîte de plugin CTE Rubrik.

- Saisissez les informations de base :
- Nom de la configuration : Nom de la configuration du plugin
- Sync Interval : Intervalle de récupération des données de cette source de plugin.
- Critères de vieillissement : Les indicateurs expirent après une période spécifique.
- Override Reputation (Ignorer la réputation) : Définissez la valeur pour remplacer la réputation des indicateurs reçus à partir de cette configuration. Laissez vide pour conserver la valeur par défaut.
- Activer la validation SSL : Activez la validation du certificat SSL.
- Utiliser le proxy du système : Utilisez le proxy système configuré dans les paramètres.

- Cliquez sur Next.
- Entrez les paramètres de configuration :
- Base URL: Base URL of Rubrik instance, like https://rubrik01.rubrikdemo.com.
- Client ID : ID du client généré par la plateforme Rubrik. Pour obtenir l'identifiant du client, il faut générer un JSON de compte de service. Dans Rubrik, allez sur Apps > Settings > Users and Access pour le générer.
- Secret du client : Secret du client généré par la plateforme Rubrik. Pour obtenir le secret du client, il faut générer un JSON de compte de service. Dans Rubrik, allez à Apps > Settings > Users et à Access pour le générer.
- Cliquez sur Save.
Configurer une règle de gestion pour le plugin Rubrik
Une règle de gestion est utilisée pour filtrer les indicateurs qui doivent être partagés. Pour partager des IoC avec Rubrik, créez une règle de gestion en suivant ces étapes :
- Allez dans Threat Exchange > Business Rules et cliquez sur Create New Rule.

- Ajoutez le nom de la règle et sélectionnez les champs selon lesquels vous souhaitez filtrer les indicateurs de compromission (IoC). Une fois terminé, cliquez sur Save.
Ajouter un partage pour le plugin Rubrik
Pour configurer le partage, procédez comme suit :
- Allez dans Threat Exchange > Sharing et cliquez sur Add Sharing Configuration.
- Select une configuration Source (Source à partir de laquelle vous souhaitez partager des données vers Rubrik), une règle de gestion et une destination.
- Select la valeur de la cible, et entrez ces valeurs :
- Nom de la chasse aux menaces : Saisissez le nom de la chasse aux menaces. Une chasse à la menace portant ce nom sera lancée sur Rubrik.
- Nom du cluster : Cluster Rubrik pour lequel vous souhaitez lancer la chasse aux menaces.
- Taille maximale du fichier à numériser (en Ko) : Taille maximale du fichier à numériser (en Ko). La valeur par défaut est de 1024 KB. La taille maximale supportée est de 15000000 KB et la taille minimale supportée est de 1 KB.
- Taille minimale du fichier à numériser (en Ko) : Taille minimale du fichier à numériser (en Ko). La valeur par défaut est de 5 KB. La taille maximale supportée est de 15000000 KB et la taille minimale supportée est de 1 KB.
- Max IOC Matches (Per Snapshot) : Nombre maximum de correspondances IOC par instantané. La valeur par défaut est 1. La valeur maximale supportée est de 1000 et la valeur minimale supportée est de 1.
- Inclure les fichiers : Fichiers à inclure dans la chasse aux menaces.
- Fichiers d'exclusion : Fichiers à exclure de Threat Hunt.
- Ne pas exclure les fichiers : Fichier qui ne doit pas être exclu de la chasse aux menaces.


- Cliquez Save.

Valider le plugin Rubrik
La traction n'est pas prise en charge.
Valider le push
Les IoC partagés vers Rubrik peuvent être vérifiés à partir des journaux disponibles sur la page Logging de Cloud Exchange.
Les IOC partagés sur Rubrik peuvent être vérifiés à Apps > Data Threat Analytics > Threat Hunt. Cliquez sur la Chasse à la Menace que vous avez créée.
Cliquez sur l’onglet Paramètres pour voir les IoC partagés.
Dépannage
Impossible de configurer le plugin Rubrik
Si vous n'arrivez pas à configurer le Rubrik Plugin, cela peut être dû à l'une des raisons mentionnées ci-dessous :
- L'autorisation n'est pas donnée pour les titres de compétences.
- Vous avez fourni des informations d'identification incorrectes.
Pour résoudre les problèmes mentionnés ci-dessus, suivez les étapes suivantes :
- Vérifiez les journaux du plugin dans Cloud Exchange.
- Assurez-vous que les informations d'identification fournies disposent des autorisations nécessaires.
- Assurez-vous que les informations d'identification correctes sont fournies lors de la configuration du plugin.
Impossible d'envoyer des données à Rubrik
Si vous n'arrivez pas à partager les IoCs avec le plugin Rubrik, cela peut être dû à l'une des raisons suivantes :
- Valeur invalide de MD5 et SHA256 fournie.
- Si les données partagées ont un type autre que MD5 ou SHA256.
Pour résoudre les problèmes mentionnés ci-dessus, suivez les étapes suivantes :
- Vérifiez les journaux du plugin dans Cloud Exchange.
- Assurez-vous que le MD5 et le SHA256 qui doivent être partagés sont valides.
- Assurez-vous que les IoC sont de type MD5 ou SHA256.

