• Курсы Академии Кодебай, стартующие в мае - июне, от команды The Codeby

    1. Цифровая криминалистика и реагирование на инциденты
    2. ОС Linux (DFIR) Старт: 16 мая
    3. Анализ фишинговых атак Старт: 16 мая Устройства для тестирования на проникновение Старт: 16 мая

    Скидки до 10%

    Полный список ближайших курсов ...

Гостевая статья Внедрение SQL-кода в BigTree CMS 4.4.6

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

bigtree446_blog.png



Мы отсканировали одну из последних версий BigTree CMS 4.4.6 и обнаружили множество уязвимостей. Среди них уязвимость SQL Injection и уязвимость Phar Deserialization, приводящая к удаленному выполнению кода в небольшом веб-приложении.

Усеченные результаты анализа доступны в нашем демонстрационном приложении RIPS. Обратите внимание, что мы ограничили результаты проблемами, описанными в этом посте, чтобы обеспечить исправление.


Цепная инъекция SQL и XSS
BigTree CMS страдает простым SQL-инъекцией, которую можно использовать на панели инструментов. Необработанный параметр позволяет переопределить Tableсвойство, позволяя манипулировать основным синтаксисом SQL для извлечения произвольной конфиденциальной информации из базы данных. Затем веб-приложение продолжает печатать все данные, полученные с помощью SQL-запроса, и возвращает их аутентифицированному администратору.

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

PHP:
$form = BigTreeAutoModule::getForm($_GET["form"]);   
// Create a generic module class to get the decoded item data
$m = new BigTreeModule;
$m->Table = $form["table"];
$item = $m->get($_GET["id"]);

В строке 6 пользовательский ввод принимается через formпараметр и сохраняется в $formпеременной. Затем его значение присваивается $m->Tableсвойству BigTreeModuleэкземпляра. Наконец, get()метод вызывается для объекта, который запускает SQL-запрос в строке 10. Этот метод $itemбезопасно внедряет пользовательский ввод переменной и небезопасно внедряетTable свойство tainted .

PHP:
class BigTreeModule {
  ⋮
  public function get($item) {
  ⋮
  $item = sqlfetch(sqlquery("SELECT * FROM `".$this->Table."` WHERE id = '".
                                sqlescape($item)."'"));

Затем данные могут быть вывезены контрабандой с помощью уязвимости межсайтового скриптинга. Для этого злоумышленник должен контролировать значения $itemмассива, возвращаемого SQL-запросом, чтобы начать со строки «http» . Это заставляет поток управления переходить в программный блок, который автоматически обрабатывает ссылки, начиная со строки 19 следующего исходного кода.

PHP:
<?php
foreach ($form["fields"] as $field => $resource) {
  ⋮
  if ($resource["type"] == "text" && is_string($item[$field])) {
    $href = $item[$field];
    ⋮
    if (substr($href,0,4) == "http" && strpos($href,WWW_ROOT) === false) {
    ⋮
      if (!$admin->urlExists($href))
          $integrity_errors[$field] = array("a" => array($href));
    }
  }
}
⋮
foreach ($integrity_errors as $field => $error_types) {
  foreach ($error_types as $type => $errors) {
    foreach ($errors as $error) { ?>
      <p>Broken <?=(($type == "img") ? "Image" : "Link")?>: <?=$error?>
      in field &ldquo;<?=$form["fields"][$field]["title"]?>&rdquo;</p>


Для каждой потенциальной ссылки программа отправит веб-запрос с помощью urlExists()метода. Если запрос не выполняется, данные добавляются в массив ошибок $integrity_errorsв строке 22. Значения этого массива печатаются без цикла в foreachцикле в строке 30, что приводит к выводу нашего SQL-инъекции непосредственно рядом с нашей полезной нагрузкой межсайтового скриптинга, извлекающей данные на внешний сервер. Хотя это обычно сложно использовать SQL-инъекцию через CSRF, , в этом случае мы можем использовать уязвимость межсайтового скриптинга, чтобы легко переправлять результаты с помощью запроса AJAX.

Десериализация Phar через оболочку CURL
позволяет загружать файлы из файловой системы, добавляя к имени файла @символ. Добавление параметра -d param=@/path/to/filenamecurl в CLI curl позволит удобно загружать содержимое указанного имени файла на целевой сервер. BigTree разработала свою собственную функцию обертки curl BigTree::cURL()для реализации этой функции.

PHP:
public static function cURL($url, $post = false, $options = [],
  $strict_security = true, $output_file = false, $updating_bundle = false) {
  ⋮
  if ($post !== false) {
    if (function_exists("curl_file_create") && is_array($post)) {
      foreach ($post as &$post_field) {
        if (substr($post_field, 0, 1) == "@"
            && file_exists(substr($post_field, 1))) {
          $post_field = curl_file_create(substr($post_field, 1));

Метод получает данные для отправки в теле HTTP в качестве второго аргумента $postстатического метода. В строке 268 он выполняет итерацию по массиву и проверяет значения для @символа, который может содержать суффикс имени файла. Это имя файла используется в качестве аргумента для file_exists()строки 270 перед добавлением содержимого файла в запрос curl, что приводит к уязвимости Phar Deserialization, если мы имеем контроль над значением $postмассива. Это предположение верно для URL, http://<host>/bigtree446/site/index.php/admin/developer/services/instagram/return/?code=@phar://myphar.pharкоторый направляет аутентифицированного внутреннего пользователя непосредственно в следующую точку входа:

PHP:
$token = $api->oAuthSetToken($_GET["code"]);

Пользовательский ввод, сохраненный в codeпараметре, передается методу в качестве $codeаргумента oAuthSetToken(). Это перенаправляет значение прямо в BigTree::cURL()обертку сверху, что приводит к уязвимости Phar Deserialization.

PHP:
public function oAuthSetToken($code) {
    $response = json_decode(BigTree::cURL($this->TokenURL,array(
        "code" => $code,
                ⋮
    )));


Чтобы воспользоваться этой уязвимостью, необходимо загрузить файл. Этого можно достичь, только правильно разместив токен CSRF. Однако этот токен CSRF можно украсть, воспользовавшись уязвимостью межсайтового скриптинга сверху и украдя токен. Это позволит загрузить файл, который можно использовать в процессе десериализации Phar.

Резюме
В этом посте мы увидели, что ручная очистка каждого параметра - утомительный и опасный метод защиты вашего приложения. Опытные злоумышленники могут объединить несколько эксплойтов, чтобы начать успешную целевую атаку с высоким уровнем воздействия. Рекомендуется потратить время на разработку и использование централизованного модуля безопасности, который будет объединять очистку и подготовку базы данных. Автоматическое тестирование безопасности может помочь в процессе обнаружения уязвимых остатков унаследованного кода при ретроактивной реализации функций безопасности. Сканер RIPS обнаружил проблемы в течение 7 минут. В частности, начало пути к файлу не должно контролировать злоумышленник, чтобы отрицать использование через произвольные фильтры PHP, такие как phar://обертка.

Источник:
 
  • Нравится
Реакции: Дядюшка Рик
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!