Fig. 1. Ferido, mas não quebrado. A calculadora do Windows, cujo código foi publicado recentemente no Github , acabou sendo um dos dois aplicativos testados que não travaram e não caíram em oposição ao fuzzer das mensagens de janela desenvolvido em 2000. Tamanho da janela especialmente ampliado para mostrar artefatos difusosEstá na hora da segunda parte de nossos esforços para testar técnicas antigas de difusão em sistemas modernos. Se você perdeu, aqui está a
primeira parte . Desta vez, testaremos o Windows 10 usando técnicas de difusão do artigo “Investigação empírica da confiabilidade de aplicativos do Windows NT usando testes aleatórios” (também conhecido como “Relatório de difusão do NT”) de Justin Forrester e Barton Miller, publicado em 2000.
Os pesquisadores testaram 33 aplicativos do Windows NT e uma versão anterior do Windows 2000 quanto à suscetibilidade a mensagens distorcidas da janela e eventos aleatórios de mouse e teclado. Desde que o Dr. Miller publicou o código do difusor, usamos
exatamente as mesmas ferramentas que os autores originais para procurar bugs nos aplicativos modernos do Windows.
Os resultados são quase idênticos: 19 anos atrás, 100% dos aplicativos testados travavam ou travavam quando encontravam mensagens distorcidas na janela. Hoje, o mesmo fuzzer caiu ou travou 93% dos aplicativos testados. Apenas dois estavam em pé, incluindo o nosso velho amigo
Calculator (Fig. 1). Também encontramos um bug (mas não um problema de segurança) no Windows.
Uma breve introdução ao Windows
Então, o que são mensagens da janela e por que elas causam uma falha no programa?
Os aplicativos da GUI do Windows são orientados a eventos: movimentos do mouse, pressionamentos de botões, pressionamentos de teclas etc. Um aplicativo orientado a eventos não fará nada até receber um evento. Depois que um evento é recebido, o aplicativo executa a ação com base no evento e espera outros eventos. Parece familiar? Essa arquitetura
recebeu uma segunda vida em plataformas como node.js.As mensagens da janela são um método de notificação de eventos do Windows . Cada um deles tem um
código numérico associado a um evento específico . Cada mensagem possui um ou mais parâmetros, que
por convenção são chamados lParam e wParam . Eles definem informações mais detalhadas sobre o evento. Exemplos dessas informações são as coordenadas do movimento do mouse, qual tecla é pressionada ou qual texto exibir na janela. Essas mensagens podem ser enviadas pelo próprio programa, pelo sistema operacional ou por outros programas. Eles podem chegar a qualquer momento e em qualquer ordem e devem ser processados pelo aplicativo no lado de recebimento.
Implicações de segurança
Antes do Windows Vista, um processo de baixo privilégio poderia enviar uma mensagem para um processo de alto privilégio. Usando a combinação certa de mensagens, você pode executar o código nesse processo. No Vista, esses
"ataques subversivos" foram amplamente protegidos pelo
UIPI e pelo isolamento dos serviços do sistema em uma sessão separada.
É improvável que o processamento incorreto de mensagens na janela afete a segurança dos sistemas modernos do Windows por dois motivos. Primeiro, as mensagens da janela não podem ser enviadas pela rede. Em segundo lugar, travar um aplicativo ou executar código no mesmo nível de privilégio não é muito útil para um invasor. Provavelmente, era óbvio para os autores do relatório confuso do NT. Eles não fazem declarações de segurança, mas apontam corretamente que falhas no processamento de mensagens na janela implicam na falta de testes rigorosos.
Existem algumas áreas em que a execução de código com os mesmos privilégios pode comprometer a segurança. Alguns aplicativos combinam várias primitivas de segurança para criar um nível de privilégio artificial que não foi originalmente encontrado no sistema operacional. Um exemplo típico é uma sandbox para renderização em um navegador. Os fabricantes de navegadores estão cientes desses problemas e
tomaram medidas para resolvê-los . Outro exemplo são os produtos antivírus. Lá, o painel de controle funciona com privilégios normais, mas é isolado de outros módulos antivírus.
Metodologia de teste
Para confundir todos os aplicativos no conjunto de testes, usamos o mesmo código principal e técnica de difusão descrita no relatório inicial do NT. Em particular, nos modos
SendMessage e
PostMessage , o criador usou três iterações de 500.000 mensagens com 42 sementes e três iterações de 500.000 mensagens com 1.337 sementes. Os resultados apareceram após a execução de apenas uma iteração de cada método.
Perdemos a entrada aleatória de mouse e teclado devido a restrições de tempo e um desejo de focar apenas nas mensagens da janela. Também encorajamos aqueles que desejam repetir os testes e confirmar os resultados.
Armadilhas
Para fuzzer no Windows 10 teve que fazer duas pequenas alterações. Primeiro, adapte-o para uma plataforma de 64 bits. A segunda alteração permitiu ao fuzzer selecionar um identificador de janela específico usando o argumento da linha de comando. A difusão de um descritor específico é uma solução rápida para a difusão de aplicativos da
Plataforma Universal do Windows (UWP) . O programa original é focado em janelas confusas pertencentes a um determinado processo, mas todos os aplicativos UWP exibem sua interface do usuário através do mesmo processo (Fig. 2). Isso significa que o fuzzer não pode ser direcionado para a janela principal do aplicativo UWP.
Fig. 2. Na plataforma UWP, todos os aplicativos pertencem a um processo ( ApplicationFrameHost.exe
). Para confundir esses aplicativos, tive que alterar o fuzzer original do NT e direcioná-lo para identificadores de janela específicosHouve uma falha grave na modificação do fuzzer: os valores escolhidos para as duas principais fontes de entrada aleatória, os argumentos
lParam
e
wParam
para
SendMessage
e
PostMessage
, estão limitados a números inteiros de 16 bits. Ambos os argumentos são de 32 bits no Windows de 32 bits e de 64 bits no Windows de 64 bits. O problema ocorre no
Fuzz.cpp
, onde
lParam
e
wParam
:
wParam = (UINT) rand(); lParam = (LONG) rand();
A função rand () retorna um número no intervalo [0, 2
16 ], o que limita bastante o conjunto de valores testados. Salvamos este erro intencionalmente durante o teste para que os resultados sejam correspondidos com precisão ao trabalho original.
Aplicativos testados
No relatório original do NT, 33 programas foram testados. Temos apenas 28, porque apenas uma versão de cada programa é usada para teste. O ecossistema de software do Windows mudou significativamente desde 2000, embora surpreendentemente muito permaneça inalterado. O pacote do Microsoft Office contém os mesmos programas que nos testes originais. O Netscape Communicator evoluiu para o Firefox. O Adobe Acrobat foi renomeado como Adobe Reader, mas ainda é válido. Até o Winamp lançou um novo lançamento em 2018, que permite uma comparação justa com o relatório original. No entanto, alguns programas obsoletos tiveram que ser substituídos. Veja abaixo uma lista de alterações e razões para elas:
- CD Player ⇨ Windows Media Player: a funcionalidade CD Player está incluída no novo programa.
- Eudora ⇨ Windows Mail: A Qualcomm agora está lidando com chips em vez de com clientes de email. Como o Eudora não existe mais, o cliente de email padrão do Windows foi testado.
- Command AntiVirus ⇨ Avast Free Edition: O Command AntiVirus não está mais disponível. Foi substituído pelo Avast como o antivírus de terceiros mais popular.
- GSView ⇨ Fotos: O GSView não é mais suportado. Foi substituído pelo visualizador de fotos padrão do Windows.
- JavaWorkshop Net IDE NetBeans: O JavaWorkshop IDE não é mais suportado. O NetBeans parece ser uma boa alternativa gratuita que corresponde ao espírito do que precisa ser verificado.
- CRT seguro ⇨ BitVise SSH: o CRT seguro ainda existe, mas é necessário um formulário da Web muito longo para baixar a versão de avaliação. O BitVise SSH ofereceu uma inicialização rápida.
- Telnet ⇨ Putty: O aplicativo telnet ainda existe no Windows, mas agora é um aplicativo de console. Para confundir a GUI, a substituímos por Putty, o popular emulador de terminal de código aberto para Windows.
- Encontramos Freecell e Solitaire na Microsoft Solitaire Collection do catálogo de aplicativos da Windows App Store.
A versão específica do aplicativo é exibida na tabela de resultados. Toda a difusão foi realizada no Windows 10 Pro versão 1809 do sistema de 64 bits (compilação 17763.253).
Resultados
Conforme mencionado no relatório original, os resultados não devem ser vistos como vulnerabilidades de segurança, mas como um indicador da confiabilidade e qualidade do software.
"Finalmente, nossos resultados formam um ponto de partida quantitativo para julgar a melhoria relativa na confiabilidade do software".
- Do "Estudo empírico da confiabilidade de aplicativos do Windows NT usando testes aleatórios", de Justin Forrester e Barton Miller
Os números não são particularmente encorajadores, embora a situação esteja melhorando. No relatório inicial do NT, todos os aplicativos travaram ou ficaram parados. Agora, dois programas: a calculadora e o Avast Antivirus, sobreviveram ao faseamento das mensagens da janela sem consequências negativas. Louvamos as equipes do Avast e da Calculadora do Windows por sua abordagem a mensagens de janela incorretas. A equipe da Calculadora ganhou respeito adicional por abrir o código-fonte e demonstrar como criar um aplicativo UWP de alta qualidade. Consulte a tabela 1 para obter todos os resultados de difusão, juntamente com a versão específica do software usado.
Tabela 1. Resultados da reprodução da distorção original no Windows 10. Após 19 anos, quase todos os aplicativos ainda não lidam corretamente com mensagens distorcidas da janelaBug do Windows?
Infelizmente, a curiosidade prevaleceu e tivemos que fazer uma exceção. Parecia que vários aplicativos não relacionados foram atingidos por um problema comum. A depuração mostrou que o problema está relacionado à mensagem
WM_DEVICECHANGE
. Quando o fuzzer enviou essa mensagem, até o aplicativo mais simples caiu - o
HelloWorld, o exemplo oficial da API do Windows (Fig. 3).
Fig. 3. O HelloWorld.exe de 32 bits falha ao receber uma mensagem da janela do fuzzer. Isso não deve acontecer, pois o programa é completamente simples. Entende-se que o problema está em algum lugar do WindowsApós a queda do HelloWorld, percebemos imediatamente que o problema afeta apenas aplicativos de 32 bits, mas não aplicativos de 64 bits. Algumas
depurações rápidas mostraram que a falha ocorre no
wow64win.dll, uma camada de compatibilidade de aplicativos de 32 bits para 64 bits . Minha análise superficial (e possivelmente incorreta) do problema leva à conclusão de que a
wow64win.dll!whcbfnINDEVICECHANGE
considera o wParam como um ponteiro para a estrutura
DEV_BROADCAST_HANDLE64
no programa de destino. A função converte essa estrutura na estrutura
DEV_BROADCAST_HANDLE32
para compatibilidade com aplicativos de 32 bits. A falha ocorre porque o valor
wParam
gerado pelo difusor indica memória inválida.
Tratar o
wParam
como um ponteiro local é uma má idéia, embora tenha sido provavelmente uma decisão deliberada de design para que notificações de dispositivos removíveis funcionem com aplicativos Windows de 32 bits herdados. Mas ainda é errado que você possa travar outro aplicativo sem problemas. Relatamos o problema ao MSRC, embora o limite de segurança não tenha ultrapassado. Eles confirmaram que o erro não era um problema de segurança. Esperamos encontrar uma correção para esse problema estranho geralmente aceito em uma versão futura do Windows.
Conclusão
As mensagens da janela são subestimadas e frequentemente ignoradas como entrada não confiável para os programas do Windows. Mesmo 19 anos após o primeiro fuzzer de mensagens de janela de código aberto aparecer, 93% dos aplicativos testados ainda congelam ou travam quando o mesmo programa é iniciado. Mas é encorajador que alguns aplicativos lidem graciosamente com essa entrada distorcida: isso significa que algumas organizações têm estruturas e conhecimento institucional para evitar esses erros.
Obviamente, o fuzzer pode ser aprimorado de várias maneiras, mas mesmo o método mais simples travou 93% dos aplicativos. Talvez, em alguns casos, as mensagens da janela cruzem a fronteira de segurança real. Se você explorar esta área, esperamos que você compartilhe as conclusões.