malware · cryptomining · rootkit · linux · kernel · monero · privilege-escalation · cve-2026-31431 · container-escape
Rootpacket: набор для Linux-криптоджекинга, прячущийся в ядре
Kinryū Labs проанализировала Rootpacket — набор для Linux-криптоджекинга, который несёт руткит уровня ядра, чтобы подделывать загрузку CPU и памяти, повышается до root через CVE-2026-31431 (изъян страничного кэша AF_ALG, который к тому же сбегает из контейнера на хост), маскируется под драйвер Intel и отключает те же открытые сервисы, через которые входят майнеры-конкуренты.
Автор Davis Zheng·
TLP:CLEAR. Согласовано к публикации. Это только статический анализ: ни один образец не запускался, и каждый вывод получен из извлечения строк, дизассемблирования и разбора исходного кода. Кошелёк Monero, пул и инфраструктура атакующего публикуются как защитные индикаторы.
Краткое резюме
- ~45%CPU показывает top, пока тот работает у 100%
- 3механизма закрепления
- 7.8CVSS, CVE-2026-31431 (AF_ALG page-cache LPE)
- хостroot из непривилегированного контейнера
Rootpacket — это набор для криптоджекинга под Linux из нескольких компонентов. Он связывает воедино руткит уровня ядра для скрытности, эксплойт повышения привилегий для CVE-2026-31431 в криптоинтерфейсе Linux AF_ALG, UPX-упакованный майнер Monero XMRig 6.26.0, переименованный в xrandom, и скрипт устранения конкурентов. Код написан в основном по-турецки (имена переменных, комментарии, строки состояния), что указывает на оператора, говорящего по-турецки.
Набор работает в одном из двух режимов. В режиме root он загружает руткит — загружаемый модуль ядра (LKM), замаскированный под intel_uncore_freq_aux, устанавливает его через DKMS, чтобы тот пережил обновления ядра, регистрирует systemd-сервис и очищает машину от соперников. Когда получить root не удаётся, он откатывается к пользовательскому режиму, который закрепляется через crontab и запускает майнер как демон. Майнер соединяется с pool.supportxmr.com:443 по stratum+ssl и майнит Monero алгоритмом RandomX.
Компонент, на котором стоит задержаться, — руткит. Пока майнер держит процессор у ста процентов, руткит переписывает /proc/stat так, что top и htop сообщают спокойные 40–50 процентов, и колеблет эту цифру через jiffies, чтобы нагрузка выглядела настоящей, а не застрявшей на постоянном значении. То же он делает с /proc/meminfo и фильтрует листинги каталогов, скрывая собственные процессы и файлы.
Ключевые выводы
- Цель — криптоджекинг (высокая уверенность). Набор несёт XMRig 6.26.0, жёстко заданный кошелёк Monero и конфигурацию майнинга на
pool.supportxmr.com, причём донат разработчику XMRig выключен, так что вся выручка идёт оператору. - Повышение привилегий — это CVE-2026-31431 («Copy Fail»), детерминированная запись в страничный кэш на пути Linux AF_ALG
algif_aead(CVSS 7.8, раскрыта в апреле 2026). Поскольку страничный кэш общий для всего хоста, та же запись сбегает из контейнера, чтобы захватить root на хосте, так что заражённый контейнер — это скомпрометированный хост (высокая уверенность). - Оператор заметно выше типичной команды «сбросил-и-майню» (высокая уверенность). Кастомный LKM-руткит с ftrace-хуками, закрепление через DKMS, которое само пересобирается под новые ядра, рабочий эксплойт страничного кэша для CVE-2026-31431 и многослойное закрепление systemd/DKMS/cron — это уровень инженерии, до которого большинство криптоджекеров никогда не доходит.
- Оператор, вероятно, говорит по-турецки (средняя уверенность). Турецкие имена переменных, комментарии и сообщения о состоянии вроде
ROOT ele gecirildi!проходят через весь набор. - Rootpacket создан, чтобы владеть хостом единолично и удерживать его. Его
killservice.shубирает майнеры-конкуренты, а затем отключает выставленные наружу сервисы, которые криптоджекеры используют для первичного доступа, включая Docker API на 2375/2376 — тот же вектор, что мы задокументировали в разборе RedTail. Эти команды дерутся за одни и те же неверно настроенные машины.
Архитектура набора
Rootpacket — модульный дроппер. Его части:
setup.sh Точка входа. Проверяет уровень привилегий, выбирает режим развёртывания.
getroot Повышение привилегий. Эксплуатирует CVE-2026-31431 (AF_ALG) для локального root.
xrandom UPX-упакованный XMRig 6.26.0, переименован для ухода от детекта по имени.
kernel/
stealth.c LKM-руткит, компилируется через DKMS, замаскирован под драйвер Intel.
install.sh Движок закрепления через DKMS.
killservice.sh Устранение конкурентов и «закаливание».
rootpacket.tar.gz Внутренняя копия всего набора, упакована для перераспространения.
Режим root. setup.sh запускает getroot, если ещё не root, копирует xrandom в /opt/kernel-kd/, создаёт systemd-сервис, запускает kernel/install.sh, чтобы скомпилировать и загрузить руткит через DKMS, запускает killservice.sh, чтобы убрать конкуренцию, и стартует майнер как постоянный сервис.
Откат в пользовательский режим. Когда root недосягаем, setup.sh копирует xrandom в ~/.xrandom/, пишет лаунчер с PID-блокировкой, ставит запись crontab, срабатывающую при перезагрузке и каждую минуту, и запускает майнер через setsid, чтобы тот пережил родительскую оболочку.
| Свойство | Режим root | Пользовательский режим |
|---|---|---|
| Расположение майнера | /opt/kernel-kd/xrandom | ~/.xrandom/xrandom |
| Закрепление | systemd (kernel-kd.service) | crontab (@reboot + */1 * * * *) |
| Руткит | Да (LKM через DKMS) | Нет |
| Убийство конкурентов | Да (killservice.sh) | Нет |
| Работает как | root (systemd) | текущий пользователь (демон setsid) |
getroot: CVE-2026-31431, root через порчу страничного кэша
getroot — это статически слинкованный, не-stripped бинарник ELF64 x86-64, собранный из getroot.c. Он эксплуатирует CVE-2026-31431 («Copy Fail»), логический изъян в интерфейсе ядра Linux AF_ALG algif_aead, раскрытый 29 апреля 2026 года (CVSS 7.8). Баг даёт детерминированную, управляемую атакующим 4-байтовую запись в страничный кэш ядра, и getroot использует её, чтобы пропатчить SUID-бинарник в памяти и выйти наружу как root.
| Свойство | Значение |
|---|---|
| Тип | ELF 64-bit LSB executable, x86-64, статически слинкован, не stripped |
| CVE | CVE-2026-31431 «Copy Fail» (CVSS 7.8, AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| Подсистема | AF_ALG algif_aead, AEAD-шаблон authencesn(hmac(sha256),cbc(aes)) |
| Затронуто | Linux 4.14 — 6.19.11 (изъян появился в 2017, коммит 72548b093ee3); исправлено в 6.18.22, 6.19.12, 7.0+ |
| Цель | /usr/bin/su — его .text в памяти патчится в страничном кэше |
| Надёжность | Детерминированно, без состояния гонки |
| Использование / откат | ./getroot <cmd> [args...]; если эксплойт не сработал, всё равно выполняет команду с текущими привилегиями |
Механизм. Внутренняя оптимизация AEAD-кода 2017 года оставила сплайснутые страницы страничного кэша лежать одновременно и в исходном, и в целевом scatterlist. Когда шаблон authencesn пишет своё 4-байтовое временное значение ESN по выбранному атакующим смещению assoclen + cryptlen, эта запись приземляется внутри страницы страничного кэша файла, читаемого пользователем. Затем проверка HMAC проваливается и recvmsg() возвращает EBADMSG, но ядро никогда не откатывает запись. getroot разбирает ELF-заголовки /usr/bin/su, чтобы вычислить файловое смещение его точки входа, затем зацикливает splice → sendmsg (неся в AAD 4 байта для записи) → recvmsg, по разу на каждый 4-байтовый кусок шелл-кода, патча /usr/bin/su в страничном кэше. Затем он делает execve для /usr/bin/su: ядро загружает теперь уже испорченную страницу, шелл-код выполняется как SUID-root, и getroot подтверждает getuid() == 0, прежде чем выполнить команду оператора (печатая турецкое [+] ROOT ele gecirildi!). Файл на диске не трогается, так что мониторинг целостности файлов ничего не видит.
Побег из контейнера на хост. Страничный кэш Linux глобален для хоста; у контейнеров своего нет. Процесс внутри непривилегированного контейнера, сплайснувший хостовый /usr/bin/su, портит хостовую кэшированную копию, так что execve даёт root на хосте, а не только в контейнере. Поэтому заражённый контейнер — это скомпрометированный хост, и setup.sh дальше загружает руткит ядра в хост. Остановить и удалить контейнер недостаточно; хост придётся пересобрать.
Мы запустили getroot один раз в изолированной ВМ (Kali, ядро 6.6.15). Он выполнил полную последовательность AF_ALG, но не получил root на этой сборке и откатился к выполнению команды без привилегий, что соответствует эксплойту, нацеленному на конкретные раскладки ядра. Майнер мы не запускали.
xrandom: майнер
xrandom — это переименованная, UPX-упакованная копия XMRig 6.26.0, опенсорсного майнера Monero.
| Свойство | Значение |
|---|---|
| Реальная личность | XMRig 6.26.0 |
| Упаковка | UPX 4.2.4 (2,8 МБ упакован, 10,1 МБ распакован) |
| Алгоритм | RandomX (rx/0) |
| Пул | pool.supportxmr.com:443 по stratum+ssl |
| Кошелёк | 46NVDFL6v5STw5Qw4j77PoBSHRTYnHZGZ8WRoGvHmpaMX7ZyhNUP2u24TLV9pNgncz1bZF2Vm8KkaNTzU7SXqrnFUx5zgHQ |
| Уровень доната | 0 (донат разработчику XMRig отключён) |
Майнинг по порту 443 с TLS позволяет трафику с первого взгляда сливаться с обычным HTTPS, хотя у stratum-рукопожатия — иной TLS-отпечаток для всякого, кто присматривается.
stealth.c: руткит ядра
Это наиболее проработанная часть набора. Это LKM-руткит, который использует перехват функций через ftrace, чтобы вклиниваться в функции ядра и стирать след малвари, и который повсюду маскируется под аппаратный драйвер Intel.
| Свойство | Значение |
|---|---|
| Имя модуля | intel_uncore_freq_aux |
| Поддельные метаданные | MODULE_AUTHOR("Intel Corporation"), MODULE_DESCRIPTION("Intel Uncore Frequency Control Driver"), MODULE_VERSION("1.2.0") |
| Перехват | ftrace через kallsyms_lookup_name (на ядрах 5.7 и новее разрешается через kprobe) |
| Управление | sysfs по /sys/kernel/intel_uncore_freq/ (enabled, cpu_lo, cpu_hi, mem_lo, mem_hi, hide_tag) |
Что он перехватывает и зачем:
- Маскировка CPU. Он перехватывает
show_stat, чтобы переписывать/proc/stat, подделывая загрузку между настраиваемыми границами (по умолчанию 40–50 процентов) и колебля её через jiffies, чтобы число двигалось как настоящая нагрузка, а не стояло ровно. - Маскировка памяти. Он перехватывает
meminfo_proc_show, чтобы переписывать/proc/meminfo, подделываяMemFree,MemAvailable,Buffers,Cached,ActiveиInactive. - Скрытие процессов. Он перехватывает
iterate_dir, чтобы фильтровать листинги/proc, скрывая PID, чьи имена совпадают с жёстко заданным набором:stealth,masscan,sshruns,ransomx,cpumask,xrandom,cpm_,kcpm,mask_helper,ftrhook,kintel_aux. Оператор может добавить новые имена во время выполнения через/sys/kernel/intel_uncore_freq/hide_tag. - Скрытие файлов. Он скрывает пути, совпадающие с
stealth,cpumask,kintel_aux,intel_uncore_freq_aux, и сам каталог sysfs. - Самоскрытие. При загрузке он убирает себя из
/proc/modulesи/sys/module/черезlist_del_init, удаляет свой kobject в sysfs и увеличивает собственный счётчик ссылок черезtry_module_get, чтобыrmmodне смог его выгрузить.
Этот список скрываемого — тоже улика: рядом с майнером он прячет masscan, sshruns и ransomx, так что оператор, вероятно, гоняет сканер, и в наборе может быть не только майнер.
Практический эффект таков: администратор, смотрящий в top, видит занятую, но нормальную машину, не находит постороннего процесса и не видит модуль ядра, который и занимается ложью. Улики — физические и внеполосные: машина греется, раскручиваются вентиляторы, растёт энергопотребление, и ничего из этого руткит подделать не может.
Закрепление: три механизма, разделённые по режимам
Закрепление Rootpacket зависит от режима, в котором он приземлился. В режиме root он наслаивает два взаимоусиливающих механизма; в пользовательском режиме откатывается к третьему.
| # | Механизм | Режим | Деталь |
|---|---|---|---|
| 1 | systemd-сервис | root | kernel-kd.service, Type=simple, Restart=always, RestartSec=3 |
| 2 | DKMS-модуль | root | Ставит руткит под /lib/modules/$(uname -r)/extra/; переживает обновления ядра |
| 3 | crontab | user | @reboot плюс каждую минуту (* * * * *), с PID-блокировкой и setsid |
Запись DKMS — самая упрямая: она ставит руткит через собственную систему сборки модулей ядра, так что рутинное обновление ядра пересобирает и перевооружает его, а не удаляет.
killservice.sh: зачистка и запирание машины
Скрипт в своём баннере зовёт себя «cryptojacker hardening» («закаливание криптоджекера»), и с точки зрения оператора это описание точно. Он работает в три фазы.
Фаза 1: погасить открытые сервисы. Он нацеливается на сервисы, слушающие на 0.0.0.0, которые являются типичными точками входа криптоджекинга, останавливая, отключая и маскируя каждый, ставя chmod 000 на бинарники и добавляя правила iptables DROP:
| Сервис | Порт |
|---|---|
| Redis | 6379 |
| Docker | 2375/2376 |
| PostgreSQL | 5432 |
| MongoDB | 27017 |
| Elasticsearch | 9200/9300 |
| Memcached | 11211 |
| Hadoop YARN | 8088 |
| Jenkins | 8080 |
| Confluence | 8090 |
Строка Docker — это связующая ткань с нашим отчётом по RedTail: Rootpacket закрывает ровно ту дверь 2375/2376, через которую входит RedTail. Оператор, приземлившийся первым, майнит на хосте, а затем запирает следующую команду снаружи, закаляя машину против техник, которые они бы использовали.
Фаза 2: убрать майнеры-конкуренты. Он убивает процессы, удаляет файлы, чистит cron-задания и вычищает SSH-ключи, привязанные к известным семействам криптоджекинга, включая XMRig, Kinsing (kdevtmpfsi), TeamTNT (tntrecht, mdrfckr), sustes, watchdogs и minerd, а также сканеры вроде masscan, pnscan и zgrab.
Фаза 3: убрать пользовательские руткиты. Он срезает известные вредоносные записи LD_PRELOAD (libprocesshider.so, libjdk.so, libpamx.so, поддельный libselinux.so.3 и xhide) из /etc/ld.so.preload и удаляет библиотеки, вычищая пользовательские руткиты конкурентов, которые могли бы мешать его собственному.
Атрибуция
Турецкие имена переменных, комментарии и строки состояния набора (например ROOT ele gecirildi!, «root получен») указывают на оператора, говорящего по-турецки, со средней уверенностью. Мы нашли URL распространения или стейджинга по адресу linuxutil5.pages[.]dev, размещённый на Cloudflare Pages, что укладывается в шаблон стейджинга полезных нагрузок на бесплатной, авторитетной инфраструктуре для слияния с фоном. Внутренний rootpacket.tar.gz, самодостаточная копия всего набора, даёт оператору готовый пакет, чтобы отправить его на следующий хост.
Индикаторы компрометации
Сеть
| Индикатор | Контекст |
|---|---|
pool.supportxmr.com / pool.supportxmr.com:443 | Основной майнинг-пул Monero, stratum+ssl |
linuxutil5.pages[.]dev | Распространение / стейджинг (Cloudflare Pages) |
api.xmrig.com, randomx.xmrig.com:443 | Эндпоинты API и бенчмарка XMRig |
donate.v2.xmrig.com, donate.ssl.xmrig.com | Пулы доната разработчику XMRig (присутствуют, донат отключён) |
stratum+ssl:// на порт 443 | Исходящий TLS-трафик майнинга |
Кошелёк Monero: 46NVDFL6v5STw5Qw4j77PoBSHRTYnHZGZ8WRoGvHmpaMX7ZyhNUP2u24TLV9pNgncz1bZF2Vm8KkaNTzU7SXqrnFUx5zgHQ
Файлы (SHA-256)
| Файл | SHA-256 | MD5 |
|---|---|---|
rootpacket.tar.gz (внешний) | e2d0dab6b29df89d123fe8581047a03ac9b89ae8fa0d1f334b5aefbb93152857 | |
getroot | dda96d8a4bcc39dc7679347a4386bf1024152d2ccc46d333725ad0cda855d952 | |
xrandom (упакован) | ec3ef3dce99fa6cbc480f0f0b0c292676afed68704c44396271c7dc6afea2937 |
Build ID: getroot 148d8d902efd93ed892a541972fbcea3a99d05a3, xrandom d7a91225bdd2e3ab67cabded9d7809bcc724401f.
Артефакты на хосте
| Путь | Контекст |
|---|---|
/opt/kernel-kd/xrandom | Бинарник майнера (режим root) |
~/.xrandom/xrandom, ~/.xrandom/run.sh | Майнер и лаунчер (пользовательский режим) |
/tmp/.xrandom.lock | PID-блокировка (пользовательский режим) |
/etc/systemd/system/kernel-kd.service | Вредоносный systemd-юнит |
/usr/src/intel_uncore_freq_aux-1.2.0/ | Исходники DKMS для руткита |
/sys/kernel/intel_uncore_freq/ | Интерфейс управления руткитом в sysfs |
/lib/modules/*/extra/intel_uncore_freq_aux.ko | Скомпилированный модуль руткита |
Поведенческие
- Процесс с именем
xrandom, работающий как root или как текущий пользователь. - Цифры CPU в
/proc/stat, расходящиеся с аппаратными счётчиками производительности (perf stat) или со скоростью вентиляторов и энергопотреблением. - systemd-сервис
kernel-kd(включён,Type=simple,Restart=always). - Запись cron с тегом
# xrandom-userland-autostart. - Модуль ядра
intel_uncore_freq_aux, загружающийся при старте, но отсутствующий вlsmod.
Обнаружение
Если руткит не загружен
systemctl status kernel-kd.service
ls -la /opt/kernel-kd/ ~/.xrandom/
dkms status | grep intel_uncore_freq
crontab -l | grep xrandom
lsmod | grep intel_uncore
Если руткит загружен
Пользовательские представления скомпрометированы, так что обнаружение должно идти снизу или сбоку от руткита:
- Сравните CPU из
/proc/statс аппаратными счётчиками черезperf stat. Большой разрыв — это улика. - Следите за ftrace-хуками на
show_stat,meminfo_proc_showиiterate_dir. - Считайте расхождение между сообщаемым CPU и реальной мощностью, теплом или скоростью вентиляторов сильным сигналом.
Поймать повышение привилегий
- Сокет
AF_ALG,SOCK_SEQPACKET, открытый процессом, который не является известным криптоинструментом (cryptsetup,openssl,gpg,systemd-cryptsetup), — это главная улика. Полный порядок таков:socket(AF_ALG)→bind→setsockopt(SOL_ALG)→accept→pipe→splice→sendmsg→splice→recvmsg(повторно), затемexecve(/usr/bin/su). - Сравните дисковые байты каждого SUID-бинарника с его представлением в страничном кэше.
sha256sumчитает через кэш и показывает испорченную копию, так что читайте диск напрямую черезdd if=<file> iflag=directи хешируйте это, затем сравните. Несовпадение на SUID-бинарнике — это порча страничного кэша.
Кандидатное YARA
rule Rootpacket_Cryptojacker
{
meta:
description = "Rootpacket Linux cryptojacking toolkit"
reference = "Kinryu Labs CTI 2026-06-16"
strings:
$wallet = "46NVDFL6v5STw5Qw4j77PoBSHRTYnHZGZ8WRoGvHmpaMX7ZyhNUP2u24TLV9pNgncz1bZF2Vm8KkaNTzU7SXqrnFUx5zgHQ" ascii
$svc = "kernel-kd" ascii
$cron = "xrandom-userland-autostart" ascii
$mod = "intel_uncore_freq_aux" ascii
condition:
$wallet or 2 of ($svc, $cron, $mod)
}
Устранение
- Уберите руткит из заведомо чистого состояния. Загрузитесь с live- или recovery-носителя. Удалите
/lib/modules/*/extra/intel_uncore_freq_aux.ko*и выполнитеdkms remove intel_uncore_freq_aux/1.2.0 --all, затем удалите/usr/src/intel_uncore_freq_aux-1.2.0/и пересоберите initramfs (update-initramfs -u,dracut -fилиmkinitcpio -P). Запись DKMS должна уйти, иначе она пересоберётся. - Уберите сервис:
systemctl stop kernel-kd; systemctl disable kernel-kd; rm /etc/systemd/system/kernel-kd.service; systemctl daemon-reload. - Уберите майнер:
rm -rf /opt/kernel-kd/ ~/.xrandom/ /tmp/.xrandom.lock, затемpkill -9 -f xrandom. - Почистите cron от строк
# xrandom-userland-autostart. - Восстановите то, что сломал killservice.sh. Он ставит
chmod 000на Redis, Docker, PostgreSQL, MongoDB и другие бинарники и добавляет правила iptables DROP. Переустановите затронутые пакеты и пересмотрите файрвол. - Ищите вширь. Внутренний
rootpacket.tar.gzсоздан для перераспространения, так что проверьте другие хосты на те же индикаторы и просмотрите журналы на эксплуатацию сервисов изkillservice.sh, чтобы найти точку входа. - Закройте CVE-2026-31431. Обновитесь до исправленного ядра (6.18.22, 6.19.12, 7.0+ или бэкпорт вашего дистрибутива). Где нельзя пропатчить сразу, отключите уязвимый интерфейс:
echo 'install algif_aead /bin/false' > /etc/modprobe.d/disable-algif-aead.conf, затемrmmod algif_aead. Для контейнеров заблокируйтеAF_ALG(family 38) в профиле seccomp. - Исходите из компрометации хоста из контейнера. Поскольку запись в страничный кэш пересекает границу контейнера, считайте любой хост, на котором запускался
setup.sh, — даже изнутри контейнера, — полностью скомпрометированным. Пересоберите хост, а не просто удалите контейнер.
Сопоставление с MITRE ATT&CK
| Тактика | Техника |
|---|---|
| Initial Access | T1190 Exploit Public-Facing Application (Redis, Docker, MongoDB, Elasticsearch, Jenkins, Hadoop YARN, подразумевается) |
| Execution | T1059.004 Unix Shell |
| Privilege Escalation | T1068 Exploitation for Privilege Escalation (CVE-2026-31431, AF_ALG algif_aead); T1611 Escape to Host (общий страничный кэш) |
| Persistence | T1543.002 Systemd Service; T1053.003 Cron; T1547.006 Kernel Modules (DKMS) |
| Defense Evasion | T1014 Rootkit; T1036.005 Masquerading: Match Legitimate Name; T1027.002 Software Packing (UPX); T1070.004 File Deletion; T1564.001 Hidden Files |
| Discovery | T1057 Process Discovery (охота на соперников) |
| Lateral Movement | T1570 Lateral Tool Transfer (внутренний пакет перераспространения) |
| Impact | T1496 Resource Hijacking (майнинг Monero) |
Методология и заметки аналитика
- Анализ был преимущественно статическим (извлечение строк, дизассемблирование, разбор исходного кода, структурный анализ) на Kali Linux x86-64. Мы также запустили
getrootодин раз в изолированной ВМ (ядро 6.6.15), чтобы посмотреть на его поведение: он попытался выполнить последовательность AF_ALG, не получил root на этой сборке и откатился к выполнению команды без привилегий. Майнер не запускался, и ничего не выгружалось. - Компонент повышения привилегий — это CVE-2026-31431, опознанный по шаблону
authencesn(hmac(sha256),cbc(aes)), привязанному к сокету AF_ALG, по цели в страничном кэше/usr/bin/suи по циклу записиsplice/sendmsg/recvmsgв бинарнике. - Образцы (набор и его компоненты) доступны другим исследователям и защитникам по запросу. Напишите на [email protected] с короткой запиской о том, кто вы и зачем они вам.