Format Strings





            Este post aborda a vulnerabilidade conhecida por “Format Strings”, que pode ser utilizada na exploração de binários em sistemas Unix.
O objetivo não é ensinar ao leitor como explorar a vulnerabilidade, mas sim alertar que implementações desenvolvidas de maneira incorreta podem se tornar um crítico vetor de exploração, comprometendo drasticamente a segurança da aplicação.
O conteúdo aqui apresentado não é “entry level” e, embora a postagem tenha sido elaborada buscando a utilização de uma linguagem facilitada, o assunto depende da assimilação prévia de conceitos implícitos ao tema.  
           

O que é String?

É a identificação de uma sequência de caracteres, geralmente usada para representações de texto. Em linguagem C, não existe um tipo de dado que declare nativamente uma string, na verdade, trata-se de um vetor do tipo “char”, obrigatoriamente terminado em um caractere nulo “\0”, que identifica o final da string.

            char nome[80];

A declaração da string acima cria um vetor de caracteres com 81 posições, considerando a necessidade da indicação do final da string ser referenciada por um caractere nulo. Dessa maneira, o armazenamento do nome deve ocupar as 80 posições e ser finalizado por “\0” na posição 81.


Entendendo a Vulnerabilidade

            Como em grande parte das vulnerabilidades, a exploração de Format Strings é diretamente relacionada a um erro de implementação, onde o programador não trata corretamente o “tipo” de saída da string. Por meio desta técnica é possível ganhar controle do fluxo de execução de um programa vulnerável.
Essa vulnerabilidade pode ser encontrada em funções da família printf (printf, vsprintf, fprintf, vsnpr, sprintf, vfprintf, snprintf,  vprintf) e explorada por meio do abuso dos formatadores (%d, %s, %u, %n):
Para exemplificar de maneira prática vamos ao seguinte trecho de código:

//dados de entrada
  AAAA.%x.%x.%x.%x

// recebendo valor para variável texto
  strcpy(texto, argv[1]);

// método de exibição utilizado de maneira correta
  printf("Saída: ");
  printf("%s", texto);
  Saída: AAAA.%x.%x.%x.%x 

// método de exibição utilizado de maneira incorreta
  printf("Saída: ");
  printf(texto);
  Saída: AAAA.bff6e518.0.4e91f3.41414141

Perceba que, quando a implementação é feita de maneira incorreta (vulnerável), são retornados endereços de memória em formato hexadecimal. Por meio da técnica de exploração de Format Strings, essa saída, devidamente manipulada, pode ser utilizada por um atacante para ganhar controle do fluxo de execução do programa.
Os argumentos passados para a função são inseridos na pilha em ordem reversa, no modo e operação LIFO (last in first out), logo, o trecho de código abaixo justifica essa afirmação.

printf("A eh %d e esta em %08x. B eh %x.\n", A, &A, B);
A eh 5 e esta em 71dba9d8. B eh 7.

Endereço da string formatada
Valor de A
Endereço de A
Valor de B
Fundo da Pilha
* Representação da pilha de memória

Ainda analisando a execução, se o último parâmetro for removido, a saída apresentada deve ser algo do tipo:

printf("A eh %d e esta em %08x. B eh %x.\n", A, &A);
A eh 5 e esta em bfe541d8. B e 4771d0.

            Nota-se que o valor 0x4771d0, foi despejado pois não havia um valor armazenado na pilha, logo, a resposta apresentou os dados de onde o último argumento seria armazenado.


Leitura e Escrita com Format Strings

            Por meio da manipulação dos parâmetros de formatação, essa vulnerabilidade permite que seja possível realizar procedimentos de leitura e gravação de endereços de memória arbitrários.
Utilizando o formatador %s é possível efetuar a leitura de endereços, bem como, utilizando a mesma técnica por meio do formatador %n é possível a gravação.
Por exemplo:

Leitura: Para ler a variável de ambiente “LOGNAME” (lembrando que é necessário adicionar 4 bytes devido a diferença de 2 bytes entre os nomes “poc_fms1” e “getenvaddr”):

root@kali:~ # env|grep LOGNAME
LOGNAME=root

root@kali:~# ./getenvaddr LOGNAME ./poc_fms1
LOGNAME will be at 0xbffffeac

root@kali:~# ./poc_fms1 $(printf "\xAC\xfE\xff\xbf")%08x.%08x.%08x.%s
O metodo correto:
%08x.%08x.%08x.%s
O metodo incorreto:
bfffeea0.b7fd0110.080491dd.root
[*] valor_teste -> 0x0804c02c = -72 0xffffffb8

Escrita: para exemplificar o processo de escrita, aos mesmos moldes das operações realizadas para a leitura, porém formatando a saída com %n, foi possível sobrescrever a variável valor_teste.

root@kali:~ # ./poc_fms1 $(printf "\x2c\xc0\x04\x08")%08x.%08x.%08x.%n
O metodo correto:
,%08x.%08x.%08x.%n
O metodo incorreto:
,bfffeea0.b7fd0110.080491dd.
[*] valor_teste -> 0x0804c02c = 31 0x0000001f

Obs.: é possível realizar a manipulação também alterando o tamanho do campo a ser apresentado

root@kali:~ # ./poc_fms1 $(printf "\x2c\xc0\x04\x08")%x.%x.%120x.%n
O metodo correto:
,%x.%x.%120x.%n
O metodo incorreto:
,bfffeeb0.b7fd0110.                                                                                                                 80491dd.
[*] valor_teste -> 0x0804c02c = 143 0x0000008f
*perceba a criação de linhas em branco

O formatador %n grava os dados e não apresenta nenhuma saída. Ao encontrar o formatador %n, a função grava o número de bytes que foram escritos até então no endereço do argumento da função correspondente e o operador do endereço unitário é usado para gravar os dados das variáveis.


Operações de Acesso Direto

Para “reduzir” esforços durante o desenvolvimento dos exploits que utilizam “Format String”, é possível que os parâmetros sejam acessados diretamente utilizando o sinal de “$” %n$d, conforme exemplificado abaixo:

printf("Quinto elemento: %5$d, Quarto elemento: %4$05d\n", 1, 2, 3, 4, 5, 6, 7, 8);
Quinto elemento: 5, Quarto elemento: 00004


Escritas Curtas

Um dado do tipo “short”, é uma palavra (WORD) de dois bytes e, recorrendo ao formatador %hn, esta técnica pode ser utilizada para também facilitar a exploração. A execução consiste na utilização dos formatadores para escrever um valor de quatro bytes com o uso de apenas dois parâmetros (%hn).


Conclusão

            Para que seja possível efetivar a exploração por meio da técnica de Format Strings, permitindo a possibilidade e interação do atacante com o alvo por meio de um interpretador de comandos, o uso de alguns outros recursos se faz necessário, como por exemplo a utilização de construtores e destrutores (.ctors, .dtors), ou mesmo sobrescrevendo a “Global Offset Table”. Detalhes foram suprimidos intencionalmente, considerando que este post não tem a finalidade de instruir o processo de exploração.


Referências
            http://phrack.org/issues/59/7.html
Book: Hacking, The Art Of Exploitation
Book: The Shellcoders Handbook



Vulnerabilidade Mutagen Astronomy – Linux Local Privilege Escalation



Após testes, uma equipe de pesquisadores focados em segurança cibernética veio a público com uma prova de conceito (PoC) detalhado sobre uma vulnerabilidade no kernel do Linux, que atualmente afeta as distribuições do CentOS, Debian e do Red Hat Enterprise Linux (RHEL).

A vulnerabilidade foi denominada Mutagen Astronomy e é rastreada como CVE-2018-14634. Ela foi descoberta pela equipe do Qualys Research Labs, que caracterizou essa falha de segurança como um problema de Local Privilege Escalation (escalonamento de privilégio local).

Esse tipo de vulnerabilidade exige que um invasor tenha um acesso estável (shell ou acesso físico) em um sistema vulnerável, mas é uma das falhas de segurança que pode transformar uma invasão simples em algo muito ruim para o administrador do sistema, pois ele pode ser usado para dar acesso a um intruso, fornecendo controle completo sobre os sistemas infectados.

De acordo com os pesquisadores da Qualys, o bug atual reside na função create_elf_tables () do kernel do Linux, em que um exploit habilmente criado, pode causar um estouro de buffer (buffer overflow), que executa código malicioso com privilégios de root.

A vulnerabilidade estava presente no kernel do Linux entre 19 de julho de 2007 (kernel commit: b6a2fea39318) e 7 de julho de 2017 (kernel commit: da029c11e6b1).

"Apesar de todos os kernels Linux serem tecnicamente vulneráveis, esse problema é mitigado por um patch de um ano atrás que foi desenvolvido para a maioria dos kernels de longo prazo, o que impossibilita a exploração. No entanto, o Red Hat Enterprise Linux e o CentOS não deram backport a esse patch e, portanto, são vulneráveis ​​e exploráveis", disse um porta-voz da Qualys.

Em um comunicado publicado, a equipe da Red Hat confirmou esse problema. Além disso, descobriu-se que o CVE-2018-14634 também afeta distribuições Debian mais antigas. "Este problema afeta a versão dos pacotes do kernel como fornecidos com o Red Hat Enterprise Linux 6, 7 e Red Hat Enterprise MRG 2. Futuras atualizações de kernel para Red Hat Enterprise Linux 6, 7 e Red Hat Enterprise MRG 2 irão resolver este problema" disse a equipe da Red Hat.

Até que um patch esteja pronto, a equipe de segurança da Red Hat publicou conselhos básicos de mitigação sobre como proteger sistemas vulneráveis ​​até que um patch seja lançado.
Os pesquisadores da Qualys publicaram uma descrição detalhada (ver em referências) da vulnerabilidade estranhamente chamada de Mutagen Astronomy, junto com dois PoCs [1, 2].

Referências:




https://nvd.nist.gov/vuln/detail/CVE-2018-14634

Evitando RCE por Shellshock



RCE (Remote Code Execution) – que na tradução significa execução de código remota — é a ação de um atacante ao executar códigos remotos utilizando de vulnerabilidades do sistema. Uma dessas milhares de vulnerabilidades detectadas é o Shellshock, que afetou diversas versões de sistemas baseados em linux/unix em 2014, como você pode ver no CVE.
Neste artigo, iremos discorrer como funciona o ataque na prática.
 
O que é shellshock?  

Shellshock é uma vulnerabilidade que ocorre no bash, que permite executar comandos de uma forma arbitraria, já que o ele é inserido depois que uma determinada função é definida.
Errata: No post antigo, Nova Vulnerabilidade: Shellshock, informamos que, ao executar o comando para saber se há a vulnerável, retornaria uma mensagem de erro. Na realidade não há retorno de erro, a aplicação estará vulnerável caso os dois comandos sejam executados, ou seja, ao executar:
 env x='() { :;}; echo vulneravel' bash -c "echo teste"

Se for apresentado apenas “teste”, não há vulnerabilidade. Caso seja apresentado a mensagem “vulnerável” antes de “teste” e também o “teste”, neste caso estará vulnerável.

Então como ocorre o ataque?

Vamos supor que um atacante queira explorar um servidor web e executar um comando especifico, como fazer o driver de DVD abrir. Para tal, um usuário com permissão, apenas digita /bin/eject. Mas, supondo que o servidor esteja vulnerável ao Shellshock, o atacante pode adicionar uma string () { :; };  para o /bin/bash e enviar o comando para o servidor web via HTTP. O servidor deveria receber o comando identificado pelo User-Agent. Entretanto, no caso do servidor vulnerável ao Shellshock, nada é informado.
Por exemplo, se o domínio “domínio.com.br” está vulnerável, utilizando o Curl, o ataque funcionaria assim:
curl -H "User-Agent: () { :; }; /bin/eject" http://dominio.com.br

É o suficiente para que o comando seja executado, fazendo com que o driver de DVD abra.
Isso ocorre pois o atacante modifica a origem do HTTP request e insere a string () { :; };.
Neste cenário, o User-Agent ficaria deste modo:

HTTP_USER_AGENT=() { :; }; /bin/eject

Se a variável passar pelo bash do servidor web, o Shellshock ocorre.

Qual a solução?

A solução é atualizar a versão do Bash para que o mesmo não interprete a string () { :; }; de uma maneira especial.

Depende de outros fatores...

Para que a vulnerabilidade seja explorada neste cenário, o servidor web precisa estar como root. Entretanto, basta utilizar o Shellshock com outra vulnerabilidade para consegui-la. Por exemplo, a falha da má configuração do CGI.

Mas o que é CGI? 
CGI (Common Gateway Interface) é um modulo do Apache, que permite que scripts e programas sejam executados no servidor web. Além disso, o modulo pode dar detalhes da comunicação entre o servidor web e o browser.   
Alguns exemplos de suas funções são:

·         auxiliar no processamento de dados submetidos por forms;
·         fazer as conversões de HTML para SQL;
·         converter os dados do sistema em HTML;
·         retornar o response para o cliente;
·         gerenciar contadores de acesso.

Portanto, um atacante pode usar o CGI para enviar uma determinada variável para o servidor web vulnerável por má configuração do CGI, pois o servidor utiliza o bash para interpretar a variável, que irá executar qualquer comando malicioso contido.
Sendo assim, utilizando ShellShock com o CGI mal configurado, é possível fazer interpretação de comandos no servidor alvo. 


Solução?
Para mitigação, nas configurações do apache em /etc/httpd.conf, altere o ServerTokens de FULL para PRODUCTONLY. Altere o ServerSignature de ON para OFF. Assim, irá mitigar o footprint do sistema utilizado, não deixar o diretório CGI aberto e permitir que apenas um determinado IP seja capaz de executar comandos.



Conclusão
O intuito deste artigo é mostrar, mesmo que de forma superficial, como funciona um ataque e como mitigar um ataque. Pois é possível utilizar de diversas vulnerabilidades em uma aplicação, ou mesmo em diferentes aplicações que se comunicam, para conseguir explorar um determinado alvo.



Referencias: