Utilize este identificador para referenciar este registo: http://hdl.handle.net/10451/39907
Título: Generating software tests to check for flaws and functionalities
Autor: Araújo, Francisco João Guimarães de Almeida
Orientador: Neves, Nuno Fuentecilla Maia Ferreira, 1969-
Medeiros, Ibéria Vitória de Sousa, 1971-
Palavras-chave: Fuzzing
Detecção de vulnerabilidades
Testes de cobertura
Testes de software
Segurança no Software
Teses de mestrado - 2019
Data de Defesa: 2019
Resumo: O rápido crescimento da complexidade de software unido com a grande necessidade de software no dia a dia causou uma exigência para testar os mesmos de modo a conseguir garantir um certo nível de qualidade, funcionamento e segurança. Por exemplo, tanto o carro que conduzimos hoje como o frigorifico que usamos para manter a temperatura desejada dos nossos alimentos, requer software de tal complexidade que quando postos sobre alto stress, poderiam apresentar algum tipo de bug. No caso desse bug ser uma vulnerabilidade, e, por conseguinte, poder ser explorada, seria capaz de por vidas em perigo e mesmo causar danos financeiros no valor de milhões de euros. Essa vulnerabilidade conseguiria, por exemplo, criar a hipótese ao atacante de tomar controlo do carro ou, no caso do frigorifico, aumentar a temperatura fazendo com que a comida se estrague. Não obstante a isso, depois de essas vulnerabilidades terem sido descobertas, é necessário iniciar um processo de correção do software, custando tempo e dinheiro. A complexidade do software cresce quando é necessário criar variantes das aplicações a partir de diversos componentes de software, como acontece em sistemas embebidos. Tal complexidade dificulta o teste e a validação do software para as funcionalidades que foi desenhado, podendo aumentar também o número vulnerabilidades de segurança. Estas vulnerabilidades podem permanecer ocultas durante vários anos em qualquer programa, independentemente de quantos testes foram executados para tentar assegurar a sua qualidade e segurança. Isto é tanto devido à eficiência destes testes que podem ser de uma qualidade limitada, bem como ao curto tempo disponível para garantir a correta funcionalidade. Um atacante externo, ao contrário, possui tempo teoricamente ilimitado para explorar o software quando este já se encontra no mercado. Vulnerabilidades são a principal causa de problemas de segurança e o foco principal quando os atacantes estão a tentar explorar o sistema. Estes, podem também causar diversos tipos de danos ao sistema e aos stockholders da aplicação, como por exemplo o dono da aplicação e os utilizadores. Uma distinção importante é que nem todos os bugs são vulnerabilidades. Uma vulnerabilidade tem de ser explorada de modo a possibilitar a corrupção do comportamento normal do programa, levando a um estado erróneo deste. De modo a conseguir tomar partido de um pedaço de software, os atacantes externos necessitam apenas de conseguir encontrar uma vulnerabilidade. No entanto, os testes desenvolvidos pelos responsáveis pela qualidade de segurança têm de encontrar inúmeros. Como resultado disto, hoje em dia as companhias gastam recursos em termos de custo e de tempo para conseguirem melhorar o processo de verificação e validação de software, por forma a tentar garantir o nível de qualidade e segurança desejado em qualquer dos seus produtos. No entanto, como acima referido, os recursos e tempo são limitados nos testes, fazendo com que vários bugs e vulnerabilidades possam não ser detetados por estes testes, mantendo-se ainda nos produtos finais. Embora já existam ferramentas automáticas de validação de segurança, não existe nenhuma ferramenta que possibilite a reutilização de resultados de testes entre versões de aplicações, de modo a validar estas versões e variantes da maneira mais eficiente possível. Validação de Software é o processo de assegurar um certo nível de confiança, que o software corresponde às espectativas e necessidades do utilizador e funciona como é suposto, não tendo nenhuma incoerência de comportamento e tendo o menor número de bugs possível. Neste contexto, cada teste examina o comportamento do software em teste de modo a verificar todas as condições mencionadas anteriormente e contribui para aumentar a confiança no sistema em si. Normalmente, esta verificação é feita com conhecimento à priori do programa a ser testado. Isto, no entanto, é um processo muito lento e pode ser sujeito a erros humanos e suposições sobre o programa a ser testado, especialmente se forem efetuadas pela mesma pessoa que fez o programa em si. Existem várias técnicas para testar software de maneira rápida, automática e eficiente, como por exemplo fuzzers. Fuzzing é uma técnica popular para encontrar bugs de software onde o sistema a ser testado é corrido com vários inputs semivalidos gerados pelo fuzzer, isto é, inputs certos o suficiente para correr no programa, mas que podem gerar erros. Enquanto o programa está a ser submetido a todos os testes, é monitorizado na espectativa de encontrar bugs que façam o programa crashar devido ao input dado. Inicialmente, os fuzzers não tinham em consideração o programa a ser testado, tratando-o como uma caixa preta, não tendo qualquer conhecimento sobre o seu código. Assim, o foco era apenas na geração rápida de inputs aleatórios e a monitorização desses inputs na execução do programa. No entanto, estes poderiam levar muito tempo para encontrar bugs somente atingíveis após certas condições logicas serem satisfeitas, as quais são pouco prováveis de ser ativadas com inputs aleatórios. A fim de resolver esse problema, um segundo tipo de fuzzers foi desenvolvido, whitebox fuzzers (fuzzers de caixa branca), que utilizam inputs de formato conhecido de modo a executar de maneira simbólica o programa a ser testado, guardando qualquer condição lógica que esteja no caminho de execução de um input, para depois as resolver uma a uma e criar novos inputs a partir das soluções dessas condições. No entanto, a execução simbólica é bastante lenta e guardar as condições todas leva a uma explosão de condições a serem resolvidas perdendo muito tempo nelas. De modo a resolver estes problemas com o whitebox fuzzers (fuzzers de caixa branca), foram criados greybox fuzzers, uma mistura dos dois tipos de fuzzer descritos anteriormente que usa instrumentação de baixo peso para ter uma ideia da estrutura do programa sem necessitar analise previa causando muito tempo nessa instrumentalização, mas compensado com a cobertura devolvida. No entanto, não existe nenhuma ferramenta, ou fuzzer, que consiga usufruir de informação obtida de testes realizados a versões mais antigas de um dado software para melhorar os resultados dos testes de uma versão do mesmo software mais recente. Hoje em dia, dois produtos que partilham funcionalidades implementadas de maneira semelhante ou mesmo igual irão ser testadas individualmente, repetindo assim todos os testes que já foram realizados no outro programa. Isto representa, claramente, uma falta de eficiência, perdendo tempo e dinheiro em repetições de testes, enquanto outras funcionalidades ainda não foram testadas, onde provavelmente podem existir vulnerabilidades que continuam por não ser descobertas. Este trabalho propõe uma abordagem que permite testar variantes ainda não testadas a partir de resultados das que já foram avaliadas. A abordagem foi implementada na ferramenta PandoraFuzzer, a qual tem por base a aplicação de fuzzing American Fuzzy Lop (AFL), e foi validada com um conjunto de programas de diferentes versões. Os resultados experimentais mostraram que a ferramenta melhora os resultados do AFL. A primeira etapa consiste na compreensão das várias vulnerabilidades comuns em programas desenvolvidos em C/C++ e os modos mais comuns de detetar e corrigir tais vulnerabilidades. A segunda etapa deste projeto é a implementação e validação da ferramenta. Esta ferramenta vai ser construída sobre um Fuzzer guiado por cobertura já existente, AFL, e segue um princípio semelhante. A terceira etapa deste projeto consiste na avaliação da ferramenta em si, usando várias medidas de comparação e foi validada com um conjunto de programas de diferentes versões. Os resultados experimentais mostraram que a ferramenta melhora os resultados do AFL.
Industrial products, like vehicles and trains, integrate embedded systems implementing diverse and complicated functionalities. Such functionalities are programmable by software containing a multitude of parameters necessary for their configuration, which have been increasing due to the market diversification and customer demand. However, the increasing functionality and complexity of such systems make the validation and testing of the software highly complex. The complexity inherent to software nowadays has a direct relationship with the rising number of vulnerabilities found in the software itself due to the increased attack surface. A vulnerability is defined as a weakness in the application that if exploitable can cause serious damages and great financial impact. Products with such variability need to be tested adequately, looking for security flaws to guarantee public safety and quality assurance of the application. While efficient automated testing systems already exist, such as fuzzing, no tool is able to use results of a previous testable programme to more efficiently test the next piece of software that shares certain functionalities. The objective of this dissertation is to implement such a tool that can ignore already covered functionalities that have been seen and tested before in a previously tested program and give more importance to block codes that have yet to been tested, detect security vulnerabilities and to avoid repeating work when it is not necessary, hence increasing the speed and the coverage in the new program. The approach was implemented in a tool based on the American Fuzzy Lop (AFL) fuzzing application and was validated with a set of programs of different versions. The experimental results showed that the tool can perform better than AFL.
Descrição: Tese de mestrado, Engenharia Informática (Engenharia de Software) Universidade de Lisboa, Faculdade de Ciências, 2019
URI: http://hdl.handle.net/10451/39907
Designação: Mestrado em Engenharia Informática (Engenharia de Software)
Aparece nas colecções:FC-DI - Master Thesis (dissertation)

Ficheiros deste registo:
Ficheiro Descrição TamanhoFormato 
ulfc125550_tm_Francisco_Araújo.pdf1,8 MBAdobe PDFVer/Abrir


FacebookTwitterDeliciousLinkedInDiggGoogle BookmarksMySpace
Formato BibTex MendeleyEndnote 

Todos os registos no repositório estão protegidos por leis de copyright, com todos os direitos reservados.