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

Шифрование бинаря и высокая энтропия в LoadPE

distamx

clr.dll
Premium
Регистрация
08.06.2019
Сообщения
117
Реакции
47
Гарант сделки
2
Депозит
0.0072
Имеется LoadPE с запуском RAW PE файла из секции .data (обычный массив байтов unsigned char rawData[] ={ ... } полученный из HXD). Оставлять его голым, как и просто ксорить не хочется и бесполезно.
Испробован обычный XOR (эмулируется), Base64 (эмулируется), GZIP (очень высокая энтропия), GZIP+BASE64 (энтропия 6 но дает практически ровную кривую энтропии), GZIP+BASE64+XOR (особого смысла нету), генерация PE заголовка в рантайме. Вешается статик детект (если не локально, то в облаке) на массив байтов по алгосу/энтропии/ровной кривой энтропии. Детекта на уже расшифрованный файл как и его использование нету.

Есть ли смысл разбавлять код «однородным мусором» (раздувая файл и с последующей резкой мусора)? Может быть есть эффективный алгоритм который не раздует файл и который не так просто сэмулировать до запуска, или затея бесполезна? (приходила идея порезать файл на совпадения по байтам и его генерацию в рантайме по индексу в массиве, заполнение в цикле).
 
Последнее редактирование:
Решение
У меня есть хороший алго сохранения энтропии, который генерирует данные кодом, степень запутанности (соответственно степени раздувания) регулируется
Генерируется случайный код из операций xor/and/or/add/sub/shr/shr и тд, целый набор инлайн функций на Си, затем они последовательно вызываются, выход каждой предыдущей является входом следующей, промежуточное состояние - очередной байт генерируемого массива
На вход нужно подать всего лишь один байт который является seed этой конструкции, на выходе получаешь заполненный массив данных, которые вычисляются алгоритмически в рантайме, напиши в лс если интересно
Тема раскрывалась еще в далеком 13-ом году, на этом форуме данную технику представил Left4Dead, в этом топе подробности...
У меня есть хороший алго сохранения энтропии, который генерирует данные кодом, степень запутанности (соответственно степени раздувания) регулируется
Генерируется случайный код из операций xor/and/or/add/sub/shr/shr и тд, целый набор инлайн функций на Си, затем они последовательно вызываются, выход каждой предыдущей является входом следующей, промежуточное состояние - очередной байт генерируемого массива
На вход нужно подать всего лишь один байт который является seed этой конструкции, на выходе получаешь заполненный массив данных, которые вычисляются алгоритмически в рантайме, напиши в лс если интересно
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Есть смысл сначала сжать, потом зашифровать, потом понизить энтропию до исходного уровня, засчет того, что исходный буфер будет сжат до шифрования, размер буфера с пониженной энтропией будет примерно равен размеру исходного буфера.
 
У меня есть хороший алго сохранения энтропии, который генерирует данные кодом, степень запутанности (соответственно степени раздувания) регулируется
Генерируется случайный код из операций xor/and/or/add/sub/shr/shr и тд, целый набор инлайн функций на Си, затем они последовательно вызываются, выход каждой предыдущей является входом следующей, промежуточное состояние - очередной байт генерируемого массива
На вход нужно подать всего лишь один байт который является seed этой конструкции, на выходе получаешь заполненный массив данных, которые вычисляются алгоритмически в рантайме, напиши в лс если интересно
Хороший вариант, но звучит сложновато, я не додумался до генерации инлайн асма и его морфинга, думаю можно обойтись простым инлайном с генерацией алго без "промежуточных состояний" и сида (либо я плохо понял технологию), спасибо :).
Есть смысл сначала сжать, потом зашифровать, потом понизить энтропию до исходного уровня, засчет того, что исходный буфер будет сжат до шифрования, размер буфера с пониженной энтропией будет примерно равен размеру исходного буфера.
Спасибо, буду пробовать, звучит легче чем генерация алго, буду думать как понизить энтропию в рандомных кусках что бы получить не ровную кривую (пока на уме только base64 который по умолчанию улетает в статик, подобные его вариации).
 
Хороший вариант, но звучит сложновато, я не додумался до генерации инлайн асма и его морфинга, думаю можно обойтись простым инлайном с генерацией алго без "промежуточных состояний" и сида (либо я плохо понял технологию), спасибо
Там не инлайн асм, а функции обычные Cишные с модифиатором __forceinline
выглядят примерно так
Скрытый контент для пользователей: distamx.

1663254436372.png
 
Грубо генерируется цепочка таких вот функций, как на скрине выше
Каждая такая функция генерирует всего 1 байт данных, размер функции настраивается, она может быть как огромной так и маленькой, указывается диапазон количества операций, количество как и сами операции выбираются случайно, операции внутри функции совершенно рандомные, но приводят к нужному результату в процессе выполнения, так как последние итерации генерации используют уже не полностью рандомные операции, а псевдорандомные с подгонкой результата до нужного байта
Функции вызываются последовательно одна за одной , результат предыдущего вызова передается в следующий и так далее пока не сгенерится весь массив
В первую функцию подается seed, каждая последующая берет результат предыдущей
Так же там генерируется удобная функция обертка, которая на вход получает seed и указатель на выделенный участок памяти, куда нужно записать массив и внутри она уже вызывает все эти функции последовательно
 
Последнее редактирование:
Там не инлайн асм, а функции обычные Cишные с модификатором __forceinline

Грубо генерируется цепочка таких вот функций, как на скрине выше
Каждая такая функция генерирует всего 1 байт данных, размер функции настраивается, операции внутри функции совершенно рандомные, но приводят к нужному результату в процессе выполнения
Функции вызываются последовательно одна за одной , результат предыдущего вызова передается в следующий и так далее пока не сгенерится весь массив
Теперь звучит попроще чем асм, но думаю что настолько сложная генерация не понадобится, ав пропустит и попроще, главное не попасть на паттерн.

Скрытый контент для пользователей: arsarsov.
 
Теперь звучит попроще чем асм, но думаю что настолько сложная генерация не понадобится, ав пропустит и попроще, главное не попасть на паттерн
Ну да тему генерации данных кодом поднимали очень много раз, как очень хороший способ избегать шифрования и соответственно плохой энтропии, поэтому я и запилил свою реализацию
Кстати используя огроменные размеры таких функций можно обламывать эмулятор, он просто останавливается где-то в середине не доходя до конца
 
Хороший вариант, но звучит сложновато
Можешь на экспе, в старых конкурсных статьях поискать статью от @merdok'а - там было что-то похожее.
 
У меня есть хороший алго сохранения энтропии, который генерирует данные кодом, степень запутанности (соответственно степени раздувания) регулируется
Генерируется случайный код из операций xor/and/or/add/sub/shr/shr и тд, целый набор инлайн функций на Си, затем они последовательно вызываются, выход каждой предыдущей является входом следующей, промежуточное состояние - очередной байт генерируемого массива
На вход нужно подать всего лишь один байт который является seed этой конструкции, на выходе получаешь заполненный массив данных, которые вычисляются алгоритмически в рантайме, напиши в лс если интересно
Тема раскрывалась еще в далеком 13-ом году, на этом форуме данную технику представил Left4Dead, в этом топе подробности: https://xssforum7mmh3n56inuf2h73hvhnzobi7h2ytb3gvklrfqm7ut3xdnyd.onion/threads/23817/. Техника крайне интересная, советую изучить всем интересующимся.

Вкратце такой аутпут выходил:

пример генерируемых формул:
Код:
( ( ( ( ( ( (unsigned char)( ~( (unsigned char)x ) ) + x ) & (unsigned char)( (unsigned char)(unsigned char)( (unsigned char)x << 1 ) >> 3 ) ) | x ) & (unsigned char)( (unsigned char)(unsigned char)( (unsigned char)( (unsigned char)( (unsigned char)x - 1 ) + (unsigned char)( (unsigned char)x >> 1 ) ) >> 1 ) >> 1 ) ) - (unsigned char)( (unsigned char)( ( (unsigned char)( (unsigned char)(unsigned char)( (unsigned char)x >> 4 ) << 4 ) ^ ( ( x - x ) & (unsigned char)( (unsigned char)x + 1 ) ) ) ^ x ) >> 4 ) ) | x )
x = 8, y = 10, count_tree = 10
(unsigned char)( (unsigned char)(unsigned char)( (unsigned char)( x + x ) << 3 ) >> 2 )
x = 235, y = 44, count_tree = 44
( x + ( x | (unsigned char)( (unsigned char)(unsigned char)( (unsigned char)(unsigned char)( ~( (unsigned char)x ) ) << 2 ) >> 4 ) ) )
x = 41, y = 86, count_tree = 86

К слову конкретно для понижения энтропии данная техника применима да, но с точки зрения эвристики ,а конкретно с точки зрения статистики опкодов и их соотношения к нормальному, будет большой перевес в сторону аномалии и нормального распределения, и будут прилетать генерики отовсюду :).
Потенциальным решением может быть обработка таким способом части строки с завязкой на магические значения для противодействия эмуляции.
Для понижения энтропии массива байт хранимого блоб буфера есть гораздо более простые техники, недавно выкладывали к примеру технику понижения энтропии по мат формуле в конкурсной статье, тут threads/64659/. Способов масса :)
 
Решение
Тема раскрывалась еще в далеком 13-ом году, на этом форуме данную технику представил Left4Dead, в этом топе подробности: https://xssforum7mmh3n56inuf2h73hvhnzobi7h2ytb3gvklrfqm7ut3xdnyd.onion/threads/23817/. Техника крайне интересная, советую изучить всем интересующимся.
Его алгоритм медленный, я изучал ту тему, годится только для генерации сверхнебольших массивов, изучи подробнее исходники и поймешь в чем дело, он генерирует деревья до тех пор, пока результат не сойдется, если выбрать большой файл, допустим 5 мб, и при этом выбрать достаточно большой размер деревьев, то генерация будет длиться вечность
У меня алгоритм оптимизированный, адаптивный + многопоточный, при достаточно большом размере генерируемых данных и больших формулах все равно работает очень быстро, плюс оптимизации рекурсии, кеширование вершин, что бы не бегать каждый раз по дереву полностью сверху вниз и обратно. Скорость рулит.

А вот описание его сорцев и собственно сам код с той темы, это глупо генерировать рандомные операции в цикле do while который по счастливой случайности должен выдать нужный результат, и только тогда цикл закончится
И это происходит с КАЖДЫМ его байтом, который он генерирует, представь генерацию 5мб данных побайтно, это 5242880 циклов do while которые будут ожидать чуда перед завершением, да еще и все это в одном потоке
1663419192336.png

1663419272912.png

К тому же код в теме содержит другие мелкие недочеты, поэтому советовать его для изучения я бы не стал.
Даже если ты пишешь малвару, ты должен писать ее качественно, особенно если это касается алгоритмической части, а говнокодеров надо гнать палками в шею, любой код должен писаться качественно, либо вообще не писаться.
К слову конкретно для понижения энтропии данная техника применима да, но с точки зрения эвристики ,а конкретно с точки зрения статистики опкодов и их соотношения к нормальному, будет большой перевес в сторону аномалии и нормального распределения, и будут прилетать генерики отовсюду :).
Морфинг, разбавление мусором, решений миллион привести код к нормальному виду после таких манипуляций, как на уровне сорцев сразу можно генерить, так и на уровне ассемблера уже после сборки
 
Последнее редактирование:
Ну так это же PoC, важна суть идеи, которую, считаю его наработка отлично доносит.
Ваш код я не видел и могу только поверить о возможностях и отличиях на слово ;)

Тут ведь важна идея, а в его примере даже две:
1. Формирование данных кодом.
2. Привязка генерации к магической переменной, которой может быть всё что угодно :cool:.

Морфинг, разбавление мусором, решений миллион привести код к нормальному виду после таких манипуляций, как на уровне сорцев сразу можно генерить, так и на уровне ассемблера уже после сборки
Тут важно учесть тот факт, что если задача именно понизить (нормализовать) энтропию, то большинство манипуляций это оверхед (нарушит соотношения размера кодовой и дата секции к примеру, статистика опкод будет нарушена и т.д.), когда можно алгоритмически пройтись по массивау и "разбавить его" "правильными" байтами и иметь формулу обратно вырезающую такие байты.
Кстати помимо энтропии эвристики используют и другие статистические методы оценки, например гуглите Chi Square distribution, Monte Carlo Error rate.

В любом случае это большая интересная тема, получать одинаковый результат можно кучей способов и существует масса путей оптимизации и улучшения.
Я рад что люди делятся техниками и обсуждают их, это двигатель прогресса.
 
Последнее редактирование:
Ваш код я не видел и могу только поверить о возможностях и отличиях на слово
Смысл моего кода тот же самый, что и в цитате ниже, только цель достигается другими, более оптимизированными и быстрыми алгоритмами, к слову, писал я этот код только потому, что увидел говнокод из той статейки, меня прям накалил тот участок с do while, да и другие моменты и я решил, что у меня должна быть нормальная, качественная реализация. А так разницы концептуально нет, такая же завязка на magic, генерация данных кодом.
1. Формирование данных кодом.
2. Привязка генерации к магической переменной, которой может быть всё что угодно
 
Пожалуйста, обратите внимание, что пользователь заблокирован
You can use AES encryption and store in unsigned char and then compile that's what I am using , using pe sections to store the encrypted hex is good but it can dumped easy i was using it in past
 


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