Vortex777
Интересующийся
- Регистрация
- 27.06.2022
- Сообщения
- 98
- Реакции
- 0
- Гарант продажи
- 0
- Гарант покупки
- 0
- Депозит
- 0 р
Публикацию статьи автора 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 на директории позволяет пройти в эту директорию...
Прочитать мы её не сможем, но, например, вложенные директории и файлы могут иметь уже более демократичные права доступа.
Рассмотрим пример.
Таким образом, обратившись по абсолютному пути "/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 .
<!-- Темп, сцуко, опасный! =) -->
Казалось бы, что такого примечательного в общей временной папке?
То, что она - ОБЩАЯ. Это самое главное.
Как правило каждому виртуалхосту прописывают индивидуальные настройки вроде сэйфмода, опенбаздира.
Но временную папку ставят одну на всех вместо создания индивидуальной в домашней директории клиента.
(напоминаю, в 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), об этом читай чуть ниже.
(Здесь и далее многие аспекты вопросов рассмотрены с точки зрения 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 на директории позволяет пройти в эту директорию...
Прочитать мы её не сможем, но, например, вложенные директории и файлы могут иметь уже более демократичные права доступа.
Рассмотрим пример.
Код:
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/
Даже в случае отсутствия листинга папок нам ничто не мешает тупо подобрать вероятное имя по словарю брутфорсом, скрипт которого ищи на диске.
Перебор возможных путей через скрипт брутфорса [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), об этом читай чуть ниже.