Productos y Servicios PRODUCTOS Y SERVICIOS

Protocolo de escritorio remoto: ejecución de la consulta RDP externa

¿A la caza de conexiones RDP exitosas que hayan entrado en tu red desde el exterior? Una guía paso a paso (y una consulta para empezar)

La función de la consulta RDP Logins from External IPs.sql es bastante autoexplicativa, basándonos en el nombre. En este post, la utilizaremos para buscar conexiones RDP satisfactorias que hayan tenido lugar desde direcciones IP externas, es decir, cualquiera que no sea RFC 1918. Para esta demostración, haremos el trabajo de construir y ejecutar la consulta en sí a través de nuestro propio servicio Sophos Central, pero lo básico es válido independientemente de la herramienta de investigación. Como alternativa, el vídeo “Ejecutar la consulta RDP externa” enlazado a continuación muestra los pasos relevantes, en lugar de describirlos como hacemos aquí.

Crear y ejecutar la consulta

El primer paso es crear la consulta, para eso en Sophos Central ve a:

Centro de Análisis de Amenazas > Live Discover > Modo Diseñador

haciendo clic en el botón Crear nueva consulta, como se muestra en la Figura 1.

Figura 1: cómo ir hasta el botón de creación de consulta

Al hacer clic en el botón se abre una pantalla con un cuadro SQL, en el que pegarás la siguiente consulta (también disponible en nuestro Github):

SELECT 

strftime('%Y-%m-%dT%H:%M:%SZ',datetime) AS date_time, 

eventid, 

CASE eventid 

   WHEN 21 THEN eventid || ' - Session logon succeeded' 

   WHEN 22 THEN eventid || ' - Shell start notification received' 

   WHEN 25 THEN eventid || ' - Session reconnection successful' 

   ELSE NULL 

END AS description, 

JSON_EXTRACT(data, '$.UserData.User') AS username, 

SUBSTR(JSON_EXTRACT(data, '$.UserData.User'), 1, INSTR(JSON_EXTRACT(data, '$.UserData.User'), '\') - 1) AS domain, 

JSON_EXTRACT(data, '$.UserData.Address') AS source_IP, 

JSON_EXTRACT(data, '$.UserData.SessionID') AS session_ID, 

CASE 

    WHEN JSON_EXTRACT(data, '$.UserData.Address') GLOB '*[a-zA-Z]*' THEN 'private_IP' 

    WHEN INSTR(JSON_EXTRACT(data, '$.UserData.Address'), '192.168.') = 1 THEN 'private_IP'   

    WHEN INSTR(JSON_EXTRACT(data, '$.UserData.Address'), '172.') = 1 AND CAST(SUBSTR(JSON_EXTRACT(data, '$.UserData.Address'), 5, 2) AS INTEGER) BETWEEN 16 AND 31 THEN 'private_IP' 

    WHEN INSTR(JSON_EXTRACT(data, '$.UserData.Address'), '10.') = 1 THEN 'private_IP' 

    WHEN INSTR(JSON_EXTRACT(data, '$.UserData.Address'), '127.') = 1 THEN 'private_IP' 

    WHEN JSON_EXTRACT(data, '$.UserData.Address') = '0.0.0.0' THEN 'private_IP' 

    WHEN JSON_EXTRACT(data, '$.UserData.Address') LIKE '%::%' THEN 'unknown' 

    WHEN JSON_EXTRACT(data, '$.UserData.Address') = '' THEN 'private_IP' 

   ELSE 'external_IP' 

END AS status, 

'TS LocalSession EVTX' AS data_source, 

'Logins.01.4' AS query 

FROM sophos_windows_events 

WHERE source = 'Microsoft-Windows-TerminalServices-LocalSessionManager/Operational' 

    AND eventid IN (21,22,25) 

    AND (status = 'external_IP' OR status = 'unknown') 

  

UNION ALL 

  

SELECT 

strftime('%Y-%m-%dT%H:%M:%SZ',datetime) AS date_time, 

eventid, 

CASE eventid 

   WHEN 1149 THEN eventid || ' - User authentication succeeded' 

   ELSE NULL 

END AS description, 

JSON_EXTRACT(data, '$.UserData.Param1') AS username, 

JSON_EXTRACT(data, '$.UserData.Param2') AS domain, 

JSON_EXTRACT(data, '$.UserData.Param3') AS source_IP, 

NULL AS Session_ID, 

CASE 

    WHEN INSTR(JSON_EXTRACT(data, '$.UserData.Param3'), '192.168.') = 1 THEN 'private_IP' 

    WHEN INSTR(JSON_EXTRACT(data, '$.UserData.Param3'), '172.') = 1 AND CAST(SUBSTR(JSON_EXTRACT(data, '$.UserData.Param3'), 5, 2) AS INTEGER) BETWEEN 16 AND 31 THEN 'private_IP' 

    WHEN INSTR(JSON_EXTRACT(data, '$.UserData.Param3'), '10.') = 1 THEN 'private_IP' 

    WHEN INSTR(JSON_EXTRACT(data, '$.UserData.Param3'), '127.') = 1 THEN 'private_IP' 

    WHEN JSON_EXTRACT(data, '$.UserData.Param3') = '0.0.0.0' THEN 'private_IP' 

    WHEN JSON_EXTRACT(data, '$.UserData.Param3') LIKE '%::%' THEN 'unknown' 

    WHEN JSON_EXTRACT(data, '$.UserData.Param3') = '' THEN 'private_IP' 

    ELSE 'external_IP' 

END AS status, 

'TS RemoteConnection EVTX' AS data_source, 

'Logins.01.4' AS query 

FROM sophos_windows_events 

WHERE source = 'Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational' 

    AND eventid = 1149 

    AND (status = 'external_IP' OR status = 'unknown') 

Una vez pegado esto, seleccionarás las máquinas contra las que debe ejecutarse esta consulta. La consulta es específica de Windows; si se ejecuta en máquinas macOS o Linux no se obtendrán resultados, por lo que deseleccionarlas (en la opción Filtros -> Sistema operativo) es un buen primer paso. Más allá de eso, las necesidades de cada empresa son únicas. Sin embargo, hay razones de peso para ejecutar la consulta en todos los equipos Windows de tu red, incluso en los endpoints, por si alguno está incorrectamente expuesto a Internet. Por desgracia, nuestros investigadores de Respuesta a Incidentes se encuentran con esto mucho más a menudo de lo que cabría esperar.

Haz clic en Actualizar Dispositivos Seleccionados para confirmar tus selecciones y selecciona Ejecutar Consulta en la parte inferior derecha para ejecutarla. El sistema te pedirá que confirmes que deseas ejecutar esta consulta no probada: lo haces. La consulta comienza a ejecutarse; la velocidad a la que se devuelven los resultados depende de cuántos dispositivos se consulten y de sus conexiones de red. Cuando termine, la columna Estado te avisará de la finalización de la consulta (o, si algo ha ido mal, del fallo de la consulta). Desplázate hacia arriba; hay una sección llamada Resultados de la consulta que muestra los resultados. Si no aparece nada, ¡enhorabuena! No se han encontrado inicios de sesión RDP desde direcciones IP externas. Si, por el contrario, se muestran resultados…

Entender los resultados

Si tu consulta devuelve resultados, el primer campo a tener en cuenta en esos resultados es el nombre del endpoint. En el ejemplo que se muestra a continuación (tomado del banco de pruebas que montamos para hacer nuestro vídeo), dos máquinas informaron de que tienen conexiones RDP externas.

Figura 2: nuestro banco de pruebas tenía dos máquinas y ambas las tocó un ángel RDP externo

Al ampliar los resultados vemos la fecha y hora en que se produjo la conexión, el ID de evento devuelto por la consulta (con una breve descripción de lo que significa ese ID de evento), el nombre de usuario de la cuenta que se conectó y la dirección IP de origen desde la que se conectaron. Las direcciones no RFC 1918 demuestran que estas conexiones no procedían del espacio de direcciones privado de la red.

Cabe señalar que, como con cualquier consulta de este tipo, es necesario investigar más para descartar falsos positivos. Sin embargo, un “falso” positivo (una conexión externa peculiar que en realidad no era más que un administrador abriendo RDP en un servidor temporalmente) sigue mereciendo la pena comprobarlo. Como hemos señalado anteriormente en esta serie de artículos, los atacantes son impresionantemente rápidos para saltar a una conexión RDP abierta. Si el administrador pudo conectarse, son muchas las probabilidades de que un atacante también pudo encontrar el puerto abierto. Si fuéramos muy precavidos podríamos aislar el dispositivo y examinarlo más a fondo en busca de un posible compromiso.

Protocolo de escritorio remoto: la serie

Parte 1: protocolo de escritorio remoto: introducción (postvídeo)

Parte 2: RDP expuesto (es peligroso) (postvídeo)

Parte 3: consultas para la investigación (postvídeo)

Parte 4: factor zona horaria RDP (postvídeo)

Parte 5: ejecución de la consulta RDP externa (estás aquí, vídeo)

Parte 6: ejecución de la consulta de inicio de sesión 4624_4625 (post, vídeo)

Repositorio de consultas en GitHub: SophosRapidResponse/OSQuery

Repositorio de transcripciones: sophoslabs/video-transcripts

Lista de reproducción de YouTube: Protocolo de escritorio remoto: la serie

Dejar un comentario

Your email address will not be published. Required fields are marked *