Remarque :
- Ce tutoriel nécessite un accès à Oracle Cloud. Pour vous inscrire à un compte gratuit, reportez-vous à Introduction à Oracle Cloud Infrastructure Free Tier.
- Il utilise des exemples de valeur pour les informations d'identification Oracle Cloud Infrastructure, la location et les compartiments. A la fin de votre atelier, remplacez ces valeurs par celles propres à votre environnement cloud.
Assimilation des connexions Oracle Cloud Infrastructure à Microsoft Azure Sentinel à l'aide des fonctions OCI
Introduction
Oracle Cloud Infrastructure (OCI) Functions est une plate-forme Functions-as-a-Service entièrement gérée, colocative, hautement évolutive et à la demande. Ce service s'appuie sur Oracle Cloud Infrastructure pour les entreprises et s'appuie sur le moteur open source du projet Fn.
Service Connector Hub est une plate-forme cloud de bus de messages qui offre une interface unique pour la description, l'exécution et la surveillance des interactions lors du déplacement de données entre les services Oracle Cloud Infrastructure. Utilisez le service Service Connector Hub pour transférer des données entre services dans Oracle Cloud Infrastructure.
Grâce aux services Service Connector and Functions, vous pouvez connecter la génération de journaux de votre environnement cloud OCI avec l'envoi automatique et évolutif de tous les enregistrements de sécurité des informations de votre environnement à votre instance de Microsoft Azure Sentinel, SIEM (Security Information and Event Management).
Objectif
Ingérez OCI se connecte à Microsoft Azure Sentinel à l'aide d'OCI Functions.
Prérequis
- Accès à une location Oracle Cloud
- Configuration d'un réseau cloud virtuel dans votre location
- Toutes les configurations de stratégie pour les journaux, la diffusion en continu et les fonctions.
Tâche 1 : démarrer l'instance OCI
-
Créez une instance OCI via la console Web et activez l'un de ses modules d'extension par défaut. Accédez à la page Instances et cliquez sur Créer une instance.

-
Renseignez toutes les informations requises pour la création d'instance.

-
Accédez à la fin de la page et cliquez sur Afficher les options avancées.

-
Certains onglets apparaîtront à l'écran. Cliquez sur Agent Oracle Cloud et sélectionnez les modules d'extension à activer une fois la création de l'instance terminée.

-
Tous les modules d'extension sélectionnés dans cet onglet seront automatiquement activés une fois que l'instance sera prête à être utilisée.

-
Après avoir sélectionné les modules d'extension, cliquez sur Créer à la fin de la page.

Tâche 2 : configuration des paramètres de journalisation OCI
Tâche 2.1 : Configurer les journaux personnalisés d'instance Windows
Après avoir créé l'instance Windows, vous devez configurer votre environnement OCI pour capturer les journaux du visualiseur d'événements via l'agent Oracle installé sur le serveur.
-
Avant de commencer, assurez-vous que le module d'extension "Journaux personnalisés" est actif sur le serveur à partir duquel collecter les journaux. Dans votre console OCI, accédez à Compute, Instances.

-
Sélectionnez l'instance à surveiller.

-
Cliquez sur l'onglet Agent Oracle Cloud et assurez-vous que le module d'extension nommé Surveillance des journaux personnalisés est activé.

- Si le module d'extension n'est pas activé dans votre instance, activez-le. Ensuite, configurons la journalisation OCI de sorte que les événements Windows Event Viewer puissent être capturés par cet agent.
Tâche 2.2 : Configuration du groupe dynamique de serveurs
Pour capturer les journaux du visualiseur d'événements à partir d'un ou de plusieurs serveurs Windows, un groupe dynamique doit être créé. Ce groupe contiendra toutes les instances Windows dont les journaux doivent être capturés.
-
Pour créer le groupe dynamique, cliquez sur le menu principal de votre console OCI et accédez à Identité et sécurité, Identité.

-
Dans le menu Identité, accédez au sous-menu *Domaines.

-
Cliquez sur votre domaine d'identité (dans cet exemple de tutoriel, nous utilisons Par défaut).

-
Maintenant, dans le domaine d'identité, cliquez sur le menu Groupes dynamiques afin de créer le groupe dynamique qui contiendra tous les serveurs Windows à surveiller. Une fois cette opération terminée, cliquez sur Créer un groupe dynamique.

-
Une nouvelle page s'ouvre. Renseignez les informations relatives à la création du groupe dynamique (nom et description) et, dans Règles de correspondance, cliquez sur le lien Générateur de règles pour pouvoir créer votre règle de sélection des instances qui seront regroupées dans ce groupe dynamique.

-
L'exemple de règle que nous allons créer regroupe tous les serveurs existants dans notre compartiment. Pour ce faire, il vous suffit de capturer l'ID de compartiment et de l'insérer dans le champ Valeur, comme illustré dans l'image ci-dessous.

-
Pour plus d'informations sur la création de groupes dynamiques, reportez-vous à la documentation officielle : Création de groupes dynamiques et de stratégies pour accéder à d'autres ressources Oracle Cloud Infrastructure à partir de sessions de bloc-notes.
-
Lorsque la création est terminée, une page contenant les informations du groupe dynamique est disponible.

-
Le groupe dynamique est créé et prêt à être utilisé pour centraliser les journaux de votre environnement OCI.
-
Remarque : vous pouvez utiliser des filtres avancés et créer des groupes dynamiques pour capturer uniquement les instances avec certaines balises. Pour ce faire, nous vous recommandons de lire la documentation officielle OCI à l'adresse suivante : Ecriture de règles de correspondance pour définir des groupes dynamiques.
Tâche 2.3 : création d'un groupe de journalisation
Vous devrez également créer un groupe de journalisation pour pouvoir concentrer tous les journaux envoyés par les agents installés sur les serveurs Windows de votre environnement.
-
Cliquez sur le menu principal de votre console OCI et accédez à Observation & gestion, Groupes de journaux.

-
Lorsque vous accédez à la page de service, cliquez sur Créer un groupe de journaux.

-
Dans la page de création du groupe de journaux, entrez les informations demandées et cliquez sur Créer.

Une fois cette étape terminée, commençons à créer la capture du journal du visualiseur d'événements par l'agent Oracle Cloud installé dans l'instance OCI.
Tâche 2.4 : Configurer OCI Logging
-
Une fois l'instance, le groupe dynamique et le groupe de journaux configurés, accédez à Observation et gestion, puis cliquez sur Journalisation.

-
Sur la page OCI Logging, cliquez sur Configurations d'agent afin de créer la configuration permettant l'envoi des journaux Windows Event Viewer à OCI Logging. Une fois dans la page de configuration de l'agent, cliquez sur Créer une configuration d'agent.

-
Renseignez tous les champs nécessaires sur la page et sélectionnez le groupe dynamique que vous avez créé à l'étape précédente.

-
Lorsque vous remplissez ces éléments initiaux, faites défiler la page vers le bas et renseignez les champs Configuration de l'agent, en indiquant que vous souhaitez capturer le "journal des événements Windows" de chacun des canaux disponibles (Application, Sécurité et Système). Ici, vous devrez répéter le processus de création d'entrées de journal pour chacun des canaux.
-
Une fois la configuration terminée, la page de configuration de l'agent sera disponible et ressemblera à ceci.

Remarque : la configuration d'agent ci-dessus a été créée pour capturer les journaux et les journaux du visualiseur d'événements générés dans le fichier
/var/log/messagessur les serveurs Linux. -
Une fois que la configuration d'agent a le statut Actif, attendez environ 5 minutes jusqu'à ce que la première collecte de journaux puisse être effectuée. Pour visualiser les journaux des instances surveillées en cours de collecte, cliquez sur le menu Explorer le journal comme indiqué dans l'image ci-dessous.

-
Tâche 3 : Notez les détails de Microsoft Azure Sentinel
-
Après avoir configuré l'environnement de journalisation centralisé dans votre région OCI, accédez à votre abonnement Microsoft Azure et collectez les informations suivantes :
- ID d'espace de travail : ID d'espace de travail Log Analytics utilisé par Microsoft Azure Sentinel dans votre abonnement Microsoft Azure.
- Clé partagée : clé d'accès à votre espace de travail Log Analytics.
-
Ces valeurs se trouvent dans le menu Gestion des agents comme indiqué dans l'image ci-dessous de votre abonnement Azure :

-
Notez ces valeurs.
Important : Ce n'est pas la portée de cette documentation qui fournit des conseils sur la création et la configuration de Microsoft Azure Sentinel dans votre abonnement Microsoft Azure. Pour ce faire, accédez à la documentation officielle du produit sur le site Web de Microsoft.
Tâche 4 : création de votre coffre OCI
Maintenant que nous disposons déjà des données Microsoft Azure Log Analytics Workspace appartenant à SIEM Sentinel, créons un coffre OCI pour stocker la valeur secrète copiée dans la tâche précédente. Cette clé secrète doit être stockée dans OCI Vault pour que vous n'ayez pas besoin de l'insérer dans le code OCI Functions que nous allons créer à l'étape suivante.
-
Pour créer votre coffre OCI, accédez au menu principal de votre console OCI et accédez à Identité et sécurité, Coffre.

-
Une fois la page Vault chargée, cliquez sur Créer un coffre, sélectionnez le compartiment souhaité et nommez votre coffre.

-
Après avoir créé le coffre, vous devez créer votre clé de cryptage maître. Cette clé sera utilisée pour crypter toutes les clés secrètes de votre coffre. Pour ce faire, cliquez sur Créer une clé comme indiqué dans l'image ci-dessous.

-
Lorsque vous avez terminé de créer votre clé maître, cliquez sur le menu Clés secrètes et créez la clé secrète Microsoft Azure que vous avez notée à l'étape précédente.

-
Remplissez les champs nécessaires pour créer votre clé secrète dans le coffre avec les données de clé primaire ou secondaire de votre espace de travail Microsoft Azure Sentinel Log Analytics, comme indiqué dans la tâche 3.
-
Les autres éléments (Sentinel Workspace ID et le nom de la table où les journaux seront stockés dans Sentinel) peuvent ou non être insérés dans le coffre-fort. Ici, insérons-les dans le code de notre fonction.
Important : notez l'OCID de la clé secrète que vous créez dans le coffre.
Tâche 5 : création et configuration des fonctions OCI
Après avoir configuré l'environnement de journalisation centralisé dans votre région OCI, le coffre et votre environnement Azure sont prêts. Il est temps de créer la fonction OCI qui enverra les journaux personnalisés et d'audit de votre région OCI à Microsoft Azure Sentinel.
Tâche 5.1 : création de la fonction OCI
-
Accédez au menu principal de votre console OCI et accédez à Services de développeur, Fonctions.

-
Une fois la page Fonctions chargée, cliquez sur Créer une application.

-
Renseignez les champs obligatoires et cliquez sur Créer.

-
Après la création, notez que votre fonction ne sera protégée par aucun groupe de sécurité réseau. Vous devez l'ajouter à un groupe de sécurité réseau.

Points importants :
-
Votre fonction accédant à l'adresse Microsoft Azure publique pour l'envoi de journaux à Microsoft Azure Sentinel, cette fonction doit être créée dans un sous-réseau ayant accès à Internet.
-
Validez également vos listes de sécurité VNET pour vous assurer qu'aucune d'entre elles n'empêche votre fonction OCI d'accéder à Internet.
-
Tâche 5.2 : configuration des fonctions OCI et démarrage
Une fois la fonction OCI créée, vous verrez à l'écran les commandes nécessaires à la configuration de la fonction dans l'environnement. A titre d'exemple, nous allons suivre étape par étape via Cloud Shell, mais il est également possible d'effectuer ces paramètres directement sur votre équipement.
-
Ouvrez Cloud Shell directement dans la console Web de la région OCI à configurer (dans ce tutoriel, la région est Brésil Est).

-
Suivez les étapes indiquées sur la page Fonction et exécutez les commandes demandées dans votre terminal Cloud Shell.

-
Les 3 premières commandes à exécuter ne nécessitent aucune modification. Toutefois, dans la quatrième commande, vous devrez fournir le nom du référentiel dans lequel l'image d'application sera stockée. Dans notre exemple, le nom saisi était repo-ocilog-to-azuresiem.
$ fn update context registry gru.ocir.io/xxxxxxxxxa/repo-ocilog-to-azuresiem
-
Générez un jeton d'authentification dans votre profil Oracle Cloud Infrastructure Identity and Access Management (OCI IAM). Le jeton d'authentification est les informations d'identification d'accès qui vous permettront d'interagir avec le référentiel OCI dans lequel l'image Docker de votre fonction sera stockée. Cliquez sur votre icône utilisateur dans la console Web OCI, puis sur Mon profil.

-
Faites défiler la page utilisateur et cliquez sur Jetons d'authentification.

-
Dans la section Jetons d'authentification, cliquez sur Générer un jeton.

-
Indiquez le nom de votre jeton d'authentification et cliquez sur Générer un jeton.

Important : notez ce jeton et stockez-le en lieu sûr. Ce jeton est votre mot de passe d'accès au registre OCI dans lequel vos images de fonction seront stockées.
-
Revenez à la page Functions en accédant au menu principal de la console Web OCI et en accédant à Services de développeur, Fonctions.

-
Dans la page Functions, accédez à votre fonction créée aux étapes précédentes.

-
Cliquez sur le menu Mise en route et continuez étape par étape après l'étape de création du jeton d'authentification.

-
Exécutez la commande
docker loginet, en tant que mot de passe, utilisez la chaîne que vous venez de copier à partir de la création du jeton d'authentification à la dernière étape exécutée.
-
Maintenant, dans les étapes suivantes, nous allons créer, déployer et appeler la fonction. Pour initialiser la fonction dans Cloud Shell, modifiez la commande suggérée dans l'exemple affiché à l'écran. Cette modification est nécessaire car l'environnement d'exécution que nous allons utiliser est en Python (et non en Java, comme indiqué dans l'exemple hello-world suggéré par la création de la fonction).
$ fn init --runtime python func-ocilog-to-azuresiem
Tâche 5.2.1 : Ecriture du code source de votre fonction OCI
-
Une fois la commande
initexécutée, accédez au répertoire Function créé.$ cd func-ocilog-to-azuresiem/- Notez que dans le répertoire auquel vous venez d'accéder se trouve un fichier Python (
func.py), un fichier YAML (func.yaml) et un fichier de conditions (requirements.txt). Nous allons devoir modifier deux de ces fichiers.
- Notez que dans le répertoire auquel vous venez d'accéder se trouve un fichier Python (
-
Modifiez le fichier
func.py, supprimez tout le contenu et insérez-y le contenu ci-dessous.import io import json import requests import datetime import hashlib import hmac import base64 import logging import oci import base64 import sys from fdk import response # Global variable logger = logging.getLogger() # Get Resource Principal Credentials # OCI Functions get permission to read vault from OCI IAM signer = oci.auth.signers.get_resource_principals_signer() # Retrieve secret from OCI Vault def get_binary_secret(secret_ocid): try: client = oci.secrets.SecretsClient({}, signer=signer) secret_content = client.get_secret_bundle(secret_ocid).data.secret_bundle_content.content.encode('utf-8') secret_content_decoded = base64.b64decode(secret_content).decode('UTF-8') except Exception as ex: logger.critical("ERROR: failed to retrieve the secret content from OCI Vault. ", ex) raise return secret_content_decoded # Build the API signature def build_signature(customer_id, shared_key, date, content_length, method, content_type, resource): x_headers = 'x-ms-date:' + date string_to_hash = method + "\n" + str(content_length) + "\n" + content_type + "\n" + x_headers + "\n" + resource bytes_to_hash = bytes(string_to_hash, encoding= "utf-8" ) decoded_key = base64.b64decode(shared_key) encoded_hash = base64.b64encode(hmac.new(decoded_key, bytes_to_hash, digestmod=hashlib.sha256).digest()).decode() authorization = "SharedKey {}:{}" .format(customer_id,encoded_hash) return authorization # Build and send a request to the POST API (Microsoft Azure Sentinel public endpoint) def post_data(customer_id, shared_key, body, log_type, logger): method = 'POST' content_type = 'application/json' resource = '/api/logs' rfc1123date = datetime.datetime.utcnow().strftime( '%a, %d %b %Y %H:%M:%S GMT' ) content_length = len(body) signature = build_signature(customer_id, shared_key, rfc1123date, content_length, method, content_type, resource) uri = 'https://' + customer_id + '.ods.opinsights.azure.com' + resource + '?api-version=2016-04-01' headers = { 'content-type' : content_type, 'Authorization' : signature, 'Log-Type' : log_type, 'x-ms-date' : rfc1123date } response = requests.post(uri,data=body, headers=headers) if (response.status_code >= 200 and response.status_code <= 299 ): logger.critical( '===> Upload to Microsoft Azure Sentinel was accepted %s', content_length ) else: logger.critical( "Error during upload. Response code: {}" .format(response.status_code)) #### ## PART 3 #### # # Entrypoint and initialization # def handler(ctx, data: io.BytesIO=None): logger.info("OCI Function - Handler function init fired.") # Update the customer ID to your Log Analytics workspace ID customer_id = ‘<PUT_HERE_YOUR_AZURE_LOG_ANALYTICS_WORKSPACE_ID>' # For the shared key, use either the primary or the secondary Connected Sources client authentication key shared_key_OCID = "<PUT_HERE_THE_OCID_OF_YOUR_OCI_VAULT_SHARED_KEY_SECRET>" shared_key = get_binary_secret(shared_key_OCID) # The log type is the name of the event that is being submitted log_type = '<SENTINEL_TABLE_NAME>' try: log_body = data.getvalue() post_data(customer_id, shared_key, log_body, log_type, logger) except Exception as err: logger.error( "Error in main process: {}" .format(str(err))) return response.Response( ctx, response_data=json.dumps({ "status" : "Success" }), headers={ "Content-Type" : "application/json" } )-
Il s'agit du script Python qui se connectera au SIEM Azure et enverra les journaux OCI à l'adresse distante.
-
Outre la copie et le collage de ce script, vous devez modifier 3 champs qu'il contient.
-
_customer_id : ID d'espace de travail Log Analytics dans votre abonnement Azure, dans le menu Gestion des agents.
-
_shared_key : clé primaire ou secondaire qui peut également être obtenue à partir du menu Gestion des agents.
-
_log_type : nom de l'espace de travail Log Analytics utilisé par SIEM Sentinel. Tous les journaux provenant de cet espace de travail sont analysés par Sentinel. Dans notre exemple, nous avons utilisé OCILogging.
-
-
Vous trouverez ci-dessous un exemple d'impression de l'écran où vous pouvez obtenir les informations ci-dessus.

Remarque : ce document ne porte pas sur la configuration de l'espace de travail Log Analytics dans votre abonnement Azure. Pour cela, recherchez plus d'informations dans la documentation officielle de Microsoft.
-
-
Après avoir modifié le fichier
func.py, il est temps de modifier le fichierrequirements.txt. Nous insérerons une exigence dans laquelle le gestionnaire de packages OCI Functions installera les dépendances Python nécessaires pour que notre script fonctionne correctement. Dans ce cas, insérez le mot requests sur la dernière ligne du fichier :
-
Une fois cette opération terminée, exécutez l'étape de déploiement de votre fonction.
$ fn -v deploy --app app-ocilog-to-azuresiem
Au bout de quelques minutes, la configuration de la fonction et la création de l'image Docker seront effectuées.

Tâche 5.2.2 : fournir les droits d'accès requis pour la fonction OCI
Pour que la fonction OCI s'exécute correctement, elle a besoin de droits d'accès permettant de lire la clé secrète Azure dans le coffre. Pour cela, nous devrons créer un groupe dynamique pour la fonction que nous avons créée et, pour ce groupe dynamique, nous donnerons le droit d'accès nécessaire (le moins privilège) afin que notre code puisse lire le coffre-fort et capturer la clé partagée d'Azure de manière sécurisée.
Donc, de la même manière que nous l'avons fait au point 2.2 ci-dessus, où nous avons créé un groupe dynamique pour agréger les serveurs qui collecteront les journaux, retracez les étapes et créez un groupe dynamique pour inclure notre fonction.
Lors de la création du groupe dynamique, vous aurez besoin d'une règle de correspondance qui sera utilisée pour capturer votre fonction. Dans notre exemple, nous allons créer une règle de correspondance qui répertorie toutes les fonctions du compartiment que nous utilisons exclusivement pour ce tutoriel.
ALL {resource.type = 'fnfunc', resource.compartment.id = 'ocid1.compartment.oc1..aaaaaxxxxgjxxxxglxxxxiqxxxxjdxxxxnxxxxmxxxxm3xxxxmoxxxxsxxx'}
-
Capturez l'OCID de votre compartiment, insérez-le dans votre règle de mise en correspondance et créez votre groupe dynamique.

-
Après avoir créé votre groupe dynamique, accédez à Identité et sécurité, Stratégies pour créer la stratégie qui permettra à la fonction d'accéder au coffre en mode lecture.

- Une fois le groupe dynamique créé, créez la stratégie qui permettra à la fonction d'accéder au coffre.
-
Utilisez la stratégie ci-dessous pour accorder l'accès minimal requis à la fonction afin d'exécuter l'activité de lecture des informations d'identification Vault.
Allow dynamic-group <FUNCTION\_DYNAMIC\_GROUP\_NAME> to read secret-bundles in compartment <COMPARTMENT\_NAME>
Tâche 5.2.3 : exécution de votre fonction OCI
-
Exécutez votre fonction pour vérifier qu'elle fonctionne correctement.
$ fn -v deploy --app app-ocilog-to-azuresiem
Maintenant, pour finaliser, nous devons configurer les connecteurs de service OCI pour capturer tous les journaux OCI de votre région et les envoyer à Azure SIEM à l'aide de la fonction que nous venons de créer.
Tâche 6 : configuration des connecteurs de service
Afin de pouvoir envoyer les journaux des régions de votre locataire OCI pour l'analyse de Microsoft Azure Sentinel, il est nécessaire de configurer les connecteurs de service.
Fondamentalement, ce service capture les journaux OCI que nous avons déjà configurés et les envoie à notre fonction qui, à son tour, transmettra tous les journaux à l'abonnement Azure.
-
Accédez au menu principal de votre console OCI, puis à Observabilité et gestion, **Connecteurs de service.

-
Une fois dans les connecteurs de service, cliquez sur Créer un connecteur de service.

-
Remplissez les champs de nom et de description requis, sélectionnez le compartiment dans lequel créer votre connecteur de service.

-
Sélectionnez maintenant la source des données qui seront transmises via le connecteur de service. Ici, utilisez Logging. En tant que cible, c'est-à-dire là où les données seront modifiées, utilisez Functions.

-
Pour finaliser la configuration, sélectionnez dans Configurer la source les journaux qui seront envoyés aux fonctions OCI. Dans cette étape, nous devons sélectionner le journal
\_Auditet, en ajoutant un autre journal, nous allons sélectionner le groupe de journaux que nous avons créé lors des étapes initiales de cette procédure.
- Si vous souhaitez ajouter un autre groupe de journaux, cliquez sur + Autre journal.
-
Une fois cette étape terminée, nous devons maintenant définir les paramètres cible, c'est-à-dire notre fonction OCI qui enverra les données à l'abonnement Azure. Pour ce faire, sélectionnez le compartiment dans lequel se trouve la fonction, puis sélectionnez l'application et, après cela, le nom de la fonction. Cliquez ensuite sur Créer comme indiqué dans l'image ci-dessous.

Le processus est terminé. A ce stade, attendez simplement que les journaux commencent à être envoyés automatiquement à Microsoft Azure.
Vous pouvez surveiller le fonctionnement du connecteur de service créé par le menu "Mesures".

Tâche 7 : Lire les journaux à Microsoft Azure Sentinel
-
Au bout de quelques instants, les journaux de tous les serveurs seront envoyés à l'abonnement Microsoft Azure comme indiqué dans l'image ci-dessous.

-
Selon votre configuration Microsoft Azure Sentinel, les incidents commenceront à s'afficher dans l'interface lorsque les règles SIEM seront déclenchées.

-
Incident ouvert pour le serveur de région Est du Brésil (nous avons créé une règle personnalisée appelée "[Lab] Regex Incident" pour générer nos exemples d'incidents).

-
Incident ouvert pour le serveur de région Us-Phoenix.

-
Liens connexes
Accusés de réception
Auteur - Rodrigo Pace de Barros (ingénieur solutions de sécurité Oracle LAD A-Team Cloud)
Ressources de formation supplémentaires
Explorez d'autres ateliers sur docs.oracle.com/learn ou accédez à davantage de contenu de formation gratuit sur le canal Oracle Learning YouTube. En outre, accédez à education.oracle.com/learning-explorer pour devenir un explorateur Oracle Learning.
Pour consulter la documentation produit, consultez Oracle Help Center.
Ingest Oracle Cloud Infrastructure logs into Microsoft Azure Sentinel using OCI Functions
F80858-01
April 2023
Copyright © 2023, Oracle and/or its affiliates.