Небезопасная выгрузка файлов на веб-сайты: эксплуатация и обход фильтров

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

Перечислим некоторые варианты атаки на сайты, позволяющие выгружать на них файлы:

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

Возможны ещё более экзотические варианты, связанные с атакой на веб-приложения, которые обрабатывают полученные картинки.

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

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

Как узнать, какую фильтрацию использует тот или иной сайт?

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

1. Отсутствие какой-либо проверки выгружаемых данных

Это самый простой вариант, такое можно встретить только на самодельных сайтах начинающих программистов на PHP.

Алгоритм здесь следующий:

  1. Определяем, какой адрес получают файлы, выгруженные на сайт.
  2. Создаём бэкдор.
  3. Выгружаем его на уязвимый сайт.
  4. Подключаемся к бэкдору.

В качестве «полигона» для тестирования я воспользуюсь Damn Vulnerable Web Application (DVWA). Я не буду пытаться установить этот набор уязвимых программ в Kali Linux (на данный момент присутствуют некоторые проблемы с установкой в современные системы, т.к. DVWA требует именно PHP 5, а в современных дистрибутивах Linux по умолчанию используется PHP 7). Я воспользуюсь Web Security Dojo, где DVWA уже установлен и прекрасно работает.

В Web Security Dojo откройте браузер и перейдите по ссылке http://localhost/dvwa/index.php

01

Перейдите во вкладку DVWA Security и измените уровень безопасности на low, сохраните изменения.

02

Перейдите во вкладку Upload:

03

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

Сама картинка не выводится, нам сразу показывают её расопложение:

04

../../hackable/uploads/1.jpg succesfully uploaded!

Две точки означают переход на один уровень вверх от показываемой страницы, т.к. мы сейчас находимся в http://localhost/dvwa/vulnerabilities/upload/#, то нам нужно подняться два раза на один уровень вверх, это получается http://localhost/dvwa/ и уже из этого каталога адрес нашего файла hackable/uploads/1.jpg, т.е. полный адрес получается таким:

http://localhost/dvwa/hackable/uploads/1.jpg

Давайте проверим, открыв этот адрес в строке браузера:

05

Да, всё так.

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

На каждой уязвимой странице DVWA есть кнопка View Source, которая позволяет увидеть уязвимый исходный код:

06

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

Создание бэкдора для выгрузки на веб-сайт

Для этого можно использовать Weevely, PhpSploit, другую программу или вообще написать бэкдор самому.

Я по старой привычке буду использовать Weevely. В Web Security Dojo отсутствуют и Weevely, и PhpSploit, поэтому я начну с установки Weevely:

sudo apt-get update
sudo apt-get install g++ python-pip libyaml-dev python-dev
sudo pip install prettytable Mako PyYAML python-dateutil PySocks --upgrade
git clone https://github.com/epinna/weevely3.git
cd weevely3/
python2 ./weevely.py

Для создания бэкдора с именем index2.php, защищённого паролем hackware, я использую следующую команду:

python2 ./weevely.py generate hackware ~/index2.php

07

Отлично, бэкдор создан и размещён по в файле /home/dojo/index2.php.

Наконец-то, выгружаем этот файл на сервер:

08

09

Файл успешно выгружен и теперь должен быть доступен по адресу http://localhost/dvwa/hackable/uploads/index2.php

Подключаемся к нашему бэкдору так:

python2 ./weevely.py http://localhost/dvwa/hackable/uploads/index2.php hackware

10

Бэкдор на связи и он работает!

2. Обход фильтрации Content-Type

Опять перейдите на страницу DVWA Security и выберите там medium (средний) уровень безопасности. Возвращаемся в File Upload, и опять пробуем выгрузить наш бэкдор:

11

Т.е. мы получили «Your image was not uploaded.».

Хмммм… Давайте заглянем в исходный код:

12

Строки, которые не позволили нам выгрузить бэкдор:

$uploaded_type = $_FILES['uploaded']['type'];
$uploaded_type == "image/jpeg"

Т.е. на стороне сервера проверяется, файл какого типа загружен. Принимаются файлы только image/jpeg. Что можно сделать в этой ситуации?

Нужно подумать, а ОТКУДА скрипт на сервере получает информацию о типе присланного файла? А получает он его (в данном случае) от… нашего веб-браузера, из тела запроса Content-Type.

А всё, что приходит от пользователя, может быть поддельным и модифицированным любым образом!

Есть разные способы реализации изменения передаваемых данных, я покажу на примере Burp Suite.

Настройка прокси в Burp Suite для модификации передаваемых данных

В Web Security Dojo уже имеется Burp Suite – можете воспользоваться им. Если вы хотите самую последнюю версию Burp Suite, то скачайте её с официального сайта по этой ссылке.

Алгоритм действия:

  1. Мы настроем прокси сервер в Burp Suite.
  2. Нашему браузеру мы укажем использовать прокси сервер для связи с сайтами.
  3. В Burp Suite мы настроем правило для замены на лету нужных нам отправляемых данных.

Запустите Burp Suite, это можно сделать из меню, либо, если вы скачали свежую версию, так:

java -jar ./Downloads/burpsuite_free_*.jar

Переходим во вкладку Proxy -> Options. Там в самом верху в Proxy Listeners нажимаем Add и добавляем новый прослушиватель: на любом не занятом порту, например, 7070. В качестве Specific Address выберите IP компьютера атакующего (т.е. той машины, где запущен Burp).

13

Здесь же перейдите во вкладку Request handling и поставьте галочку на Support invisible proxying (enable only if needed):

14

Когда добавите новый прослушиватель, поставьте галочку там, где Running (это будет означать, что он задействован в данное время):

15

Теперь спуститесь в самый низ, найдите Allow requests to web interface using fully-qualifyed DNS hostnames и поставьте там галочку:

16

Теперь перейдите в Proxy -> Intercept, отключите его:

17

Теперь в браузере открываете Настройки -> Advanced -> Network -> Connections Settings:

18

Там выберите Manual Proxy Configuration и в полях HTTP Proxy введите IP и порт прокси в Burp Suite.

19

Обновим страницу http://localhost/dvwa/vulnerabilities/upload/ и убедимся, что связь действительно осуществляется через прокси:

20

Давайте выгрузим на сервер самую обычную картинку. Она успешно загружено, а мы переходим в Burp Suite для анализа данных:

21

Очень внимательно смотрим на строку:

Content-Type: image/jpeg

Теперь давайте попробуем выгрузить наш бэкдор. Я переименовал свой файл в index3.php, просто чтобы не путаться с предыдущим примером. Итак, пробуем его выгрузить, получаем ошибку, возвращаемся в Burp Suite для анализа данных:

22

Ещё внимательнее смотрим на строку:

Content-Type: application/x-php

Думаю, теперь всем понятно, что мы будем отправлять файл index3.php, но будем заменять строку Content-Type: application/x-php на строку Content-Type: image/jpeg. Т.е. сервер получит наш вредоносный файл, и получит строку Content-Type: image/jpeg. Тип image/jpeg разрешён в скрипте для сохранения на сервер, поэтому сервер сохранит его.

В Burp переходим в Proxy -> Options. Находим там Match and Replace. Нажимаем Add для добавления нового правила:

23

Переключаемся с Request header на Request body.

В поле Match вводим Content-Type: application/x-php, в поле Replace вводим строку Content-Type: image/jpeg:

24

Сохраняем, проверьте, чтобы стояла галочка на Enabled:

25

Теперь возвращаемся к DVWA и пытаемся выгрузить файл с бэкдором index3.php:

26

Получаем:

27

Т.е. «../../hackable/uploads/index3.php succesfully uploaded!».

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

Подключимся к новому бэкдору:

cd weevely3/
python2 ./weevely.py http://localhost/dvwa/hackable/uploads/index3.php hackware

Отлично, мы внутри:

28

3. Эксплуатация XSS уязвимости при выгрузке изображений

Перейдите во вкладку DVWA Security и измените уровень безопасности на high, сохраните изменения.

Пара слов об уровне high в DVWA. Разработчики утверждают, что на «этом уровне приложение является неуязвимым, а исходный код веб-приложениях на уровне high является примером безопасных практик программирования». Это не так, на уровне high такой же говнокод как и на других уровнях и учиться нужно не по нему. Если вы «обложились» защитами от одной из угроз, а о других угрозах забыли, то это не делает ваш код намного безопаснее. [Начиная с DVWA v1.9. введён уровень «невозможный», который теперь безопасен ко всем уязвимостям, а уровень «высокий» теперь назван «расширением среднего уровня».]

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

Создайте файл примерно с таким названием:

"><img src=x onerror=prompt(1)>.jpg

Обратите внимание, что в Windows у вас это не получится, файл с таким названием возможно создать только в Linux. Выбираем его для выгрузки:

29

И вот что мы получаем:

30

4. Обход фильтрации по имени файла

Здесь возможны самые разные варианты, которые связаны с неудачной фильтрацией, приведём только некоторые общие случаи:

  • фильтрация на основе наличия в файле строки расширения. Например, на сервере разрешены изображения и скрипт для проверки полученного файла ищет в нём строку .jpg. Это неправильный подход, поскольку shell.jpg.php пройдёт такую проверку как разрешённый для сохранения. Нужно делать проверку именно по расширению присланного файла.
  • фильтрация на основе чёрного списка. В этой ситуации фильтры могут не знать о некоторых расширениях, которые также могут выполнятся на сервере, например, .phtml, .php3/.php4/.php5, .jsp, shell.jpg.PhP (обфускация). Кроме того, использование чёрного списка, если в нём отсутствует фильтр файла .htaccess могут привести к реализации следующей схемы:

загружается файл .htaccess примерно следующего содержания:

AddType application/x-httpd-php .mp3

После этого все (как в этом примере) файлы .mp3 начинаются обрабатываться PHP интерпретатором. Т.е. может быть загружен файл с разрешённым расширением .mp3, но в этом файле будет PHP код, который на сервере будет обрабатываться именно как PHP.

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

5. Запись файла в любую директорию файловой системы.

В DVWA даже на низком уровне безопасности применяется PHP функция basename. И это правильно! Поскольку если бы её не было, то заменяя на лету передаваемое имя файла, например, с 1.jpg на ../../dvwa/images/logo.png мы могли бы заменить логотип сайта.

6. Проверка только содержимого файла без проверки расширения

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

7. Проверка безопасности файла на стороне клиента

Это самое наивное, что может придумать веб-разработчик. Ни в коем случае нельзя полагаться на какую-либо валидацию с помощью JavaScript, HTML5 и т.д.

Проверка на стороне клиента = отсутствию проверки вообще.

8. Отсутствие проверки размера выгружаемого на сервер файла

Если такая проверка отсутствует, то недоброжелатели с автоматизированными скриптами выгрузки буквально за считанные часы/дни займут всё выделенное под директорию выгрузки место, а если размер этой директории не ограничен, то и на всём сервере…

9. Загрузка вредоносных файлов, не предназначенных для выполнения на сервере

Примерами таких файлов могут быть вирусы с расширением .exe. Они не страшны серверу на Linux, тем не менее, они предоставляются угрозу другим пользователям и могут привести к тому, что сервер (его IP, адрес домена) попадут в разнообразные чёрные списки.

Также сайты со зловредным содержимым исключаются из результатов поиска или писсимизируются поисковыми системами.

Т.е. такие файлы приносят вред не только сторонним лицам, но и вполне определённый, измеряемый вред серверу и веб-сайту.

Заключение

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

Тема не исчерпывается этим разделом. Существует больше методик обхода фильтров. Кроме того, при выгрузке бэкдора на сервер не всегда достаточно прав для получения полного контроля. Возможны ситуации, когда нужно изменять файлы, которые администратор выполняет со своими привилегиями. Внесённые таким образом атакующим команды будут выполнены с недоступными для него привилегиями. Также в рамках последующей эксплуатации возможно внедрение XSS на страницы сайта и расширение атаки на инфраструктуру с уязвимого сервера.

Рекомендуемые статьи:

2 комментария на Небезопасная выгрузка файлов на веб-сайты: эксплуатация и обход фильтров

  1. ta-kyn:

    За статью спасибо. По ссылке "подписаться" -> Not Found The requested URL /comment-subscriptions/ was not found on this server.

Добавить комментарий

Ваш e-mail не будет опубликован.