Unconfigured Ad Widget

Collapse

Anúncio

Collapse
No announcement yet.

Vulnerabilidades Web Explicadas

Collapse
X
 
  • Filter
  • Tempo
  • Show
Clear All
new posts

  • Font Size
    #1

    Equipe de Tradução Vulnerabilidades Web Explicadas

    Introdução

    Todos sabemos que vulnerabilidades web são razoavelmente comuns hoje em dia. Elas variam entre
    SQL Injection, XSS, CSRF etc. Neste artigo mostrarei exemplos básicos das vulnerabilidades mais
    comuns que você encontrará em páginas web - especialmente WordPress.


    1. DoS (Denial of Service)

    A negação de serviço ocorre por várias razões, mas não descreverei nada relacionado a atacantes
    tentando um DoS contra uma paágina web específica com um Botnet de computadores comprometidos, mas
    irei descrever como um vulnerabilidade de DoS pode ocorrer ao se programar.

    Normalmente são erros lógicos que criam um cenário que possibilita o DoS em um aplicação.
    Vamos usar de exemplo como cenário esse pequeno código em PHP. O código abaixo contem um erro
    lógico que pode ser exploitado para causar um DoS.


    Código PHP:
    <?php

    if(empty($_GET['file']))
      die(
    'You didn't enter the file parameter.');
     
    $file = $_GET['
    file'];

    if(!file_exists($file))
      die('
    The chosen file does not exist.');

    include($file);
    ?>

    No código acima, primeiro se testa a existência do parâmetro file. Se positivo, o programa
    le o valor armazenado no arquivo, caso contrário a aplicação é terminada com uma mensagem de
    erro que diz que o parametro file não foi inserido. Após isso, o programa ler o valor armazenado no
    parametro file e verifica se ele existe ou não. Caso não existe, denovo a aplicação termina
    com uma mensagem de erro sobre a inexístência do parametro file. Mas se o parametro file existe,
    ele é incluido na execução da aplicação. No código acima não instantâneamente evidente que
    o código contem uma vulnerabilidade que pode resultar em uma negação de serviço.

    Vamos dizer que salvamos o código acima como index.php e estamos fornecendo o valor testing.php
    no parametro file. Nesse cenário tudo corre bem desde que o arquivo testing.php exista e faça
    seu trabalho. No entanto o que acontece se nós fornecermos index.php como valor para o parametro
    file. Nesse caso, o index.php está se incluindo na execução atual, e isso se repete infinitamente,
    resultando em uma negação de serviço. Por padrão, o sistema operacional aloca tanta memória para
    cada aplicação, que, se caso a aplicação queira mais, ela é forcadamente fechada pelo sistema
    operacional. E isso é exatamente o que ocorre nesse caso. Quando index.php aloca toda a memória
    permitida o sistema operacional o termina forçadamente.

    A requisição que teriamos que mandar para a aplicação acima para forçar o DoS seria:


    GET /index.php?file=index.php HTTP/1.0


    2. SQL Injection

    Vulnerabilidades de SQLi ainda são bastante comuns hoje em dia, apesar de terem sido apresentadas
    há mais de 10 anos. A vulnerabilidade de SQLi acontece quando a aplicação não verifica os valores
    fornecidos atrás de caracteres especiais e encapsula eles, e utiliza tais valores em uma SQL
    query. Um exemplo de tal aplicação pode ser vista abaixo:


    Código HTML:
    <html>
    <body>
     
      <?php
      $show = 1;
      if(!empty($_GET['username']) and !empty($_GET['password'])) {
        $user = $_GET['username'];
        $pass = $_GET['password'];
     
        mysql_connect("localhost", "admin", "admin");
        mysql_select_db("db");
        $result = mysql_query("SELECT * FROM users WHERE username='".$user."' 
          AND password='".$pass."';");
        $row = mysql_fetch_row($result);
        if($row) {
          echo "Welcome user: ".$user;
          $show = 0;
        }
      }
    ?>
     
    <?php if($show) { ?>
    <form action="#">
      Username: <input type="text" name="username" /><br />
      Password : <input type="password" name="password" /><br />
    </form>
    </body>
    </html>
    Podemos ver que a aplicação verifica que os parametros username e password existem e tem um
    valor correspondente. Se eles tem, os valores são passados para as variáveis $user e $password,
    respectivamente. Depois, a aplicação se conecta ao banco de dados no localhost:3306 com o
    usuário admin e a senha admin e seleciona o banco de dados db. Após o estabelecimento da
    conexão a aplicação constroi uma SQL query que inclui os valores username e password fornecidas
    sem a checagem por caracteres especiais.

    A aplicação acima é vulnerável pois não está encapsulando o valores de username e password.
    imagine que coloquemos o valor 'OR 1=1 --'nos campos de usuario e senha. Após isso a SQL
    query construída ficará da seguinte forma:


    SELECT * FROM users WHERE username='' OR 1=1--'' AND password='' OR 1=1--''

    Isso efectivamente seleciona todos os usuários da tabela users devido ao OR que foi passado
    para a aplicação. A SQL query acima é sempre verdadeira, não sendo necessário colocar um usuário
    e senha validos, e nos logará na aplicação.


    3. CSRF (Cross-Site Request Forgery)


    Vulnerabilidades de CSRF são presentes quando pode-se mandar uma solicitação para o usuário
    , que será enviada logo em seguida para o site alvo no nome de tal usuario. A solicitação executa
    determinada ação no site alvo no nome do usuário. Há duas questões que precisamos nos perguntar:

    Como podemos mandar a solicitação para o usuario?
    Que tipo de ação essa solicitação pode executar no site alvo?

    A resposta para a primeira pergunta é simples. Podemos mandar a requisição de várias formas
    nas quais o objetivo final é sempre o mesmo: o browser do usuário deve mandar a solicitação
    para o site alvo de alguma forma. Podemos mandar a solicitação para o usuário das seguintes formas:

    Caso o site alvo seja vulnerável e possamos temporariamente injetar códigos nele, nós precisamos
    construir a URL certa que será enviada para o usuario, que deverá clicar nela. Ao clicar na URL,
    a solicitação inicial será enviada, mas devido a vulnerabilidade a segunda solicitação também será
    enviada e e executará a ação por nós especificada.

    Caso o site seja vulneravel e possamos injetar permanentemente código nele, podemos simplesmente
    inserir outra solicitação no código fonte da página. Quando o usuário visitar essa página específica
    em algum momento no futuro, nossa solicitação será executada como se fosse do usuário.

    Nós também podemos construir nossa prórpria página, que temos total controle sobre. Por isso podemos
    incluir o código que fará a solicitação maliciosa no código fonte da página. Mas no final o usuario
    ainda tem que visitar a página, e devido a isso temos que mandar a ele o link de nossa própria
    página web. Quando o usuário visita a página, a solicitação será executada como se fosse do usuário.

    Podemos que ver que há várias maneiras de mandar a solicitação para o browser do usuário,
    que deve executá-la. Mas isso é apenas metade da estória; nós ainda precisamos falar sobre
    quais tipos de solicitações podem ser incluídas em uma página web. A ação solicitada pode
    ser qualquer coisa que queiramos, mas a página alvo tem de suportar a executar a ação devidamente.

    Vamos dizer que programamos a página web abaixo:


    Código HTML:
    <html>
    <body>
      <img src="http://www.anything.com/index.php?id=1000&action=up"/>
    </body>
    </html>
    Quando o usuário visitar está página, uma nova requisição será feita solicitando a index.php
    na página web "http://www.anything.com" com os parâmetros id=1000 e action=up. Agora, se essa página
    web não tiver a index.php a solicitação irá falhar. Isso significa que precisamos saber sobre
    os arquivos presentes na página web alvo, assim como os parâmetros que a página usa para fazer
    alguma ação. Desta maneira poderíamos, por exemplo, alterar o resultado de uma pesquisa, na qual nós fariamos
    um solicitação que votaria a favor do primeiro candidato da pesquisa ao invés de outro.
    Depois disso precisaríamos atrair usuários para a nossa página, assim as solicitações de votação
    seriam mandadas para a pesquisa.

    Mas isso é apenas a ponta do iceberg; imagine o que poderíamos fazer se podermos mandar solicitações
    que adicionariam outro administrador ao banco de dados, deletar todos os usuários, ou até mesmo
    mandar emails arbitrários para contatos na caixa de entrada de um usuário assinados por esse usuário, etc.



    4. XSS (Cross-Site Scripting)


    O XSS permite-nos injetar código arbitrário na página vulnerável, que pode ser usada para
    obter informações sensíveis como usernames, senhas, cookies etc. Com o ataque de XSS nós podemos
    contornar a política de "mesma origem", que está presente em todas as linguagem de scripting
    executadas client side em um browser. Um exemplo de linguagem é o Javascript. A política de
    "mesma origem" permite o browser executar o código client side apenas na página onde foi originado.

    Existem 3 tipos de ataques XSS:


    a) XSS refletido: A página web é vulnerável a ataques de XSS refletidos se aceitar o input
    do usuário e o exibir na página sem a devida validação de caracteres especiais como a barra
    ('/'), apostrofo ('"') etc. Em tais casos podemos incluir javascript na URL que mandamos para o
    usuário, que clicará no link. Assim, o Javascript incluído será executado no browser do usuário.
    O Javascript pode capturar os cookies do usuários e mandá-los para o atacante. Um exemplo de aplicação
    vulnerável a XSS pode ser visto abaixo:


    Código HTML:
    <html>
    <body>
     
    <?php
      if(isset($_GET['p'])) {
        print "V parametru p se nahaja vrednost: " . $_GET['p'];
      }
      else {
        print "Niste nastavili parametra p.";
      }
    ?>
    </body>
    </html>
    Primeiro o código verifica se o parametro p está definido e mostra o seu valor sem filtragem
    de nenhum caracter especial. Nós podemos armazenar um Javascript no valor do parametro p que
    será executado quando o usuário clicar na URL. Um exemplo de URL que contem Javascript, que
    irá exibir os cookies do usuário:


    GET /index.php?p=<script>alert(document.cookie)</script> HTTP/1.1



    b) XSS Persistente: A vulnerabilidade de XSS quando podemos armazenar código malicioso permanentemente
    na página web. Assim, nosso código será executado sempre que o usuário visitar tal página web,
    não necessitando enviar emails para os usuários para convence-los a clicar no link. Tal página
    web deve usar algum tipo de banco de dados paraarmazenar os valores fornecidos pelo usuário.
    Quando algum outro usuário visitar a página esses valores são pegos do banco de dados e exibidos
    na página web, executando o código malicioso.


    c) DOM-based XSS: ataques de DOM-based XSS ocorre quando nós mandamos uma URL maliciosa para
    o usuário, que clica nela. Mas isso não é o mesmo que o ataque de XSS, pois o website retorna
    uma resposta válida e não maliciosa. O ataque ocorre porque o site usa Javascript que utiliza
    os valores da URL. Ou seja, a resposta do site é normal, quem será explorado será o Javascript
    client-side (no browser do usuário). Um exemplo de DOM-based XSS é apresentado no código abaixo:



    Código HTML:
    <html>
    <body>
     
    <script type="text/javascript">
      p = document.location.href.substring(document.location.href.indexOf("p=")+2);
      document.write("V parametru p se nahaja vrednost: " + p);
    </script>
     
    </body>
    </html>

    Desse código fonte podemos ver que o Javascript está sendo retornado como resposta a uma solicitação.
    O Javascript primeiro le o valor do parâmetro p usado na URL e o armazena na variável p. Em
    seguida ele exibe o valor do parâmetro p. Por causa disso, o Javascript está se referindo ao
    valor armazenado no parametro p, que pode conter Javascript malicioso. Vamos supor que estamos
    executando a solicitação abaixo:


    /index.php?p=<script>alert(document.cookie)</script>



    Quando o Javascript é executado, ele irá ler o valor do parâmetro p, que é <script>alert(document.cookie)</script>
    e incluir no processamento. Dessa forma o código malicioso do parametro p será executado, mesmo
    se o website não for vulnerável ao ataque de XSS refletido ou persistente.


    5. Buffer Overflow

    Algumas vezes podemos ver programas executáveis sendo parte de aplicações fornecendo funcionalidades
    unicas. Mas mesmo que os executaveis sejam parte da aplicação web, vulnerabilidades de buffer
    overflow ainda existem. Imagina que a aplicação web está chamndo uma função do sistema para
    chamar um executável com o parametro fornecido pelo usuário. Isso não previne os buffer overflows
    que podem estar presentes no executável de transbordar as estruturas stack ou heap do programa.

    Um exemplo de programa em C que contem uma vulnerabilidade de Buffer Overflow segue abaixo:


    Código:
    void copy(char **argv) 
    {
      char array[20];
      strcpy(array, argv[1]);
      printf("%sn", array);
    }
     
    main(int argc, char **argv) 
    {
      copy(argv);
    }

    O programa aceita uma argumento de entrada, mas não verifica seu tamanho. Quando ele aceita
    o argumento, ele é passado para função copy, que copia o argumento em um buffer local com a
    função strcpy. Mas existem apenas 20 bytes reservados no array local, então se copiarmos um
    argumento mais longo que 20 caracteres, um buffer overflow irá ocorrer. Isto fará o sistema
    parar de funcionar, mas um argumento especialmente desenvolvido pode resultar na execução de
    código arbitrário no sistema alvo.


    6. Format String

    Format String é uma vulnerabilidade especial na qual o usuário pode controlar o que será fornecido
    a uma função como printf, fprintf, sprintf, snprintf, vprintf, vprintf, vsprintf and vsnprintf.
    A melhor forma de entender esse ataque é analisar um exemplo. Um código em C vulnerável a format
    string segue abaixo:




    Código:
    #include <stdio.h>
     
    int main(int argc, char **argv) 
    {
      printf(argv[1]);
      return 0;
    }

    Nós podemos ver que o programa aceita um argumento, que é diretamente passado para a função
    printf. Por padrão, o programa exibe o argumento fornecido na tela, mas o que acontece se
    colocarmos algum caractere especial que a função printf tratará diferentemente, como %n, %x
    %s. Se colocarmos o caracter especial %x, a função printf retornará 4 bytes da pilha (stack),
    se colocarmos dois %x, a função printf vai retornar 8 bytes da pilha e assim por diante. Isso
    ocorre pois chamamos a função printf sem os parametros necessarios, que deveriam estar presentes
    Mas a função não tem como saber se esses parâmetros estão presentes ou não e o próximo valor
    da pilha (onde o parametro faltando deveria estar).

    Com o %x podemos ler valores arbitrários da pilha, e com o %n podemos escrever valores arbitrários
    em um endereço arbitrário na memória. Com ambos %n e %x, podemos ter controle sobre a execução
    do programa e executar código arbitrário.



    7. Directory Traversal

    A vulnerabilidade de directory traversal pode estar presente em aplicações que permitem o usuário
    ler arquivos do sistema de arquivos, mas falha em identificar se o usuário tem permissão para
    ler tal arquivo. A vulnerabilidade geralmente está presente porque a aplicação não verifica
    qual arquivo o usuário está tentando acessar. O problema básico é que a aplicação não está checando
    se o usuário está tentando ir para o diretório acima com o uso caracteres especiais como "../"
    ou "..". Assim o usuário não consegue apenas ler arquivos no diretório permitido, mas também de
    todos os outros diretórios que a aplicação também tem acesso.

    Um exemplo de aplicação vulnerável escrita em PHP segue abaixo:



    Código PHP:
    <?php
    if(empty($_GET['file']))
      die(
    'You didn't enter the name of the file.');
     
    $file = getcwd().'
    /'.$_GET['file'];
    if(!file_exists($file))
      die('
    The filename doesn't exist.');
     
    readfile($file);
    ?>
    No código acima primeiro verifica-se se o parâmetro file existe r contem um valor. Após isso
    constroi-se o caminho completo do arquivo que estamos tentando ler com o uso da função getcwd
    que pega o diretorio atual e junta ao valor do parametro p. No final le-se o arquivo do do caminho
    construído e exibi-se para o usuário.

    O problema ocorre quando não estamos verificando a presença de caracteres maliciosos no parâmetro
    p. Isso permite atacantes atingir diretorioss acima usando a sequencia especial de caracteres
    "../" ou "..". Uma requisição que leria o arquivo /etc/shadow (arquivo que contém senhas
    criptografadas dos sistemas linux) pareceria com a abaixo:


    GET /index.php?file=../../../../etc/passwd HTTP/1.0



    8. File Inclusion


    O ataque de inclusão de arquivo é muito similar ao directory traversal. A única diferença
    é que com o directory traversal nós podemos apenas ler arquivos, mas com o file inclusion podemos
    incluir arquivos a execução da página web, logo, executando um arquivo que não poderíamos executar.

    Existem 2 tipos de ataques de inclusão de arquivo:

    LFI(Local File Inclusion): Aqui inclui-se um arquivo local a execução. Por arquivo local entende-se
    arquivos já presentes no sistema de arquivos do servidor. O ataque LFI é possível pois a aplicação
    não encapsula os dados fornecidos pelo usuário.

    RFI(Remote File Inclusion): Aqui inclui-se um arquivo remota a execução da página. Isso pode
    ocorrer se a aplicação tiver a opção de enviar um arquivo para o sistema de arquivos do servidor.
    Em tais casos, podemos enviar um arquivo malicioso do nosso cliente para o servidor e executá-lo.
    Com este ataque podemos enviar web shells maliciosas para a aplicação vulnerável e obter total
    controle sobre servidor web.

    Um exemplo de código vulnerável segue abaixo:


    Código PHP:
    <?php
    if(empty($_GET['file']))
      die(
    'You didn't enter the name of the file.');
     
    $file = getcwd().'
    /'.$_GET['file'];
    if(!file_exists($file))
      die('
    The filename doesn't exist.');
     
    include(
    $file);
    ?>
    No código acima estamos primeiramente verificando se o parametro file existe e contem algum
    valor. Depois, construimos o caminho completo para o arquivo que estamos tentando ler com
    a função getcwd que pega o diretório atual e junta ao valor do parametro p. No final inclui-se
    o arquivo do caminho construído a execução da página web.


    9. Command Injection

    A vulnerabilidade de injeção de comando pode estar presente em uma aplicação onde o usuário
    fornece valores que podem afetar o comando que será executado no servidor. Um exemplo de aplicação
    vulnerável escrita em PHP segue abaixo:




    Código HTML:
    <html>
    <body>
    <?php
      if(empty($_GET['user']))
        die('You didn't enter the name of the user.');
      $user = $_GET['user'];
      system("id $user");
    ?>
    </body>
    </html>



    No código acima primeiramente verifica-se a existência do parametro user, em caso positivo
    le-se o valor desse parametro e armazena-se o seu valor na variável $user. Depois disso, o
    comando id user é executado no sistema. A vulnerabilidade está presente pois a aplicação não
    verifica caracteres especiais nos valores fornecidos pelo usuário. Por causa disso podemos
    executar um segundo comando no sustema se passarmos um valor como esse; "root;ls -l/" no parâmetro
    user. A aplicação irá executar o seguinte comando: "id root;ls -l/". Mas devido ao ';' ser um
    separador entre dois comandos a aplicação irá executar dois comandos, um depois do outro, e
    retornar o resultado de ambos.


    10. Privilege Escalation

    Escalação de privilégios é que na qual usamos um erro lógico na aplicação para obter privilégios
    para fazer algo que supostamente não deveríamos fazer. Essa vulnerabilidade ocorre em aplicações
    que usam vários papéis de usuários, como usuário autorizado, não autorizado, administrador etc.
    É redundante dizer que alguns usuários tem mais permissões que outros. Por exemplo, o administrador
    deve ter direito de adicionar outras contas de usuários, enquanto outros usuários não devem ter
    esse privilégio. A vulnerabilidade ocorreria se um usuário pudesse criar outras contas de usuários.

    Conclusão

    Vimos que há diversas vulnerabilidades que precisamos observar ao se programar uma aplicação web.
    Nós vimos exemplos básicos das vulnerabilidades mais comuns e explicamos em detalhes para meelhor
    apresentá-las.

    Referência: Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...
    "Nobody can give you freedom.
    Nobody can give you equality or justice or anything.
    If you're man, you take it."

    Malcolm X

  • Font Size
    #2
    Breve, mas Bem bacana, parabéns !

    Comment

    X
    Working...
    X