Utilisation de l’API REST

Utilisez MDR via l’API REST pour obtenir, créer et mettre à jour des ressources, des incidents, des réponses et des utilisateurs.

OUVRIR LA RÉFÉRENCE DE L’API REST

Les méthodes de l’API REST nécessitent la valeur client_id. Vous pouvez récupérer votre valeur client_id dans le bloc Informations sur le jeton de n’importe quel jeton d’actualisation dans la Console MDR en ligne.

Voici des exemples de script pour Python et Shell qui illustrent les fonctionnalités de base de l’API REST :

Exemple (Python) :

###################################################

# Partie générale

###################################################

 

import time

import datetime

import requests

import jwt

 

# Le certificat est requis pour l’authentification d’une ressource externe

# Vous pouvez télécharger le certificat à l’adresse https://mdr.kaspersky.com,

# enregistrez-le sur votre disque et ajoutez son chemin dans la variable :

VERIFY_CERT_PATH = "C:\\tools\\DigiCert Global Root G2.crt"

 

# URL de l’API REST MDR :

API_URL = "https://mdr.kaspersky.com/api/v1"

 

# L’identifiant de votre client et vos jetons.

# Pour en savoir plus sur l’obtention de votre identifiant et des jetons, consultez l’aide https://support.kaspersky.com/MDR/fr-FR/258285.htm

CLIENT_ID = "9ed43ed54sAmpleIdf349323951f" # (Collez la valeur)

REFRESH_TOKEN = "ReFrEsHToKeN" # (Collez la valeur)

ACCESS_TOKEN = "AcCeSsToKeN" # (Collez la valeur)

 

 

###################################################

# Obtenir un jeton d’accès et un jeton d’actualisation pour la prochaine mise à jour du jeton d’accès

###################################################

 

if REFRESH_TOKEN:

refresh_token_exp = jwt.decode(REFRESH_TOKEN, options={"verify_signature": False}).get("exp")

print(f"REFRESH_TOKEN date et heure d’expiration: {datetime.datetime.fromtimestamp(refresh_token_exp)}")

if refresh_token_exp > time.time():

print("REFRESH_TOKEN existe")

else:

print(

" Vous devez mettre à jour REFRESH_TOKEN. Veuillez le récupérer depuis la Console MDR (https://support.kaspersky.com/MDR/fr-FR/258285.htm). "

)

exit()

else:

print(

" Vous devez renseigner la valeur REFRESH_TOKEN. Veuillez le récupérer depuis la Console MDR (https://support.kaspersky.com/MDR/fr-FR/258285.htm). "

)

exit()

 

# Vérifier la présence et la validité du jeton d’accès

need_update_access_token = False

if ACCESS_TOKEN:

access_token_exp = jwt.decode(ACCESS_TOKEN, options={"verify_signature": False}).get("exp")

print(f"ACCESS_TOKEN date et heure d’expiration : {datetime.datetime.fromtimestamp(access_token_exp)}")

if access_token_exp > time.time():

print("ACCESS_TOKEN existe")

else:

need_update_access_token = True

else:

need_update_access_token = True

 

# Si nécessaire, mettre à jour le jeton d’accès et actualiser le jeton pour la prochaine mise à jour du jeton d’accès

access_token = ACCESS_TOKEN

if need_update_access_token:

request_body = {"refresh_token": REFRESH_TOKEN}

result = requests.post(url=f"{API_URL}/{CLIENT_ID}/session/confirm", json=request_body, verify=VERIFY_CERT_PATH)

result_json = result.json()

 

if "error" in result_json:

print(result_json)

exit()

 

# Il est nécessaire d’enregistrer le jeton d’actualisation afin d’obtenir le prochain jeton d’accès après l’expiration du jeton d’accès actuel

refresh_token = result_json["refresh_token"]

print(

f'!!! Votre nouveau REFRESH_TOKEN pour votre prochaine demande de ACCESS_TOKEN (veuillez remplacer la valeur de REFRESH_TOKEN par celle-ci) : "{refresh_token}"’

)

 

# Un nouveau jeton d’accès est requis pour récupérer les données

access_token = result_json["access_token"]

print(f'!!! Votre nouveau ACCESS_TOKEN (veuillez remplacer la valeur de ACCESS_TOKEN par celle-ci) : "{access_token}"’)

 

# Le jeton d’accès est ajouté à l’en-tête de la requête

headers = {"Authorization": f"Bearer {access_token}"}

 

 

###################################################

# Obtenir le nombre de ressources

###################################################

 

# La date et l’heure sont exprimées en millisecondes depuis 1970-01-01 T00:00:00Z

request_body = {

"max_last_seen": int(time.time())

* 1000, # Limiter la durée maximale de la dernière apparition de la ressource à l’heure actuelle

"min_last_seen": 1639311132000, # Limiterla durée de la dernière apparition de la ressource avec la constante – Dimanche 12 décembre 2021 12:12:12 (GMT)

}

result = requests.post(

url=f"{API_URL}/{CLIENT_ID}/assets/count", json=request_body, headers=headers, verify=VERIFY_CERT_PATH

)

print(result.json())

 

 

###################################################

# Obtenir la liste des ressources

###################################################

 

request_body = {

# Paramètres de recherche :

"max_last_seen": int(time.time())

* 1000, # Limiter la durée maximale de la dernière apparition de la ressource à l’heure actuelle

"min_last_seen": 1639311132000, # Limiterla durée de la dernière apparition de la ressource avec la constante – Dimanche 12 décembre 2021 12:12:12 (GMT)

"domain": "",

"host_names": ["MA-MDR-KES-S", "SIN-MDR-KSC"], # (Collez la valeur) Liste des noms d’hôtes

"is_isolated": False,

"network_interface": "10.70.104.1",

"os_version": "Windows", # La ressource doit contenir la ligne indiquée dans le nom du système d’exploitation

"product": "",

"search_phrase": "mdr", # Phrase à rechercher en fonction du contenu des champs : "host_name", "domain", "installed_product_info", "network_interfaces", "os_version"

"statuses": ["OK", "ABSENT"], # Rechercher des ressources dont l’état actuel est indiqué ici

# Options d’affichage des résultats de la recherche :

"sort": "first_seen:asc", # Trier les résultats en fonction de l’heure de la première occurrence. Dans le cas où les résultats sont affichés page par page, il est nécessaire de d’indiquer un champ de tri qui ne changera pas d’une requête à l’autre, par exemple « first_seen » (ne pas indiquer de champs dont les valeurs changent constamment, par exemple le champ « last_seen » ; les résultats obtenus pourraient être erronés).

"page_size": 100, # Nombre de ressources par page – 100

"page": 1, # Affiche la première page des résultats de recherche

"version": 2, # Version de la solution

}

result = requests.post(

url=f"{API_URL}/{CLIENT_ID}/assets/list", json=request_body, headers=headers, verify=VERIFY_CERT_PATH

)

print(result.json())

 

 

###################################################

# Obtenir les détails de la ressource

###################################################

 

request_body = {

"asset_id": "0xFA6A68CC9A9415963DE841048A3BE929", # (Collez la valeur) ID de la ressource

"version": 2, # Version de la solution

}

result = requests.post(

url=f"{API_URL}/{CLIENT_ID}/assets/details", json=request_body, headers=headers, verify=VERIFY_CERT_PATH

).json()

print(result)

 

 

###################################################

# Obtenir le nombre d’incidents

###################################################

 

request_body = {

"max_update_time": int(time.time())

* 1000, # Limiter la durée de la dernière mise à jour de l’incident à l’heure actuelle

"min_update_time": 1639311132000, # Limiter l’heure minimale de la dernière mise à jour de l’incident avec la constante - dimanche 12 décembre 2021 12:12:12 (GMT)

"affected_hosts": [

"MA-MDR-KES-S:0xFA6A68CC9A94145456E841048A3BE929"

], # (Collaez la valeur) Liste des hôtes au format "host_name:asset_id"

}

result = requests.post(

url=f"{API_URL}/{CLIENT_ID}/incidents/count", json=request_body, headers=headers, verify=VERIFY_CERT_PATH

)

print(result.json())

 

 

###################################################

# Obtenir la liste des incidents

###################################################

 

request_body = {

# Paramètres de recherche :

"max_creation_time": int(time.time())

* 1000, # Limiter la durée de création de l’incident à l’heure actuelle

"min_creation_time": 1639311132000, # Limiter la durée minimale pour la création d’un incident avec la constante –Dimanche 12 décembre 2021 12:12:12 (GMT)

"asset_ids": [

"0xFA6A68CC9A9415963DE841048A3BE929"

], # (Collez la valeur) Liste des ressources pour lesquelles nous obtenons des incidents

"priorities": ["HIGH"],

"resolutions": ["True positive"],

"response_statuses": ["Confirmed"],

"response_types": ["hash"],

"statuses": ["Closed"],

# Paramètres d’obtention des résultats

"markdown_to_html": True, # Résultats au format HTML. Si la valeur est « False », les résultats sont au format Markdown.

"sort": "creation_time:asc", # Trie les résultats par date et heure de création de l’incident. Dans le cas où les résultats sont affichés page par page, il est nécessaire de d’indiquer un champ de tri qui ne changera pas d’une requête à l’autre, par exemple « creation_time » (ne pas indiquer de champs dont les valeurs changent constamment, par exemple le champ « update_time » ; les résultats obtenus pourraient être erronés).

"page_size": 100, # Nombre d’incidents par page – 100

"page": 1, # Affiche la première page des résultats de recherche

}

result = requests.post(

url=f"{API_URL}/{CLIENT_ID}/incidents/list", json=request_body, headers=headers, verify=VERIFY_CERT_PATH

)

print(result.json())

 

 

###################################################

# Obtenir les détails de l’incident

###################################################

 

request_body = {

"incident_id": "60gWG4UBMUGN-LWUuv1m", # (Collez la valeur) ID de l’incident

"markdown_to_html": True, # Résultats au format HTML. Si la valeur est « False », les résultats sont au format Markdown.

}

result = requests.post(

url=f"{API_URL}/{CLIENT_ID}/incidents/details", json=request_body, headers=headers, verify=VERIFY_CERT_PATH

)

print(result.json())

 

 

###################################################

# Obtenir la liste des réponses à l’incident

###################################################

 

request_body = {

"incident_id": "60gWG4UBMUGN-LWUuv1m", # (Collez la valeur) ID de l’incident

"page_size": 10, # Nombre de réponses par page – 10

"page": 1, # Affiche la première page des résultats de recherche

}

result = requests.post(

url=f"{API_URL}/{CLIENT_ID}/responses/list", json=request_body, headers=headers, verify=VERIFY_CERT_PATH

)

print(result.json())

 

 

###################################################

# Confirmer la réponse

###################################################

 

request_body = {

"response_id": "CEgYG4UBMUGN-LWULP7W", # (Collez la valeur) ID de la réponse

"comment": "comment_text", # Commentaire à ajouter à la réponse

"status": "Confirmed", # Nouvel état de la réponse – « Confirmé »

}

result = requests.post(

url=f"{API_URL}/{CLIENT_ID}/response/update", json=request_body, headers=headers, verify=VERIFY_CERT_PATH

)

print(result.json())

 

 

###################################################

# Refuser la réponse

###################################################

 

request_body = {

"response_id": "CEgYG4UBMUGN-LWULP7W", # (Collez la valeur) ID de la réponse

"comment": "comment_text", # Commentaire à ajouter à la réponse

"status": "Declined", # Nouvel état de la réponse – « Refusé »

}

result = requests.post(

url=f"{API_URL}/{CLIENT_ID}/response/update", json=request_body, headers=headers, verify=VERIFY_CERT_PATH

)

print(result.json())

 

 

###################################################

# Mettre à jour la liste des réponses

###################################################

 

request_body = {

"responses_ids": [

"CEgYG4UBMUGN-LWULP7W",

"2ESl6IgB4cAOUyXBb5IB",

], # (Collez les valeurs) ID des réponses

"comment": "comment_text", # Commentaire à ajouter aux réponses

"status": "Confirmed", # Nouvel état des réponses – « Confirmé »

}

result = requests.post(

url=f"{API_URL}/{CLIENT_ID}/responses/update", json=request_body, headers=headers, verify=VERIFY_CERT_PATH

)

print(result.json())

Exemple (shell) :

# Obtenir un jeton d’accès et un nouveau jeton d’actualisation

curl -X POST https://mdr.kaspersky.com/api/v1/{client_id}/session/confirm -H "Content-Type: application/json" -d '{"refresh_token": "{refresh_token}"}'

# Exemple de réponse. Ensuite, vous devez utiliser la valeur « access_token » pour récupérer les données et la valeur « refresh_token » pour récupérer le nouveau jeton d’accès et le jeton d’actualisation.

{

"access_token": "SamPLET346yoKEnSamPLEToK25EnSamPLEToK35EnS",

"refresh_token": "tOKenSaMPlet259OKenS123aMPle926tOKenSaMPle"

}

 

# Obtenir le nombre de ressources

curl -X POST https://mdr.kaspersky.com/api/v1/{client_id}/assets/count -H "Content-Type: application/json" -H "Authorization: Bearer {access_token}" -d '{"max_last_seen": 1704103200000, "min_last_seen": 1704762000000}'

 

# Obtenir la liste des ressources

curl -X POST https://mdr.kaspersky.com/api/v1/{client_id}/assets/list -H "Content-Type: application/json" -H "Authorization: Bearer {access_token}" -d '{"max_last_seen": 1704103200000, "min_last_seen": 1704762000000, "domain": "", "host_names": ["MA-MDR-KES-S","SIN-MDR-KSC"], "is_isolated": false, "network_interface": "10.70.104.1", "os_version": "Windows", "product": "", "search_phrase": "mdr", "statuses": ["OK","ABSENT"], "sort": "first_seen:asc", "page_size": 100, "page": 1, "version": 2}'

 

# Obtenir les détails de la ressource

curl -X POST https://mdr.kaspersky.com/api/v1/{client_id}/assets/details -H "Content-Type: application/json" -H "Authorization: Bearer {access_token}" -d '{"asset_id": "0xFA6A68CC9A9415963DE841048A3BE929", "version": 2}'

 

# Obtenir le nombre d’incidents

curl -X POST https://mdr.kaspersky.com/api/v1/{client_id}/incidents/count -H "Content-Type: application/json" -H "Authorization: Bearer {access_token}" -d ’{"max_update_time": 1704103200000, "min_update_time": 1704762000000, "affected_hosts": ["MA-MDR-KES-S:0xFA6A68CC9A9415963DE841048A3BE929"]}’

 

# Obtenir la liste des incidents

curl -X POST https://mdr.kaspersky.com/api/v1/{client_id}/incidents/list -H "Content-Type: application/json" -H "Authorization: Bearer {access_token}" -d ’{"max_creation_time": 1704103200000, "min_creation_time": 1704762000000, "asset_ids": ["0xFA6A68CC9A9415963DE841048A3BE929"], "priorities": ["HIGH"], "resolutions": ["True positive"], "response_statuses": ["Confirmed"], "response_types": ["hash"], "statuses": ["Closed"], "markdown_to_html": true, "sort": "creation_time:asc", "page_size": 100, "page": 1}’

 

# Obtenir les détails de l’incident

curl -X POST https://mdr.kaspersky.com/api/v1/{client_id}/incidents/details -H "Content-Type: application/json" -H "Authorization: Bearer {access_token}" -d ’{"incident_id": "60gWG4UBMUGN-LWUuv1m", "markdown_to_html": true}’

 

# Obtenir la liste des réponses à l’incident

curl -X POST https://mdr.kaspersky.com/api/v1/{client_id}/responses/list -H "Content-Type: application/json" -H "Authorization: Bearer {access_token}" -d ’{"incident_id": "60gWG4UBMUGN-LWUuv1m", "page_size": 10, "page": 1}’

 

# Mettre à jour la réponse

curl -X POST https://mdr.kaspersky.com/api/v1/{client_id}/response/update -H "Content-Type: application/json" -H "Authorization: Bearer {access_token}" -d ’{"response_id": "CEgYG4UBMUGN-LWULP7W", "comment": "comment_text", "status": "Confirmed"}’

 

# Mettre à jour la liste des réponses

curl -X POST https://mdr.kaspersky.com/api/v1/{client_id}/responses/update -H "Content-Type: application/json" -H "Authorization: Bearer {access_token}" -d '{"responses_ids": ["CEgYG4UBMUGN-LWULP7W", "2ESl6IgB4cAOUyXBb5IB"], "comment": "comment_text", "status": "Confirmed"}'

Exemple de réponse de l’API REST avec le jeton d’accès et le nouveau jeton d’actualisation :

{

"access_token": "SamPLET346yoKEnSamPLEToK25EnSamPLEToK35EnS",

"refresh_token": "tOKenSaMPlet259OKenS123aMPle926tOKenSaMPle"

}

Exemple de réponse de l’API REST avec la structure et les valeurs des commentaires :

[{

"comment_id": "bfu6TiNghqp",

"author_name": "Jean Paillet",

"text": "<p>Le premier commentaire.</p>",

"creation_time": 1601295428640

}, {

"comment_id": "bfu6TiNghqt",

"author_name": "Jeanne Paillet",

"text": "<p>Le deuxième commentaire.</p>",

"creation_time": 1601295433441

}]

Exemple de réponse de l’API REST lorsque l’API REST crée un nouveau commentaire et envoie une réponse avec les détails du commentaire :

{

"comment_id": "AXTej0Qi4bfu6TiNgmvT",

"author_name": "Nom du jeton",

"text": "Ceci est un nouveau commentaire créé via l’API REST.",

"creation_time": 1601461748122

}

Voir également :

Scénario : effectuer une autorisation basée sur des jetons

Haut de page