Archive for category Security

Gestão de Passwords (KeePass)

Um post rápido sobre um software (KeePass) para gestão de password’s, que utilizo à algum tempo, e que sem dúvida veio facilitar e muito a minha vida.

Aspecto gráfico do KeePass

Aspecto gráfico do KeePass

Além de seguro é muito fácil de utilizar.

O donwload pode ser efectuado aqui: http://keepass.info/download.html

Tags: , ,

SQL Injection: segurança de aplicações Web

Na semana passada ao navegar por um site, lembrei-me de fazer um pequeno teste à segurança do mesmo e para minha surpresa, ou não, o site era vulnerável a ataques do tipo sql injection.

Depois de ter enviado um e-mail aos responsáveis do site a avisar e de eles terem corrigido o problema, lembrei-me de falar um pouco sobre este tema.

O que é que são ataques do tipo SQL Injection?

Basicamente são ataques que exploram o facto as instruções SQL serem criadas dinamicamente com os valores dos inputs (formulários / querystring), sem que estes sejam devidamente tratados. Estes ataques tornam possível executar código sql, tal como U_PDATE, I_NSERT, D_ROP, etc., e até executar programas no servidor web!

Mas como é que funciona?

Vou tentar mostrar como é que o SQL Injection funciona através  de um exemplo muito simples.

Para isso vou criar uma página de autenticação de utilizadores feita em PHP e MySQL.
Resumidamente vou ter:

  • uma base de dados MySQL com uma tabela “utilizadores”;
  • um ficheiro em php (login.php) onde vou ter o formulário HTML e o código PHP para validar os utilizadores na base de dados.

O aspecto da página login.php será qualquer coisa deste género:

sqlInjection-login-vazio

Formulário de Login (login.php)

Passando à parte prática

Neste exemplo, a construção da instrução SQL é feita de forma dinâmica, utilizando os valores dos formulários sem qualquer tipo de validação.
Temos então que:

$sql="S_ELECT id F_ROM utilizadores WHERE login='".$_POST["utilizador"]."' and password='".$_POST["password"]."'";

Se no formulário introduzirmos os dados:  “admin” e “1234“, a nossa instrução sql vai ficar:

S_ELECT id F_ROM utilizadores WHERE login='admin' and password='1234'

Aparentemente até aqui não existe qualquer problema. Só se adivinharmos o utilizador e a password é que vamos conseguir efectuar o login com sucesso.

O problema começa quando começamos a utilizar caracteres especiais do sql (que podem variar consoante a base de dados) nos inputs.
Por exemplo: vamos ver o que acontece se introduzirmos  no utilizador o seguinte texto:

 xpto' or 1=1#

O SQL resultante seria:

S_ELECT id F_ROM utilizadores WHERE login='xpto' or 1=1#' and password='1234'

Neste caso estou a utilizar dois caracteres especiais. a pelica “  ” e o cardinal “  # “.
O 1.º serve para delimitarmos campos do tipo “texto”.
O 2.º serve para fazer comentários.

Assim sendo, como carácter # é um carácter especial ( carácter p/ comentários), tudo o que vier depois do # vai ser ignorado pelo motor da BD. Ficamos então com:

S_ELECT id F_ROM utilizadores WHERE login='xpto' or 1=1#

Se analisarmos o sql vemos que além de termos ignorado todo o código sql que vier depois do #, estamos também a inserir a condição “ OR 1=1 “. Como esta condição é sempre verdade (1=1), o resultado da pesquisa vai devolver sempre pelo menos um id (a não ser que a tabela utilizadores esteja vazia).
Isto é, apesar de até poder não existir nenhum utilizador com o login=xpto, 1 é sempre igual a 1 :)

Outro código que podem experimentar é:

 xpto' or 1=1 limit 1#

Porquê o “limit 1″?
porque desta forma limitamos o n.º de resultados a 1.

Então mas porque é que isso é importante?
Pode ser ou não. Depende da forma como o programador está a validar o resultado da query à base de dados.
Se o programador tivesse feito qualquer coisa deste género:


// ligação à base de dados
 mysql_connect("localhost", "root", "******")or die("cannot connect");
 mysql_select_db("junkDB")or die("cannot select DB");
 // construção da instrução sql
 $sql="S_ELECT * F_ROM utilizadores WHERE login='".$_POST["utilizador"]."' and password='".$_POST["password"]."'";
 // execução da instrução sql
 $result=mysql_query($sql);
 // variável que diz o n.º de resultados obtidos
 $count=mysql_num_rows($result);

 // se o n.º de resultados for igual a 1, então é porque os dados introduzidos
 // no formulário são válidos. Isto é, existe um utilizador com o login e password
 // iguais aos introduzidos no formulário
 if($count==1) {
    echo "Dados correctos!";
 }
 else{
    echo "Dados incorrectos!";
 }

com o código:

 xpto' or 1=1#

Só iríamos conseguir “entrar” caso existisse apenas 1 registo na tabela utilizadores.
Bastava a tabela ter dois utilizadores para já não conseguirmos “entrar”.
Ao utilizarmos o “limit 1″ estamos a dizer que só queremos 1 registo. Logo a condição ($count==1) vai ser sempre verdadeira.

Código Necessário para simular este exemplo:

Criar a tabela “utilizadores”:

--
-- Table structure for table `utilizadores`
--
C_REATE TABLE IF NOT EXISTS `utilizadores` (
 `id` int(4) NOT NULL AUTO_INCREMENT,
 `login` varchar(65) NOT NULL DEFAULT '',
 `password` varchar(65) NOT NULL DEFAULT '',
 PRIMAR Y KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
--
-- Dumping data for table `utilizadores`
--
I_NSERT INTO `utilizadores` (`id`, `login`, `password`) VALUES
(1, 'gestor', '1234'),
(2, 'admin', '1234');

O conteúdo do ficheiro login.php é:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Login - Security test</title>
        <style type="text/css">
            /*folha de estilos básica*/
            *{font-family:verdana; font-size:12px; color:#333;}
            form{width:400px; border:2px solid #ddd;}
            form p{font-size:14px; font-weight:bold;}}
            input{ border: solid 1px #ddd; background-color:#f5f5f5;}
            label{font-weight:bold;}
            .red{color:red;}
            .green{color:green;}
            #sql{ width:400px; background-color:#336699; color:white; padding:5px; margin:10px; text-align:left;}
        </style>
    </head>
    <body>
        <center>
<!-- formulário -->
        <form name="form1" method="post" action="login.php?action=validateUser">
            <p>Acesso Reservado</p>
            <label for="username">Utilizador:</label>
            <input name="utilizador" type="text" id="username" />
            <br />
            <label for="password">Password:</label>
            <input name="password" type="password" id="password" />
            <br />
            <input type="submit" name="Submit" value="Login" />
        </form>
<!-- // formulário -->

        <?php
// "verificar" se o formulário foi submetido e validar o utilizador
            if(isset($_POST["utilizador"]) && isset($_POST["password"]) ) {

// ligação à base de dados
mysql_connect("localhost", "root", "********")or die("cannot connect");
mysql_select_db("junkDB")or die("cannot select DB");

// construção da instrução sql
// notem que estou a utilizar os inputs directamente, sem qualquer tipo de validação.
                $sql="S_ELECT * F_ROM utilizadores WHERE login='".$_POST["utilizador"]."' and password='".$_POST["password"]."'";

// execução da instrução sql
                $result=mysql_query($sql);

// variavel que diz o n.º de resultados obtidos
                $count=mysql_num_rows($result);

// se o n.º de resultados for igual a 1, então é porque os dados introduzidos
// no formulário são válidos. Isto é, existe na base de dados UM utilizador
// com o login e password iguais aos introduzidos no formulário
                if($count==1) {
                    echo "<p class=\"green\">Dados correctos!</p>";
                }
                else{
                    echo "<p class=\"red\">Dados incorrectos!</p>";
                }
                echo "<div id=\"sql\"><b>SQL:</b><br>$sql</div>";
            }
            ?>
        </center>
    </body>
</html>

Para quem quiser aprofundar os conhecimentos sobre este tema ficam aqui alguns links muito interessantes:

Notas:
  • Este exemplo é muito simples e tem como objectivo apenas mostrar o que é o sql Injection.
  • Relativamente ao site do meu teste, de referir que enviei um e-mail aos responsáveis pelo site a avisar dos problemas de segurança, tendo corrigido de imediato os problemas e agradecido o meu aviso. Gostei :)
Testing for SQL Injection (OWASP-DV-005)

Tags: , ,

Routers/Firewalls Open-Source

Ultimamente tem-se falado cada vez mais em routers/firewall’s open-source.

Um exemplo disso é o artigo “Open-source routers are becoming an option for enterprise IT” publicado na www.computerworld.com.

Fica um excerto do artigo:

Many large IT operations are extensively using open-source technology — in operating systems, applications, development tools and databases. So why not in routers, too?

It’s a question Sam Noble, senior network system administrator for the New Mexico Supreme Court’s Judicial Information Division, pondered while looking for a way to link the state’s courthouses to a new centralized case management system.

Noble wanted an affordable and customizable DSL router but found that ISP-supplied modems lacked the ability to remotely monitor local link status, a key requirement of the courts… continuar a ler

Aproveito também para enumerar algumas das soluções que já utilizei e outras que apesar de ainda não ter utilizado, têm tido um feedback positivo da comunidade:

Se quiserem experimentar algumas destas soluções e não tiverem um PC para o fazer, podem sempre utilizar uma máquina virtual: até já existem algumas prontas a usar: VmWare Virtual Appliances

Podem encontrar uma lista mais completa de soluções neste artigo da wikipedia.

A ver se um dia destes escrevo um artigo com um comparativo entre algumas destas soluções…Embarassed

Tags: , , , , , , , ,

10th Annual System Administrator Appreciation Day (SysAdminDay)

System Administrator Appreciation DayPois é, os administradores de sistemas também têm direito a um dia só deles :)

Este dia comemora-se na última sexta-feira do mês de Julho, que este ano é no próximo dia 31.

É a décima vez que se comemora o dia do Administrador de Sistemas.

http://www.sysadminday.com

Tags: