• XSS.stack #1 – первый литературный журнал от юзеров форума

Актуальность CRT в 2024

coree

(L2) cache
Пользователь
Регистрация
27.12.2021
Сообщения
303
Решения
1
Реакции
116
Гарант сделки
1
Депозит
0.0006
Сабж. Насколько сейчас, в 2024 году, актуально пытаться выпилить crt из своих "проектов"? В чем смысл такого выпиливания кроме очевидного уменьшения размера?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Меньше вызовов будет которые авер сможет отследить и уловить
 
Сабж. Насколько сейчас, в 2024 году, актуально пытаться выпилить crt из своих "проектов"? В чем смысл такого выпиливания кроме очевидного уменьшения размера?
да ни в чем, даже наоборот, отсутствие crt большой красный флаг для аверов, потому что легитное по часто его имеет, а вот малварь нет, то бишь это неплохой такой знак отличия.
 
Имеет смысл выпиливать CRT разве что для удобства дальнейшей упаковки/крипта, в остальных случаях от этого больше минусов, чем плюсов.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Шеллкод ты не сможешь сделать с CRT.
 
Шеллкод ты не сможешь сделать с CRT.
Ну так речь то идёт, скорее всего, о малвари (учитывая раздел и контекст вопроса). ¯\_(ツ)_/¯

Более того, чисто технически вообще-то можешь (надеюсь под шеллкодом мы понимаем одно и тоже), ибо технически ничто (кроме всяких EDR) не запрещает тебе найти по сигнатурам в другом процессе нужные тебе функции и вставить E8 коллы на них в твоём шеллкоде, или тоже самое, но с предварительной возможной подгрузкой msvcrt.dll, если CRT не был прилинкован ни в каком виде. Понятно, что это всё дикое палево, но опять же, чисто технически это реализуемо. Хотя если подумать, можно сам шеллкод заставить искать нужные ему сигнатуры будучи уже в процессе перед выполнением основной части и селф-патчем, но опять же, дополнительная ненужная заморока.

Если уж говорить про выпиливание CRT в таком контексте, то я согласен с reqwest, от этого действительно гораздо больше проблем, нежели пользы:
  • Из самого очевидного - ты лишаешься средств языка и тратишь время на изобретение велосипедов, разработка удлиняется без какой-либо очевидной выгоды.
  • Ты делаешь свою малварь гораздо более подозрительной для АВ. Наверное все нативные современные языки линкуют сишный рантайм, начиная от самого си, заканчивая тем же растом. Таким образом отсутствие CRT это большой красный флаг для АВ, ибо это означает, что это скорее всего какое-то говно - либо это легитная прога, которая была запакована / виртуализирована / "закриптована" / ещё что-то, либо это потенциальная малварь - в любом случае с ней что-то не так и стоило бы её отправить на дополнительный анализ.
  • Ну и касательно анализа, убирая CRT ты не только усложняешь себе жизнь, но и ещё немного упрощаешь её реверсерам, ибо теперь им не нужно дополнительно ковыряться в нераспаршенных идой CRT функциях, которые ты мог бы потенциально вызывать вместо самописных, а твоя логика нередко будет гораздо проще CRT'шной, ибо там нередко встречаются SIMD оптимизации например. =)
А из плюсов за всё это ты получаешь только уменьшенный размер своего бинарника. ¯\_(ツ)_/¯
 
Насколько сейчас, в 2024 году, актуально пытаться выпилить crt из своих "проектов"?
Если белые проеты, то зачем из них выпиливать crt? Под малварь имеет смысл только для уменьшение размера билда который потом будет "зашифрован" в теле криптованного файла в .data/.text секции, ну и без crt будет чуть меньше энтропия (хотя это еще смотря какой алгоритм шифрования будет использовать криптор). Сейчас лучше вообще не хранить шеллкод в бинарнике а через инет его тащить с серва, при этом домены что б были не новорег а лучше всего с open redirect сайтов по типу как было с amp гугл`а https://www.google.com/amp/s/xss.pro (уже баян).
Меньше вызовов будет которые авер сможет отследить и уловить
Какие вредоносные вызовы делает crt что б их ав отслеживал? Привычные всем нам хуки уже уходят на третий план, сейчас ав больше надеется на встроенную и на собственную реализацию ETW ну и конечно же он мониторит патчи для etw (EtwEventWrite, NtTraceEvent и тд) и в последнее время еще VEH.
Шеллкод ты не сможешь сделать с CRT.
Собрать с /MT а потом обернуть в donut с аргументом /b 1 , и все прекрасно будет работать.
 
Собрать с /MT а потом обернуть в donut с аргументом /b 1 , и все прекрасно будет работать.
Ага, вот только это называется не "написанием шеллкода" а конвертацией бинарника в шеллкод. Такой бинарь будет минимум 80кб на новых студиях, что для шеллкода не всегда позволительно, тк при экспулуатации каких-либо уязвимостей может быть размер шк жестко ограничен и туда 80кб которые генерируются с /MT тупо не вставишь.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Собрать с /MT а потом обернуть в donut с аргументом /b 1 , и все прекрасно будет работать
8xjekt.jpg
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Если у тебя в проекте црт, и криптор тоже собран с црт, могут быть трудноуловимые нюансы.
 
CRT это не только размер, но и тормоза, а так же использование неясных и абсолютно не нужных, к примеру new/malloc, которые к примеру хз как кучу выделяют/очищают от версии к версии. Не все функции из CRT нормально отработают (тот же malloc, rand, memset,memcpy и другая хрень), если к примеру маппинг файла на исполнение в памяти делать.
 
CRT хорошо сгодится только если ты "руками" хочешь почистить свой код от детектов и как-то точечно его использовать, в остальных случаях он нахрен не нужен и только добавляет проблем и веса бинарю. И это не только 2024, это на все времена.
 
Получается, с выпиливанием CRT придется отказаться и от STL? В чем смысл малвари на плюсах, если функционал языка становится урезанным до уровня C с классами?
 
Получается, с выпиливанием CRT придется отказаться и от STL? В чем смысл малвари на плюсах, если функционал языка становится урезанным до уровня C с классами?
Не знаю как там в плюсах, но в расте 70% всей стандартной либы доступно без CRT - отсутствуют только платформозависимые фичи (работа с файловой системой/процессами/потоками/...), большинство коллекций, по типу Vec/VecDeque/HashMap (правда в отдельном крейте)/... доступно после реализации глобального аллокатора.
К черту плюсы, даёшь раст!
 
доступно после реализации глобального аллокатора.
Ты чего, какие ещё глобальные аллокаторы, какие страшные слова, тут у нас чуваки боятся malloc использовать, у которого под капотом HeapAlloc и который "хз как работает", а ты про какие-то аллокаторы им затираешь.
Честно говоря почитав комментарии выше в моменте даже захотелось расписать по пунктам, почему написанное выше чепуха полнейшая, но учитывая уровень аргументации из разряда CRT не нужен, потому что "ниасилил" и "не понял", и вообще он много места занимает (!!!), учитывая что ТС изначально обозначил, что этот момент ему и так очевиден и его обсуждать не стоит, крайне маловероятно, что это возымеет хоть какой-то эффект.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
тут у нас чуваки боятся malloc использовать, у которого под капотом HeapAlloc и который "хз как работает"
С этим согласен. Как работает маллок\фри надо на зубок знать от версии к версии, чтобы кучу корраптить. Уважающий себя малварщик знает кучу и может закорптить кучу чтобы написать червя. например для .rtf Тем более я писал мини статью про фулл-сплойты, что собирают адреса смещения, а люди до сих пор не могут сделать это в том же фортиос. Там даже чел в каком-то топике выложил все гаджеты для разных версий glibc. В винде тоже самое, тем более все давно уже задокументировано, утечки тоже можно получить.
 
Хотя ладно, пост выше был немного эмоциональным, признаю, как наверное будет и этот, потому что я словил эмоцию и продолжаю её ловить при каждом перепрочтении, но наверное нормально ответить всё же стоит. Просто если честно, меня очень сильно раздражают заявления, которые никак не подтверждаются и даже не аргументируются / не объясняются, но при этом претендуют на истину, как например это заявление:
CRT это не только размер, но и тормоза, а так же использование неясных и абсолютно не нужных, к примеру new/malloc, которые к примеру хз как кучу выделяют/очищают от версии к версии. Не все функции из CRT нормально отработают (тот же malloc, rand, memset,memcpy и другая хрень), если к примеру маппинг файла на исполнение в памяти делать.
CRT это тормоза... Почему, ну... - Наверное, потому что гладиолус. Наверное, если вызывать HeapAlloc напрямую, а не через прокладки в виде new / malloc, то от этого он станет работать быстрее и аллоцировать лучше. Тут важно понять, что VirtualAlloc не является альтернативой, об этом я распишу ниже. Про маппинг файла на исполнение так же скажу ниже, но если кратко, то описанное называется skill issue или "не осилил", и почему вдруг приведенные им выше функции при нормальном маппинге в память не должны "нормально" отработать, он не объяснил, как и то, как в этот список попали memset и memcpy (насчет rand не скажу, не смотрел имплементацию). Ниже постараюсь без эмоций.

Если у тебя в проекте црт, и криптор тоже собран с црт, могут быть трудноуловимые нюансы.
Что касается крипта, да, некоторые крипторы действительно прилинковывают CRT к твоему проекту, потому что это уменьшает количество детектов, почему, я расписывал выше, и да, твой CRT может конфликтовать с CRT крипта, только вот вопрос, а причем тут ты и почему это вдруг стало твоей проблемой? Это проблема криптора, хороший криптор должен знать эти нюансы и уметь их обойти, чтобы конфликтов не было. Я сейчас всё не вспомню, давно было (где-то года 2 назад), но когда я пилил свой "морфер", насколько я помню, основные проблемы у меня были следующие:
1. __tls_index (это вообще мем, можешь погуглить =D), у экзешника он всегда 0 и CRT юзает его для инициализации статической TLS даты, таким образом очевидно будет конфликт между CRT крипта и экзешника, ибо они оба будут писать по одному и тому же индексу, и если этот момент не учесть, то будет краш при первом же обращении к tls (как правило это происходит в самом же CRT ещё на этапе вызова различных коллбеков, которые инициализируют глобальные переменные и прочие детали). С дллкой всё проще, загрузчик вызывает LdrpHandleTlsData который (если мне не изменяет память) в том числе выставляет __tls_index для каждой дллки, при выгрузке вызывается LdrpReleaseTlsEntry соответственно. Более подробно расписывать не буду, нужно код смотреть.
2. CRT очень любит ресолвить функции динамически из всяких api-ms, это заглушки, которые форвардят в реальные имплементации или просто ничего не делают, с этим тоже могут быть проблемы, если эти всякие api-ms и/или соответствующие либы не были подгружены.
3. CRT создает глобальные массивы с RVA на функции внутри .text, которые могут стать невалидными, если вы двигаете секции или меняете положение функций внутри .text секции.
Это то, что сразу вспомнил, вроде CRT ещё кеширует stdin / stdout / stderr с чем тоже могут гипотетически возникнуть проблемы, может быть есть и другие нюансы, под x64 например ещё придется функции зарегать через RtlAddFunctionTable чтобы эксепшены нормально работали (и удалять их при выгрузке через RtlDeleteFunctionTable соответственно), но мысль здесь в том, что если даже я их знаю, то человек, который занимается криптом, уж тем более должен их знать и учитывать, в противном случае это плохой криптор и работать с ним просто не стоит.

использование неясных и абсолютно не нужных, к примеру new/malloc, которые к примеру хз как кучу выделяют/очищают от версии к версии.
На самом деле в винде есть 2 хепа, если быть точнее то Segment Heap и NT Heap, более подробно об этом было в статье на blackhat, если вдруг интересно. Но вообще это не должно иметь никакого значения, даже больше, если вместо HeapAlloc предлагается использовать VirtualAlloc, то это плохой совет, потому что сегодня на это уже даже дефендер дрочит, что можно понять не только пореверсив его, но и например по наличию соответствующего апи, таким образом используя VirtualAlloc вместо malloc / new, ты лишь вызываешь больше подозрений у ав, потому что легитный софт так часто VirtualAlloc не использует. Есть ещё альтернатива - секции, их уже юзает легитное по, тот же хром например, или стим, и вот тут ав будет посложнее, но всё равно, использовать его для частых аллоков тоже такое себе и может вызвать подозрения. Самый лучший вариант написать кастомный аллокатор с монотонно увеличивающимся баффером (и возможно максимальным пределом, после которого будет происходить системная деаллокация) и использовать его, и тормозов не будет, и лишних обращений к непонятному тебе апи. =)

если к примеру маппинг файла на исполнение в памяти делать.
Если нормально маппить файл, то никаких проблем не будет. Инициализируй TLS, обрабатывай конфиг директорию (если что, речь идёт об IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG) и либо выставляй __guard_check_icall_fptr / __guard_dispatch_icall_fptr в джампы, либо выставляй битмапы в ntdll (сейчас не вспомню, чекни LdrpValidateUserCallTarget в иде (удивительно, как я помню названия этих функций, но не помню деталей), там всё должно быть понятно), и так далее. Если же под маппингом у тебя подразумевается заресолвить импорты и зафиксить релоки, то неудивительно, что у тебя ничего нормально не работает.

Если у кого-то ещё остались аргументы помимо маленького размера и легкого крипта, то милости прошу, будет интересно послушать. =)

С этим согласен. Как работает маллок\фри надо на зубок знать от версии к версии, чтобы кучу корраптить.
👍

Edit: Извиняюсь, на эмоциях случайно приписал ТСу слова другого человека, поправил.
Edit 2: Подробнее про __tls_index здесь, если кому интересно. =)
Edit 3: Добавил уточнение, чтобы было понятнее.
 
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
В чем смысл малвари на плюсах, если функционал языка становится урезанным до уровня C с классами?
Вообще-то, C с классами тебе дает RAII, что уже не мало. Потом есть хоть и ебанутое, но метапрограммирование, лямбды (через которые можно сделать полноценный defer, например, который до Цэ так вроде и не доехал еще) и тд.

насчет rand не скажу, не смотрел имплементацию
Самый обычный линейный конгруэнтный генератор (умножение и сложение с константами по модулю), CRT студии/mingw от glibc отличается только константами a и c.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх