SQLi по прежнему в строю

Для взлома TalkTalk, который привел к краже личных данных порядка 150 000 пользователей, была использована уязвимость, обнаруженная еще до его рождения. Этим методом атаки была SQL инъекция (SQLi). В данном виде атак хакеры обычно вводят вредоносные команды в формы на веб-сайте, чтобы заставит базу сайта выдать нужные данные.

b81d15b5c854499794cc611b60fb8a8b.jpg

Такой метод использовался для воровства персональных данных сотрудников Всемирной организации здравоохранения, похищения данных Wall Street Journal и взлома сайтов американских федеральных агентств.

Это самый простой способ взломать сайт

Это выражение одного из хакеров, известного под псевдонимом w0rm и ответственного за взлом Wall Street Journal. Вторжение тогда заняло всего несколько часов.

При всей своей простоте SQLi в тоже время обладает высокой эффективности для получения цифровых данных корпораций и даже правительственных сайтов.

SQL-инъекции стали бичом для эпохи Интернета. Год за годом, они упоминаются как одни из лучших видов уязвимости безопасности, ответственных за бесчисленные краж данных в Интернете.

Джефф Форристал (Jeff Forristal), возможно, самым первым опубликовал инструкцию взлома и способа защиты сервера на Windows NT с помощью инъекций SQL в журнале для хакеров Phrack. На данный момент Джефф возглавляет должность директора по кибербезопасности в BlueBOX Security.

5f560976fac447a1a0e85baa4301ed45.jpg

SQL или Structured Query Language — язык программирования, используемый для управления базами данных. В сущности, он применяется, когда сайт должен вызвать кусок информации из своей базы данных, либо обработать ее или представить пользователю. Но Форристал пришел к выводу, что ввод определенных команд вынудит сервер показать информацию, которая на нем хранится.

Люди могут комбинировать SQL команды.


В номере Phrack за декабре 1998 года Форристэл записал о серии проблем с версией Microsoft SQL server. Когда коллега Форристэла сообщил об этом компании Microsoft,

Их ответ был весьма забавным

То что вы можете прочитать это не несет никакой угрозы, поэтому не стоит волноваться и принимать поспешные меры, чтобы это остановить.

Спустя более чем 15 лет после того, как данная уязвимость была публично описана, SQLi неоднократно занимал первое место в Топ-10 уязвимостей от OWASP, выходивших раз в три года. Open Web Application Security Project (OWASP) -некоммерческая организация, отслеживающая различные угрозы, с которыми сталкиваются веб-сайты.

c89305eadddc4d9c8feb916612ea89e8.jpg

SQL инъекции по прежнему остаются риском номер один для множества веб-проектов.

Когда вы переходите на веб-странице, то выполняете запрос, который анализируется и после этого вам предоставляются данные в соответсвии с запросом .

Мелкий пример когда приложение использует ненадежные данные в построении последующего вызова уязвимой SQL:

String query = "SELECT * FROM accounts WHERE custID='" + request.getParameter("id") + "'"; 


Точно также слепое доверие со стороны приложения к платформам может привести к уязвимым запросам.
Например, Hibernate Query Language (HQL):

Query HQLQuery = session.createQuery("FROM accounts WHERE custID='" + request.getParameter("id") + "'");


В обоих случаях, злоумышленник модифицирует значение параметра «id» в браузере, чтобы отправить: ' or '1'='1.
Например:

http://example.com/app/accountView?id=' or '1'='1


Это меняет смысл в обоих запросах, что заставляет выдать все записи из таблицы аккаунтов. Более опасные атаки могут изменять данные или даже вызывать сохраненные процедуры.

Разовая атака можем предоставить одну часть или раздел информации, а это означает, что нападавшему необходимо будет повторить такого рода запросы пока он не получит все данные из базы данных. Естественно подобный подход занимает уйму времени. Таким образом хакеры могут использовать инструменты, которые автоматизируют этот процесс, выполняя запросы вместо него. Довольно популярным инструментом для скрипт-кидди стал Havij, потому как он хорошо оптимизирован для Windows и имеет удобный GUI (графический пользовательский интерфейс). Другая часть использует сканер SQLMAP, выпущенный в 2006 году. Но более стремительно SQLMAP стал развиваться только тогда, когда в работу над ним включились Мирослав Штампар — разработчик из Хорватии и Бернардо Дамеле — консультант по ИБ из Италии. Этот сканер подобно боту поисковой системы ищет формы для ввода на веб-странице и представляет формы с данными, которые могли бы вызвать синтаксическую ошибку MySQL.

Пример того как Трой Хант (Troy Hunt), основатель haveibeenpwned.com, учит своего сына использовать SQLi с помощью Havij.

Поиск жертвы для нападения также просто автоматизировать. Как правило злоумышленники используют популярнейший поисковик Google для поиска URL адресов, которые связываются с скриптами уязвимыми к SQLi. У нападающего существуют скрипты, автоматически проверяющие все URL на предмет уязвимости. Этот процесс настолько прост, что ему можно обучить даже ребенка. Также существует достаточно учебных пособий на YouTube о том, как совершить нападение SQLi.

Но существуют готовые решения, чтобы остановить атаки SQLi и они могут быть развернуты разработчиками сайтов для избежания утечки потребительских или корпоративных данных. Эти решения существуют на протяжении многих лет.

Один из наиболее простых способов решения данной проблемы — это применение «подготовленных запросов». В таком случае команды SQL, управляющие базой данных, не могут быть отправлены через форму входа пользователя.

Подготовленные запросы используются для выполнения тех же (или аналогичных) SQL-запросов неоднократно с высокой эффективностью.

Подготовленные запросы в основном работают так:
1. Подготовка: шаблон SQL-запроса создается и отправляется в базу данных. Некоторые значения не указываются, называются параметрами и маркируются »?». Пример: INSERT INTO MyGuests VALUES (?, ?, ?)
2. Базе данных разбирает, компилирует и выполняет оптимизацию запросов на шаблоне SQL-запроса и сохраняет результат без его выполнения.
3. Выполнение: Позднее приложение связывает значения с параметрами и база данных выполняет запрос. Приложение может выполнить запрос столько раз, сколько это потребуется с различными значениями.

По сравнению с выполнением непосредственных SQL-запросов, у подготовленных запросов есть три основных преимущества:

  • Подготовленные запросы уменьшают время парсинга, так как подготовка запроса делается только один раз (хотя сам запрос может выполнятся несколько раз).
  • Общие параметры экономят канал и трафик к серверу, так как нужно отправить только параметры, а не весь запрос целиком.
  • Подготовленные запросы являются очень полезными против инъекций SQL, поскольку значения параметров, которые передаются позже с помощью другого протокола, не будут полностью соответствовать отправленным. Если исходный запрос отличается от запроса с внешнего ввода, SQL инъекции не будет выполнена.


Подготовленные запроса в MySQLi

connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// prepare and bind
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);

// set parameters and execute
$firstname = "John";
$lastname = "Doe";
$email = "john@example.com";
$stmt->execute();

$firstname = "Mary";
$lastname = "Moe";
$email = "mary@example.com";
$stmt->execute();

$firstname = "Julie";
$lastname = "Dooley";
$email = "julie@example.com";
$stmt->execute();

echo "New records created successfully";

$stmt->close();
$conn->close();
?>


В данном SQL вопросительный знак (?) выставлен там, где мы хотим поместить integer, string, double или blob значение.

"INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)"


Теперь давайте посмотрите на функцию bind_param ():

$stmt->bind_param("sss", $firstname, $lastname, $email);


Эта функция связывает параметры с SQL-запросом и говорит базе данных какие нужно ввести параметры. Аргумент «sss» ограничивает тип данных, которые могут быть заданы для перечисленных параметров.

Аргумент может быть одним из четырех типов:

i — integer
s — double
s — string
b — BLOB

Рассказывая MySQL какой тип данных ожидать, мы минимизируем риск инъекций SQL.

Подготовление запроса в PDO

setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // prepare sql and bind parameters
    $stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) 
    VALUES (:firstname, :lastname, :email)");
    $stmt->bindParam(':firstname', $firstname);
    $stmt->bindParam(':lastname', $lastname);
    $stmt->bindParam(':email', $email);

    // insert a row
    $firstname = "John";
    $lastname = "Doe";
    $email = "john@example.com";
    $stmt->execute();

    // insert another row
    $firstname = "Mary";
    $lastname = "Moe";
    $email = "mary@example.com";
    $stmt->execute();

    // insert another row
    $firstname = "Julie";
    $lastname = "Dooley";
    $email = "julie@example.com";
    $stmt->execute();

    echo "New records created successfully";
    }
catch(PDOException $e)
    {
    echo "Error: " . $e->getMessage();
    }
$conn = null;
?>

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

Если SQLI настолько проста, что даже ребенок может это сделать. И решения довольно простое. Но почему тогда атаки на основе SQLI все еще успешны?

Любой серьезный программист должен знать о SQLi, но по факту найти действительно хорошего программиста на зарубежном рынке — задача не из легких. Этому есть подтверждение из личных опыта. Мой знакомый почти год назад ушел работать в зарубежный проект. Он считал себя достаточно посредственным программистом (к слову, точно также считали и его знакомые ит-специалисты, экс-коллеги). Но он был приятно удивлен тем, что на своем новом месте работы оказался лучшим. Он до сих пор на своем проекте считается высококвалифицированным специалистом. Именно по-этому зарубежные компании нанимают посредственных программистов, даже если те не имеют представления о вариантах смягчения базовых видов уязвимости.

Но и в добавок к этому, под давлением своего высшего руководства, такие программисты разрабатывают более функциональное программное обеспечение, а не более защищенное.

В конечном счете ответственность за безопасность этих сайтов и данные, которые они содержат, сводятся к самим веб-разработчикам.

© Habrahabr.ru