technological supremacy
21 subscribers
79 photos
6 videos
157 links
You either lose your mind or die. No in-between.
Download Telegram
...именно поэтому мы займемся более интересными вещами, а именно соберёмся что-нибудь спиздить доброе утро спиздить. Естественно, кроме видеозаписей с умных камер в туалетах ничто не ценится больше, чем пароли, и сегодня мы будем пиздить порося пороль. Бонусным уровнем сложности выступает написание программы в обычном блокноте на скотлине, который жирный никак не выучит, для чего и создаются подобные обстоятельства. Я давно хотел попробовать тайминг-атаку, в идеале, конечно, с хттп-сервером, но времени и на базовый вариант ушло сильно больше, чем я ожидал. Тем не менее, я горю желанием рассказать, как я спиздил пароль (собственный).

Полный всратый код найдётся по ссылке, а сейчас посмотрим на хайлайты.

Сетап

Сетап максимально простой. Есть ASCII-пользователь, который живёт с пассфразой на восемь слов:

val Constituents = listOf(
"Lighter",
"Muggy",
"Challenge",
"Banquet",
"Hunting",
"Mud",
"Obese",
"Penetrate",
"Ban",
"Store",
"Flavor",
"Merit",
"Wine",
"Upset",
"Liberal",
"Quota"
);

val Password = (1..8)
.map { Constituents[Random.Default.nextInt(Constituents.size)] }
.joinToString(" ")


https://randomwordgenerator.com/ то ли не совсем в курсе повесточки, то ли наоборот

Брутфорсеру неизвестен этот словарь, но он знает и может проверить все печатные ASCII-символы, от пробела до ~. У брутфорсера также есть доступ к вызову функции проверки пароля, функция максимально тупая:

fun theKingdomHasFallen(password: ByteArray): Boolean {
if (password.size != Secret.size) {
return false
}

for (i in 0 ..< password.size) {
if (password[i] != Secret[i]) {
return false
}
}

return true
}


О тупости мы ещё поговорим (много), но сейчас не об этом, сейчас мы обрисовали условия задачи. На первый взгляд кажется, что у тупого брутфорсера нет никаких шансов подобрать пароль из сорока-шестидесяти символов, 95^(40-60) итераций это мягко говоря многовато. Но у брутфорсера в кармане есть две полезные вещи: таймер и щепотка статистики.

Ну што

Как получить положительный ответ от фунецкции проверки пароля выше? а) Должна быть передана строка соответствующей длины, б) все символы, один за другим, должны совпадать. Как мошейник сломает первое условие? Если всмотреться в фунецкцию, то будет заметно, что в случае передачи строки нужной длины процессор пойдет выполнять последующие инструкции, и даже если он даст отлуп в цикле на первом же символе (вероятность чего 94/95), то выполнение всё равно займёт больше времени (в эпоху суперскалярных процессоров всё немного сложнее, и про это будет ниже, но в общем случае будет так). Поэтому всё, что нужно - это передавать туда строки с разной длиной в предполагаемом диапазоне и щёлкать секундомером, замеряя время выполнения.

Здесь начинается более тонкая игра толще шуток про матерей на самом-то деле и начинает свое представление самый-самый базовый статистический фреймворк. Любой к этому моменту уже догадался, что даже если разница между двумя выполнениями мизерная и составляет какой-нибудь один цикл, то за счёт многих замеров мы можем амортизировать различные всплески, и в целом нас даже не будет волновать, что в замеры подмешивается время выполнения самого таймера - нас интересует только относительная разница, а не абсолютные величины. Тем не менее, уже тут можно прострелить себе ногу несчётное количество раз.

Сборщик мусора преследует бобик
1
ГЦ является любимой самой нашей проблемой в вопросах латенси. Если вы что-то аллоцируете в этом подборе, то во-первых это собьет вам таймер, а во-вторых - что ещё багорнее - по мере использования более длинных строк вы будете всё активнее забивать хип, что будет приводить к более частому ГЦ, что скорее всего приведет к тому, что самой медленной будет отмечена какая-то длина из самого хвоста выбранного диапазона. Тут вы скажете, да это ж просто - надо нааллоцировать необходимые структуры до того, как приступать к работе, а в самом рабочем лупе просто их переиспользовать. Вообще да, но это не гарантирует, что вы не пропустили что-то где-то, что ГЦ не вызовется сам, и что например проблемой не будет

Прогрев

Так как все читающие всё равно сидят на каком-то JIT-рантайме, простой запуск брутфорсера приведёт к тому, что в замеры вмешается компиляция и разные версии кода. И даже без рантайма можно споткнуться о какую-нибудь загрузку библиотеки на первом вызове, что тоже уйдет в показания таймера. Решается это максимально просто, спасая также от некоторых других проблем: брутфорсер должен тупо работать в цикле и делать N итераций, прежде чем сдаться. Забегая вперёд, лучше засунуть в один цикл и проверку длины, и подбор пароля, чтобы неверно определённая длина не сломала всё. Но это не всё, у нас остаётся ещё как минимум

Вытеснение тредов

Здесь, естественно, происходит та же ситуация - пароль проверяется в горячем цикле, который сам по себе занимает меньше, чем вызов таймера, поэтому вытеснение с большой вероятностью попадёт между двух таймеров и разъебёт среднее по замерам. Тут уже можно понять, что, конечно, с прогревом и аллокациями надо бороться, но в целом проблема всплесков в отдельных замерах неизбежна. Поэтому с ней надо бороться каким-то другим способом, а если конкретно, то нам нужно

Удаление выбросов ну а шо мне именно так гугл перевёл "outlier"

Если мы можем обоснованно предполагать, что наше среднее поднимают только редкие но могучие паузы, то мы просто можем их выкинуть из расчётов. Жирный понятия не имеет, какие способы для этого есть вообще в целом, но знает про самый классический IQR тест - все замеры делятся на четыре квартиля, которые разделяют замеры, находящиеся в позициях 1/4, 1/2, 3/4 отсортированного массива замеров. Обращая внимания на два средних квартиля, мы можем очень грубо предположить, в каком диапазоне находятся легальные значения и в откуда начинаются аномалии - в качестве этого диапазона просто принимаются значения [Q1 - 1.5 x IQR, Q3 + 1.5 x IQR], а всё остальное отбрасывается. Таким образом можно выкинуть все долгие, но редкие паузы, после чего взять уже более правдивое среднее. Я кстати наверное проебался с этим в коде, но оно всё равно работает.

Нахождение длины

Вооружившись этими нехитрыми советами, остается только бомбить фуфнкцию данными разной длины

fun crackLength(): Int {
for (length in 0 ..< Pool.size) {
for (attempt in 0 ..< Iterations) {
val distribution = Distributions[length]
val target = Pool[length]
if (measured({ theKingdomHasFallen(target) }, distribution, attempt)) {
throw IllegalStateException("Wake up, password could not match an empty array")
}
}
}

for (length in 0 ..< Pool.size) {
Averages[length] = average(Distributions[length])
}

return Averages.outlier(Pool.size)
}


я умудрился один раз проебаться и получить-таки это исключение

Как здесь получается необходимое значение? Берётся ещё один простой инструмент из статистики думать-то я не умею, просто продолжаю двигаться по колее на автомате, squared error (нужен он буквально для положительных значений, Math.abs тоже бы подошел), и находится элемент с самым большим отклонением от среднего. Нормальный статикист не ушёл бы как минимум без Т-теста, ну а у нас и так сойдёт.
1
fun DoubleArray.outlier(limit: Int = -1): Int {
...
for (i in 0 ..< stopper) {
val residual = mean - this[i]
val error = residual * residual
if (error > peak) {
winner = i
peak = error
}
}


return winner
}


Почему не просто взять самое большое значение? Об этом будет в следующей серии, мои дорогие бинджвотчеры. А пока посмотрим на результаты:

kotlinc ArschMitOhren.kt && time kotlin ArschMitOhrenKt
Detected length: 52 symbols, the real length is 52 symbols
Averages distribution per length, in nanoseconds, +/- 3 neighbors:
49 50 51 52 53 54 55
1.295 1.295 1.294 9.347 1.328 1.327 1.329


Blam! Нужная длина найдена с первой итерации, в первой паре ревизий мне мешал прогрев, но потом получилось подкалибровать это дело. Здесь же явно видно проёб разраба, как сильно отличается прохождение условия от немедленного отлупа а знаете кто ещё его получит при попытке получить зарплату?
Не спрашивайте меня, почему после нахождения длины функция становится медленнее, я не проверял. Скорее всего, это PGO, но мне поспать ещё надо успеть.

Подбор пароля

На самом деле, кроме одного момента тут не так много о чём можно рассказать, фреймворк-то уже есть. Таблички в метро пиздить и то более увлекательно.

Round 0 result: F (raw index: 38, full prefix: F)
Averages distribution per symbol, in nanoseconds, +/- 3 neighbors:
C D E F G H I
2.478 2.475 2.481 4.290 2.477 2.478 2.478
Round 1 result: l (raw index: 76, full prefix: Fl)
Averages distribution per symbol, in nanoseconds, +/- 3 neighbors:
i j k l m n o
4.186 4.187 4.188 6.092 4.187 4.187 4.191
Round 2 result: a (raw index: 65, full prefix: Fla)
Averages distribution per symbol, in nanoseconds, +/- 3 neighbors:
^ _ ` a b c d
5.475 5.477 5.475 7.882 5.475 5.473 5.474


Ровно так же, как и с длиной, замеряется время выполнения, и время обработки префикса с правильным символом в конце резко выделяется на фоне остальных. И тут начинаются некоторые мелкие детали тех самых проклятых современных процессоров, которые поджидают неопытного брутфорсера словно в песне лагутенко или чернухзина мб:

skonsole 
Round 16 result: h (raw index: 72, full prefix: Hunting Wine Ligh)
Averages distribution per symbol, in nanoseconds, +/- 3 neighbors:
e f g h i j k
29.900 29.901 29.902 32.048 29.903 29.903 29.902
Round 17 result: t (raw index: 84, full prefix: Hunting Wine Light)
Averages distribution per symbol, in nanoseconds, +/- 3 neighbors:
q r s t u v w
39.310 39.306 39.303 33.754 39.307 39.311 39.310


Хоба! Поймать получается не каждый раз, но правильный символ здесь имеет минимальное, а не максимальное время выполнения (что и вызвало поиски сэмпла с наибольшей ошибкой вместо максимального). Почему? Опять же, я не проверял счётчики, но скорее всего это порог бранч предиктора. В случае с t бранч берётся вообще всегда, в случае с остальными, вероятно, предиктор начинает предсказывать успешное прохождение проверки следующего символа, обламывается и ломает весь пайплайн - превет костевичкам от суперскалярных. Тем не менее

Панчлайн

Round 53 result: a (raw index: 65, full prefix: Obese Penetrate Banquet Lighter Store Store Liberal Ba)
Averages distribution per symbol, in nanoseconds, +/- 3 neighbors:
^ _ ` a b c d
91.486 91.483 91.486 93.517 91.482 91.481 91.485
<последняя итерация не печатается>
Password found: Obese Penetrate Banquet Lighter Store Store Liberal Ban
kotlin ArschMitOhrenKt 65.62s user 0.07s system 100% cpu 1:05.39 total
1
Ну вы поняли, да? Злом пороля занял четыре часа, одну минуту: четыре часа пыхтения с докой по непривычному языку, минута работы брутфорсера в одно рыло ядро, который ничтоже сумляшеся ломает пароль длиной в пятьдесят ASCII-символов, и всё это исключительно подсчётом количества наносекунд, сравнимого с ликвидным балансом фнб.

Злом злома

О том, что делать, как строить из себя невиноватого, и почему это на самом деле так просто не работает.

Что делать

В первую очередь, перекладывать ответственность за проверку паролей на чужие библиотеки и коллег. Если же работы не избежать никак, то стоит взять constant time comparison function, которая вообще не будет проверять длину, а просто будет итерироваться по всей длине инпута и выполнять одинаковое количество операций вне зависимости от совпадения или несовпадения строк. Звучит приятно, но на деле это абсолютно нетривиальная задача (эй, костевички! мы уже передавали вам привет?) - любой if может сыграть свою роль с предиктором, некоторые операции в процессоре итеративные сами по себе, какие-то вещи могут вызвать лишние походы в память, etc., etc. - вы без труда найдёте в интернете пейперы, в которых ломают алгоритмы криптографии за счёт разных side channel.

Жирный на самом деле в этих делах не эксперт, но может сказать ещё одну очевидную вещь. Здесь всё получилось быстро благодаря тому, что проверка пароля выполняется плейнтекстом и занимает сотню наносекунд. Если бы этот процесс включал в себя хэш-функцию, то она во-первых бы ограничила временные возможности брутфорсинга, во-вторых, при выборе правильной функции, даже информация о префиксе не помогла бы её сломать.

Вне зависимости от этого, количество попыток входа нужно ограничивать. Мой любимый пример проблемы, тоже слегка связанный со статистикой - это шестизначные коды подтверждения. Они тоже на первый взгляд выглядят абсолютно неподбираемой историей, но если код действует пятнадцать минут, и мошейник успевает делать 1.1 запросов в секунду, то он проверяет 1000 рандомных кодов, с вероятностью успеха в 1/1000. В одном дне 96 таких пятнадцатиминутных отрезков, приводящих к вероятности устоять 0.999^96 = 0.908, а в неделе - 672, или 0.999^672 = 0.51.

Как строить из себя невиноватого

Да никак уже

И почему это на самом деле так просто не работает

Данный пример раскололся настолько тривиально по очень простой причине. Любой вменяемый человек но что вы тогда здесь делаете осуществит проверку содержимого следующим образом:

fun theKingdomHasFallen(password: ByteArray): Boolean {
return Arrays.equals(password, Secret)
}


И вся атака пойдёт по пизде, длина найдется элементарно, а вот подбор зайдет в тупик. При том что логика внутри абсолютно идентичная, цепочка вызовов придёт к

i = vectorizedMismatch(
a, Unsafe.ARRAY_BYTE_BASE_OFFSET,
b, Unsafe.ARRAY_BYTE_BASE_OFFSET,
length, LOG2_ARRAY_BYTE_INDEX_SCALE);


и то если не будет вообще выпилена интринсиком

...что будет сравнивать байты сразу чанками и что означает, что для выявления корректного паттерна нужно совпадение не одного дополнительного байта, а сразу всей длины страйда, в котором может валяться и 64 байта за раз. Обычно, конечно, сравнивают вообще строки, и в сорцах String.equals() использует наивный алгоритм, но он же помечен IntrinsicCandidate; времени копаться в этом дальше и переписывать просто нет, увы.

С замерами каких-то проверок по вебу всё ещё сложнее. Из-за времени отклика собирать статистику в разы медленнее, а количество факторов, которые могут повлиять - чуть ли не бесконечно, самый интересный для меня из которых - это дневной наплыв посетителей и автоскейл, которые подарят всем замерам отклонение, которое не будет отсечено IQR как аномалия. Данные проблемы обходятся (например, можно делать рандомный семлпинг, чтобы в любой момент времени было равномерное распределение), но для этого про них надо сначала знать.
1
Ни одно из вышеперечисленных не является надежной защитой, но пытаться устроить массовый взлом, обращаясь к чужим серверам - это довольно запарно и требует всрать вечер на котлин некоторых ресурсов, плюс способа трекинга значений и способностей к анализу, потому что при малейшей мисконфигурации алгоритм начинает играть в самую длинную комбинацию последовательных слешей в мире вместо реального подбора.

Мораль

Куплю таблетки для восстановления графика сна. А что до атаки, то она скорее больше демонстративный пример (что нужно думать out-of-the-box), чем реальная опасность. Сломают вас (и именно по вашей вине) всё равно более изощренным путём, так что начинайте это прорабатывать с психотерапевтом уже сегодня.
1
Если вы пропустили главный сериал осени 2025 - 2027 (?), то сопутствующий ущерб ещё только планирует выйти на максимум.

https://www.tomshardware.com/pc-components/storage/ssds-now-cost-16x-more-than-hdds-hybrid-ssd-hdd-datacenter-deployments-are-now-significantly-cheaper-to-deploy-than-ssd-only-equivalents

Для меня до сих пор загадка, почему мы не слышим об исках антимонопольного характера (несмотря на то, что сами фабрики не разбросаны по странам со страдающими геймерами, формальные представительства должны быть зарегистрированы по всему миру) - беглый гуглеж находит, например, американский иск даже не от государственного органа, а от конечных потребителей.
Исходная идея была постить минимум личных вещей, но, наверное, всё-таки стоит писать про некоторые штуки, с которыми сталкиваюсь.

В последнее время поверхностно погрузился в мир single board computers (с целью домашнего разворачивания личных проектов), сокращенно SBC, принцип которых, как следует из названия - это состоящий из единственного чипа компьютер, в котором единственный необходимый компонентом явдяется сторадж в виде microSD-карты, eMMC или UFS (а иногда eMMC и вовсе распаян, но это приносит некоторые сложности). Самый известный представитель - это, конечно, raspberry pi, но в тени за ним стоит тьма более экзотических борд. NUC и прочие миникомпьютеры довольно близки, но даже при распаянной оперативке редко называются SBC просто по принадлежности к другому классу, имеющему совсем другую специфику проблем.

Издалека кажется, что SBC отличаются главным образом архитектурой, но при близком обнаруживается миллион нюансов. Начну с минусов:

- Подавляющее большинство - не очень производительный ARM с базовыми кортексами (но довольно часто это свежие ревизии). С экзотикой достоверные бенчмарки найти бывает сложно, но на geekbench много измерений популярных чипов. RPi заметно не дотягивает до текущей интеловской рабочей лошадки для mini pc, но популярный в этой среде Rockchip 3588 (название компании никто за пределами SBC-мира и не слышал) подбирается по кумулятивной производительности довольно близко к интелу (разница в проивзодительности на одном ядре обуславливается в том, что у RK3588 восемь ядер против четырех).
- Естественно, оперативка всегда распаяна, если ваш хомесервер раздулся, то апгрейднуться не получится, а своп не вариант (см. сторадж ниже). Если какой-то компонент полетел (а, скажем, загнуть или отломать пины проще простого), то так и придётся жить.
- Ебучие светодиоды. Если эта штука лежит на столе и включена дольше трёх секунд, то глаза будут выжжены. Это не старый добрый интеловский NUC, где уже в шестом поколении можно было прямо в биосе настраивать яркость - управлять можно только дополнительным светодиодом, чтобы удвоить страдания.
- Компоненты от таких же неизвестных компаний на задворках мира, как и процессоры. Обычно про это даже не думаешь, оно чаще всего просто работает, но иногда можно встрять в проблему, про которую на обычных компьютерах услышать невозможно. Или внезапно рушится представление о том, что весь мир уже перешел на гигабитный ethernet. Вай-фай и bluetooth (для меня их необходимость на таком устройстве, которому место за роутером, вызывает вопросы) могут быть четвертого поколения даже в свежем продукте.
- Самая лучшая из проблем, про которые я узнал - это адаптер с отсутствием постоянного mac-адреса, т.е. ни привязать статику в DHCP-сервере (это ещё решается за счёт выставления кастомного адреса через netplan, networkd, nm), ни кастомизировать network boot.
- Ещё одна забавная проблема, связанная не с периферией, а с самим чипом. Большинство адаптеров умеют в Wake on Lan, посылать процессору сигнал для пробуждения или даже включения при получении магического пакета по сети, чтобы ваш домашний стенд бля бенчмарков жрал минимум электричества и не выделял тепло, пока не нужен. Вот только сами чипы уходить в сон или включаться тупо не умеют. Берите smart plug или managed switch с PoE за свои.
- Сторадж. Сейчас ситуация становится получше с добавлением m.2 разъемов прямо в SBC, но до недавнего времени единственными вариантами было покупать USB SATA adapter или NVMe hat, ставящийсся сверху платы и подключающийся шлейфом в PCIe-порт. При чём всё это обычно идёт с припиской PCIe 2.0 x1 [lane], что значит 500мб/с максимум - и то, если процессор способен это выдержать. Дефолтный сторадж - это вообще SD-карты с соответствующим перформансом и отвалом через какое-то время.
- Линукс. Линукс это просто пиздос. Несмотря на то, что Торвальдс делает всё, что необходимо для предоставления поддержки производителям, вместо нормальной работы с мейнлайном, растягивающейся на месяцы и требующей нового релиза для каждого апдейта, мейнтейнеры просто берут linux 5.10 и вкорячивают туда свой говнокод с изменениями (всё, включая бейзлайн, единым коммитом - даже сами изменения нельзя было отфильтровать, всё это делается максимально омерзительно, чтобы uname выдавал просто "5.10.4-tag-"), выпуская свои адаптации убунты 20.04 с этим ядром. Они обязательно обещают юзерам перенести всё в мейнлайн, и действительно добавляют поддержку GPIO и камер - совершенно игнорируя, например, системы стораджа. В результате мейнлайн поддерживает почти всю функциональность - да только вот на устройстве это не запустится, потому что он себя прочесть не сможет. Через несколько месяцев разработка прекращается на полпути.
- С самими мейнтейнерами отдельная хохма. Коммиты в ядро, даже для каких-то процессорных дел, засылают не создатели процессора, а те, кто производит сами борды. С их маржинальностью остаётся только нанять среднего студента клепать какие-то изменения, пока борда не начинает запускаться.
- Запуск борды. Во-первых, можно забыть про UEFI и ACPI. Это значит, что в само ядро линукса нужно предоставить DTO-файл (в виде сорца это DTS-файл) с описанием всех устройств, иначе он не шможет (а файл этот хоть производитель и легально обязан предоставить, делает он это не всегда, выдирайте из предоставленного образа). Во-вторых - ещё больший мрак с самим бутлоадером. Тут можно забыть уже про grub, нужно компилировать из сорцов u-boot или что-то пострашнее (для глубины проблемы можно заценить yoctoproject) с какими-то конкретными оффсетами и бинарями для тренинга DRAM, потому что иначе не сможет и сам бутлоадер. Шаг влево, шаг вправо совершается только с подключением по serial порт в надежде на то, что там будет вменяемая информация для дебага. В-третьих, сам запуск бутлоадера может быть максимально всрат - например, на плате есть гнезда для microSD, eMMC и NVMe, но вот поставить бутлоадер можно исключительно на microSD. C бутом по сети тоже как повезёт, хотя это самое рациональное в случае с SBC - какой-то чип поддерживает, какой-то нет, какой-то поддерживает, но производитель не даёт инструкций, поэтому вся надежда на какого-то рандома с непонятного форума, объясняющего, как пропатчиться в hex-редакторе.
- Виртуализация. Несмотря на соответствующую ревизию арма, её либо нет, либо она выключена бутлоадером производителя, либо производитель запускает сам бутлоадер в качестве виртуалки, запрещая ему доступ наружу к гипервизору. Докер и альтернативы, естественно, поддерживаются линуксом, пока есть необходимые дрова/модули на сеть - а тут зависит от того, как производитель ядро скомпилил.
- Совместимость с компонентами. Чаще всего расположение того-сего стараются копировать у RPi, но нет никаких гарантий, что какой-то hat подойдет. На мой вопрос "а как там с PoE, подойдет от RPi?" магазин производителя ответил "не знаю, почему бы вам не проверить самостоятельно?"
- Если вы хотите пользоваться perf, то это скорее всего не получится. В лучшем случае каунтеров просто не будет. В худшем - производитель вообще выдерет папку perf из сорцов ядра и скомпилирует так. Тем не менее, на некоторых бордах всё это присутствует.

Плюсы:
- Стоимость. Стоимость. Стоимость. Самый всратый китайский Mini PC вам обойдется минимум в 200+ евро. SBC с 4Gb оперативки (не самый производительный, конечно, но удовлетворяющий требованиям) [пока] может стоить меньше 50 евро, в самых слабых случаях даже с microSD картой. RPi относительно дорогой с 100+ за четыре гигабайта и выше. Для обычных серверных линуксовых задач при этом как правило не возникает ограничений, и производительности обычно хватает.
- Охлаждение. Оно банально не нужно, нужен только радиатор, и то если SBC существует под ощутимой нагрузкой. Точную информацию сложно найти, но большинство чипов не потребляют и десяти ватт в пике, а рекомендации для чарджеров 15-25 ватт существуют ради предоставления питания периферии, подключаемой по USB. Это же позволяет запитать некоторые SBC напрямую от других устройств, имеющих 5v / 2a USB-порты. Усеченные модели (RPi Zero и аналоги от других производителей часто выделяют ещё в пару раз меньше тепла, если у вас вообще нет требований к производительности устройства (но у них нет ethernet, и не для всех даже есть hat).
- Это отличный армовая песочница, в которой можно играться с бенчмарками, k8s и даже базами данных (естественно, потребуется NVMe или хотя бы SATA SSD через USB). С армами такая ситуация, что у вас либо мак, либо вы переплачиваете клауду за сервер, либо берёте SBC.
- Даже несмотря на вышеописанные проблемы с дистрибутивами, если внутреннего перфекциониста можно погасить, а io_uring не требуется - то живёт оно на каком-то всратом ядре и живёт, после сетапа вы и не вспомните.
- Но если ваша борда поддерживается проектом armbian, то вы в дамках - скорее всего у вас будет и свежий мейнлайн, и убунта / дебиан. У федоры тоже есть какая-то поддержка некоторых SBC, драйвера для которых доехали до мейнлайна. И самое удивительное - поддержка для популярных моделей есть у talos linux, вы можете поставить bare metal k8s без чего-либо лишнего с минимумом усилий, а там уже практически network boot его силами.
- Power over Ethernet, получения питания вместе с сетью. Это будет стоить дополнительных денег (+15-25 евро на PoE hat), и устройство, которое будет раздавать PoE нужно ещё найти (домашний роутер от провайдера таким заниматься не будет; PoE-свитчи стоят заметно дороже обычных), но кластер устройств может существовать без оккупации трёх пилотов.
- Сейчас все идут с тем или иным NPU на какие-нибудь пару TOPS. В половине случаев он есть, но его невозможно вызвать, но в другой половине можно гонять не только распознавание изображений, но даже слабые LFMки на 0.5-2 миллиарда параметров.
- Для меня это представляет нулевой интерес, но наличие обязательных GPIO, портов для камер и иногда даже встроенных микрофонов позволяет решать какие-то задачи с физическим уклоном от дверного звонка по интернету до распознавания голоса за копейки.
- Поместится даже туда, где нет места для обычного mini pc и его кирпича.
- Играться с этой штукой банально весело.
https://simple-fax.de/fax-ki

Искусственный интеллект по факсу
Искусственный интеллект сейчас у всех на слуху, и simple-fax.de внедряет эту инновационную технологию непосредственно в ваш факсимильный аппарат. Fax AI превращает ваш факсимильный аппарат в интеллектуальный инструмент, который не только отправляет и получает сообщения, но и предоставляет компетентные, персонализированные ответы на ваши вопросы.

Сервис Fax AI от simple-fax.de — это экспериментальная разработка, использующая искусственный интеллект для обработки ваших факсимильных запросов. Просто отправьте нам свой вопрос или задачу по факсу на номер 0531-490590019, и Fax AI проанализирует ваш запрос и отправит подробный ответ непосредственно на ваш факсимильный аппарат. Будь то предоставление информации, перевод документов или решение математических задач — Fax AI станет вашим надежным помощником в самых разных областях.
Публичные API ключи гугла, те, которые разработчики используют для вставки Google Maps карт себе на сайт, могут использоваться для доступа к перепискам с Gemini (ИИ от гугла) и скачивания загруженных туда файлов; а ещё с помощью этих же ключей можно пользоваться ИИ Gemini от имени создателя сайта (и гугл потом выставит им круглый счет за это).

Разработчики сообщают о счетах на десятки тысяч долларов.

Исследователи нашли уязвимость с ноябре 25го и гугл уже почистил большинство ключей, но если вы настраивали гугл-карты у себя на сайте или пользуетесь Firebase и включили на этом же GCP проекте Gemini API — стоит его выключить и перенести в отдельный проект.

🤯
сюда тоже
tl;dr: журналисты прислали на военный корабль открытку с эиртагом или его аналогом, через него получили точное расположение; скрининг осуществляется только для посылок

https://nltimes.nl/2026/04/17/eu5-gadget-tracks-dutch-navys-stealth-warship-mission

trots op Nederland.
technological supremacy
https://news.rambler.ru/incidents/54137383-top-menedzher-laboratorii-kasperskogo-otdal-moshennikam-10-millionov-rubley/ (это люди, которые натурально продают безопасность)
В рубрике кибербезопасники vs. internet 101 сегодня целый executive director of the Cyber Defense Division, приехавший в Лас-Вегас поприсутствовать на конференции для скилловых и заодно попасться на классический ханипот для педофилов от ФБР

In August 2025, Alexandrovich was arrested in Las Vegas, Nevada, and charged with soliciting a minor, a felony.[15] Alexandrovich was among 8 individuals arrested during a 2-week undercover sting operation targeting child sex predators.[2] Alexandrovich was subsequently released and allowed to return to Israel.[16]

He was in Las Vegas to attend the Black Hat computer security conference.


Needless to say, одним из остальных семи неудачников был конечно же местный пастор.