Curso Rápido de Segurança do X Window

  1. Motivação/Introdução
  2. Como são encontrados displays X abertos
  3. O problema do localhost
  4. Técnicas de espionagem: copiando janelas
  5. Técnicas de espionagem: lendo o teclado
  6. Xterm - a opção Secure Keyboard
  7. Programas Cavalo-de-Tróia para o X [xlock e xdm]
  8. Ferramentas de Segurança do X - xauth MIT-MAGIC-COOKIE
  9. Comentários Finais

1. Motivação/Introdução

O X Window representa um risco de segurança. Através de uma rede, qualquer um pode se conectar a um display X aberto, ler o tecldo, copiar a tela e janelas, e iniciar aplicações no display desprotegido. Mesmo sendo este um fato conhecido no mundo da segurança de computadores, poucas tentativas de informar a comunidade de usuários sobre os riscos de segurança envolvidos tem sido feitas. Este artigo trata de alguns aspectos da segurança do X Window. De forma alguma é um guia completo sobre o assunto, mas uma introdução a um campo não tão conhecido da segurança de computadores. É necessário um conhecimento básico do funcionamento do X Window System, eu não me incomodei em incluir uma seção introdutória para explicar os fundamentos. Eu escrevi algum código durante a pesquisa para este arquivo, mas não incluí nada no mesmo. Se o Inglês parece meio estranho e errôneo de um byte para outro, isto se deve ao fato de que sou um Escandinavo.

2. Como são encontrados displays X abertos

Um display X aberto é, em termos formais, um servidor X que tem seu controle de acesso desabilitado. A desabilitação do controle de acesso é normalmente feita com o comando xhost.

$ xhost +

permite conexões de qualquer host. Pode-se permitir acesso a um único host com o comando

$ xhost + ZZZ.ZZZ.ZZZ.ZZZ

onde Z é o endereço IP ou nome do host. O controle de acesso pode ser habilitado novamente com o comando

$ xhost -

Neste caso nenhum host além do localhost podem se conectar ao display. Ponto. É assim simples - se o display está sendo rodado no estado 'xhost -', você está protegido de programas que escaneiam e se conectam a displays X desprotegidos. Você pode checar o estado do controle de acesso de seu terminal simplesmente tecladno xhost em um shell. Infelizmente, muitos sites rodam seus displays X com o controle de acesso desabilitado por padrão. Eles são presa fácil para os vários programas scanners que circulam pela Internet.

Qualquer um com um pouco de conhecimento sobre a Xlib e programação de sockets pode escrever um scanner X em um par de horas. A tarefa é normalmente executada fazendo uma sondagem na porta que é reservada para o X Window, a de número 6000. Se houver algum coisa viva naquela porta, o scanner chama XOpenDisplay("IP-ADDRESS:0.0") que irá retornar um ponteiro para a estrutura do display, se e somente se o display testado estiver com o seu controle de acesso desabilitado. Se o controle de acesso estiver habilitado, o XOpenDisplay retorna 0 e relata que o display não pode ser aberto. Exemplo:

Xlib: connection to "display:0.0" refused by server
Xlib: Client is not authorized to connect to Server

A sondagem da porta 6000 é necessária pelo fato que chamar o XOpenDisplay() em um host que não está rodando nenhum servidor X irá pendurar o processo que está fazendo a chamada. Isto foi o suficiente sobre convenções de programação unix. :)

Eu escrevi um programa chamado xscan que pode pesquisar uma subnet inteira ou pesquisar as entradas em /etc/hosts por displays X abertos. Meu comentário sobre muitos sites rodando displays X com o controle de acesso desabilitado origina-se de ter executado o xscan contra vários sites na Internet.

3. O problema do localhost

Executar o seu display com o controle de acesso habilitado pelo uso de 'xhost -' irá proteger você do tentativas de usar o XOpenDisplay na porta 6000. Mas ainda há uma forma de um invasor driblar esta proteção. Se ele puder fazer logon em seu host, ele pode se conectar ao display do localhost. O truque é bastante simples. Executando as seguintes linhas, o dump da tela do host 'target' é feito:

$ rlogin target
$ xwd -root -display localhost:0.0 > ~/snarfed.xwd
$ exit
$ xwud -in ~/snarfed.xwd

E voilà, temos um screendump da janela root do servidor X alvo.

Obviamente um invasor precisa ter uma conta em seu sistema e deve poder fazer o login no host em que o servidor X específico está sendo executado. Em sites com muitos terminais X, isto significa que nenhum display X está protegido de quem tem acesso. Se você pode rodar um processo em um host, pode conectar a qualquer um de seus displays X.

Todas as rotinas Xlib possuem a estrutura Display como seu primeiro argumento. Abrindo com sucesso um display, pode-se manipular o mesmo com todas as chamadas Xlib disponíveis. Para um invasor, as formas mais "importantes" é a captura de janelas e de teclas pressionadas.

Técnicas de espionagem: copiando janelas

A forma mais natural de copiar uma janela de um servidor X é usando o utilitário xwd do X11R5 ou o utilitário de dumping do X Window System. Para entender como funciona o programa, segue um pequeno trecho da página man.

Descrição

Xwd é um utilitário de dumping de janelas do X Window System. O xwd permite que os Xusers armazenem imagens de janelas em um arquivo de dump com formato especial. Este arquivo pode então ser lido por vários outros utilitários X para reapresentação, impressão, formatação, arquivamento, processamento de imaem, etc. A janela alvo é selecionada clicando o ponteiro na janela desejada. O sinal "bell" de teclado é rodado uma vez no início do dump e duas vezes qando este está completo.

Em resumo, o xwd é uma ferramenta para fazer dumping de janelas X em um formato que pode ser lido por outro programa, o xwud. Para manter o costume, segue um trecho da página man do xwud:

Descrição

O Xwud é um utilitário de "undumping" de imagens do X Window System. O xwud permite que usuários do X visualizem uma imagem salva em um arquivo de dump especialmente formatado, como o que é produzido pelo xwd(1).

Eu não irei entrar em detalhes sobre como usar estes programas, já que são ambos auto-explicativos e fáceis de usar. Tanto a janela root inteira, uma janela especificada (por nome) pode sofrer o dump, ou uma tela especificada. Como "medida de segurança", o xwd irá bipar o terminal que ele está fazendo o dump, uma vez quando o dump é iniciado, e outra quando ele está completo (não importando se tiver sido executado o comando xset b off). Mas com o código fonte disponível, só é preciso uma pequena modificação para compilar uma versão do xwd que não faça o bip ou que se identifique de qualquer outra forma - na lista de processos, por exemplo. Se queremos fazer o dump da janela root, ou qualquer oura janela de um host, podemos simplesmente pegar uma janela da lista de processos, que geralmente dá o nome da janela com a flag -name. Conforme mencionado anteriormente, para fazer o dump de uma tela completa de um host:

$ xwd -root localhost:0.0 > file

A saída pode ser redirecionada a um arquivo, e lida com

$ xwud -in file

ou pode ser feito um pipe direto para o comando xwud.

As janelas Xterm são uma coisa diferente. Você não pode especificar o nome de um xterm e então fazer o dump do mesmo. Eles são bloqueados de alguma forma da primitiva X_Getimage usada pelo xwd, de forma que o comando abaixo

$ xwd -name xterm

irá resultar em um erro. Entretanto, a janela root inteira (com Xterms e tudo o mais) ainda pode sofrer um dump e ser observada pelo xwud. Alguma proteção.

5. Técnicas de espionagem: lendo o teclado

Se você pode se conectar a um display, você pode também fazer o log e armazenar cada tecla pressionada que passar pelo servidor X. Um programa que circula pela Internet, chamado xkey, faz este truque. É um tipo de versão de alto-nível do infame ttysnoop.c. Eu escrevi o meu próprio programa, que pode ler as teclas pressionadas em uma janela de ID específico (não só todas as teclas pressionadas, como minha versão do xkey). O ID da janela de uma janela root específica pode ser obtida com uma chamada a XQueryTree(), que irá retornar os XWindowAttributes de cada janela presente. O gerenciador de janelas deve poder controlar cada window-ID e quais teclas são pressionadas em quais momentos. Usando as funções de administração de janelas do Xlib, eventos KeyPress podem ser capturados, e KeySyms podem ser transformados em caracteres por chamadas contínuas a XLookupString.

Você pode até mesmo enviar KeySyms para uma janela. Um invasor pode não somente espionar sua atividade, ele pode enviar eventos de teclado a processos, como se fossem feitos no teclado. Ler/escrever eventos de teclado a uma janela xterm abre novso horizontes no processo de manipulação remota. Por sorte, o xterm possui boas técnicas de proteção para proibir o acesso aos eventos de teclado.

6. Xterm - a opção Secure Keyboard

Muitas senhas são escritas em uma janela xterm. É, portanto, crucial que o usuário possua controle completo sobre quais processos podem ler e escrever em um xterm. A permissão para o servidor X enviar eventos a uma janela Xterm é configurada durante a compilação. O padrão é falso, significando que todas as solicitações SendEvent do servidor X para uma janela xterm são descartadas. Você pode alterar a opção de compilação com uma definição de resource padrão no arquivo .Xdefaults:

xterm*allowSendEvents    True

Ou selecionando Allow SendEvents no menu Main Options do xterm (acessado pressionando a tecla Ctrl e o botão esquerdo do mouse, mas isto NÃO é recomendado, nem por mim, nem pela página man). Acesso de leitura é uma coisa diferente.

O mecanismo do Xterm para impedir outros clientes X de ler o teclado durante a entrada de dados sensíveis, senhas, etc. é usando a chamada XGrabKeyboard(). Somente um processo pode capturar o telado a qualquer momento. Para ativar a opção Secure Keyboard, escolha o menu Main Options em sua janela Xterm (Ctrl+botão esquerdo do mouse) e selecione Secure Keyboard. Se as cores do seu xterm se inverterem, o teclado foi capturado, e nenhum outro cliente X pode ler as KeySyms.

A versão do Xterm X11R5 sem o patch26 também contém um furo de segurança muito ruim e muito bem conhecido, que permite que qualquer usuário se torne root peloo uso inteligente de links simbólicos ao arquivo de senhas. O processo Xterm precisa ser feito setuid para esta vulnerabilidade ser explorada. Veja o Cert Advisory: CA-93:17.xterm.loggin.vulnerability.

Programas Cavalo-de-Tróia para o X [xlock e xdm]

Você pode pensar em um program amais apropriado para instalar um cavalo-de-tróia de captura de senhas que o xlock? Eu não. Acrescentando algumas linhas à rotina getPassword no arquivo xlock.c, as senhs de todos os usuários que utilizam a versão cavalo-de-tróia do xlock pode ser armazenada em um arquivo para uso posterior por um invasor. As alteração são tão pequenas, que somente alguns bytes irão diferenciar a versão real da versão alterada.

Se um usuário possui um diretório home que pode ser escrito e um ./ em sua variável de ambiente PAT, ele está vulnerável a este tipo de ataque. A obtenção de senhas é conseguida pela colocação de uma versão "trojan" do Xlock no diretório HOME do usuário e pelo aguardo de uma invocação. A funcionalidade do Xlock original está contida na versão "trojan". A versão "trojan" pode até mesmo destruir-se após uma tentativa com sucesso, e o usuário não irá saber que sua senha foi capturada.

O xlock, como todo programa que solicita senha, deve ser tratado como suspeito se aparece em locais em que não deveria estar, como o seu próprio diretório $HOME.

Logins baseados no X "spoofados" são um pouco mais complicados para um invasor conseguir fazer. Ele deve simular a tela de login do programa de login que é executado pelo XDM. A única forma de garantir que seja executado o programa de login XDM correto (se você uqer ser realmente paranóico) é reinicializando o X-terminal, com a combinação de teclas apropriada para o terminal em questão.

Ferramentas de Segurança do X - xauth MIT-MAGIC-COOKIE

Para evitar a ocorrência de conexões não autorizadas a seu display X, o comando xautho para conexões criptografadas X é astane usado. quando você faz o login, o xdm cria um arquivo .Xauthority em seu diretório $HOME. Este arquivo é binário, e só pode ser lido via o comando xauth. Se você executar o comando

$ xauth list

você obtem uma saída tipo:

your.display.ip:0 MIT-MAGIC-COOKIE-1   73773549724b76682f726d42544a684a
nome do display   tipo de autorização      chave

O arquivo .Xauthority às vezes contém informações de sessões antigas, mas isto não é importante, já que uma nova chave é criada a cada sessão de login. Para acessar um display com o xauth ativo, você deve ter a chave de acesso atual.

Se você quer abrir seu display para conexões de um usuário em particular, você deve informá-lo sua chave. Ele deve então executar o comando

$ xauth add your.display.ip:0 MIT-MAGIC-COOKIE-1 73773549724b76682f726d42544a684a

Agora, somente aquele usuário (além de você mesmo) pode conectar-se ao seu display. O Xauthority é simples e poderoso, e elimina muitos dos problemas de segurança do X.

Comentários Finais

Os agradecimentos devem ir a Anthony Tyssen por enviar a mim suas informações acumuladas nos problemas de segurança do X de várias discussões da USENET. Espero que alguém encontre alguma informação útil neste texto. Ele é liberado para a net.community com a idéia de que irá ajudar ao usuário entender os problemas de segurança relacionados ao uso do X Window. Questões e comentários podem ser enviados aos seguintes endereços: runeb / cF - http://www.cs.uit.no/~runeb.

1