Busca

A emoção dos jogos na sua casa!

Bem vindo ao blog aqui será divulgado o que existe de mais atual no mundo dos jogos.

Evolua com a tecnologia! O seu mundo é aqui!

Tudo sobre tecnologia, hardware, rede, próximos a você em um piscar de olhos.

Os dispositivos móveis diminuiram, e a sua liberdade aumentou!

Agora você pode ficar por dentro das maiores inovações dos novos celulares, tablets e notebooks.

Fique por dentro das atualizações do seu sistema operacional favorito!

Os sistemas operacionais estão mais estáveis e confiáveis com o passar do tempo. saiba tudo sobre o windows, osx e linux.

segunda-feira, 27 de abril de 2009

Evitando SQL INJECTION

O sql injection, retorna valores das tabelas do banco de dados.
Conhecida como tabela query.

Ele é usado como ataque, para retornar senhas e logins de sites vulneráveis.
Só é retornado os valores caso o sistema de banco de dados esteja vulnerável, o banco de dados em si não é responsável por isso, e sim o código php mal escrito.

Veja um código vulnerável:

SELECT * FROM users WHERE id = $_GET['id']


O metodo $_GET, permite que você pegue no servidor os dados dos usuários, como o GET, tem o POST, para login bypass.

O que acontece ao digitar no navegador :

http://site.com/vuln.php?id=1 and 1=1

Id:1
Username:admin

Será retornado os dados dos usuários, caso nada seja retornado o servidor não esta vulnerável.

Eu recomendo como source de blog o e107, a uns tempos atrás passei horas procurando por vulnerabilidade nos arquivos php e não encontrei nada, não coloco minha mão no fogo mas pareceu seguro.


Deixarei aqui o sql que usei para fazer os testes, basta vc inserir no seu phpmyadmin, em sql, ou salvar como database.sql e importar, tirando apenas o cabeçalho.

----------database.sql-------------------

-- phpMyAdmin SQL Dump
-- version 3.1.4
-- http://www.phpmyadmin.net
--
-- Servidor: localhost
-- Tempo de Geração: Abr 28, 2009 as 03:20 AM
-- Versão do Servidor: 5.0.51
-- Versão do PHP: 5.2.6-1+lenny2

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

--
-- Banco de Dados: `base`
--

-- --------------------------------------------------------

--
-- Estrutura da tabela `users`
--

CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL,
`username` varchar(20) NOT NULL,
`password` varchar(20) NOT NULL,
`email` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--
-- Extraindo dados da tabela `users`
--

INSERT INTO `users` (`id`, `username`, `password`, `email`) VALUES
(1, 'admin', 'secret_pass', 'admin@site.com'),
(2, 'maria', 'teste123', 'maria@site.com'),
(3, 'pedro', 'teste333', 'pedro@site.com'),
(5, 'marcos', 'gsgsdh', 'marcos@site.com');

Agora o código do arquivo vulnerável.

-------------vuln.php-------------------

as linhas:

$id = $_GET['id'];
$id_escape = addslashes($id);
$sql = mysql_query("SELECT * FROM tabela WHERE id='{$id}'");

Corrigem o sql injection.

Veja o codigo completo:


include ("config.php");
$id = $_GET['id'];
$id_escape = addslashes($id);

$sql = mysql_query("SELECT * FROM tabela WHERE id='{$id}'");


while($linha = mysql_fetch_assoc( $sql )) {
// Print out the contents of each row into a table
echo ""; 
$id = $linha['id'];
$titulo= $linha['titulo'];
echo ""; 
$texto = nl2br($linha['texto']);
echo "Titulo:$titulo
Texto:$texto";

}
?>
Para fazer o codigo do vuln.php funcionar execute: "http://localhost/vuln.php?id=1 and 1=1", os dados do banco de dados seram retornados, indicando que o servidor esta vulnerável.

Esse é o primeiro passo.

Siga os códigos que indicarei e veja como as coisas se saem, por exemplo sempre que for executado um código sql e o valor for verdadeiro, sera retornado os dados do usuário, caso seja falso, nada será retornado ou você verá um erro como se algum código estivesse errado.

http://localhost/vuln.php?id=1 and 1=1

id:1
usuario:admin

Descobrindo o número de colunas.

Para descobrir o número de colunas, você deve ir aumentando o número em ordem crescente,até retornar um valor falso assim você saberá que o último valor é o verdadeiro, por exemplo você tem 4 colunas, então os códigos devem ser digitados um por um mas no exemplo uso 1,2,3,4, para simplificar, "order by 1,2,3,4" será retornado como valor verdadeiro pois existem 4 colunas, caso você coloque 1,2,3,4,5, retornará valor falso, então sabemos que são 4 colunas.

Você deve ir mudando os números até retornar valor falso, assim descobrindo qual é o ultimo verdadeiro, conseguindo saber o número certo.
http://localhost/vuln.php?id=1 order by 1

id:1
usuario:admin


http://localhost/vuln.php?id=1 order by 2

id:1
usuario:admin


http://localhost/vuln.php?id=1 order by 3

id:1
usuario:admin


http://localhost/vuln.php?id=1 order by 4

id:1
usuario:admin
Se você colocar o order by 5 retornará valor falso descobrindo que são 4 colunas

http://localhost/vuln.php?id=1 order by 5
Sem colunas



Agora vamos aprender a corrigir a falha.


$id = mysql_real_escape_string($_GET['id']);
$sql = "SELECT * FROM users WHERE id = '".$id."'";
while ($row = mysql_fetch_array($query, MYSQL_ASSOC)) {

$res = stripslashes($row['$res']);

}

A função acima adiciona, backslashs, no servidor sql, tratando de corrigir os erros não permitindo retornar os valores do método $_GET.

Então o seu código novo e corrigido ficará assim:


------------- vuln_corrigido.php---------------


$host = 'localhost';
$dbuser = 'root';
$dbpass = 'senha_do_bando_de_dados_sql';
$dbname = 'base';


$db = mysql_connect($host, $dbuser, $dbpass);
mysql_select_db($dbname,$db);
$id = mysql_real_escape_string($_GET['id']);
$sql = "SELECT * FROM users WHERE id = '".$id."'";
$query = mysql_query($sql);
if(@mysql_num_rows($query)==0){
die('Sem colunas');
}while ($row = mysql_fetch_array($query, MYSQL_ASSOC)) {

$res = stripslashes($row['$res']);

}
$result=@mysql_fetch_row($query);

echo "ID: ".$result[0]."
";

echo "Usuario(user): ".$result[1]."
";

// echo "Password: ".$result[2]."
";

echo "";
die();
?>

-----------------------------------------
Agora você pode testar os códigos sql citados acima, o banco de dados não irá retornar os valores guardados na tabela query.

Vamos ao teste...

http://localhost/vuln_corrigido.php?id=1 and 1=1
id:
usuario:
Nada será retornado, seu servidor não esta vulnerável a sql injection, o código foi corrigido.

Então é isso, caso tenha alguma dúvida comente que estarei solucionando seu problema em breve.


Caso encontre algum erro, comente ou mande um e-mail para:camexlinux09[at]gmail[dot]com









Twitter Delicious Facebook Digg Stumbleupon Favorites More