Trabajar con la API de REST

Trabajar con MDR a través de la API de REST incluye obtener, crear y actualizar activos, incidentes, respuestas y usuarios.

ABRIR LA REFERENCIA DE LA API DE REST

Los métodos de la API de REST requieren un valor client_id. Puede obtener su valor client_id abriendo el bloque de Información del token de cualquier token de actualización en MDR Web Console.

He aquí ejemplos de secuencias de comandos para Python y Shell que muestran las capacidades básicas de la API de REST:

Ejemplo (Python):

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

# Parte general

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

 

import time

import datetime

import requests

import jwt

 

# El certificado es necesario para la autenticación de un recurso externo

#Puede descargar el certificado desde https://mdr.kaspersky.com,

#guárdelo en su disco y agregue la ruta en la variable:

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

 

#URL de la API de REST de MDR:

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

 

# La identificación de su cliente y sus tokens.

# Para obtener más información sobre cómo obtener su ID y los tokens, consulte la ayuda https://support.kaspersky.com/MDR/en-US/258285.htm

CLIENT_ID = "9ed43ed54sAmpleIdf349323951f" # (Pegue su valor)

REFRESH_TOKEN = "ReFrEsHToKeN" # (Pegue su valor)

ACCESS_TOKEN = "AcCeSsToKeN" # (Pegue su valor)

 

 

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

#Obtenga un token de acceso y un token de actualización para la próxima actualización del token de acceso

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

 

if REFRESH_TOKEN:

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

print(f"REFRESH_TOKEN fecha y hora de caducidad: {datetime.datetime.fromtimestamp(refresh_token_exp)}")

if refresh_token_exp > time.time():

print("REFRESH_TOKEN es válido")

else:

print(

" Debe actualizar REFRESH_TOKEN. Tómelo de MDR Console (https://support.kaspersky.com/MDR/en-US/258285.htm). "

)

exit()

else:

print(

" Debe rellenar el valor REFRESH_TOKEN. Tómelo de MDR Console (https://support.kaspersky.com/MDR/en-US/258285.htm)."

)

exit()

 

#Verificar la presencia y validez del token de acceso

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 fecha y hora de caducidad: {datetime.datetime.fromtimestamp(access_token_exp)}")

if access_token_exp > time.time():

print("ACCESS_TOKEN es válido")

else:

need_update_access_token = True

else:

need_update_access_token = True

 

#Si es necesario, actualice el token de acceso y actualice el token para la próxima actualización del token de acceso

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()

 

# Es necesario guardar el token de actualización para obtener el siguiente token de acceso cuando caduque el token de acceso actual

refresh_token = result_json["refresh_token"]

print(

f'!!! Su nuevo REFRESH_TOKEN para la próxima vez que solicite ACCESS_TOKEN (reemplace el valor de REFRESH_TOKEN con este valor): "{refresh_token}"'

)

 

# Se requiere un nuevo token de acceso para recuperar los datos

access_token = result_json["access_token"]

print(f'!!! Su nuevo ACCESS_TOKEN (reemplace el valor de ACCESS_TOKEN con este valor): "{access_token}"')

 

#El token de acceso se añade al encabezado de la solicitud

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

 

 

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

#Obtener el número de activos

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

 

#La fecha y la hora están en milisegundos a partir de 1970-01-01T00:00:00Z

request_body = {

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

* 1000, # Limitar el tiempo máximo de la última aparición del activo a la hora actual

"min_last_seen": 1639311132000, # Limitar el tiempo máximo de la última aparición de un activo a la constante: Domingo 12 de diciembre, 2021 12:12:12 PM (GMT)

}

result = requests.post(

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

)

print(result.json())

 

 

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

#Obtener la lista de activos

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

 

request_body = {

# Parámetros de búsqueda:

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

* 1000, # Limitar el tiempo máximo de la última aparición del activo a la hora actual

"min_last_seen": 1639311132000, # Limitar el tiempo mínimo de la última aparición del activo a la constante: Domingo 12 de diciembre, 2021 12:12:12 PM (GMT)

"domain": "",

"host_names": ["MA-MDR-KES-S", "SIN-MDR-KSC"], # (Pegue su valor) Lista de hosts

"is_isolated": False,

"network_interface": "10.70.104.1",

"os_version": "Windows", # El activo debe contener la línea especificada en el nombre del SO

"product": "",

"search_phrase": "mdr", # Frase para buscar en el contenido de los campos: "host_name", "domain", "installed_product_info", "network_interfaces", "os_version"

"estados": ["OK", "AUSENTE"], # Buscar activos que tengan los estados actuales enumerados aquí

# Opciones para mostrar los resultados de la búsqueda:

"sort": "first_seen:asc", # Ordenar los resultados por hora de primera aparición. En el caso de la recuperación de resultados página por página, es necesario especificar un campo de ordenación que no cambie de una consulta a otra, por ejemplo, "first_seen" (no especifique campos cuyos valores cambian constantemente, por ejemplo, el campo "last_seen"; esto puede llevar a resultados incorrectos).

"page_size": 100, # Activos por página: 100

"page": 1, # Obtener la primera página de resultados de búsqueda

"version": 2, # Versión de la solución

}

result = requests.post(

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

)

print(result.json())

 

 

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

# Obtener detalles de los activos

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

 

request_body = {

"asset_id": "0xFA6A68CC9A9415963DE841048A3BE929", # (Pegue su valor) Id. del activo

"version": 2, # Versión de la solución

}

result = requests.post(

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

).json()

print(result)

 

 

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

# Obtener el número de incidentes

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

 

request_body = {

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

* 1000, # Limitar el tiempo máximo de la última actualización del incidente a la hora actual

"min_update_time": 1639311132000, # Limitar el tiempo mínimo de la última actualización del incidente a la constante: Domingo 12 de diciembre, 2021 12:12:12 PM (GMT)

"affected_hosts": [

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

], # (Pegue su valor) Lista de hots en formato "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())

 

 

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

# Obtener la lista de incidentes

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

 

request_body = {

# Parámetros de búsqueda:

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

* 1000, # Limitar el tiempo máximo de creación del incidente a la hora actual

"min_creation_time": 1639311132000, # Limitar el tiempo mínimo de la creación del incidente a la constante: Domingo, 12 de diciembre de 2021 12:12:12 PM (GMT)

"asset_ids": [

"0xFA6A68CC9A9415963DE841048A3BE929"

], # (Pegue su valor) Lista de activos cuyos incidentes recopilamos

"priorities": ["HIGH"],

"resolutions": ["True positive"],

"response_statuses": ["Confirmed"],

"response_types": ["hash"],

"statuses": ["Cerrado"],

# Parámetros para entregar los resultados

"markdown_to_html": True, # Resultados en formato HTML. Si el valor es "False", los resultados se entregan en formato Markdown.

"sort": "creation_time: asc", # Ordena los resultados por fecha y hora de creación del incidente. En el caso de la recuperación de resultados página por página, es necesario especificar un campo de ordenación que no cambie de una consulta a otra, por ejemplo,"first_seen" (no especifique campos cuyos valores cambian constantemente, por ejemplo, el campo "last_seen"; esto puede llevar a resultados incorrectos).

"page_size": 100, # Incidentes por página: 100

"page": 1, # Obtener la primera página de resultados de búsqueda

}

result = requests.post(

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

)

print(result.json())

 

 

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

# Obtener detalles del incidente

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

 

request_body = {

"incident_id": "60gWG4UBMUGN-LWUuv1m", # (Pegue su valor) Id. del incidente

"markdown_to_html": True, # Resultados en formato HTML. Si el valor es "False", los resultados se entregan en formato Markdown.

}

result = requests.post(

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

)

print(result.json())

 

 

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

# Obtener una lista de respuestas al incidente

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

 

request_body = {

"incident_id": "60gWG4UBMUGN-LWUuv1m", # (Pegue su valor) Id. del incidente

"page_size": 10, # respuestas por página: 10

"page": 1, # Obtener la primera página de resultados de búsqueda

}

result = requests.post(

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

)

print(result.json())

 

 

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

# Confirmar la respuesta

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

 

request_body = {

"response_id": "CEgYG4UBMUGN-LWULP7W", # (Pegue su valor) Response ID

"comment": "comment_text", # Comentario que se añadirá a la respuesta

"status": "Confirmado", # Nuevo estado de respuesta: "Confirmado"

}

result = requests.post(

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

)

print(result.json())

 

 

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

# Rechazar la respuesta

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

 

request_body = {

"response_id": "CEgYG4UBMUGN-LWULP7W", # (Pegue su valor) Response ID

"comment": "comment_text", # Comentario que se añadirá a la respuesta

"status": "Rechazado", # Nuevo estado de respuesta: "Rechazado"

}

result = requests.post(

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

)

print(result.json())

 

 

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

# Actualizar la lista de respuestas

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

 

request_body = {

"responses_ids": [

"CEgYG4UBMUGN-LWULP7W",

"2ESl6IgB4cAOUyXBb5IB",

], # (Pegue sus valores) Id. de respuestas

"comment": "comment_text", # Comentario que se añadirá a las respuestas

"status": "Confirmado", # Estado de las nuevas respuestas: "Confirmado"

}

result = requests.post(

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

)

print(result.json())

Ejemplo (Shell):

# Obtener token de acceso y nuevo token de actualización

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

# Ejemplo de respuesta. A continuación, debe usar el access_token para recuperar los datos y el refresh_token para recuperar el nuevo token de acceso y el token de actualización.

{

"access_token": "SamPLET346yoKEnSamPLEToK25EnSamPLEToK35EnS",

"refresh_token": "tOKenSaMPlet259OKenS123aMPle926tOKenSaMPle"

}

 

# Obtener el número de activos

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}'

 

#Obtener la lista de activos

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}'

 

# Obtener detalles de los activos

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}'

 

# Obtener el número de incidentes

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"]}'

 

# Obtener la lista de incidentes

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}'

 

# Obtener detalles del incidente

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}'

 

# Obtener una lista de respuestas al incidente

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}'

 

# Actualizar la respuesta

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"}'

 

# Actualizar la lista de respuestas

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"}'

Ejemplo de respuesta de la API de REST con el token de acceso y el nuevo token de actualización:

{

"access_token": "SamPLET346yoKEnSamPLEToK25EnSamPLEToK35EnS",

"refresh_token": "tOKenSaMPlet259OKenS123aMPle926tOKenSaMPle"

}

Ejemplo de respuesta de la API de REST con la estructura y los valores de los comentarios:

[{

"comment_id": "bfu6TiNghqp",

"author_name": "John Doe",

"text": "<p>El primer comentario.</p>",

"creation_time": 1601295428640

}, {

"comment_id": "bfu6TiNghqt",

"author_name": "Jane Doe",

"text": "<p>El segundo comentario.</p>",

"creation_time": 1601295433441

}]

Ejemplo de respuesta de la API REST cuando la API de REST crea un nuevo comentario y envía una respuesta con los detalles del comentario:

{

"comment_id": "AXTej0Qi4bfu6TiNgmvT",

"author_name": "Nombre del token",

"text": "Este es un nuevo comentario creado a través de la API de REST.",

"creation_time": 1601461748122

}

Ver también:

Escenario: realizar una autorización basada en token

Parte superior de la página