Специалисты по безопасности, пожалуй, всем уже проели плешь, говоря о том, что все данные, приходящие от пользователя, нужно тщательно проверять… Казалось бы, "азбучные истины", этому должны учить в школе :-) . Мне стало интересно: а многие ли сайты действительно защищены?

Внимание: материал предоставлен только в ознакомительных/образовательных целях! Автор не несёт ответственности за всё, что может случиться. Данная статья не должна рассматриваться, как практическое руководство по взлому; статья является обзором наиболее типичных ошибок программистов и объясняет, как именно невнимательность разработчиков может служить источником дыр безопасности.

Одна из самых распространённых атак (я не беру DoS, DDoS и иже с ними) — это SQL Injection Attack.

Как пишет Wikipedia,

Инъекция SQL (англ. SQL injection) — один из распространённых способов взлома сайтов и программ, работающих с базами данных, основанный на внедрении в запрос произвольного SQL-кода.

Инъекция SQL, в зависимости от типа используемой СУБД и условий инъекции, может дать возможность атакующему выполнить произвольный запрос к базе данных (например, прочитать содержимое любых таблиц, удалить, изменить или добавить данные), получить возможность чтения и/или записи локальных файлов и выполнения произвольных команд на атакуемом сервере.

Атака типа инъекции SQL может быть возможна из-за некорректной обработки входящих данных, используемых в SQL-запросах.

Как уже было сказано, такие атаки проходят из-за недостаточной обработки входных параметров скрипта. Нередки случаи, когда программисты-новички, полагают, что если ID записи — это число, то скрипт всегда будет получать именно число, а не строку. Простой пример реального кода:

[-]
View Code PHP
    $id = $_GET['id'];
    $query = "SELECT * FROM {$members} WHERE id = $id LIMIT 1";
    $res = mysql_query($query, $link);

Всем хорош код, когда $id — это число. Например, если скрипт был вызван "script.php?id=123", то запрос принял бы следуюший вид:

[-]
View Code MySQL
SELECT * FROM members WHERE id = 123 LIMIT 1

Всё хорошо, но встречаются нехорошие дяди, которые вместо числа могут скормить скрипту всякую каку: для данного простого примера достаточно передать скрипту в параметрах script.php?id=0%20OR%201, чтобы заставить его выбрать все записи (о том, как обойти LIMIT, чуть ниже). Фактически, запрос будет переписан в виде

[-]
View Code MySQL
SELECT * FROM members WHERE id = 0 OR 1 LIMIT 1

Так как практически всегда для ID используются автоинкрементные поля, то выражение (id = 0) будет всегда ложно. А (FALSE OR 1) — всегда истинно.

Даже если запрос содержит LIMIT, это не спасает от выборки произвольной записи: script.php?id=0%20OR%201%20LIMIT%20A,B/*%20--

Вместо A и B — значения для offset и count соответственно, например:

[-]
View Code MySQL
SELECT * FROM members WHERE id = 0 OR 1 LIMIT 5,1/*-- LIMIT 1

Что примечательно: MySQL успешно выполнит запрос не смотря на то, что комментарий-то не закрыт. А так как /* */ — многострочный комментарий, то запрос отлично выполнится, даже если он многострочный.

Есть и другой метод — более простой, но не всегда рабочий — просто передать скрипту нужный id и не ломать голову с запросом. Очевидно, что если скрипт делает выборку не только по id, но и по другому полю (например, WHERE `id` = 'id' AND `member_id` = 'member_id'), то простая подмена числа не сработает. А инъекция будет работать.

Сама по себе техника простая, но очень эффективная и деструктивная. Когда я работал над сайтом uk-swingers.com (исправлял баги), я показал заказчику, как из его базы можно было воровать… номера кредитных карточек с кодами CVV, информацией о владельце и прочими данными. То, что хранение подобной информации в БД запрещено, это другая история… Да, он шифровал информацию в БД (при помощи алгоритма RC4 :-) ). Да, он стирал 4 средние цифры из номера кредитки (через несколько часов после выполнения транзакции), но был ли в этом смысл? Дело в том, что данные могли быть зашифрованы как угодно, но браузеру они передавались в открытом виде. А номер кредитной карточки можно легко восстановить — во-первых, можно угадать BIN, исходя из территориальной близости к банку, во-вторых, перебором можно вычислить возможные номера карточки (для валидации номера используется формула Луна). На другом сайте (имя пока открыть не могу) так можно было читать чужие письма и воровать почтовые адреса и пароли (и устраивать кучу других гадостей).

Немного сложнее со строками. Я провел исследование, и выяснил, что если строка передается на сервер из <input type="hidden">, то она далеко не всегда экранируется (особенно, если авторство кода принадлежит индусам).

Пример с реального сайта (кстати, писали даже не индусы, а вьетнамцы):

[-]
View Code PHP
    $name = $_REQUEST['member'];
    $query = "SELECT * FROM {$prefix}profiles WHERE user = '$name'";
    $res = mysql_query($query, $link);

script.php?member=testdavid

[-]
View Code MySQL
SELECT * FROM tuvinh_profiles WHERE user = 'testdavid'

Инъекция проходит аналогично: так как строки в MySQL заключаются в одинарные или двойные кавычки, то запрос модифицируется так, чтобы закрыть кавычку:

[-]
View Code MySQL
SELECT * FROM tuvinh_profiles WHERE user = '' OR 1 /* " OR 1 /*
[-]
View Code MySQL
SELECT * FROM tuvinh_profiles WHERE user = "' OR 1 /* " OR 1 /*

Аналогично вышеприведённому примеру, в запрос можно добавить LIMIT и ORDER BY.

Ладно, хватит голой теории, переходим к практике :-)
Большую популярность получили сайты, публикующие различные статьи различных авторов: владельцы сайтов получают контент, авторы — обратную ссылку на свой сайт и возможность показывать свою рекламу. Таких сайтов много: articledashboard.com, articledirectory.com, webarticles.com и т.п.

Один из таких сайтов (articledashboard.com) писали индусы :-) Заинтересовали они меня тем (articledashboard.com, не индусы), что они предлагали скачать "exact software that powers Article Dashboard for FREE". Кто не любит халяву :-) Хотя PHP-код зашифрован ionCube, индусское авторство доказывается наличием огромного файла functions.php (я подобное видел во всех проектах, когда приходилось переделывать код после индусов). А индусы не любят делать addslashes(). Тоже из опыта.

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

На сайте есть хорошая функция — загрузка своей аватарки. Казалось бы, что здесь можно сломать? Тем не менее, и описываемая ниже уязвимость сводится к недостаточной обработке входных данных.

Есть очень хороший extension для FireFox, который позволяет подделывать mime-type. То есть фактически мы можем проинструктировать FireFox посылать произвольный файл (например, php) с mime-type, соответствующим изображению (например, image/png). В том случае, если сервер проверяет тип файла только по данным, которые пришли со стороны пользователя, скрипт обманывает сам себя.

И на закуску: все эти сайты работают под ArticleDirectory.

А вы говорите, безопасность

Мораль сей басни такова: никогда (еще раз подчёркиваю, никогда) нельзя доверять данным, которые пришли со стороны пользователя. Все данные нужно проверять и при проверках предполагать худшее. Естественно, это увеличивает размер кода и время написания программы. Но лучше заказчику потратить пару сотен долларов на безопасность, чем рвать волосы на голове после обнаружения взлома по факту.

Добавить в закладки
  • del.ici.ous
  • Digg
  • Furl
  • Google
  • Simpy
  • Spurl
  • Y! MyWeb
  • БобрДобр
  • Мистер Вонг
  • Yandex.Закладки
  • Текст 2.0
  • News2
  • AddScoop
  • RuSpace
  • RUmarkz
  • Memori
  • Google Bookmarks
  • Писали
  • СМИ 2
  • Моё Место
  • 100 Закладок
  • Ваау!
  • Technorati
  • RuCity
  • LinkStore
  • NewsLand
  • Lopas
  • Закладки - IN.UA
  • Connotea
  • Bibsonomy
  • Trucking Bookmarks
  • Communizm
  • UCA
  • Slashdot
  • Magnolia
  • Blogmarks
  • Current
  • Meneame
  • Oknotizie
  • Diigo
  • Funp
  • Hugg
  • Dealspl.us
  • N4G
  • Mister Wong
  • Faves
  • Yigg
  • Fresqui
  • Care2
  • Kirtsy
  • Sphinn

Связанные записи

11
Март
2008

Комментарии к статье «Безопасность, о которой все так много говорят…» (10)  »

  1. Vladimir says:

    Update: несколько дней назад я предупредил владельцев сайта Article Dashboard о том, что их ПО (а также то ПО, которое они распространяют) уязвимо. Ответа от них не последовало. Что же, отсутствие ответа — тоже ответ. Но вот только решение проблем безопасности страусиным методом еще не разу себя не оправдывало.

  2. cyberquoter says:

    Ктож такие вещи в паблик выкладывает, да еще и с линком на список “жертв” до принятия мер со стороны разрабов? :)
    Чего уж там про SQL-инъекции говорить, когда еще не все про XSS забыли (по некоторым оценкам Searchengines, число дырявых сайтов ~5-6%) :)

  3. Vladimir says:

    Разработчики забили на свой продукт. Я им даже решение постил. Метод страуса - не лучший метод защиты.

  4. SaltyDog says:

    $id = $_GET['id'];
    $query = “SELECT * FROM {$members} WHERE id = $id LIMIT 1″;

    Всем хорош код, когда $id — это число. Например, если скрипт был вызван "script.php?id=123“, то запрос принял бы следуюший вид:
    SELECT * FROM members WHERE id = 5 LIMIT 1

    Это какая-то хитрая функция, которая изменила 123 на 5? :)

  5. SaltyDog says:

    а ребята вообще забавные, даже файл твой не удалили :-)

  6. Vladimir says:

    Это какая-то хитрая функция, которая изменила 123 на 5?

    Спасибо, поправил…

    а ребята вообще забавные, даже файл твой не удалили

    Да забили они на сайт, они деньги с AdSense получают (кстати, Google AdSense забанил меня именно за эту статью); видимо, им этого хватает.

  7. SaltyDog says:

    Повторил финт ушами. Покатаюсь по каталогам, ломать не буду :)

  8. DimoninG says:

    Честно, про подделку типа файла не думал.
    Был уверен, что PHP лезет в файл, смотрит, что там, а потом выдает mime ))) Я был наивен, исправился.

    Про плагин к ОгнеЛису - тоже спасибо, опять же не слышал о таком.
    Ух, и интересно же все это )))

Подписаться на RSS-ленту комментариев к статье «Безопасность, о которой все так много говорят…» Trackback URL: http://blog.sjinks.org.ua/security/9-security-they-talk-so-much-about/trackback/

Оставить комментарий к записи «Безопасность, о которой все так много говорят…»

Вы можете использовать данные тэги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, Вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя