
Han pasado dos años desde que me sumergí de lleno en el mundo de la caza de ciber amenazas (Threat Hunting), ¡y menuda experiencia! Ese aprendizaje y mejora constantes son lo que me mantiene entusiasmado con la seguridad. Sinceramente, es por eso que no creo que nadie pueda considerarse realmente un «experto» en la nube: ¡las cosas cambian demasiado rápido! 😄Una cosa que me llamó la atención desde el principio (y he visto a otros luchar con ello también) es cómo etiquetamos los indicadores usados para buscar posibles amenazas dentro de nuestros tenants o sistemas. No todo es un IoC, ¡y es hora de que dejemos de tratarlos como si lo fueran!
Los términos IoA, IoC e indicadores de fraude pueden resultar confusos, y no siempre está claro en qué se diferencian o cuándo utilizarlos. Por lo tanto, analicemos cada uno de ellos y veamos qué significa, cómo funciona y cuáles son los más importantes para mantener la seguridad de una organización
IoA – Indicators of Attack
Los indicadores de ataque (IoA) son señales de alerta temprana, como picos de tráfico de red inesperados, inicios de sesión sospechosos o comportamientos inusuales de los usuarios, los cuales pueden revelar amenazas activas antes de que se intensifiquen. A diferencia de los indicadores de compromiso (IoC), que se centran en las pruebas forenses posteriores a la infracción, los IoA revelan el «porqué» de los ataques al detectar intenciones maliciosas en tiempo real, como la escalada de privilegios o transferencias de datos inusuales. Este enfoque proactivo cambia la seguridad de reaccionar ante el daño a interrumpir las amenazas en medio de la acción. Mediante el análisis continuo de los registros del sistema, las tácticas de los atacantes (TTP) y las anomalías de comportamiento, los equipos pueden neutralizar los riesgos antes de que causen daños. Por ejemplo, algunas detecciones de IoA basadas en consultas KQL pueden ser:
1. PowerShell.exe renombrados
PowerShell es una herramienta fiable de Microsoft que los atacantes pueden utilizar indebidamente renombrando su archivo ejecutable para ocultar sus acciones y propagar amenazas. La siguiente consulta detecta comandos comunes de la CLI para identificar las ejecuciones mencionadas por un Powershell renombrado.
DeviceProcessEvents
| where ProcessCommandLine !contains "powershell"
| where ProcessCommandLine !contains "pwsh"
| where ProcessCommandLine contains "-NoProfile" or ProcessCommandLine contains "-ExecutionPolicy" or ProcessCommandLine contains "Invoke-Expression"
| project DeviceName, FileName,ActionType, ProcessVersionInfoOriginalFileName, ProcessCommandLine, ProcessRemoteSessionIP
Lenguaje del código: JavaScript (javascript)
2. Trafico SMTP inusual
Un atacante podría intentar propagar malware, robar información confidencial mediante un ataque de tipo «man-in-the-middle» (MitM), lanzar un ataque DDoS o hacer un uso indebido del servidor de una empresa para enviar spam y llevar a cabo estafas de phishing. La siguiente consulta ejecuta un análisis general sobre el alto volumen de tráfico SMTP e incluye la opción de incluir una la lista blanca los dominios de confianza.
let timeRange = 3d; // Adjust time window
let volumeThreshold = 500; // Alert threshold for email count
let recipientThreshold = 200; // Alert threshold for unique recipients
EmailEvents
//| where Timestamp >= ago(timeRange)
| where EmailDirection == "Outbound" and SenderFromDomain !in ("domain1","domain2")
| summarize
TotalEmails = count(),
UniqueRecipients = dcount(RecipientEmailAddress),
UniqueDomains = dcount(tostring(split(RecipientEmailAddress, "@")[1])),
TimeSpan = max(Timestamp) - min(Timestamp),
FirstActivity = min(Timestamp),
LastActivity = max(Timestamp),
SampleSubjects = makeset(Subject, 5),
SampleRecipients = makeset(RecipientEmailAddress, 5)
by SenderFromAddress, SenderMailFromAddress, SenderIPv4
| where TotalEmails > volumeThreshold
or UniqueRecipients > recipientThreshold
| project
Timestamp = LastActivity,
SenderEmail = SenderFromAddress,
SenderIPv4,
TotalEmails,
UniqueRecipients,
UniqueDomains,
TimeSpan,
SampleSubjects,
SampleRecipients,
AlertReason = case(
TotalEmails > volumeThreshold and UniqueRecipients > recipientThreshold, "High volume to many recipients",
TotalEmails > volumeThreshold, "High email volume",
UniqueRecipients > recipientThreshold, "High recipient count",
"Threshold exceeded"
)
| sort by TotalEmails desc
Lenguaje del código: JavaScript (javascript)
3. Ejecución de procesos inusual
Esta técnica se conoce como LOLBAS (Living Off the Land Binaries and Scripts). Estas herramientas están integradas en el sistema operativo y cuentan con la confianza de los controles de seguridad, lo que las hace ideales para eludir las defensas. Comportamientos clave:
– Ejecución de cargas útiles codificadas en base64 (común en PowerShell)
– Comandos ofuscados o sospechosos en líneas de proceso (por ejemplo, mshta, rundll32, regsvr32)
– Uso de herramientas de confianza para descargar o ejecutar scripts remotos.
Esta consulta detecta actividades sospechosas en la línea de comandos mediante la decodificación de argumentos codificados en base64, que se utilizan a menudo en los ataques. Identifica el uso de mshta.exe, una técnica común en las infecciones de Lumma Stealer y otros programas maliciosos sin archivos, revelando intentos de ejecución ocultos incluso cuando los comandos están ofuscados.
DeviceFileEvents
| extend CommandWords = split(InitiatingProcessCommandLine, " ") // Split the command into words
| extend Word1 = CommandWords[0], // First word
Word2 = CommandWords[1], // Second word
Word3 = CommandWords[2], // Third word
Word4 = CommandWords[3], // Fourth word
Word5 = CommandWords[4]
| extend LongestWord = case(
strlen(Word1) >= strlen(Word2) and strlen(Word1) >= strlen(Word3) and strlen(Word1) >= strlen(Word4) and strlen(Word1) >= strlen(Word5), Word1,
strlen(Word2) >= strlen(Word1) and strlen(Word2) >= strlen(Word3) and strlen(Word2) >= strlen(Word4) and strlen(Word2) >= strlen(Word5), Word2,
strlen(Word3) >= strlen(Word1) and strlen(Word3) >= strlen(Word2) and strlen(Word3) >= strlen(Word4) and strlen(Word3) >= strlen(Word5), Word3,
strlen(Word4) >= strlen(Word1) and strlen(Word4) >= strlen(Word2) and strlen(Word4) >= strlen(Word3) and strlen(Word4) >= strlen(Word5), Word4,
Word5 // Default case if Column5 is the longest
)
| extend tostring(LongestWord)
| extend DecodedBytes = base64_decode_tostring(LongestWord)
| extend DecodedString = tostring(DecodedBytes)
| where DecodedString contains "mshta" or InitiatingProcessCommandLine contains "mshta"
| distinct DeviceName,InitiatingProcessCommandLine,LongestWord,DecodedString
Lenguaje del código: JavaScript (javascript)
4.Comunicación Command and Control (C2)
Malware que se comunica con servidores externos controlados por atacantes. Puede utilizar puertos poco comunes, tráfico cifrado o búsquedas DNS fallidas frecuentes.
Esta consulta identifica los dispositivos de la tabla DeviceEvents que están iniciando conexiones RDP y proporciona la ubicación de las direcciones IP remotas. La tabla DeviceEvents tiene una columna llamada «LocalIP» que puede resultar confusa, pero también incluye RemoteIPs, lo que significa intentos de conexiones remotas desde el propio dispositivo. He excluido las entradas sin información sobre la ubicación de la IP (lo que significa que son potencialmente IP locales). Como opción, puede añadir una línea para excluir ubicaciones «incluidas en la lista blanca», como: ‘ | where location !contain «Spain» ‘
DeviceEvents
| where ActionType contains "RemoteDesktopConnection"
| extend location = geo_info_from_ip_address(LocalIP)
| where location contains "Country"
| project Timestamp, DeviceName, ActionType, LocalIP, LocalPort, location,ReportId, DeviceId
Lenguaje del código: JavaScript (javascript)
IoC – Indicadores de compromiso
Un indicador de compromiso (IOC) es un artefacto de datos u observación que sugiere que se ha producido una violación de la seguridad de un sistema o red, o que se ha producido una actividad maliciosa.
Los IOC pueden incluir hash de archivos, direcciones IP, nombres de dominio, cambios en el registro, anomalías en los procesos o firmas de comportamiento que se correlacionan con amenazas conocidas. Se suelen utilizar en análisis forenses, búsqueda de amenazas y flujos de trabajo de detección automatizada para identificar, rastrear y responder a incidentes de seguridad tras un compromiso ya sea en el propio entorno o comunicado por un segundo.
1. File Hashes
Los FileHashes son huellas digitales únicas de los archivos (por ejemplo, MD5, SHA256) que pueden utilizarse para identificar ficheros relacionados con malware o acciones sospechosas.
Estos hashes sirven como indicadores de compromiso (IOC) que pueden cruzarse con fuentes de inteligencia sobre amenazas para identificar amenazas basadas en archivos en distintos entornos. La siguiente consulta KQL une eventos de archivos locales con indicadores MD5 externos del conocido repositorio TI MalwareBazaar con el objetivo de detectar ficheros maliciosos conocidos.
let MalwareBazaar = externaldata(MD5: string) ["https://bazaar.abuse.ch/export/txt/md5/recent"] with (format="txt", ignoreFirstRecord=True);
let MaliciousMD5 = MalwareBazaar | where MD5 !startswith "#";
DeviceFileEvents
| join kind=inner ( MaliciousMD5) on $left.MD5 == $right.MD5
Lenguaje del código: JavaScript (javascript)
2. Direcciones IP maliciosas
Las direcciones IP maliciosas son indicadores de compromiso (IOC) que pueden estar vinculados al phishing, la distribución de malware o la infraestructura de comando y control. La comunicación con estas direcciones IP puede indicar que un usuario o un sistema puede haber sido comprometido.
Esta consulta KQL importa la fuente de amenazas IPsum y la analiza para extraer direcciones IP con una puntuación de lista negra. A continuación, combina los registros relacionados con la identidad de AADSignInEventsBeta, CloudAppEvents e IdentityLogonEvents, y los une con la lista de IP analizadas. Cualquier coincidencia revela actividad relacionada con IP de alto riesgo, lo que ayuda a identificar cuentas que interactúan con infraestructura maliciosa conocida.
let ipsumrawData = externaldata(ip_string: string)[h@"https://raw.githubusercontent.com/stamparm/ipsum/master/ipsum.txt"] with (format="txt");
let parsedData = ipsumrawData
| where ip_string matches regex @"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s+\d+$"
| extend IP = extract(@"^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})", 1, ip_string), IPPubliclyBlacklist = toint(extract(@"\s+(\d+)$", 1, ip_string));
let badIPList = parsedData
| project IP, IPPubliclyBlacklist
| order by IPPubliclyBlacklist desc;
let aadSignInEventsBeta = AADSignInEventsBeta
| project Timestamp, AccountUpn, DeviceName, LogonType, IPAddress, Application, ApplicationId, ClientAppUsed, DeviceTrustType, LastPasswordChangeTimestamp, ResourceDisplayName, ResourceId, ResourceTenantId;
let cloudAppEvents = CloudAppEvents
| project Timestamp, AccountDisplayName, AccountObjectId, IPAddress, Application, ApplicationId, ActionType, ActivityType, IsAdminOperation, IsImpersonated, DeviceType, AuditSource, RawEventData, AdditionalFields, ReportId;
let identityLoginEvents = IdentityLogonEvents
| project Timestamp, AccountUpn, AccountObjectId, AccountSid, DeviceName, DeviceType, FailureReason, IPAddress, Protocol, DestinationIPAddress, DestinationPort, LogonType, AdditionalFields, ReportId;
let combinedEvents = aadSignInEventsBeta
| union cloudAppEvents
| union identityLoginEvents
| project Timestamp, AccountUpn, AccountObjectId, AccountSid, DeviceName, DeviceType, LogonType, IPAddress, Application, ActionType, ActivityType, IsAdminOperation, IsImpersonated, DeviceTrustType, LastPasswordChangeTimestamp, ResourceDisplayName, ResourceId, ResourceTenantId, FailureReason, Protocol, DestinationIPAddress, DestinationPort, AdditionalFields, ReportId;
combinedEvents
| join kind=inner (badIPList) on $left.IPAddress == $right.IP
| project Timestamp, AccountUpn, AccountObjectId, IPAddress, IPPubliclyBlacklist, LogonType, LastPasswordChangeTimestamp, Application, DeviceName, DeviceType, DeviceTrustType, ResourceDisplayName, ResourceTenantId, AdditionalFields, ResourceId, ReportId
| order by Timestamp desc;
Lenguaje del código: JavaScript (javascript)
3. Dominios y URLS
Los dominios y las URL se encuentran entre los IOC más comunes utilizados para detectar e investigar lugares maliciosos en internet. Representan nombres de host (como malicious-site.com) o direcciones web completas (como http://malicious-site.com/payload.exe) que pueden están involucrados en:
- Campañas de phishing
- Distribución de malware
- Comunicaciones de comando y control (C2)
- Intermediarios de acceso inicial
Esta KQL extrae las URL maliciosas activas del repositorio TI URLHaus y extrae sus nombres de dominio. A continuación, inspecciona DeviceNetworkEvents para averiguar si alguna de las respuestas DNS observadas coincide con las URL maliciosas conocidas. Si hay alguna coincidencia, enriquece el resultado con información de geolocalización y contexto de TI.
let URLHausOnlineRAW = externaldata (UHFeed:string) ["https://urlhaus.abuse.ch/downloads/csv_online/"] with(format="txt")
| where UHFeed !startswith "#"
| extend UHRAW=replace_string(UHFeed, '"', '')
| project splitted=split(UHRAW, ',')
| mv-expand id=splitted[0], dateadded=splitted[1], UHUrl=splitted[2], UHurl_status=splitted[3], UHlast_onlin=splitted[4], UHthreat=splitted[5], UHtags=splitted[6], UHLink=splitted[7], UHReporter=splitted[8]
| extend UHUrl = tostring(UHUrl)
| extend UHUrlDomain = tostring(parse_url(UHUrl).Host)
| project-away splitted;
DeviceNetworkEvents
| extend answers = todynamic(tostring(parse_json(AdditionalFields).answers))
| extend answersext = todynamic(tostring(parse_json(AdditionalFields).answers))
| mv-expand answers
//| extend geo_Remote_answers = todynamic(tostring(geo_info_from_ip_address(answers).country))
| extend Type =
case(
answers matches regex @"^(\d{1,3}\.){3}\d{1,3}$", "IPv4", // Matches IPv4 format
answers matches regex @"^([a-fA-F0-9:]+)$", "IPv6", // Matches IPv6 format
answers contains ".", "URL", // Checks if it contains a dot (common in URLs)
"Unknown" // Default case
)
| where Type has "URL"
| extend tostring(answers)
| join kind=inner (URLHausOnlineRAW) on $left.answers == $right.UHUrl
| extend geo_Remote_ip = tostring(geo_info_from_ip_address(RemoteIP).country)
| project Timestamp,DeviceName,LocalIP,RemoteIP,geo_Remote_ip,MaliciousAnswers = UHUrl,answersext,UHUrlDomain, ActionType
Lenguaje del código: JavaScript (javascript)
4. Registry Keys
Las claves del Registro de Windows son configuraciones críticas del sistema almacenadas en una base de datos jerárquica utilizada por el sistema operativo Windows y las aplicaciones. Los actores maliciosos suelen atacar o manipular claves específicas del Registro para:
- Lograr persistencia (por ejemplo, ejecutar malware al iniciar el sistema).
- Desactivar las funciones de seguridad (por ejemplo, la protección en tiempo real o MAPS).
- Modificar el comportamiento del sistema para el sigilo o la escalada de privilegios.
Esta consulta inspecciona DeviceRegistryEvents en busca de rutas de registro específicas vinculadas a la configuración de políticas de Windows Defender. Señala los casos en los que se han desactivado determinadas funciones de seguridad (por ejemplo, MAPS, Protección en tiempo real) (RegistryValueData == 1), lo que puede indicar una manipulación por parte de un atacante o malware que intenta reducir las defensas del sistema.
DeviceRegistryEvents
//If you enable these policy settings (RegistryValueData == 1), Windows Defender will not take actions or report possible threats.
//Windows Defender - Defender service itself.
//Spynet = Microsoft Active Protection Service is an online community that helps you choose how to respond to potential threats. This feature ensures the device checks in real time with the Microsoft Active Protection Service (MAPS) before allowing certain content to be run or accessed. If this feature is disabled, the check will not occur, which will lower the protection state of the device.
//Real-Time Protection = protection to scan for malware and other unwanted software. Once this has been disabled, it won’t scan anything of it.
| where RegistryKey == "HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\Windows Defender" or RegistryKey == "HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\Windows Defender\\spynet" or RegistryKey == "HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\Microsoft Antimalware\\Real-Time Protection"
| where RegistryValueData == 1
| distinct Timestamp, DeviceName, RegistryKey, RegistryValueName, PreviousRegistryValueData, RegistryValueData, IsInitiatingProcessRemoteSession
Lenguaje del código: JavaScript (javascript)
Indicadores de Fraude
Los indicadores de fraude son señales de alerta que indican que alguien podría estar engañando a un sistema para obtener beneficios económicos. Aunque pueden solaparse con problemas de ciberseguridad como el malware, los indicadores de fraude suelen centrarse en acciones que parecen deshonestas o inusuales, especialmente las relacionadas con estafas económicas.
Por ejemplo, imagina que una tarjeta de crédito se utiliza para pedir comida en Londres y, solo 15 minutos después, se vuelve a utilizar para reservar una habitación de hotel en Tokio. Dado que nadie puede estar físicamente en dos lugares a la vez, esta actividad inusual podría alertar al sistema de que alguien podría estar utilizando la tarjeta de forma fraudulenta.
1. Registros y alertas del sistema: irregularidades en los registros de auditoría, modificaciones no autorizadas, etc.
Detecta manipulaciones del registro de auditoría, intentos de acceso no autorizados o cambios sospechosos en la configuración.
La siguiente consulta KQL esta enfocada a detectar los casos en los que los registros de eventos de seguridad de Windows se han eliminado directamente mediante el Visor de eventos. Entre las amenazas asociadas, tenemos:
- Pérdida de pruebas no relacionadas con la reputación.
- Falta de visibilidad sobre actividades maliciosas.
- Incumplimiento normativo.
DeviceEvents
| where ActionType has "SecurityLogCleared"
Lenguaje del código: JavaScript (javascript)
2. Intentos de phishing
Si recibe enlaces inesperados, archivos adjuntos de correo electrónico o mensajes OTP sospechosos de fuentes desconocidas, no interactúe con ellos. Pueden contener malware diseñado para robar su información personal o financiera.
La siguiente consulta KQL se basa en correos electrónicos detectados como amenazas clasificadas por el ISP. Si recibe correos electrónicos de un ASN con varias direcciones IP distintas y todos los mensajes están etiquetados como amenazas, es el momento de tomar medidas, como eliminar o mover el correo electrónico a la carpeta de correo no deseado.
//Sergio Albea
let CIDRASN = (externaldata (CIDR:string, CIDRASN:int, CIDRASNName:string)
['https://firewalliplists.gypthecat.com/lists/kusto/kusto-cidr-asn.csv.zip']
with (ignoreFirstRecord=true));
EmailEvents
| evaluate ipv4_lookup(CIDRASN, SenderIPv4, CIDR, return_unmatched=true)
| extend GeoIPData = tostring(geo_info_from_ip_address(SenderIPv4).country)
| summarize Different_IPs=make_set(SenderIPv4), Countries= make_set(GeoIPData), make_set(CIDR), make_set(SenderFromDomain), Total_different_IPs=dcount(SenderIPv4) ,Total_emails = count(),make_set(ThreatTypes),Delivered_on_Inbox= countif(DeliveryLocation has "Inbox/folder"), Email_Threat= count(isnotempty(ThreatTypes)),
Email_Valid = count( isempty(ThreatTypes)) by GeoIPData, CIDR, CIDRASNName
| extend SuspiciousRatio = Email_Threat * 1.0 / Total_emails, ValidRatio = Email_Valid * 1.0 / Total_emails
| extend SuspiciousPercentage = SuspiciousRatio * 100, ValidPercentage = ValidRatio * 100
| where SuspiciousPercentage > 95 and Total_different_IPs > 10
| order by Email_Threat
| project CIDRASNName,set_SenderFromDomain, set_CIDR, Different_IPs, Countries,Total_different_IPs, set_ThreatTypes,Total_emails, Delivered_on_Inbox, Email_Threat, Email_Valid, SuspiciousPercentage, ValidPercentage
Lenguaje del código: JavaScript (javascript)
3. Comportamiento de usuario sospechoso
El fraude puede detectarse a través de acciones inusuales, como cambios repentinos en los números de teléfono o direcciones de correo electrónico, solicitudes de transacciones inesperadas o múltiples inicios de sesión exitosos desde países lejanos en el mismo día, actividades que a menudo apuntan a un compromiso de la cuenta o al robo de identidad.
La siguiente consulta KQL busca casos en los que los inicios de sesión exitosos del usuario durante el mismo día provienen de países que están muy distantes entre sí. La consulta comprueba la diferencia de longitud y latitud de los primeros cuatro países; si hay más de cuatro países, también se me notificará.
let substring = ",";
AADSignInEventsBeta
| where Timestamp > ago(1d)
| where ErrorCode == 0
| where isnotempty(Country)
| project AccountUpn, Timestamp, ClientAppUsed, Country, Latitude, Longitude, ReportId, DeviceTrustType
| summarize ['Count of countries']=dcount(Country), ['List of countries']=make_set(Country), ['ListofLatitudes']=make_set(Latitude),
['ListofLongitudes']=make_set(Longitude) by AccountUpn, DeviceTrustType
| where ['Count of countries'] >= 3
// | where DeviceTrustType !contains "Azure AD registered"
| project splitted=split(ListofLatitudes, '"'),splitted1=split(ListofLongitudes, '"'), ['List of countries'], AccountUpn, ['Count of countries']
//split Latitude and transform it output (if you want to add more countries, add Lat(+1)= splitted[+2] From the last, example --> Lat5 = splitted[9] )
| mv-expand Lat1=splitted[1], Lat2=splitted[3], Lat3=splitted[5], Lat4= splitted[7]
| extend Lat1 =todouble(Lat1), Lat2 = todouble(Lat2), Lat3 = todouble(Lat3), Lat4 = todouble(Lat4)
| extend Lat1 = round(Lat1), Lat2 = round(Lat2), Lat3 = round(Lat3), Lat4 = round(Lat4)
//split Longitude and transform it output (if you want to add more countries, add Long(+1)= splitted[+2] From the last, example --> Long = splitted[9])
| mv-expand Long1=splitted1[1], Long2=splitted1[3], Long3=splitted1[5], Long4= splitted1[7]
| extend Long1 =todouble(Long1), Long2 = todouble(Long2), Long3= todouble(Long3), Long4 = todouble(Long4)
| extend Long1 = round(Long1), Long2 = round(Long2), Long3 = round(Long3), Long4 = round(Long4)
// susbstract operations
| serialize resta = Lat1 - Lat2, resta2 = Lat1 - Lat2, resta3 = Lat2 - Lat3, resta4 = Lat1 - Lat4
| serialize restal = Long1 - Long2, restal2 = Long1 - Long3, restal3 = Long2 - Long3
// Calculate the distance, add more than 15 or 20 to see more distant countries
| where (resta > 15 and resta2 > 15 and resta3> 20 and Lat1 != Lat2 and Lat1!= Lat2 and Lat2!= Lat3) or (resta < -20 and resta2 < -15 and resta3 < -15) or (restal > 20 and restal2 > 20 and restal3> 20 and Long1 != Long2 and Long1!= Long2 and Long2!= Long3) or (restal < -20 and restal2 < -20 and restal3 < -20) or (['Count of countries'] >4)
| project AccountUpn,['List of countries']
Lenguaje del código: JavaScript (javascript)
Resumen
El artículo aclara las diferencias entre los IoC (indicadores de ataque, pruebas de ataques pasados), los IoA (indicadores de ataque, señales de que se está produciendo o es inminente un ataque) y los indicadores de fraude (comportamientos sospechosos destinados a la manipulación financiera o de la identidad). Se proporcionan ejemplos y consultas KQL reales para ilustrar:
- IoAs: Como el uso indebido de PowerShell, el tráfico SMTP excesivo o los comandos codificados en base64.
- IoCs: Incluyen hash de archivos, IP maliciosas, dominios/URL y cambios en el registro.
- Fraud Indicators: Cambios repentinos en el comportamiento del usuario, estafas OTP o inicios de sesión desde ubicaciones geográficas muy separadas en períodos cortos.
Con cada tipo de indicador, el artículo comparte estrategias de detección prácticas utilizando Microsoft Defender XDR (consultas KQL) y explica su relevancia en la vida real. El objetivo es observer más allá de las detecciones estáticas (IoC) y detectar de forma proactiva los comportamientos de los atacantes y posibles fraudes antes de que se produzcan daños.