L9ec: волшебный патч ядра Linux
Если вам неудержимо хочется использовать оборудование из музея для современной разработки — статья специально для вас.
Машины должны служить а не требовать ресурсы. И автор патча l9 об этом знает.
Эпический баг
Сейчас наверное некоторые читатели сильно удивятся:
с 2007 года в ядре Linux живет серьезный баг, приводящий к полному зависанию системы при работе под большой нагрузкой на память.
На дворе на момент написания статьи май 2025 года, так что баг успел отпраздновать совершеннолетие и открыть первую бутылку пива.
Оригинальный репорт выглядит так:
Разумеется разработчики ядра в курсе проблемы, но по ряду причин.. не считают этот баг важным.
Да, вы правильно прочитали:
«полное зависание системы под нагрузкой» и «разработчики не считают важным исправлять» — как вам такие реалии Linux?
Более того, недавно тикет с описанием этого бага вообще закрыли с эпической формулировкой «just become obsolete»:
С легким намеком, что некоторым стоит перестать собирать себе компьютеры по помойкам:
but now I don't bother with less than 32Gb of RAM for a desktop.
Теперь прокрутите обсуждение бага в трекере вниз и посмотрите на последнее сообщение о проблеме:
Оно конечно все замечательно и у самого автора этой статьи давно 64Гб на одной из рабочих машин, а некоторые коллеги успели впихнуть даже 128Гб, причем в ноутбук — чтобы мы наконец увидели SUSE Linux, которая не тормозит.
Но к сожалению одними любителями компьютерного антиквариата данная проблема не ограничивается — на нынешние облачные времена типичное рабочее окружение Linux это виртуальная машина, с ограниченным обьемом памяти. Скорее всего даже ваш корпоративный сайт крутится на виртуальной машине с 4Гб памяти.
Так что на самом деле проблема касается практически всех пользователей Linux, а не только идейных нищебродов энтузиастов, собирающих себе оборудование по музеям.
Как так получилось
Если вы хоть немного понимаете в компьютерах, прочитав абзац выше и сопоставив масштаб проблемы и отношение к ней разработчиков Linux, думаю уже сделали определенные выводы:
либо команда разработки ядра Linux — поголовно некомпетентны, либо
у автора контракт с рептилоидамив описании выше был упущен ряд важных нюансов.
Правда как обычно где‑то между — «особенных» среди современных разработчиков Linux действительно хватает, но ряд нюансов я все же намеренно упустил.
Опишу в какой момент проявляется этот баг:
надо долго и упорно увеличивать нагрузку на использование памяти, причем маленькими порциями и обязательно из нескольких разных процессов — чтобы OOM Killer не успел отработать.
На практике надо либо заниматься тренировкой нейросетей, либо непрерывно гонять тяжелые приложения на Java/Node (в первую очередь IDE) и постоянно запускать сборку больших проектов.
И все это на неподготовленном офисном оборудовании с 4-6 Гб памяти, представляющем историческую ценность, либо в виртуальной машине.
Патч l9ec
Уже давно существует неофициальный патч, решающий описанную проблему с зависанием квадратно-гнездовым радикальным способом:
The kernel does not provide a way to protect the working set under memory pressure. A certain amount of anonymous and clean file pages is required by the userspace for normal operation. First of all, the userspace needs a cache of shared libraries and executable binaries. If the amount of the clean file pages falls below a certain level, then thrashing and even livelock can take place.
По сути этим патчем формируется небольшой объем памяти (тот самый working set), которую запрещается перегружать даже самым хитрым приложениям, откусывающим память по килобайтам.
Разумеется патч заметили и тут находится архив эпической переписки в рассылке Linux Kernel длиною в год, где автор патча пытается объяснить окружающим что он не верблюд и проблема действительно есть.
Однако патч в мейнстрим так и не попал, что наводит на определенные нехорошие мысли.
История с Xanmod
Помимо основной версии ядра т. н. «vanilla», исходники которого выкладываются на широко известном kernel.org, существуют «васянские сборки» — наборы патчей ядра, собранные энтузиастами под конкретную задачу.
Одна из таких сборок называется Xanmod и посвящена работе современного ядра на desktop-системе с минимальными визуальными задержками:
XanMod is a general-purpose Linux kernel distribution with custom settings and new features. Built to provide a stable, smooth and solid system experience.
Так вот на момент появления l9ec патча, он был включен в сборку Xanmod:
С официальной страницы с отзывами, между прочим.
Но в последних 6.х версиях Xanmod его уже нет, на что есть формальная причина — появление вот этого патча, вроде как окончательно решающего проблему c зависанием:
MGLRU is a kernel innovation we've been eager to see merged in 2022 and it looks like that could happen for the next cycle, v5.19, for improving Linux system performance especially in cases of approaching memory pressure.
На данный момент MGLRU в mainline и скорее всего работает прямо сейчас и у вас в системе, если конечно у вас современный линукс и MGLRU не отключен вручную.
К сожалению принцип работы MGLRU другой (см. комментарий выше про 32Гб памяти на десктопе) и тестировался его функционал тоже в другом месте:
On Android, our most advanced simulation that generates memory pressure from realistic user behavior shows 18% fewer low-memory kills, which in turn reduces cold starts by 16%.
Как нетрудно догадаться, «realistic user behavior» на мобильном Android несколько отличается от тотальной перегрузки тяжелыми средствами разработки на дохлом десктопе или еще более слабой виртуальной машине.
Поэтому «продвинутым пользователям Linux» в очередной раз придется заботиться о себе и своих проблемах самостоятельно.
Портирование на 6.х ядро
К сожалению автор патча l9 видимо устав бодаться с идиотами, не стал переносить свой замечательный патч в 6.х ветку ядра, решив что раз более умные ребята из Google выкатили MGLRU — от его решения толку больше не будет.
Как ни странно, но это не так и l9 патч куда более предсказуем и надежен как удар ломом, в отличие от цирка с аж 14 патчами MGLRU:
These initial multi-generational LRU patches amount to 14 patches at the moment and in a patched kernel can be enabled via the LRU_GEN Kconfig switch
Собственно эта статья появилась на свет после того как автор опять словил зависание под нагрузкой во время работы над большим проектом, из-за чего и решил откопать дедовский пулемет портировать известный патч в 6.х ядро.
За основу был взят последний патч для 5.х ветки без учета MGLRU: le9ec-5.15.patch а его логика добавлялась в Xanmod-версию ядра 6.14.5.
Ниже по шагам объясняю как выполнить перенос логики патча, чтобы процедуру можно было повторить и на более новых ядрах и на «vanilla» версиях.
Скачиваем архив с Xanmod ядром и l9-патч по ссылкам выше и распаковываем.
Стоит сразу предупредить, что размер текущей версии ядра Linux в распакованном виде ~1.8 Гигабайт, а для сборки понадобится еще ~28 Гигабайт.
Вот такие нынче ядра.
Разумеется применить готовый diff автоматически для ветки 6.х не получится, так что будем переносить логику патча по шагам.
Всего в рамках патча изменения происходят в пяти файлах:
Поскольку исправлять документацию нам не очень актуально, первый файл можно пропустить. Таким образом первое актуальное исправление находится в файле include/linux/mm.h, куда добавляются глобальные переменные, отвечающие за настраиваемые лимиты:
Все что нужно сделать — вставить строки в файл include/linux/mm.h:
extern unsigned long sysctl_anon_min_kbytes;
extern unsigned long sysctl_clean_low_kbytes;
extern unsigned long sysctl_clean_min_kbytes;
Следующий шаг чуть объемнее:
Необходимо найти массив static struct ctl_table vm_table[] в файле kernel/sysctl.c и добавить внутрь три блока, отвечающих за настройку.
{
.procname = "anon_min_kbytes",
.data = &sysctl_anon_min_kbytes,
.maxlen = sizeof(unsigned long),
.mode = 0644,
.proc_handler = proc_doulongvec_minmax,
},
{
.procname = "clean_low_kbytes",
.data = &sysctl_clean_low_kbytes,
.maxlen = sizeof(unsigned long),
.mode = 0644,
.proc_handler = proc_doulongvec_minmax,
},
{
.procname = "clean_min_kbytes",
.data = &sysctl_clean_min_kbytes,
.maxlen = sizeof(unsigned long),
.mode = 0644,
.proc_handler = proc_doulongvec_minmax,
},
Следующая правка в файле mm/Kconfig, которой добавляется управление новыми настраиваемыми параметрами ядра:
По-сути правки, вам надо добавить в файл mm/Kconfig три блока: ANON_MIN_KBYTES, CLEAN_LOW_KBYTES и CLEAN_MIN_KBYTES вместе со всем содержимым.
Все что выше отвечало лишь за настройку, основная логика патча l9 приходится на файл mm/vmscan.c, в котором будут происходить оставшиеся правки.
Первым делом добавляем локальные переменные:
Затем добавляем логику присваивания значений из параметров ядра:
Ориентируетесь на макрос #define prefetchw_prev_lru_folio, строки добавляются после него:
unsigned long sysctl_anon_min_kbytes __read_mostly = CONFIG_ANON_MIN_KBYTES;
unsigned long sysctl_clean_low_kbytes __read_mostly = CONFIG_CLEAN_LOW_KBYTES;
unsigned long sysctl_clean_min_kbytes __read_mostly = CONFIG_CLEAN_MIN_KBYTES;
Следующая правка добавляется в метод static void get_scan_countкоторый успел поменять сигнатуру:
Я добавил сразу после блока с переменными:
struct pglist_data *pgdat = lruvec_pgdat(lruvec);
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
unsigned long anon_cost, file_cost, total_cost;
int swappiness = sc_swappiness(sc, memcg);
u64 fraction[ANON_AND_FILE];
u64 denominator = 0; /* gcc */
enum scan_balance scan_balance;
unsigned long ap, fp;
enum lru_list lru;
/*
* Force-scan anon if clean file pages is under vm.clean_low_kbytes
* or vm.clean_min_kbytes.
*/
if (sc->clean_below_low || sc->clean_below_min) {
scan_balance = SCAN_ANON;
goto out;
}
Следующая правка в этом же файле должна быть вставлена в этот же метод get_scan_count, но ниже по коду — ориентируйтесь на строку nr[lru] = scan;благо она такая одна:
Я вставил логику проверки сразу над ней:
/*
* Hard protection of the working set.
*/
if (file) {
/*
* Don't reclaim file pages when the amount of
* clean file pages is below vm.clean_min_kbytes.
*/
if (sc->clean_below_min)
scan = 0;
} else {
/*
* Don't reclaim anonymous pages when their
* amount is below vm.anon_min_kbytes.
*/
if (sc->anon_below_min)
scan = 0;
}
nr[lru] = scan;
Следующей правкой добавляется новая функция prepare_workingset_protection, которая должна вызываться из существующего метода shrink_node_memcgs:
Так что вам надо найти функцию shrink_node_memcgs (она такая одна) и вставить новую функцию prepare_workingset_protection над ней:
static void prepare_workingset_protection(pg_data_t *pgdat,
struct scan_control *sc)
{
/*
* Check the number of anonymous pages to protect them from
* reclaiming if their amount is below the specified.
*/
if (sysctl_anon_min_kbytes) {
unsigned long reclaimable_anon;
reclaimable_anon =
node_page_state(pgdat, NR_ACTIVE_ANON) +
node_page_state(pgdat, NR_INACTIVE_ANON) +
node_page_state(pgdat, NR_ISOLATED_ANON);
reclaimable_anon <<= (PAGE_SHIFT - 10);
sc->anon_below_min = reclaimable_anon < sysctl_anon_min_kbytes;
} else
sc->anon_below_min = 0;
/*
* Check the number of clean file pages to protect them from
* reclaiming if their amount is below the specified.
*/
if (sysctl_clean_low_kbytes || sysctl_clean_min_kbytes) {
unsigned long reclaimable_file, dirty, clean;
reclaimable_file =
node_page_state(pgdat, NR_ACTIVE_FILE) +
node_page_state(pgdat, NR_INACTIVE_FILE) +
node_page_state(pgdat, NR_ISOLATED_FILE);
dirty = node_page_state(pgdat, NR_FILE_DIRTY);
/*
* node_page_state() sum can go out of sync since
* all the values are not read at once.
*/
if (likely(reclaimable_file > dirty))
clean = (reclaimable_file - dirty) << (PAGE_SHIFT - 10);
else
clean = 0;
sc->clean_below_low = clean < sysctl_clean_low_kbytes;
sc->clean_below_min = clean < sysctl_clean_min_kbytes;
} else {
sc->clean_below_low = 0;
sc->clean_below_min = 0;
}
}
Собственно последняя правка это вызов новой функции из существующей shrink_node_memcgs:
После внесения всех этих исправлений, запускаем один из вариантов настройки ядра:
make xconfig
И наблюдаем новые поля настройки:
Цепочка сборки и установки ядра совершенно стандартная:
make && make modules && make modules_install && make install
К сожалению это еще не все и прежде чем патч заработает надо будет отключить MGLRU, который как я уже описывал — успели внести в основную ветку ядра:
cat /sys/kernel/mm/lru_gen/enabled
Должен показать 0x0007 если MGLRU включен, отключить можно командой:
echo 0 | sudo tee /sys/kernel/mm/lru_gen/enabled
Вот тут у автора патча лежат готовые скрипты для автоматизации всего этого цирка. Я же просто добавил строчку с отключением в /etc/rc.local.
Пруфы
Для тестов портированного патча, был взят один из моих боевых ноутбуков Lenovo Z580 2012го года выпуска, с 8Гб памяти:
На нем постоянно творится всевозможная дичь — тут пять разных операционных систем и куча проектов и инструментов для разработки на каждой.
Поэтому без особого труда были одновременно запущены:
PostgreSQL с реальной базой
MySQL тоже с реальной базой
Intellij Idea
VSCode
Сборка проекта на Node.js с Webpack и hot reload
Сборка достаточно крупного Java-проекта (~3000 исходных файлов)
Chromium с 20 вкладками
Напоминаю что все это на 8Гб реальной памяти и на ноутбукe. Причем в качестве ОС в этот раз была обычная Ubuntu:
Как-то так это выглядит в действии:
Через неделю после публикации я решил пойти еще дальше и поставил пропатченное с l9 ядро на ноутбук 2007 года с 3Гб памяти. И повторил тесты с нагрузкой. Видео тут.
Все более чем работает и пропатченное ядро замечательно отрабатывает свою пайку.
Эпилог
Можно сколько угодно стебаться с пожеланиями «купи себе наконец нормальный компьютер», скажу что намеренно и давно использую старое железо — в первую очередь для оценки производительности создаваемого ПО.
И это одна из причин, по которой у нас получаются технические чудеса вроде Телепорты.
Если вы пока не дошли до столь глубокой стадии просвещения в разработке — все равно стоит знать, что мы ловили подобные зависания и в виртуальных машинах с Linux, например на CI‑сервере при сборке нескольких проектов одновременно.
Так что актуальность описанного все же высокая и как получилось, что столь простой и очевидный патч, который гарантированно решает проблему до сих пор не используют активно — ума не приложу. Ну и разумеется автору патча лучи респекта, благо это лучший представитель отечественной инженерной школы.
Статья была опубликована на Хабре, оригинал, в котором автор статьи себя не сдерживал и в красках рассказал все что думает о разработчиках ядра Linux как обычно можно найти в нашем блоге.
Ваш канал сам себя не продвинет
Телеграм, ВКонтакте, Дзен, Макс — площадок становится все больше, а вот внимание аудитории по-прежнему ограничено. Что делать? Продвигать!
На Пикабу можно рекламировать свои каналы прямо в лентах сайта. Находите новую аудиторию и получайте живые переходы без сложных рекламных кабинетов.
Подойдет для:
авторских и экспертных блогов
бизнеса
медиа и новостных каналов
мемных и развлекательных сообществ
Запускается просто: добавляете ссылку, пишете заголовок и краткое описание и выбираете географию для показов. А дальше о вашем канале узнают тысячи пользователей Пикабу!
40 ЗАПУСКОВ ЗА РАЗ | Как работает мобильная катапульта?
Узнайте, как работает мобильная катапульта для БПЛА весом всего 6 кг.
Эта портативная установка собирается за пару минут и позволяет запускать самолеты весом до 10 кг прямо из тактической сумки. И 40 раз за один баллон.
Ответ на пост «Как посадить эйчарку на измену»4
Не знаю в какой отрасли ищет работу ТС, но знаю про айти. Что тут сейчас жопа, особенно для начинающих, не имеющих опыта реальной работы людей. В эту категорию входят выпускники ВУЗов, в том числе мой сын. Так как у меня ещё 2 младшие дочки, требовалось дать сынуле пинка под жопу обеспечить молодому специалисту хорошее рабочее место.
Я сам в айти уже 30 лет, так что понятно что сверх теоретической университетской программы дал парню хорошие знания и практику, погонял в реальных проектах, нарисовал в резюме красивые и правильные вещи. Но, увы, на сегодня этого мало...
В процессе общения со знакомыми сына, которые достигли успешного успеха, выяснилось что лучше всего брать специального ментора, которые предметно натаскивает на собесы. И по технолониям и по софт скиллам и по внутренним правилам, в которые надо тупо попадать чтобы пройти на следующий этап. Ну это как подготовка к ЕГЭ, которая имеет мало общего со знаниями и наукой, тупо проработка типовых тем.
Полгода занятий и прохождения тестовых собесов параллельно с подготовкой диплома под моим чутким руководством. Результат - 2 месяца реальных собесов и оффер в одну из ведущих компаний России на 330к грязными в месяц для начала. Считаю, более чем достойно.
«Гражданин, обновитесь»: анализ вредоносной кампании Falcon
(репост с хабра, статьи Алексея Колесника из отдела экспертизы PT Sandbox)
«Обновите приложение». Для большинства пользователей это привычное сообщение, а для хакеров - один из самых надежных и эффективных способ получить контроль над устройством. В этой статье разберем вредоносную кампанию, начавшуюся с apk, замаскированного под российский сервис. То, что сначала выглядело как очередная вариация банковского трояна, при ближайшем рассмотрении оказалось гораздо интереснее.
В огромном потоке файлов очень легко пропустить интересные семплы, но в данном случае мне повезло и глаз зацепился за, казалось, ничем не примечательную, картинку:
Что полезного на ней можно увидеть?
Сработала метка «Формат подделан» и вердикт по ней «apk.tampered». Рекомендую ознакомиться с отличной статьей, которая подробно раскрывает эту вредоносную технику: Beware of BadPack: One Weird Trick Being Used Against Android Devices;
Сохраняются непонятные файлы с расширением .png (файловые дропы);
Загрузка кода в память (dex-дампы);
Название «mir-pay.apk».
Перед тем как начать изучать файл, было выдвинуто предположение, что это еще одна скучная вариация вредоноса Mamont, поскольку имя намекает на известную систему платежей, которая часто встречалась в этом семействе.
Stage 1 - загрузчик
Рассмотрим подробнее образец - 4409052221924df581fb271d27acd7338c0efb5aea593ac811f4ffdb0abed7a6
При просмотре AndroidManifest.xml в jadx виден класс io.immense.gesture.Ipperfluid, который будет запущен перед основным кодом приложения.
Обычно при запуске происходит следующее:
Ставятся обработчики на глобальные исключения, чтобы эксперты могли определять, что пошло не так, и делать исправления;
Проводятся иные подготовительные действия;
Распаковывается код полезной нагрузки.
Полезная нагрузка
В коде данного класса присутствует множество математических вычислений и код сильно отличается от реального кода стандартных приложений. Все это намекает на то, что в этом классе будет происходить распаковка полезной нагрузки.
Также приложение практически не содержит реальных классов. Это точно свидетельствует, что полезная нагрузка была упакована, чтобы сбить обнаружение статическими средствами анализа, а значит нужно ее достать.
Анализировать каждый упаковщик и разбираться в его логике задача очень трудоемкая и скучная, поэтому для распаковки приложения воспользуемся поведенческим анализом в PT Sandbox:
Анализ загрузчика
Первое, что бросается в глаза при анализе – обилие захардкоженных русских слов. Причем самое интересное, что они встречаются не просто в тексте, а в логах.
Есть функционал, который создает уведомление об успешном обновлении приложения, после установки полезной нагрузки:
Внутри одного из Java-классов содержатся ссылки, которые ведут не просто на случайный управляющий сервер, а на вполне популярные и легитимные сервисы:
С таск-трекера Trello скачивается html-файл, который просит обновить приложение при запуске. И вот тут каждому пользователю стоит задумать о том, что за приложение он установил. Подход с фейковым обновлением очень любим во вредоносах под Android по двум причинам.
Он позволяет скрыть реальную вредоносную активность от антивирусных средств;
У пользователя на телефоне появится сразу два приложения, одно из которых часто будет скрыто и не отображено в лаунчере. А значит, пользователь о нем забудет. Как часто вы заходили в настройки телефона и проверяли список установленных приложений, м?
Фишинговая страница с обновлением
А через переадресацию с Яндекс.Метрики на другой таск-трекер скачивается следующая стадия полезной нагрузки:
Забавно, что нагрузки хостятся на сервисах для управления проектами. Управлять малварью действительно тяжело :)
Stage 2 - бэкдор
Рассмотрим apk, которое скачивается на предыдущем шаге.
Можно сразу выделить элементы, которые мы видели на первоначальном разборе:
Непонятные png-файлы (файловые дропы);
Динамически загружаемый код (dex-дамп);
Можно предположить, что используется аналогичная техника для упаковки приложения.
Распаковка полезной нагрузки
Рассмотрим AndroidManifest.xml, видим аналогичный рисунок, как в первой стадии:
По коду класса biz.require.casual.Jsliceturkey можно подтвердить, что используется похожий тип обфускации:
Для экономии времени (и нервов) снова воспользуемся песочницей и скачаем распакованный дамп.
Анализ бэкдора
При открытии распакованной нагрузки сразу видна приятная картинка с красивыми именами, по которым можно выделить основной функционал ВПО. Почему «красивыми»? Да просто глаз ревёрсера обычно радуется при виде отладочных символов, которые легко можно прочитать:
Код нагрузки содержит в себе классический набор техник, который встречается буквально в каждом ВПО под Android в различных комбинациях, поэтому останавливаться детально на каждом классе мы не будем, а подсветим лишь интересные места.
Любопытно, что уже в самой полезной нагрузке присутствует перевод на три языка: английский, русский и украинский.
Сетевое взаимодействие
В интерфейсе продукта можно без глубокого анализа увидеть, что:
определяется информация об IP жертвы;
скачивается файл random_val.txt с dropbox;
отправляются данные на cold-apple[.]com.
При открытии трафика, полученного из песочницы, в Wireshark видна и полезная нагрузка, которая отправляется на управляющий сервер:
Значение api_code захардкоженно, вероятно, по нему сервер понимает, какой RC4-ключ использовать для шифрования или расшифровки отправляемых и получаемых данных:
При расшифке видно, какая конкретно информация отправляется на управляющий сервер:
Trello в качестве хостинга вредоносного ПО
Изучим файлы в Trello, поскольку именно с него скачивалась полезная нагрузка. Не часто встретишь его во вредоносных кампаниях, поэтому исследуем поглубже.
По ссылке из вложения можно получить ссылку на доску:
Обзор карточек
Поглядим, что нам откроется по ссылке.
Открываем карточку «vtb drop» и видим, что полезная нагрузка в ней была создана 28.11.2024 и обновлена 23.03.2025. Это говорит не только о том, что на Trello очень эффективно хостить фишинговые html‑файлы, но и то, что авторы обновляют эти файлы.
Также можно найти две почти похожие версии html‑страниц с фейковым обновлением. Слева на рисунке ниже — html‑файл, который был в исследуемом образце, справа — целенаправленный фишинг на банковское приложение.
Не менее интересна карточка «injects». Судя по списку приложений в названии файлов на скриншоте ниже, становится ясно, что мы имеем дело с таргетированной атакой на пользователей из России (полный список доступен в секции с IOC).
Все фишинговые окна построены схожим образом и нацелены на то, чтобы ничего не подозревающий пользователь передал свои данные злоумышленникам:
Внутри каждого html-файла содержится похожий код, который через webview передается в код приложения и отправляется через бота:
Помимо прочего в html-файлах встречается фишинг, направленный на то, чтобы пользователь дал все необходимые разрешения для «работы» приложения:
Данное разрешение опасно тем, что немногие пользователи знают, что выдача доступа к «Специальным возможностям» фактически предоставляет полный доступ к пользовательской системе. Злоумышленник может полностью считывать информацию с экрана телефона (СМС, звонки, банковские данные и так далее), а также не давать удалить приложение, перехватывая управление.
Поэтому после выдачи этого разрешения обычному пользователю будет очень трудно избавиться от вредоносного приложения со своего телефона.
Активность на доске
Trello позволяет увидеть, кому принадлежит публичная доска, а также посмотреть активность владельца:
Активность пользователя alexsentov говорит о том, что автор(ы) вредоноса регулярно обновляют нагрузки и ведут активность на доске.
Архивные записи
По архивным записям мы увидели, что примерно с 21.02.2025 по 11.08.2025 полезные нагрузки активно загружались на доску таск-трекера:
Вероятно позже злоумышленники решили использовать связку из Яндекс.Метрика и (surprise!) еще одного таск-трекера, YouGile (может, Trello стал удалять образцы, поскольку в них стало обнаруживаться вредоносное ПО), которую и видно в исследуемом образце.
Атрибуция
На данном этапе у нас была уверенность, что мы имеем дело с новой кампанией, но не тут-то было!
Поиск по найденным IOCам приводит к двум упоминаниям похожих образцов от 2022 года из вредоносной кампании Falcon:
Образцы: 2022 vs. 2026
Индикаторы компрометации (IOCs):
4a9851b10361d4efc9657233aedfa3b0a0040ee016cc9891252d838b4e9ce0f2
6f475db05055d2ff4c12568b09bca5d272eaf157edde90fd7755c04d87b4f215
Обфускация
В образцах 2022 года используется тип обфускации, которая отличается от образцов 2026 года.
Cпособ загрузки распакованного кода образца 2026 года также отличается. С помощью Java-рефлексии вредоносный код подменяет системные поля JVM (Java Virtual Machine) для загрузки в память распакованной нагрузки.
Полезная нагрузка: сравнение версий
Отличается набор возможностей, который представлен в прошлой и новой версиях:
Спустя четыре года малварь обросла новыми возможностями:
ActivityRequestVnc - запись экрана пользователя;
ActivityStartMainService - постоянный перезапуск себя, чтобы приложение не было убито в фоне;
AllServiceFaApp - создание скрытого канала уведомлений и перезапуск через alarm;
CallReceiverFaApp - обработка входящих звонков;
DropperReceiverFaApp - запуск фонового сервиса, чтобы приложение не было убито в фоне;
MyMessagingService - обработка входящих СМС;
MyServiceReceiver - постоянный ping сервера с отправкой информации;
OpenRedirectActivity - сбор введенных пользователем данных через JavaScript-интерфейс и их отправка на C&C;
ScreenCaptureServiceFaApp - возможность создавать скриншоты экрана;
WhiteActivity - «окирпичивание» телефона посредством открытия произвольной HTML-страницы поверх экрана блокировки.
Как видите, со временем функционала у малвари стало больше и, что самое важное, он стал опаснее для конечного пользователя, так как теперь злоумышленники могут в любой момент получить полную информацию с телефона жертвы, а при необходимости забрать полное управление над устройством посредством «Специальных возможностей».
Помимо прочего, коллеги из Cyble упоминают URL вида /api/api.php?get_lend=, который сохранился в версии 2026 года:
Совокупность вышеперечисленных факторов позволяет нам атрибутировать найденные образцы к Falcon: начиная с характерной цепочки атаки и заканчивая индикаторами компрометации. И как видим, хищник из расследования четырёхлетней давности становится всё более грозным и опасным.
Work In Progress
В процессе изучения этой кампании нам удалось получить свежие вариации этого семейства.
В мае этого года злоумышленники стали использовать в качестве хостинга полезной нагрузки уже другой отечественный сервис управления проектами.
По данным с Virustotal, файлы были загружены недавно (на момент написания этого материала). Примечательно, что имя скачиваемого вредоносного файла содержит названия популярных банков, поэтому в файловом менеджере пользователь может не заметить ничего необычного.
В свежих образцах используется новый вариант обфускации, который ранее не встречался в этом семействе.
При анализе полезной нагрузки, видна уже доработанная нагрузка с новыми классами PatternActivity и PinActivity:
Оба класса практически идентичны, создают фейковые экраны ввода PIN-кода или графического пароля, которые затем сохраняются локально на устройстве.
Помимо прочего, перед скачиванием нагрузки видно, что авторы стали использовать трекер от Mail.ru, вместо AppMetrica, как это было раньше:
Лето хакеров не останавливает и в июне авторы вредоноса продолжают активно его дорабатывать, расширяя функционал и экспериментируя с новыми видами фишинговых страниц. Появились новые фишинговые страницы, новые версии окон с вводом PIN-кода, графического пароля.
Также в новых версиях загрузчиков появилось шифрования строк, чтобы обойти детектирование антивирусными средствами:
А на Trello появилось больше карточек с расширенным набором артефактов:
Думаю, впереди нас ждет много интересного, и мы с коллегами продолжаем наблюдать. А ведь всё началось с того, что некий сомнительный образец просто попал в нашу песочницу...
Заключение
Все чаще обнаруживаются атаки, которые направлены конкретно на российских пользователей: Mamont, АИ-95 с вредоносной присадкой.
Общие рекомендации пользователям:
Не скачивать приложения с недоверенных ресурсов: случайные сайты, мессенджеры и т.п. лучше обходить стороной;
Даже если ресурс «легитимный» не стоит доверять на 100% тому, что было скачано с него, на них тоже могут располагаться вредоносные файлы;
Лучше перестраховаться и удалить приложение, которое сразу после установки запрашивает множество разрешений и требует обновиться для якобы корректной работы;
Ни в коем случае не выдавайте разрешение для доступа к «Специальным возможностям» устройства, это самая вкусная часть, за которой охотятся злоумышленники.
Иногда именно одно необдуманное нажатие кнопки «Обновить» становится первым шагом к полной компрометации устройства.
Неделя из жизни Ока Навигатора
Друзья, всем привет! Продолжаю делиться процессом разработки антиспойлерной энциклопедии по книгам Warhammer.
Возросший поток посетителей на этой неделе выявил несколько проблем, которые пришлось чинить экстренно — но не переживайте, всё уже поправлено. Например оказалось, что часть писем с кодом просто не доходила — почтовый сервер не доставлял письма части адресатов, и пришлось переехать на Resend. Зато теперь письма с кодом авторизации доходят стабильно для всех. Продолжаю добавлять рассказы из сборников отдельными произведениями, а сами сборники убрал при сортировке по хронологии. К Легендам Ереси уже добавились рассказы из сборника Око Терры. Так же капитально проверил и навёл порядок в хронологических датах, теперь книги размещены точнее.
На следующую неделю в планах добить добавление рассказов, продолжить добавлять персонажей, также очень хочется начать заполнять данные о фракциях, но времени катастрофически не хватает.
Ну и по традиции, если вы еще не видели проект, вот ссылка на него: https://nav-eye.ru
Также присоединяйтесь к нашей Телеграм-группе! Там можем пообщаться, пообсуждаем лор и новый функционал, туда же можно закинуть фидбек, зарепортить баг и даже поделиться любимым мемом по вселенной (и не только): https://t.me/navigator_eye
Модернизация координатно-расточного станка 2Д450
На одном из предприятий Москвы купили такой станок 2Д450 по цене металлолома, за 300к кажется. Железо вроде нечего, более или менее живое а вот электрике полный трындец. Шпиндельный мотор с приводом умерли и запустить их не удалось, приводы подач кое как ёрзали.
Сначала приобрели сервопривод от Балт-Систем на место шпиндельного мотора и простенький ПЛК DELTA для того чтобы, после того как я их интегрирую в старую схему на станке можно было хоть как-то попробовать работать.
Прошло какое-то время и руководство всё таки решило немного вложиться и полностью заменить систему управления станком ( всё это время станочник на станке работал как обезьяна из-за того что приводы подач работали не пойми как и помимо того что нельзя было поймать необходимую подачу так она ещё и могла самопроизвольно меняться во время работы хD )
Итак, я начал проект модернизации, подобрал контроллер (ПЛК), новые сервоприводы в количестве трёх штук, ручной моховичок и сенсорный экран (HMI). Заказал. Нарисовал новый пульт в CorelDRAW и заказал изготовление. Пока всё это ехало разработал принципиальную электрическую схему и дозаказал все необходимые электротехнические изделия, кабеля и провода. После того как приехал контроллер и все остальные дорогие прибамбасы приступил к написанию электроавтоматики и запуску движков с контроллера через экран, по EtherCAT с помощью MotionControl на столе. Следом собрал шкаф управления и проводку по станку.
В итоге всё получилось на отлично. Можно выбрать любую подачу, мы даже сверлили на нём сверлом диаметром 0.5мм с ооооочень медленной подачей чтобы не сломать (регулировка подач стала иметь более широкий диапазон в сравнении с оригинальной системой управления).
Подача задаётся на экране для каждой оси в мм\мин и при этом на пульте существует корректор подачи (потенциометр) для того чтобы можно было на ходу регулировать подачу в меньшею сторону. С оборотами шпинделя всё тоже самое. Также на пульте отображается нагрузка на оси и шпиндель, коэффициент корректоров, положение осей по линейкам и скорость вращения шпинделя. Также осями можно управлять в режиме ручного маховичка т.е. на каждый щелчок моховичка ось будет проезжать заданное расстояние. Также на станке реализован режим MDI в двух вариантах, абсолютном и относительном (abs и rel). При выборе заданных координат на все три оси и нажатии кнопки "кадр пуск" оси поочерёдно будут выведены в заданные позиции, сначала "Х", затем "Y", затем "Z". Так же можно по одной или двум осям, оси поедут в упомянутом выше приоритете.
Существуют меню диагностики через которые можно посмотреть состояния дискретных входов и выходов, состояние аналоговых входов и выходов, показания энкодеров и меню с настройками некоторых параметров станка.
Если это кому-то интересно, то задавайте вопросы )





















































































