КатегорияВзлом



Ловушка на маковода. Как работает уязвимость в клиенте GitHub для macOS


В клиенте GitHub для macOS до версии 1.3.4 beta 1 нашлась возможность вызвать удаленное выполнение произвольных команд простым переходом по специально сформированной ссылке. В этой статье я расскажу о причинах возникновения и способах эксплуатации этой уязвимости.

Баг нашел Андре Баптиста (André Baptista) в рамках ивента H1-702 2018. Уязвимость заключается в некорректном механизме обработки кастомной URL-схемы x-github-client://, с помощью которой происходит общение с приложением.

 

Тестовый стенд

Так как сегодня рассматриваемая уязвимость работает только в macOS, все манипуляции будут производиться в ней. Я скачал виртуальную машину для VMware с macOS 10.14.1 Mojave на одном всем известном трекере.

Информация о виртуалке с macOS

Теперь нужно установить XCode и менеджер пакетов brew.

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 

Разработчики GitHub не предоставляют возможность скачивать старые версии приложения. Поэтому придется компилировать его из исходников. Клонируем репозиторий с десктопным клиентом GitHub и не забываем, что последняя уязвимая версия — 1.3.4 beta 0, ее мы и будем использовать.

$ git clone --depth=1 -b release-1.3.4-beta0 https://github.com/desktop/desktop.git 

Клиент разработан на основе фреймворка Electron и написан на TypeScript с использованием React. А это значит, что нам понадобится Node.js с кучей библиотек. Чтобы понять, как скомпилировать приложение, можно заглянуть в файл appveyor.yml. Это конфигурационный файл для сервиса системы непрерывной интеграции (CI) с таким же названием AppVeyor.

/desktop-release-1.3.4-beta0/appveyor.yml

install: - cmd: regedit /s scriptdefault-to-tls12-on-appveyor.reg - ps: Install-Product node $env:nodejs_version $env:platform - git submodule update --init --recursive - yarn install --force 

Git у нас уже имеется, а вот менеджер пакетов yarn нужно установить с помощью brew.

$ brew install yarn 

Он уже идет в комплекте с Node, но имеющаяся версия слишком нова для нашего проекта.

/desktop-release-1.3.4-beta0/appveyor.yml

environment: nodejs_version: '8.11' 

Установка менеджера пакетов yarn

Поэтому устанавливаем версию из ветки 8.х.

$ brew install node@8 

Затем заменяем версию «Ноды» на более старую с помощью команд link/unlink.

$ brew unlink node $ brew link node@8 --force --overwrite 

Даунгрейд версии Node с 11.х до 8.х для корректной компиляции

Все готово для компиляции. Сначала последовательно выполняем команды из раздела install. Это подгрузит все необходимые зависимости и пакеты.

$ git submodule update --init --recursive $ yarn install --force 

Установка зависимостей для компиляции GitHub Desktop

После этого переключаемся на команды из раздела build_script.

/desktop-release-1.3.4-beta0/appveyor.yml

build_script: - yarn lint - yarn validate-changelog - yarn build:prod 

Причем первые две можно пропустить и обойтись только последней.

$ yarn build:prod 

Успешная компиляция десктопного приложения GitHub под macOS

Теперь в директории /dist/GitHub Desktop-darwin-x64/GitHub Desktop.app находится готовое приложение. Можно скопировать его в папку Applications и запустить.

Окно About приложения GitHub Desktop для macOS

Пройди начальную настройку, и стенд готов.

 

Детали уязвимости

Посмотрим на исходники. Нас интересует, какие протоколы регистрирует приложение.

Источник: xakep.ru


Атака на приложение. Используем Xposed, чтобы обойти SSLPinning на Android


Есть разные подходы к анализу защищенности приложений, но рано или поздно все упирается в изучение взаимодействия программы с API. Именно этот этап дает больше всего информации о работе приложения, об используемых функциях и собираемых данных. Но что, если приложение защищено SSLPinning и защита реализована на уровне? Давай посмотрим, что можно сделать в этом случае.

WARNING

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

 

Прежде чем начать

SSLPinning в мобильных приложениях реализуют, внедряя сертификат SSL в саму программу. При открытии защищенного соединения приложение не обращается в хранилище устройства, а использует свой сертификат. Это сразу же устраняет возможность направить трафик на Burp и анализировать его. Ведь для того, чтобы увидеть трафик SSL, нужно внедрить на устройство Burp CA, который бы подтвердил, что созданный Burp сервер валиден и ему можно доверять.

SSLPinning — это не панацея, очень часто появляются заметки про обход защиты на банковских приложениях или вообще про уязвимости в самом SSL. Но если защита построена правильно, то это создает огромные проблемы для исследователя.

Xposed представляет собой фреймворк, который внедряется в Zygote. Это происходит при старте системы, дальше от Zygote делается .fork(), что копирует Xposed во все запущенные процессы. Сам фреймворк предоставляет возможность внедрить любой код перед функцией и после нее. Можно изменить входящие параметры, заменить функцию, прочитать данные, вызвать внутренние функции и многое другое. На самом деле на описания и демонстрацию всех возможностей Xposed уйдет не одна статья. В общем, если ты раньше с ним не работал, рекомендую ознакомиться.

Для работы Xposed нам понадобится рутованный девайс. Для демонстрации атаки возьмем простое мобильное приложение, которое использует одну из самых часто встречающихся сетевых библиотек. В этом приложении отсутствует защита от SSLUnpinning, так как описанная мной атака не пытается атаковать сертификат и сетевое общение, а нацелена на перехват данных до покрытия их SSL. Для демонстрации серверной стороны атаки и бэкенда мобильного приложения используем быстрое решение в виде Python и Flask. Все исходники ты можешь найти на моем GitHub.

Вернемся к проблеме перехвата трафика SSL. С помощью Xposed можно попытаться отключить проверку сертификата, например «затереть» его для программы. Но предположим, атакуемое приложение хорошо защищено, бэкенд проверяет валидность защиты, детектирует попытки перехвата или проксирования трафика. Что делать в таком случае? Сдаться и заняться другим приложением? А что, если перехватить трафик еще до того, как он станет сетевым?

С этого вопроса началось мое исследование.

INFO

В статье я буду работать с Android и Xposed, но подобного результата можно добиться с помощью фреймворка Frida, который доступен и на других ОС.

 

Сбор информации

Для начала попробуем запустить приложение. Видим на экране кнопку SEND и текстовое приглашение ее нажать. Нажимаем — надпись меняется сначала на «Wait…», а после отображается «Sorry, not today». Скорее всего, отправляется запрос, который не проходит проверку на стороне сервера. Давай посмотрим, что происходит внутри приложения.

 

Реверс APK

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

$ apktool d app-debug.apk 

Открываем проект в Android Studio и смотрим, что есть в smali. Сразу видим okhttp3.

INFO

Я специально использовал OkHttp, так как эта библиотека лежит в основе других библиотек для работы с API, например Retrofit 2.

.method protected onCreate(Landroid/os/Bundle;)V .line 34 iget-object v0, p0, Lcom/loony/mitmdemo/Demo;->sendButton:Landroid/widget/Button; new-instance v1, Lcom/loony/mitmdemo/Demo$1; invoke-direct {v1, p0}, Lcom/loony/mitmdemo/Demo$1;-><init>(Lcom/loony/mitmdemo/Demo;)V invoke-virtual {v0, v1}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V 

Найдем класс Main, в данном случае это com.loony.mitmdemo.Demo. В onCreate видим создание OnClickListener. Выше от него, через v1, передается как аргумент Demo$1. Посмотрим, что реализует этот класс.

.method public onClick(Landroid/view/View;)V .line 41 .local v0, "sr":Lcom/loony/mitmdemo/Demo$SendRequest; const-string v1, "test" filled-new-array {v1}, [Ljava/lang/String; move-result-object v1 invoke-virtual {v0, v1}, Lcom/loony/mitmdemo/Demo$SendRequest;->execute([Ljava/lang/Object;)Landroid/os/AsyncTask; 

В конце функции onClick вызывается асинхронная задача, которая носит очевидное имя SendRequest. Перейдем в com/loony/mitmdemo/Demo$SendRequest. Здесь мы видим множество обращений к okhttp3. Значит, мы не ошиблись в предположении.

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

Посмотрим на стандартное применение okhttp3 в проектах Android.

OkHttpClient client = new OkHttpClient(); RequestBody body = RequestBody.create(JSON, requestJson.toString()); Request request = new Request.Builder() .url(url) .post(body) .build(); Response response = client.newCall(request).execute(); 

Наиболее выгодным здесь будет перехват execute. Почему? Эта функция возвращает Response и, очевидно, отправляет Request. Это значит, что, перехватив эту функцию, мы получим возможность изменить Request до отправки и получить Response до возвращения в основную функцию.

Источник: xakep.ru


Цепная реакция. Разбираем уязвимость от забытого комментария до полной компрометации


В этой статье нам предстоит преодолеть длинную цепочку препятствий на пути к заветному руту. По дороге мы в разных вариантах обнаружим уязвимости типа LFI, RCE и эскалации привилегий. А упражняться будем на виртуальной машине ch4inrulz: 1.0.1, полученной с VulhHub.

INFO

VulnHub — ресурс, предоставляющий образы операционных систем с сервисами, в которых «зашиты» уязвимости. Скачав такой образ, любой желающий может получить опыт взлома или системного администрирования.

Также читай наш предыдущий отчет — о взломе виртуальной машины Wakanda: 1.

 

Сканирование портов

Итак, мы скачали и развернули виртуальную машину. Начнем с классики: сканируем ее при помощи Nmap. Для этого выполним такую команду (если захочешь повторить, IP будет другим):

$ nmap -Pn -A 192.168.56.101 

Обнаруживаем, что у тачки торчат порты 21/22, то есть FTP и SSH, а также 80 и 8011 — с веб-сервером.

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

На 8011-м порте видим заманчивое сообщение, но больше ничего полезного на странице не нашлось.

 

Фаззинг директорий

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

Первым мы исследовали 80-й порт, где обнаружился путь /development.

Тут нас встречает basic authentication — пробуем HTTP Verb Tampering, но безуспешно.

INFO

HTTP Verb Tampering — атака, которая использует уязвимость в HTTP-Verb-аутентификации и механизмах контроля доступа. Многие механизмы аутентификации только ограничивают доступ по своим параметрам, не предусматривая несанкционированный доступ к закрытым ресурсам с помощью других методов.

Можно начать брутить, но прежде посмотрим, что нам даст фаззинг на 8011-м порте.

Интересно! Кажется, мы нашли API какого-то приложения. Срочно лезем смотреть!

Источник: xakep.ru


Поиграем в карты? Полное прохождение заданий со смарт-картами OFFZONE Badge Challenge


На OFFZONE была серия задач на смарт-карте с интерфейсом ISO/IEC 7816. Особо внимательных даже предупредили заранее. Тут опубликовали фотографию бейджа и прямо заявили, что «бейдж можно будет взломать, если вам это будет по силам». Нам оказалось это по силам, и из этой статьи ты узнаешь — как. ?

Чтобы решать задачи, нужно было иметь подходящий картридер. Те, кто пришел на конференцию неподготовленным, имели возможность приобрести картридер в «Лавке старьевщика» за OFFCOIN или российские рубли. Правда, продавалось всего 30 ридеров, и их быстро разобрали.

Описание задач было приведено на этой странице.

 

Официальные задания

Авторы заданий сделали очень хорошее «краткое введение» в терминологию, базовые принципы и популярные инструменты.

 

Как работать с картой

Общение со смарт-картами ведется при помощи USB-картридеров, которые можно найти в GAME.ZONE, а также купить в «Лавке старьевщика».
APDU-команда

Пакеты, которые воспринимает карта, называются APDU-командами. APDU-команда представляет собой последовательность 4-байтового заголовка и данных команды.

Общий формат APDU-команды:

  • [CLA INS P1 P2 Lc DATA Le]
  • CLA (Instruction class) определяет тип посылаемой команды.
  • INS (Instruction code) определяет конкретную команду внутри класса.
  • P1, P2 (Parameter 1/2) являются аргументами команды.
  • Lc (Length of command data) определяет размер данных в поле DATA.
  • DATA (?) содержит в себе Lc байт данных команды.
  • Le (Length of expected data) определяет размер данных, которые ожидается получить в ответе карты.

Команда обязательно содержит 4 первых байта, остальные байты опциональны. В ответ мы получаем код ошибки, состоящий из 2 байт (SW1, SW2), и опциональное поле данных размера <= Le байт.

Для отправки APDU-команд удобно пользоваться библиотекой pyscard для Python. Например, так выглядит код для получения серийного номера Java-карты:

from smartcard.System import readers from smartcard.util import * r = readers() reader = r[0x00] # Let's assume that we only have one reader connection = reader.createConnection() connection.connect() SELECT_MANAGEMENT = [0x00, 0xA4, 0x04, 0x00, 0x08] + [0xA0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00] (data, sw1, sw2) = connection.transmit(SELECT_MANAGEMENT) GET_CPLC_DATA = [0x80, 0xCA, 0x9F, 0x7F, 0x00] (data, sw1, sw2) = connection.transmit(GET_CPLC_DATA) print data 

Если давать высокоуровневое описание Java-карты, то она представляет собой совокупность Java-апплетов, которые выполняют определенные задачи. Апплеты идентифицируются с помощью уникального Applet Identifier (AID), задаваемого при разработке апплета. По умолчанию Java-карта должна содержать Manager-апплет (AID = [0xA0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00]), который используется для управления другими апплетами на карте. Задания также представляют собой отдельные апплеты. Перед началом работы с апплетом нужно выполнить команду SELECT и AID апплета:

AID=[...] SELECT_APPLET = [0x00, 0xA4, 0x04, 0x00] + [len(AID)] + AID 

В качестве основного способа общения с картой предполагалось использовать язык Python и библиотеку pyscard. Небольшая сложность, с которой лично я столкнулся на начальном этапе, была в том, что я не нашел готового инсталлятора и не справился со сборкой pyscard под Python 3.7. А после установки старой версии pyscard 1.7.0 под Python 2.7 выяснилось, что простейшие примеры из документации pyscard падают с ошибкой. Зато связка pyscard 1.9.3 и Python 3.6.7 x64 заработала сразу и без нареканий.

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

from smartcard.System import readers def hx(ab): return ".".join("%02X" % v for v in ab) # Convert bytes to hex def sx(ab): return "".join(chr(v) for v in ab) # Convert bytes to string SELECT_APPLET = [0x00, 0xA4, 0x04, 0x00] class OFFZONE(object): dCmds = { # List of known commands (for debugging) hx(SELECT_APPLET): "SELECT_APPLET", } def __init__(self, ind=0): self.DBG = False self.r = readers() if self.DBG: if self.r: print("Readers:") for i, v in enumerate(self.r): print("%3d: %s" % (i, v)) else: print("No readers") self.conn = self.r[ind].createConnection() self.conn.connect() def exch(self, cmd, arg=None): # Perform APDU command exchange if self.DBG: msg = [self.dCmds.get(hx(cmd), hx(cmd))] if arg is not None: msg.append(hx(arg)) print("Send: %s" % " + ".join(msg)) ext = [] if arg is None else [len(arg)] + list(arg) data, sw1, sw2 = self.conn.transmit(cmd + ext) if self.DBG: print("Recv: %02X.%02X + [%s]" % (sw1, sw2, hx(data))) return data, sw1, sw2 def select(self, AID): # Select applet by AID or task index if isinstance(AID, int): # Task index provided AID = [0x4F, 0x46, 0x46, 0x5A, 0x4F, 0x4E, 0x45, 0x30+AID, 0x10, 0x01] return self.exch(SELECT_APPLET, AID) def command(self, cla, ins, arg=None): # Execute command cmd = [cla, ins, 0, 0] return self.exch(cmd, arg) def main(): oz=OFFZONE() ## Task1(oz) ## Task2(oz) ## Task3(oz) ## Task4(oz) 

 

Training Mission

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

  • AID: [0x4f, 0x46, 0x46, 0x5a, 0x4f, 0x4e, 0x45, 0x31, 0x10, 0x01]
  • CLA: 0x10
  • INS:
    • 0x??: getFlag: [0x10, 0x??, 0x00, 0x00]
    • 0xE0: checkFlag(flag):
      • [0x10, 0xE0, 0x00, 0x00, 0xNN] + flag (0xNN bytes of flag)

В первой задаче требовалось найти однобайтовое значение INS, и очевидно, что проще всего это было сделать перебором 256 возможных вариантов.

Решение

def Task1(oz): print("nTask #1 (Training Mission)") oz.select(1) CLA = 0x10 INS_CheckFlag = 0xE0 for INS_GetFlag in range(0x100): data, sw1, sw2 = oz.command(CLA, INS_GetFlag) if 0x90 == sw1 and 0x00 == sw2 and data: print("INS_GetFlag=0x%02X, Flag: %s" % (INS_GetFlag, repr(sx(data)))) data, sw1, sw2 = oz.command(CLA, INS_CheckFlag, data) print("CheckFlag: %02X.%02X + [%s]" % (sw1, sw2, hx(data))) break else: print("INS_GetFlag value not found") 

Легко заметить, что на большинство запросов (с неподдерживаемыми значениями INS) в качестве статуса ответа (sw1 и sw2) возвращаются значения 0x6D и 0x00. Если свериться с таблицей кодов APDU-ответов, становится понятно, что 6D 00 соответствует ошибке Instruction code not supported or invalid. Для правильного запроса возвращается статус 90 00 и флаг.

Источник: xakep.ru


Старый сарай, новые грабли. Эксплуатируем PHAR-десериализацию в phpBB


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

INFO

Уязвимость связана с техникой PHAR-десериализации, которую мы недавно освещали. Баг актуален для phpBB версии 3.2.3.

Думаю, что phpBB в представлении не нуждается. Он существует аж с 16 декабря 2000 года. Поднимем бокалы за его совершеннолетие! За это время движок повидал множество уязвимостей самого разного рода. Одна из самых известных — CVE-2004-1315, или в миру viewtopic highlight PHP injection. Этот баг был одним из первых, который я изучил.

Впрочем, вернемся к современным реалиям. Сейчас phpBB, конечно, растерял былую популярность, но все еще огромное количество площадок выбирает его как основную платформу общения пользователей.

Уязвимость нашел исследователь из RIPS Technologies, воспользовавшись сканером исходных кодов производства своей компании. Можно даже заценить его отчет.

 

Стенд

Начнем с привычного — поднятия среды для тестирования уязвимости. Форум работает со многими базами данных, но я буду использовать старый добрый MySQL в виде контейнера Docker. Рекомендую использовать версии из ветки 5.х, так как в последних бранчах (8.х) изменился протокол авторизации по умолчанию и клиентские библиотеки текущих репозиториев PHP не работают с ним. Такое поведение можно поменять в конфигурационном файле MySQL, но зачем лишние телодвижения для тестового стенда, верно?

$ docker run -e MYSQL_USER="phpbb" -e MYSQL_PASSWORD="JaLdqX5on0" -e MYSQL_DATABASE="phpbb" -d --rm --name=mysql --hostname=mysql mysql/mysql-server:5.7 

Теперь можно приступать к разворачиванию самого сервера. По традиции использую Debian.

$ docker run --rm -p80:80 -ti --name=phpbb --hostname=phpbb --link=mysql debian /bin/bash 

Обновляем репозитории и ставим нужные пакеты.

$ apt update && apt install -y zip wget nano apache2 php php-mysql php-xml php-mbstring php-gd 

Скачиваем архив с уязвимой версией форума phpBB (3.2.3) и распаковываем его.

$ cd /var/www/html $ wget https://www.phpbb.com/files/release/phpBB-3.2.3.zip $ unzip phpBB-3.2.3.zip $ chown www-data:root -R phpBB3 

Если хочется побаловаться с отладкой, то дополнительно ставим xdebug.

$ apt install -y php-xdebug 

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

$ echo "xdebug.remote_enable=1" >> /etc/php/7.0/mods-available/xdebug.ini $ echo "xdebug.remote_host=192.168.99.1" >> /etc/php/7.0/mods-available/xdebug.ini $ phpenmod xdebug 

Далее правим конфиги веб-сервера и запускаем его.

$ sed 's/html/html/phpBB3/' -i /etc/apache2/sites-enabled/000-default.conf $ service apache2 start 

Теперь переходим в браузере по адресу контейнера и устанавливаем и настраиваем форум.

Установка форума phpBB

После завершения инсталляции не забудь снести папку install.

$ rm -rf /var/www/html/phpBB3/install 

Стенд готов.

 

Часть первая: внедряем враппер phar

Начнем с просмотра исходников. Если ты внимательно изучал мою прошлую статью про PHAR-десериализацию, то знаешь, на вызовы каких функций стоит обратить особое внимание при поиске потенциально уязвимых мест. Конкретно в этом случае нужно поискать file_exists. Код phpBB объемный (~300 тысяч строк), и вызовов этой функции там предостаточно. Но нас интересуют только те, которым в качестве аргумента можно пропихнуть юзердату. Не буду тянуть и скажу, что интересующий нас вызов находится в файле functions_acp.php.

/phpBB3.2.3/includes/functions_acp.php

420: function validate_config_vars($config_vars, &$cfg_array, &$error) 421: { ... 428: foreach ($config_vars as $config_name => $config_definition) 429: { ... 443: switch ($validator[$type]) 444: { ... 544: case 'rpath': 545: case 'rwpath': ... 568: case 'absolute_path': 569: case 'absolute_path_writable': 570: // Path being relative (still prefixed by phpbb_root_path), but with the ability to escape the root dir... 571: case 'path': 572: case 'wpath': ... 588: $path = in_array($config_definition['validate'], array('wpath', 'path', 'rpath', 'rwpath')) ? $phpbb_root_path . $cfg_array[$config_name] : $cfg_array[$config_name]; 589: 590: if (!file_exists($path)) 591: { 592: $error[] = sprintf($user->lang['DIRECTORY_DOES_NOT_EXIST'], $cfg_array[$config_name]); 593: } 594: 595: if (file_exists($path) && !is_dir($path)) 596: { 597: $error[] = sprintf($user->lang['DIRECTORY_NOT_DIR'], $cfg_array[$config_name]); 598: } 599: 600: // Check if the path is writable 601: if ($config_definition['validate'] == 'wpath' || $config_definition['validate'] == 'rwpath' || $config_definition['validate'] === 'absolute_path_writable') 602: { 603: if (file_exists($path) && !$phpbb_filesystem->is_writable($path)) 604: { 605: $error[] = sprintf($user->lang['DIRECTORY_NOT_WRITABLE'], $cfg_array[$config_name]); 606: } 607: } 

Из названия файла можно понять, что функция валидации конфигурационных переменных (validate_config_vars) заходит в нужную нам ветку, когда выполняется проверка путей в панели администратора (в терминологии phpBB ACP — Administrator Control Panel).

Проверим это. Откроем админку и найдем любой раздел, где можно указать путь.

Раздел настроек прикрепляемых файлов

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

Отладки функции validate_config_vars в phpBB

Брейк-пойнт сработал, так как валидатором переменной upload_path служит wpath.

/phpBB3.2.3/includes/acp/acp_attachments.php

138: $display_vars = array( ... 150: 'upload_path' => array('lang' => 'UPLOAD_DIR', 'validate' => 'wpath', 'type' => 'text:25:100', 'explain' => true), 

Никаких дополнительных проверок переменной $path не производится, и указанное пользователем значение попадает в качестве аргумента в функцию file_exists.

Передача пользовательских данных в функцию file_exists

Обрати внимание на добавленный префикс ./../. Он появляется, потому что мы имеем дело с настройкой, которая подразумевает относительные пути. Но для выполнения атаки нам нужен полный контроль над всей переменной, поскольку требуется передать значение, начинающееся с враппера phar://. Для этих целей отлично подойдут те настройки, у которых есть валидатор absolute_path.

Одна из таких — это img_imagick. Путь до бинарника утилиты ImageMagick для манипуляции с загруженными изображениями. Находится она там же, в разделе настройки аттачей.

/phpBB3.2.3/includes/acp/acp_attachments.php

138: $display_vars = array( ... 167: 'img_imagick' => array('lang' => 'IMAGICK_PATH', 'validate' => 'absolute_path', 'type' => 'text:20:200', 'explain' => true, 'append' => '&nbsp;&nbsp;<span>[ <a href="' . $this->u_action . '&amp;action=imgmagick">' . $user->lang['SEARCH_IMAGICK'] . '</a> ]</span>'), 

Использование враппера phar в качестве пути к ImageMagick

Вот теперь получается настоящее внедрение, и первая часть атаки успешно выполнена.

Внедрение враппера phar в аргумент функции file_exists

Источник: xakep.ru


Энкодеры msfvenom. Разбираемся с кодированием боевой нагрузки при бинарной эксплуатации


Генерация полезной нагрузки — неотъемлемая часть эксплуатации. При использовании модулей Metasploit пейлоад генерируется автоматически, достаточно выбрать тип и задать некоторые переменные. В этой статье мы попробуем разобраться с ролью энкодеров в бинарной эксплуатации и рассмотрим несколько реальных примеров энкодинга на боевых эксплоитах.

Обычно модули скрывают от пользователя детали реализации полезной нагрузки. Ситуация немного меняется, когда дело доходит до необходимости воспользоваться эксплоитом, для которого не существует модулей Metasploit, но есть, например, PoC на Python или любом другом языке.

В таких обстоятельствах очень полезным инструментом может оказаться утилита msfvenom, входящая в состав Metasploit Framework, которая умеет генерировать полезные нагрузки на основании заранее определенных шаблонов. Эта утилита настолько удобна, что сводит процесс генерации пейлоада к все тому же выбору типа и заданию необходимых переменных.

Одна из опций при генерации шелл-кода с msfvenom — это выбор энкодера. Шелл-кодинг — не самая простая для понимания тема, поэтому даже такая вспомогательная часть этого процесса, как энкодинг полезной нагрузки, порождает огромное количество мифов и заблуждений.

 

Buffer Overflow

Поскольку тема шелл-кодинга неотделима от эксплуатации бинарных уязвимостей, давай рассмотрим небольшой фрагмент кода, содержащего в себе типичный Stack-based Buffer Overflow.

#include <stdio.h>
#include <string.h>

int main (int argc, char** argv) {
 char buffer[100];
 strcpy(buffer, argv[1]);

 return 0;
} 

Уязвимость этого кода происходит из функции strcpy(char *destination, const char *source). Вот так выглядит описание этой функции в официальной документации:

В двух словах: если длина строки (то есть разница между адресом первого байта строки и адресом первого нулевого байта, именуемого NULL-терминатором), на которую указывает argv[1], больше размера буфера buffer, то произойдет тот самый Stack-based Buffer Overflow.

Если рандомизация адреса стека отключена, атакующий может предсказать то место, куда будут записаны данные. Таким образом, манипуляциями с argv[1] можно записать полезную нагрузку в стек, а также подменить адрес возврата так, чтобы передать ей управление.

Если защита от исполнения данных также отключена, то шелл-код будет исполнен.

Хорошим примером полезной нагрузки будет шелл-код, запускающий командную оболочку sh, который можно сгенерировать с помощью msfvenom.

Здесь и начинается все интересное.

 

Зачем нужны энкодеры?

Если передать нашей программе строку вида argv[1] = shellcode + "BBBB" + shellcode_address, то переполнение не произойдет. Это связано с тем, что шестнадцатый байт шелл-кода равен x00, так что копирование этого буфера в стек прекращается после 15 байт.

Источник: xakep.ru


Дырявый Word. Как спрятать боевую нагрузку в документе


В современных версиях Microsoft Office документы по умолчанию сохраняются в формате, основанном на Office Open XML, однако Microsoft не во всем следует открытому стандарту. Вариант Microsoft часто называют MOX, Microsoft Open XML. Он содержит некоторые вольности, создающие угрозы безопасности. Сегодня мы подробно разберем одну из них — так и не закрытую на момент написания статьи.

Почти сразу после публикации чернового варианта OOXML началась битва за его стандартизацию. Вот краткая хронология версий.

  • 2006 год — ЕСМА-376, первая версия;
  • 2008 год — ISO/IEC 29500:2008 Transitional, переходная вторая версия;
  • 2008 год — ЕСМА-376, part 2, и ISO/IEC 29500:2008 Strict, финальная вторая версия;
  • 2011 год — ЕСМА-376, part 3, и ISO/IEC 29500:2011, третья версия;
  • 2012 год — ЕСМА-376, part 4, и ISO/IEC 29500:2012, четвертая версия;
  • 2015 год — ЕСМА-376, part 5, и ISO/IEC 29500-3:2015, пятая версия OOXML.

В 2016 году появились дополнения к пятой версии: ISO/IEC 29500-1:2016 и ISO/IEC 29500-4:2016. Работа над стандартом продолжается, а Microsoft допускает все больше проприетарных особенностей его реализации в новых версиях Office. Хуже того: компания не признает старые уязвимости, оставляя их в новых продуктах. Описываемая в статье дыра появилась в Microsoft Office 2013 и сохранилась вплоть до Office 2019.

INFO

ECMA-376 включает в себя три различные спецификации для каждого из трех основных типов документов Office — WordprocessingML для текстовых документов, SpreadsheetML для электронных таблиц и PresentationML для презентаций. Мы будем использовать WordprocessingML.

Я возьму на себя смелость указать на два критичных с точки зрения безопасности недостатка MOX, унаследованных от OOXML:

  • возможность легкого редактирования внутренней структуры документов;
  • отсутствие проверок на злонамеренную модификацию.

По сути, MOX и OOXML — это XML в ZIP. Это отличный hacker-friendly-формат, поскольку найти и заменить свойства объектов в нем исключительно просто даже без использования HEX-редакторов и прочих специфических утилит. Достаточно встроенной в Windows поддержки ZIP и «Блокнота». Весь код легко читается глазами и правится, как текст. Ни сверки контрольных сумм, ни каких-то иных специфических проверок при этом не выполняется. Word лишь проверяет целостность документа, которая не нарушается при подменах с соблюдением правил синтаксиса.

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

WARNING

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

 

Описание уязвимости

В базе уязвимостей MITRE есть много однотипных записей вида: «Microsoft Office… do not properly validate record information during parsing of (Excel spreadsheets / Word documents, Power Point presentations)… which allows remote attackers to execute arbitrary code or cause a denial of service (memory corruption) via a crafted file)». Проще говоря, проблемы парсинга XML в MS Office неисчерпаемы, как атом.

Я уже рассматривал одну из них в статье «Pass the Hash через Open XML». Сейчас мы реализуем другую атаку, также слегка поковыряв недра файла Word.

Начиная с Office 2013 в OOXML стал доступен класс WebVideoProperty. Он появляется в разметке при вставке в документ онлайн-видео и описывает параметры его воспроизведения через набор атрибутов.

Нас будет интересовать атрибут embeddedHtml. Он нужен для вставки внешних объектов и содержит ссылку на них (например, на видеоролик YouTube). Из-за того что этот параметр «знает», из какого закоулка интернета тянуть картинку видеозаписи, его нельзя опустить при парсинге.

 

Ищем объект подмены

Давай выполним простую атаку подмены и пощупаем уязвимость своими руками. Запускаем Word (требуется версия 2013 или выше, так как нам нужна полная поддержка ISO/IEC 29500 Strict) и идем в меню «Вставка».

Источник: xakep.ru