Suas aplicações são seguras?

Conheça a Conviso!

Hackeando o post “Hacking com controle remoto da sua TV”

 Ocorreu uma discussão extremamente interessante sobre o artigo anterior que escrevi, chamado “Hacking com controle remoto da sua TV”. No post apresentei um código com a funcionalidade de mapear teclas de um controle remoto e esse código teria uma possível vulnerabilidade na função “serialread()”.

No seguinte código, não temos limitação para escrita na variável “buf” e dependendo de alguns fatos isso poderia resultar em um stack buffer overflow.

Embora seja visível um possível Buffer Overflow, precisamos ter uma prova de conceito. A entrada vem de uma comunicação “serial” e isso seria um problema para testar nossos “payloads”. Uma opção seria programar um “fuzzer” no arduino, assim como na imagem abaixo.

O exemplo acima envia uma sequência crescente de caracteres ‘A’, mas no nosso caso, enviando uma “string” única longa já demonstra o problema de corrupção de memória.

 Compilando o código com adição do argumento “-g” e “-fno-stack-protector”, depois rodando com GDB, podemos ver os seguintes detalhes.

 

Ao enviar uma string contendo 64 letras ‘A’ concatenadas com 10 letras ‘B’, temos então um crash. Ao ver o valor de “fd”, vamos notar seu valor ser “66” ao invés de “8”. Podemos ver que foi possível mudar o valor de “fd”, entretanto isso não é o suficiente para conseguir execução de código. Logo de forma conseguir mais informações, resolvi testar com a ferramenta “pmcma”.

( https://github.com/toucan-system/pmcma )

Embora seja evidente o problema, não pareceu ser explorável, mesmo podendo escrever no endereço de retorno da função “main()” , não foi possível fazer algo por conta da função “exit()”.

De forma mitigar o ocorrido, podemos seguir o seguinte exemplo para limitar o buffer no código:

 

https://github.com/CoolerVoid/arduino_ppt_walk/blob/master/IR_remote.c

Código teve adição da variável “max”, trabalhando em conjunto com variável “ i ”, para contar a leitura dos elementos do buffer, só então limitar o loop até o valor da variável “max”.

Então podemos chamar a função da seguinte forma “serialread(fd,buffer,’n’ ,62);”, repare o último argumento, variável “max”, este valor seria responsável para definir o limite no buffer, fazendo lembrar funções do OpenBSD como strlcpy() e strlcat(), que também necessitam do tamanho do buffer para limitação.

Exemplo de um “Overflow”

Talvez poder escrever um valor em uma variável não pareça tão útil no nosso caso, entretanto em alguns casos pode nos levar para algum graal, tenha em mente um sistema qualquer,em um cenário bem menor, onde temos seguinte código:

 

Embora seja teoricamente impossível fazer o programa mostrar a mensagem “Welcome to MaTriX Ne0 !”, pelo simples fato de não ter nada na variável “auth”, notamos a variável “login” recebendo um valor que não foi limitado, logo se o valor ultrapassar 12 caracteres podemos ter problemas.

Explorando essa vulnerabilidade entorno da variável “login”, logo acabamos escrevendo na variável “auth” qualquer valor, isso ocorre pois a pilha(stack) cresce ao contrário.

 

 

Além de fazer isso, seria interessante ver se foi escrito algo na “EIP”(instruction pointer),se sim tentar algo como “ret2libc”.

 

Conclusão

Concluímos então, que até mesmo entradas via serial podem ser suscetíveis a alguma vulnerabilidade, por este fato todas entradas de dados devem ser limitadas para evitar problemas de corrupção de memória.

Originalmente postado no Blog da Conviso Application Security – Siga-nos no Twitter @conviso Google+

Tags

Um comentário

Deixe um comentário

topo
%d blogueiros gostam disto: