Авторские статьи Атака на WEB. Миссия невыполнима

Discussion in 'Статьи' started by Elekt, 26 Oct 2008.

  1. Elekt

    Elekt Banned

    Joined:
    5 Dec 2005
    Messages:
    944
    Likes Received:
    427
    Reputations:
    508

    ..::[ Атака на WEB. Миссия невыполнима. ]::..

    [ Intro ]

    Есть мнение, что баги WEB избиты, скучны и однообразны. Это_заблуждение.
    Человеку кажется, что уже все что можно придумали\сделали\построили\написали\изобрели\открыли.
    Вспомним историю: так считали в 19веке, и в 20... Не стоит поддаваться этой иллюзии.
    Нестандартное мышление - то, что отличает нас и дает рог изобилия решений.
    "Невозможное возможно" словно ключ от всех дверей. Это главное, что тебе нужно не только поверить, но понять.
    Если все методы испробованы и вариантов более нет, если надежда угасла и ты в тупике -- не отчаивайся.
    Баги есть, их не может не быть.

    <!-- Я покажу тебе немного уличной магии =) -->

    [ Кривой chmod ]

    Публикацию статьи автора NSD о технологии атаки через reverse-ip(lookup-ip) можно считать началом открытого противостояния администраторов хостингов и желающих залезть на смежный сайт соседа.
    (Здесь и далее многие аспекты вопросов рассмотрены с точки зрения rever-ip подхода)
    Многие начинающие хостинги вообще не занимаются разделением прав доступа.
    Через какое-то время( видимо после пары тысяч жалоб\дефейсов ), сисадмин прикручивает suphp ибо suexec и какое-то время все работает.
    Инициатива попеременно переходит от одной стороне к другой в ритме выхода нового паблик эксплойта под PHP и выхода патча =)
    Прошло довольно прилично времени, чтобы всем наконец стало ясно (кто-то еще сомневается?) - PHP дыряв как друшлаг и доверять ему НЕЛЬЗЯ.
    Пусть не сегодня, но завтра выйдет новое адвизори с новым мегабагом и снова все будут ахать и патчится... в который уже раз - и уж точно не в последний.

    В настоящий момент идет тенденция в упоре на разделение прав через стандартную файловую систему в купе с suexec и ftp-доступом разделения прав.
    Довольно бронебойный прием, поскольку попасть в директорию, тебе не принадлежащую, может разве что только root.

    Для надежности дополнительно чмодят все системные директории на -rwx--x--x .
    Действительно, кому еще (и, главное, зачем?) может потребоваться листинг корневой директории, /etc, /var, /usr помимо root'a ?
    Полезные бинарники вроде id,cwd,uname,find тоже порой имеют права root:wheel -r-xr-x---, так что и не выполнишь команды.

    Но есть одна маленькая тонкость чмода.
    Дело в том, что наличие байта выполнения --x на директории позволяет пройти в эту директорию...
    Прочитать мы её не сможем, но, например, вложенные директории и файлы могут иметь уже более демократичные права доступа.

    Рассмотрим пример.
    Code:
    id
    uid=80(www) gid=80(www) groups=80(www) 
    ls -liaR /home
    -rwx--x--x root:root /home/
    -rwx--x--x user:user /home/user/
    -rwxr-xr-x user:user /home/user/htdocs/
    -rwxrwxrwx user:user /home/user/htdocs/tmp/
    Таким образом, обратившись по абсолютному пути "/home/user/htdocs/tmp/" мы окажемся в папке, доступную на запись и видимую из веба.

    Даже в случае отсутствия листинга папок нам ничто не мешает тупо подобрать вероятное имя по словарю брутфорсом, скрипт которого ищи на диске.
    Перебор возможных путей через скрипт брутфорса [a-z] символами на путь длинной в 5-ть символов займет не более минуты на .php и еще меньше через .sh скрипт)
    Даже в случае нечитабельных папок не составляет труда прочесть .htaccess\index.php и уже из них повытягивать логины\пароли\инклуды на конфиги и др.

    Таким образом, так или иначе определив существование директории\файла, мы скорее всего получим доступ на чтение + возможный бонус листать\писать во вложенные директории и файлы.

    Ну, а где же достать этот самый полный путь?
    Конфиги Апача httpd.conf, vhosts.conf идеально подходят для этого.
    Однако, они практически всегда защищены от любопытных глаз уже правильным чмодом.
    Но, несмотря на это, извечный "/etc/passwd" всегда расскажет нам о домашнем каталоге юзеров.
    А уж наличие соотвествующих папок можно определить исходя из аналогии имеющегося домашнего каталога, либо незатейлевым брутфорсом.
    И даже если включен safe_mode и\или open_basedir, мешающий получить passwd и никто не делится с тобой приватными эксплоитами для обхода этого фашистского изобретения, виновного в геноциде хаксоров, -- даже тут можно вывернуться через фичу в posix_getpwuid(): http://packetstormsecurity.org/0712-exploits/php525-bypass.txt

    Защита проста как два байта -- достаточно лишь одной директории в пути быть чмоднутой на "-rwx--x---" или даже "-rwx------" и хэккеры пойдут лесом.
    ..Хотя вспоминая прошлый номер ][ с описанием багов файловых систем от Криса Касперски, я начинаю задумываться, а что если... =) Но это уже совсем другая история.

    PS: уже после написания подтемы chmod, вынашиваемой и проверяемой мной в течении многих месяцев, и руководствуясь исключительно лишь своим насыщенным опытом, было решено, в давно заведенном порядке, посерфить секурити-блоги, в надежде разжиться мало-мальски свежей инфой и новыми идеями.
    Как выяснилось, не одну мою голову(ака пытливый моск) затронула вышеописанная бага.
    ( и это нормально, в истории одинаковые идеи часто посещают двух людей сразу -- чего только стоят открытые законы в физике, математике и др. науках, названные двойными фамилиями соавторов, порой живших в разных точках земного шара и понятия на имевших друг о друге... эк меня понесло =) )
    c0nst#secureblog.org в своем блоге также разобрал тему кривого чмода и разработал свой (надо сказать, весьма неплохой) скрипт пентестинга на бажность.
    Также в статье немало внимания уделено борьбе с проблемой средствами PHP ака "safe_mode" + "open_basedir" + "disable_functions" , однако, повторяюсь, что имхо это не секурно.
    Просто правильно чмодьте.


    [ Коммунальный /tmp ]

    И только одно остается по прежнему незыблемым - /tmp .
    <!-- Темп, сцуко, опасный! =) -->

    Казалось бы, что такого примечательного в общей временной папке?
    То, что она - ОБЩАЯ. Это самое главное.

    Как правило каждому виртуалхосту прописывают индивидуальные настройки вроде сэйфмода, опенбаздира.
    Но временную папку ставят одну на всех вместо создания индивидуальной в домашней директории клиента.
    (напоминаю, в php.ini это параметр "session.save_path")
    Почему? Темп - это по факту мусорка.
    Проходит пара месяцев и в одно недоброе утро администратору приходит пара десятков жалоб на многочисленные ошибки с варнигами.
    Темп оказывается переполненным, ведь созданные сессии удаляются только при вызове session_destroy(), которой часто брезгуют\забывают\не жмут на Exit\недогружают страницу.
    Тем более если сервер имеел долгий аптайм (в некоторых никсовых дистрибутивах встроена очистка темпа при ребуте по дефолту).
    Не долго думая, в cron.month админом ставится новая задача, призванная периодически чистить "/tmp" .
    Разумеется написать sh-скрипт очистки одной статичной папки проще, чем N юзверских папок.
    (хотя можно возложить почетную задачу уборки на юзера, особенно если квоты дискового пространства уже прикручены)

    Вобщем, так или иначе, но индивидуальный "session.save_path" необходим для секурности.

    Как впрочем и... "upload_tmp_dir" !
    Ведь сбои происходят довольно часто при загрузке файлов, ибо аплоад файла - это прежде всего POST-пакет нехилых размеров.
    А по моему опыту далеко не каждый провайдер\прокси-сервер\VPN корректно его переваривает особенно в часы пик.
    Да и PHP не всегда удаляет недогруженные куски, подвисая баластом в ожидании оконечной части.
    Это дает вероятный бонус найти в темпе что-либо либо интересное, например, кусок недогруженного конфига или дампа БД, логи, а иногда какие-либо творческие эксперименты(или экскременты?) администрации\юзеров в процессе программирования с наличием чувствительных данных.

    Более того, ЛЮБОЙ php-скрипт при "file_uploads=ON" автоматически принимает файл в POST-пакете.
    Это позволяет загрузить на целевой сервер большое кол-во файлов(тем более используя ботнет).
    ~ колличество загружаемых файлов за раз неограничено!
    ~ [upload_max_filesize] лимитируется для 1го файла.
    ~ В PHP 5.1.x [upload_max_filesize] вообще игнорирует [post_max_size].

    Значит в PHP 5.1.x можно загрузить за раз неограниченное кол-во файлов! А в свежем PHP - не более [post_max_size].
    Что повлечет за собой исчерпание свободного дискового пространства в папке временных файлов.
    ~ загруженные файлы не удаляются до тех пор, пока php-скрипт не закончит исполняться
    ~ сервер продолжает поддерживать соединение и не начинает выполнение php-скрипта до тех пор, пока не будет принят весь HTTP-POST-пакет.

    Атакующий может намеренно исказить величину HTTP-POST-пакета и удерживать соединение,
    а следовательно загруженные файлы будут присутствовать на диске до тех пор, пока не истечет таймаут соединения на стороне сервера.

    Схема атаки:
    1) Атакующий посылает специально сформированный POST-запрос ("multipart/form-data") , содержащий файл(ы), к любому php-скрипту на сервере
    - размер 1-го отсылаемого файла должен быть не больше максимально установленного значения директивы PHP [upload_max_filesize] (Default=32Мб) и не более [post_max_size] (Default=16Мб) по минимальному значению любого из параметров.
    - Размер пакета (Http-хидер) "Content-Length" указывается заведомо больше истинного(как минимум на 5 байт).
    2) Сервер принимает POST-пакет с файлом
    - в незаконченной передаче держим коннект и заставляем сервер слушать соединение максимально возможное время
    - все это время загруженный файл будет занимать место на диске сервера, реализуя атаку на исчерпание дискового пространства

    Варианты защиты от атаки:
    ~ запретить [file_uploads]
    ~ ограничить время установленного соединения клиент-сервер в фаерволе или веб-демоне(apache)
    ~ http://sysoev.ru/web/upload.html

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

    Что интересно - в ряде случаев мне встречаются системы, где загружаемые временные файлы имеют не псевдослучайное имя, а именуются строго последовательно.
    От версии PHP это не зависит(испытывал на разных). И от чего зависит - мне пока не известно.
    Проверить конкретный сервер на предмет предсказуемых имен временных файлов легко - достаточно найти вывод phpinfo().
    На это скрипт посылаем пакет с файлом и смотрим в ответе значение [tmp_name]. Посылаем еще раз и сравниваем.
    Если имя вполне последовательно прибавило пару чисел - это баг.
    Используя вышеописанный алгоритм задержки загруженных файлов на сервере, можно загрузить вебшелл.
    И теперь, если где-то на сервере имеется php-include... ;)

    Однако, помимо описанного, на мой взгляд, самым интересным здесь является (о, да!) угон чужой сессии(session hijacking), об этом читай чуть ниже.


    [ Коварные сессии ]

    Немалая часть веб-приложений юзает сессии PHP для разграничения прав доступа между юзерами.
    (Важно: здесь и далее рассматриваются уязвимости PHP сессий; определить, что php-скрипт юзает php-сессии можно по вызову session_start() и др. )

    Напомню забывчивым, что вызов <?php;session_start();?> создает файл сессии с id из случайных alpha-numeric,
    например, /tmp/sess_50d7ed4b37f95f991679fdd92ba894e2
    ( случайных или определенных в скрипте посредством вызова в скрипте session_id('<alpha-numeric>') перед session_start() )
    после чего это имя дублируется в браузер пользователю как значение кукис с дефолтным именем "PHPSESSID"
    ( можно изменить глобально из php.ini или локально в скрипте, вызвав session_name('<MY_SESSID>') перед session_start() )
    Set-Cookie: PHPSESSID=50d7ed4b37f95f991679fdd92ba894e2;

    Как минимум, атака на сессии является одним из эффективнейших тестов на раскрытие полного пути в десятке лидеров,
    таких как поиск и обращение к левым скриптам, передача массива вместо строки в переменной, ддос на БД, переполнение мусором логфайла и др.
    Например, достаточно передать в гете или куках "PHPSESSID=123!@#$%^" и получим еррор уровня варнига, если error_reporting(E_WARNING) :

    Code:
    Warning: session_start() [function.session-start]: The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in...
    Либо передадим "PHPSESSID" длинной более 256 символов. Файл с таким именем не может быть создан, и ответом сервака будет:

    Code:
    Warning: Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct
    
    Сам факт создания файла лишь на основании PHPSESSID в гете или куках, с именем аналогичным id, наводит на мысль о... ддосе.
    Точнее сказать - на эффекте его усиления.
    Ресурсы системы, затраченные на создание файла сессии, ничтожны. А сам файл сессии зачастую и вовсе пуст.
    ( это зависит от того, были ли внесены значения в $_SESSION в процессе выполнения скрипта )
    Но генерируя мусорный трафик с рэндомным PHPSESSID можно создать кол-во файлов сессий равное числу http-пакетов при ддосе, тоесть уххх как дофига.
    А MFT никто не отменял. Совсем недавно Крис писал, что даже совершенно пустой файл занимает 1 кластер.

    Да что там раскрытие пути... К сведению, к PHP написаны более 10-ти эксплоитов, с атакой BoF на функции сессий, а это уже кое о чем да говорит.
    И те, кто с презреньем утверждает, что BoF для PHP -- полная лажа -- лишь оправдавают свое незнание.
    Между прочим - это порой единственный шанс из клетки опен_баздира с сэйф-модом, когда exec-эксплоиты кончились, а выполнения сис. команд так и нет.

    Ну а теперь подробно рассмотрим перехват сессий.
    Примечательной особенностью пользовательской сессии является уникальность её id.
    Знание которого, как ни странно, является достаточным для успешного прохождения авторизации юзверя.
    Хранятся сессии либо в базе данных приложения(и это правильно ибо максимально безопасно), либо в созданных средствами PHP файлах в папке.. "/tmp" .
    Ну а поскольку "/tmp" как мы уже выяснили часто доступен всем желающим на листинг\чтение\запись, то нетрудно догадаться о выводах.
    Здесь в зависимости от условий возможные различные варианты атаки.

    Фактически можно обойтись только листингом темпа, ведь как правило достаточно знать лишь id сессии.
    Подменив id своей сессии на id чужой сессии в кукисе, мы успешно авторизуемся под другим юзверем.
    Зачастую, если возможен лишь листинг темпа, то сессии каждого сайта имеют uid\guid , принадлежащий конкретному сайту.
    Это очень удобно, ибо вместо перебора всех сессий из "/tmp" легко отделить нужные.
    Защитой может служить хранимый в сессии IP-address и\или User-Agent пользователя, срок действия, и соответствующая их проверка при авторизации.

    Если же можно читать файлы чужих сессий, тогда мы уже будем иметь хотя бы представление о её структуре и содержании.
    Это важно, если используется какой-либо самописный\неизвестный движок, структура сессий которого не известна заранее, или если стоит секурити проверка на ip, browser, срок действия.
    Тогда, пусть мы и не сможем использовать существующие сессии, но исходя из примеров читабельных сессий, становится возможным сгенерировать свою собственную!
    Закинуть её в темп, чмоднуть на 0777, чтобы другой пользователь имел доступ к ней(правда, с safemode=on это не прокатит), после чего использовать.
    Защитой здесь может служить хранение данных не в открытом виде, а в зашифрованном.
    Либо обратимым алгоритмом(AES,blufish,twufish) с ключом, хранящимся в конфиге или БД, либо необратимым алгоритмом(md5,sha1) с рэндомной солью, хранящийся опять же в конфиге,БД или другом недосягаемом месте.
    Тогда, даже если хакеру будет известен механизм генерации хеша - он не сможет сгенерировать собственную подложную сессию.

    Самый редкий, но благоприятный случай, если Апач работает на правах www-data\nobody для всех.
    А значит все файлы(в том числе и сессионные) создаются с одинаковыми правами и доступны всем не только на чтение, но и на запись.
    Права на запись хороши тем, что становится возможным обойти простую(не зашифрованную) привязку к пользователю, изменив в существующей сессии параметры под себя.
    Алгоритмы защиты аналогичны предыдущему пункту.

    Проблем взломщику заметно прибавит вызов session_regenerate_id(), меняющий session_id() при каждом вызове.
    <!--хотя больше ему проблем прибавит вызов братков на хату =))-->

    Говоря о сессиях следует упомянуть еще об одном баге PHP от Stefan Esser
    http://www.php-security.org/MOPB/PMOPB-46-2007.html - "EXT/Session HTTP Response Header Injection Vulnerability PHP4<=4.4.7,PHP5<=5.2.3"
    Однако, так и быть, я сэкономлю несколько часов твоего времени, в ином случае будучи гарантировано тобой убитыми(ибо время для хэккеров бесценно, ты не забыл наш манифест?).
    Если мы обратимся к сайту так: "/session.php?PHPSESSID=123" -- мы просто заюзаем сессию sess_123, если она есть или создадим её, если её нет.
    Но так будет ТОЛЬКО В ТОМ СЛУЧАЕ, если в браузере еще нет куки "PHPSESSID", поскольку она имеет более высокий приоритет в сравнении с гетом.
    Дело обстоит совсем по другому при обращении к линку вида "/session.php/PHPSESSID=123456;INJECTED=ATTRIBUTE;/"
    В ответ браузеру отправится пакет с хидером "Set-cookie: PHPSESSID=123456;INJECTED=ATTRIBUTE;;path=/"
    Для успешной эксплуатации уязвимости необходим error_reporting(0) !
    PoC урл немного вводит в заблуждение словом "INJECTED" - сразу чудится CSRF и прочее.
    К сожалению внедрить какой-либо символ в urlencode вроде %0D,%0A нельзя - urlencode просто не обрабытывается.
    Тоесть ни "Location" , ни дополнительный "Set-cookie" добавить не выйдет, а только expired, domain и path для текущей куки.
    Если заблаговременно создать свой файл сессии, чмоднуть его на 0777, заманить админа по линку и тем фактически вынудить его браузер юзать сессию с нашим id!
    Тогда мы получим его файл сессии с правами на запись.

    Также стоит затронуть тему перехвата cессии через REFERER.
    С одной стороны звучит даже как-то неправдоподобно, но это лишь кажется.
    Во первых главное условие - атака становится возможной, если приложение так или иначе добавляет сессию пользователя в GET(урл).
    Причем это может быть отнюдь не глюком, а документированной поддержкой. Зачем это нужно?
    Подобный механизм авторизации через GET активируется в двигах в случаях:
    - отключенных куков в браузере ( аля так безопаснее ;) )
    - отключенной явой( тотже [NoScript] )

    И в итоге вместо повышения безопасности - вы получаете бонусную течь.
    Так какже это использовать?? Да оч просто. Второе главное условие - поддержка чатом\форумом\блогом\коментами тэга
    HTML:
    <img>\[img], <a>\[url]
    .
    Ну или поддержка удаленного аватара. Краааайне редко разрешают закачивать файлы, а на удаленные -- ссылайся пожалуйста!
    Вот тут и дырка - мы можем сослаться на изображение на своем сервере и снифать поступающие рефереры его просмотра через access_log или через php подобно капча-скриптам.
    В реферере помимо урл предыдущей страницы будет содержаться сессия юзера.

    Ярким примером служат ПРАКТИЧЕСКИ ВСЕ WAP порталы. 0-day ;)
    Даже в профайле часто бывает личная ссылка для входа без пароля, видели?
    Я не специалист по такому софту, но (видимо) некоторые сотики\PDA\КПК не держат cookie, и это компенсируется передачей сессии в гете.

    Как пример уязвимого движка - всеми любимый: phpBB 2.0.23 Session Hijacking Vulnerability -- http://www.securityfocus.com/archive/1/489815
    Утечка сессии просходит при закрытии темы модератором\админом.


     
  2. Elekt

    Elekt Banned

    Joined:
    5 Dec 2005
    Messages:
    944
    Likes Received:
    427
    Reputations:
    508


    [ Multy-Byte ]

    Рассказывает товарищ (c)[cash]#hack-shop.org.ru , я лишь изредка дополняю и уточняю детали, итак...
    Опять Stefan Esser и опять баги в PHP. В частности интересна уязвимость addslashes() к мультибайтовым символам.
    В первые о данной уязвимости заговорили в 2006, обсуждение шло о недостаточной фильтрации в функции addslashes(), ставшей популярной как простая защита от SQL-иньекций.
    Как всегда сначало общественность не достойно отреагировала на появление уязвимости за что и была наказана.
    Многие достаточно крупные и очень крупные серверы подверженны данной уязвимости.
    Уязвимость присутствует как в версиях MySQL 4.1.х->4.1.20 , 5.0.x->5.0.22, так и в самом PHP <= 5.2.5

    Addslashes() некорректно обрабатывает 3 различные кодировки SJIS, BIG5 (болле известную как CP950), и GBK(CP936).
    Все эти кодировки основаны на двоичной системе.
    Данные кодировки являются расширенными и используются преимущественно в азиатских странах, где требования языка\алфавита не удовлетворяет стандартное 256-символьное ограничение.
    Таким образом, вероятная уязвимость азиатского сайта несоизмеримо выше по сравнению со всеми остальными к атаке на мультибайт.

    Первый адвизори вышел для GBK поэтому подробно рассмотрим особенность именно этой кодировки.

    В GBK символы интерпритируются по одному.
    0xbf27 состоит из 2 символов в 2-ной системе именно этот символ будет некорректно отфильтрован.
    0xbf5c будет так некорректно отфильтрован и вызовет ошибку, так как будет недопустимый символ (\).
    Рассмотрим теперь эти данные обработанные функцией addslashes().
    Первый вариант 0xbf27 будет интерпритирован как одиночные символы 0xbf при переводе будет (?), а затем 0x27 ('), и второй вариант 0xbf5c, 0xbf при переводе будет (?), а затем 0x5c (\).

    Addslashes(string str) возвращает сроку str, в которой перед каждым спецсимволом добавлен обратный слэш (\), например для последующего использования этой строки в запросе к базе данных.
    Экранируются одиночная кавычка ('), двойная кавычка ("), обратный слэш (\) и NUL (байт NULL).
    Таким образом данный фильтр может пропустить некорректные символы символы к базе данных, а именно (').
    После чего станет возможно составления запроса к базе данных.

    Имея синтаксис бд.

    PHP:
    CREATE TABLE tables (
    id VARCHAR(32CHARACTER SET GBK,
    data VARCHAR(8000CHARACTER SET GBK,
    PRIMARY KEY (data)
    );

    mysql_query("SELECT data FROM tables WHERE id='".addslashes($id)."'");  
    В данном случае что бы составить корректный запрос нам обязательно надо закрыть параметр "id='" и привести его к виду "id='1'", но передать одинарную кавычку мы не сможем, так как она экранируется.
    Если версия нашей базы данных совпадает с одной из указанных выше мы можем применить данный способ в деле, передав следующий пакет:

    /?id=%BF%27' union select 1,2/*';

    Данный метод будет работать только при magic_quotes_gpc = OFF. Так как при включенном magic_quotes_gpc по умолчанию все GET/POST/COOKIE буду обрабатываться функцией addslashes() что приведет к что приведет к двойной фильтрации.

    Примером паблик эксплоитов могут служить SQL-inj в Wordpress <= 2.3.2 с БД в GBK кодировке
    http://securityvulns.ru/Sdocument635.html

    /wordpress/index.php?exact=1&sentence=1&s=%b3%27)))/**/AND/**/ID=-1/**/UNION/**/SELECT/**/1,2,3,4,5,user_pass,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24/**/FROM/**/wp_users%23

    Особого внимания заслуживает паблик эксплоит под SMF<=1.1.4
    http://milw0rm.com/exploits/5826
    Основанный на принудительной смене локали базы данных на уязвимую BIG5, эксплоит уже не зависит от локали кодировки сервера.
    Неисключено существование аналогичных багов и в других приложениях.

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


    [ Фрагментированная SQL-inj ]

    Также рассмотрим такой малоизвестный вид уязвимости как фрагментированная SQL-inj.
    По сути это таже самая SQL-inj, только с той лишь разницей, что её обнаружение и эксплуатация на порядок сложнее.
    Классический пример такой инъекции можно встретить, когда данные извлекаются из первого SQL-запроса и далее без должной фильтрации подставляются во второй SQL-запрос.
    Тоесть имеется дефект обработки данных, либо полное отсутствие фильтрации данных на одной из стадий манипуляции ими.

    Расмотрим уязвимость на практическом примере для Coppermine Photo Gallery <= 1.4.19.
    Предварительно опишу детали бага:
    1) В GET,POST,REQUEST опасные символы заменяются на html аналоги, но '\' не затрагивается.
    Заодно они обрабатываются stripslashes(), что дает возможность использовать NULL-byte.
    2) При регистрации нового пользователя для email используется регулярка, основанная на ereg(), который в свою очередь уязвим к NULL-byte (обработка строки прекращается при встрече с ним).
    Таким образом email вида "[email protected]%00\" успешно проходит проверку.

    В базу данных email попадает со слешем на конце. Что это дает?
    Если где-либо в скрипте первый query получит email и передаст его во второй query без фильтрации, то слэш заэкранирует закрывающую ковычку, синтаксис запроса нарушится и возникет SQL-Error.

    SQL-error:
    PHP:
    INSERT INTO cpg1418_ecards (sender_namesender_emailrecipient_namerecipient_emaillinkdatesender_ipVALUES ('123''[email protected]\', 'SomeUserName', 'SomeUser@email.com', '5OntzOjI6InJuIjtzOjk', '', '127.0.0.1')
    Ошибка как таковая бесполезна, но если сразу после параметра email будет идти еще один параметр, который мы можем произвольно менять, то становится возможным проведение фрагменитированной SQL-injection.

    SQL-inj more1row:
    PHP:
    INSERT INTO cpg1418_ecards (sender_namesender_emailrecipient_namerecipient_emaillinkdatesender_ipVALUES ('123''[email protected]\', '[SQL-inject more1row]', 'SomeUser@email.com', '5OntzOjI6InJuIjtzOjk', '', '127.0.0.1')
    Как видно, открывающаяся ковычка поля recipient_name превращается в закрывающуюся ковычку sender_email. Мы получаем возможность провести SQL-inj в поле recipient_name.

    Для эксплуатации уязвимости потребуется:
    ~ включена регистрация новых пользователей(по дефолту отключено)
    ~ не требуется подтверждение через email(по дефолту требуется)
    ~ включен лог открыток(по дефолту отключено)


    Алгоритм действий прост:
    1) Отснифать POST-пакет регистрации, заменить в нем емаил на "[email protected]%00\" и отослать серверу.
    2) Авторизовавшись, выбираем любое загруженное изображение в галерее и жмем на значок письма (Отправить этот файл как открытку).
    3) Корректно заполняем и отсылаем. Если сервер сообщает об ошибке базы данных, значит лог открыток включен и возможна SQL-inj.
    4 Далее в поле "Имя получателя" проводим SQL-more1row используя автоматизированный скрипт.

    FALSE - "Имя получателя":
    PHP:
     or if(ascii(substring((select concat(user_id,0x3a,user_name,0x3a,user_password,0x3a,user_emailfrom cpg14x_users where user_group=1 limit 1),1,1))=254,1,(select 1 union select 2))=10x6861636b6572 0x6861636b6572406d61696c2e7275 0x6861636b 0x31323039333931343430 0x3230372e34362e3233322e313832 )/*
    TRUE - "Имя получателя":
    PHP:
     or if(ascii(substring((select concat(user_id,0x3a,user_name,0x3a,user_password,0x3a,user_emailfrom cpg14x_users where user_group=1 limit 1),1,1))=49,1,(select 1 union select 2))=10x6861636b6572 0x6861636b6572406d61696c2e7275 0x6861636b 0x31323039333931343430 0x3230372e34362e3233322e313832 )/*
    [*] Из-за фильтрации '<' '>' можно использовать только знак '=', но это уже мелочи и дело техники как говорится.

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

    PS: уже было закончив подтему, я получил ссылку на новый вариант фрагментированной атаки. no-no-no,Stefan Esser,no! =)
    На этот раз демон скукожил Mysql. Речь идет о особенностях сравнения строк и автоматического усечения данных в MySQL.
    Любой столбец имеет собственную максимальную длину. При её превышении MySQL отсекает оставшуюся часть запроса по умолчанию.
    Более подробно читай в переводе [Raz0r] http://raz0r.name/vulnerabilities/sql-column-truncation-security/
    Уязвимости могут быть подвержены самые разнообразные приложения, не проверяющие длину строки перед передачей в БД.
    Вобщем, Стефан как всегда отжог(я уже молчу про предсказуемость случайных чисел в PHP, и это совсем другая история...)


    [ END ]

    Вроде никого не обидел: хэкерам - баги, админам - патчи =)
    Надеюсь, читатель, ты узнал для себя что-то новое и не жалеешь о потраченном времени.
    Чтож, думаю, мы еще встретимся с тобой на полосе журнала. Удачи.

     
  3. Elekt

    Elekt Banned

    Joined:
    5 Dec 2005
    Messages:
    944
    Likes Received:
    427
    Reputations:
    508
    Заметка о фрагментированной SQL-inj


    Заметка о фрагментированной SQL-inj

    Использование "substr\substring" создает потенциальную уязвимость.

    Предположим, что $_POST['name'] слэшируется magic_quotes либо addslashes()
    Перед подстановкой в SQL $query переменная $_POST['name'] обрезается по длине(в эстетических соображениях приемлемой длины имени, либо с целью профилактики уязвимости обрезания транзакций SQL). Кстати, обрезание транзакций можно использовать точно также.

    Пусть исходное $_POST['name'] будет [ cooladmin' ]
    После слеширования: [ cooladmin\' ]
    Пусть сабстринг обрезает до 10ти символов: [ cooladmin\ ]

    PHP:
    mysql_query("SELECT * from users WHERE user='".substr($_POST['name'],0,10)."' AND passwd='".$_POST['pass']."'");
    История аналогична ecard дыре в копермайне.
    Слэш экранирует ковычку, открывающая ковычка pass превращается в закрывающую, а через сам pass проводится атака.

    Сабстринг может быть как php так и sql. Только в случае sql сложнее: нужен первичный инсерт\апдейт\реплэйс запрос, а затем второй запрос, чувствительный в выборке к слэшу.

    Полагаю, что данная атака эффективна против приложений любой сложности и "вылизанности"... сколь и сложна в нахождении бага. Ну, увидим.
     
  4. Qwazar

    Qwazar Elder - Старейшина

    Joined:
    2 Jun 2005
    Messages:
    989
    Likes Received:
    904
    Reputations:
    587
    Классно! Имхо следует ещё добавить про генератор, с примерами, чтобы обзор был полным :)

    З.Ы.
    Не явой, а яваскриптом! (И зачем ECMAScript в JavaScript переименовали вообще??)
     
    #4 Qwazar, 1 Dec 2008
    Last edited: 1 Dec 2008
    3 people like this.
  5. Buffalon

    Buffalon Elder - Старейшина

    Joined:
    22 Mar 2008
    Messages:
    241
    Likes Received:
    34
    Reputations:
    8
    Насчёт 1 части , Сессии - всё сводится к тому что если мы не знаем чужую сессию - то вряд ли мы её надём :D.
    Короче статья` вводная` типа информация к размышлению ,а как написать
    Додумываемся сами :)

    А написанно много и много умных слов ,
    Отлично .
     
    #5 Buffalon, 1 Dec 2008
    Last edited: 1 Dec 2008
  6. Twoster

    Twoster Members of Antichat

    Joined:
    20 Aug 2008
    Messages:
    287
    Likes Received:
    402
    Reputations:
    159
    Отличная статья! Читал как говорится 'взахлеб'! =)
    P.S. Вот именно это отличает квалифицированного человека от тысяч остальных! Материал выложен в идеальной форме! 'умный поймет, дурак не спросит!'
     
  7. [Raz0r]

    [Raz0r] Elder - Старейшина

    Joined:
    25 Feb 2007
    Messages:
    425
    Likes Received:
    484
    Reputations:
    295
    поподробей пожалуйста, что-то у меня сомнения на этот счет...
     
  8. devscripts

    devscripts Elder - Старейшина

    Joined:
    8 May 2007
    Messages:
    131
    Likes Received:
    182
    Reputations:
    134
    Ковычка=кАвычка ;D
    ---
    по сути, хотелось бы добавить о фрагментированных инъекциях
    даже если при первичном запросе заэкранируется слеш/кавычка, то в базе мы все равно будем иметь одинарный слеш или одинарную кавычку, так?
    PHP:
    $test=addslashes("lala\lala");
    print 
    $test//lala\\lala
    mysql_query("insert into table values('$test')"); //в базе имеем lala/lala
    так что, в конечном итоге, имеем следующее
    1. Необязательно, чтобы не было addslashes при первом запросе (занесении инъекта в базу)
    2. Уязвимость сводится всего лишь к недостаточной фильтрации данных, извлеченных из бд
    3. Редко где такое встретишь :) в WP 2.2 было такое, что данные извлекаются, затем идет extract, а после extract только проверка) то есть перепутано местами-проверка и извлечение из бд
     
  9. Qwazar

    Qwazar Elder - Старейшина

    Joined:
    2 Jun 2005
    Messages:
    989
    Likes Received:
    904
    Reputations:
    587
    Я такое вроде в DLE-Forum находил, если не путаю.
     
  10. chekist

    chekist Elder - Старейшина

    Joined:
    14 Nov 2007
    Messages:
    215
    Likes Received:
    160
    Reputations:
    100
    Elekt -Гуру

    про file_upload, права у временново файла будут теже что и у скрипта которому отпровляли POST запрос, правда что нам это дает? ну кроме как для LFI. А права поднять ника не получится ?
     
    #10 chekist, 13 Dec 2008
    Last edited: 13 Dec 2008
  11. goluzov

    goluzov New Member

    Joined:
    27 Jun 2010
    Messages:
    4
    Likes Received:
    1
    Reputations:
    0
    /session.php/PHPSESSID=123456;INJECTED=ATTRIBUTE;/

    ниче не понял
     
  12. raven314

    raven314 New Member

    Joined:
    30 Jan 2009
    Messages:
    44
    Likes Received:
    2
    Reputations:
    0
    Ребят. Вопрос в любом случае вглядит по-идиотски, но таки он назрел. А о чем в статье речь шла? В плане, есть ли вводный материал к тому, что здесь описано?
    алсо, учу php,js в данный момент. попутно гляжу в справочник mysql. Так что мне на будущем проф-поприще быть может пригодится, да и вообще - интересно.