SQL — INJECTION Урок 2. SQL — инъекции в ASP.NET

SQL   7 мая 2012  Автор статьи:  

В данном уроке создадим страницы, которые будут уязвимы для SQL инъекций и проверим работоспособность теории, которую мы прочитали в предыдущем уроке, а в следующем уроке попробуем защитить наши страницы от подобных атак.
Создадим страницу авторизации. На ней расположим два текстовых поля и кнопку войти. При нажатии на кнопку войти у нас должен запускаться скрипт, который будет проверять имя и пароль в базе данных. Для реализации данной страницы создадим следующую разметку:

Login
Password


Вот как она будет выглядеть:

Label на данной странице используется для того, чтобы узнать смог ли авторизоваться пользователей. Если да, то она показывает true, если нет, то она показывает false.
Как мы и говорили до этого, проверка имени и пароля в базе данных будут осуществляться с помощью следующего sql запроса:

SELECT * FROM Users WHERE Name = 'name' AND Password = 'password'

Теперь если запрос вернет нам больше нуля записей, то мы говорим, что пользователь прошел авторизацию. При создании запроса мы конечно должны допустить ошибку и произвести конкатенацию строк.
Поместим на страницу следующий код:

protected void btnLogin_Click(object sender, EventArgs e)
{
string connectionString = WebConfigurationManager.ConnectionStrings["ourBase"].ConnectionString;
SqlConnection con = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand("SELECT * FROM Users WHERE Name = '"+tbLogin.Text+"' AND Password = '"+tbPassword.Text+"'", con);
con.Open();
SqlDataReader reader = command.ExecuteReader();
lblInfo.Text = reader.Read().ToString();
}

Проверим этот код на уязвимость. Попробуем вместо имени написать ‘ OR 1 = 1—
SQL инъекция сработала и неизвестный злоумышленник проник в нашу систему.(Конечно же в нашей базе данных должны быть какие — то записи, а то никто не сможет проникнуть в столь неприступную систему, если не добавит туда своих записей)
Следующая страница будет заниматься тем, что выводит информацию об одной новости. В качестве параметра она принимает id записи. Для реализации данной страницы нам достаточно будет один label, который будет выводить новость, в случае, если такая новость есть и нет данных в противном случае.




Код страницы:

protected void Page_Load(object sender, EventArgs e)
{
String ID = Request.QueryString["id"];
if (ID == null)
{
ID = "0";
}
string connectionString = WebConfigurationManager.ConnectionStrings["ourBase"].ConnectionString;
SqlConnection con = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand("SELECT * FROM News WHERE ID =" + ID , con);
con.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.Read())
{
lblInfo.Text = reader.GetInt32(0).ToString() + reader.GetString(1) + reader.GetString(2);
}
else
{
lblInfo.Text = "Нет данных";
}
}

Таблица News содержит три поля: ID, Title и Text, также как и в предыдущем уроке. Попробуем начать атаку SQK инъекцией на эту страницу. Для начала проверим отображаются ли ошибки на сервере. Для этого добавим кавычку после id. В зависимости от настроек сайта вам либо отобразиться, либо нет информация об ошибке, но так как я работаю под localhost в Visual Studio, то все ошибки мне отображаются. Дальше попробуем вместо номера просунуть какое — нибудь вычисляемое выражение. Например 1+1 Мы видим, что ASP.NET выводит ошибку, а символ плюса куда — то делся, соответственно запрос стал неверным с точки зрения sql. Попробуем другое выражение со знаком минус, например 2-1. Запрос выполнился отобразив новость с id = 1. То, что у нас сработала данная подстановка свидетельствует о наличии sql инъекции на данной странице. Продолжим процесс исследования сайта на предмет внедрения sql кода. Для этого попробуем узнать сколько параметров отображается. Попробуем как и в предыдущем уроке выяснить это с помощью UNION. Для этого попробуем объединить null. Тогда наш параметр будет иметь вид: id=-1 UNION SELECT null
Мы получаем ошибку исполнения. Нам говорят о том, что использовать null плохо. На всякий случай попробуем три null(так как у нас три параметра передается в select запросе). И опять нас ждет такая же ошибка. Попробуем заменить null на 1. В этом случае нам придется чуть чуть поиграться с параметрами, подобрав все так, чтобы там, где находиться число единица была без кавычек, а где строковой в кавычках. Для того, чтобы вывести три единицы на странице нужно передать следующий параметр:id=-1 UNION SELECT 1, ‘1’, ‘1’
Теперь вместо двух строковых полей выведем не единицы, а имя и пароль из таблицы Users:id=-1 UNION SELECT 1, Name, Password FROM Users
Теперь злоумышленник сможет узнать все имена и пароли пользователей.
Создадим страницу на которой пользователь сможет регистрироваться. Она будет состоять из двух текстовых полей и кнопки зарегистрироваться.

Login
Password


При регистрации нового пользователя опять воспользуемся сложением строк. Тогда наш запрос будет иметь следующий вид:

INSERT INTO Users (Name, Password, ROLE) VALUES (myname, mypassword, 0)


protected void btnRegistr_Click(object sender, EventArgs e)
{
string connectionString = WebConfigurationManager.ConnectionStrings["ourBase"].ConnectionString;
SqlConnection con = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand("INSERT INTO Users (Name, Password, ROLE) VALUES ('" + tbLogin.Text + "', '" + tbPassword.Text + "', 0)", con);
con.Open();
lblInfo.Text = command.ExecuteNonQuery().ToString();
}

Label на этой странице показывает количество записей, которое было вставлено. Попробуйте сами найти и использовать уязвимость на этой странице.
В следующем уроке мы узнаем как защититься от этих уязвимостей и попробуем найти новые, чтобы злоумышленники не смогли эксплуатировать наши сайты.

Научиться программировать

  • на Delphi

  • на Java

  • на C++