Stack Overflow некоторое время назад запретил использование LLM (ChatGPT и пр.) для генерирования и ответов, и вопросов на сайте. Причины запрета были названы разные, но ситуация стала особенно забавной на днях, когда из OpenAI объявили, что контент Stack Overflow будет официально предоставлен для “обучения” ChatGPT (пока что – несмотря ни на какие протесты некоторых пользователей). То есть, если бы изначального запрета на использование LLM не было, то могла бы возникнуть ситуация, когда в ChatGPT транслируется выдача ChatGPT, что далеко не всегда хорошо (хоть и составляет существенную часть штатной работы данных LLM).



Комментировать »

В прошлом году (да и раньше – надо бы сделать подборку) я писал про возможности по анализу навигационного поля GNSS, которые есть у провайдеров различных распределённых сервисов. Цитата:

“Так вот, если у вас есть устройства “на местах”, которые приносят дополнительную информацию, а не только “координатные данные” GPS, то можно на центральном сервере выстраивать динамику изменения реального навигационного поля по сравнению с моделью, учитывающей только положение и состояние спутников. Это позволяет не просто получить корректирующую величину для всех участников системы, но также увидеть возникающие на местах пространственные дефекты и искажения с развёрткой по времени (то есть, не просто спуфинг), что весьма ценно.”

Вот, судя по описанию, сходным, – но не совсем похожим на описанный выше, – образом, и работает сервис от Flightradar24, показывающий помехи GNSS.

Много интересной информации в реальном времени может, – в теории, – вычислять, например, “Яндекс” со своими приложениям на смартфонах. Впрочем, для обработки данных потребуется задействовать довольно сложный вычислительный механизм, вряд ли удастся обойтись “обучением нейронки”.



Комментировать »

Что касается новостей про атаку TunnelVision, которой соответствует CVE-2024-3661, и про которую сейчас СМИ пишут, что это “уязвимость всех VPN”. Очень (слишком даже) подробное изложение есть по исходной ссылке, однако там начинается весьма издалека, с самых азов. Но для сетевого инженера саму атаку можно детально описать в несколько строчек: к VPN это отношения не имеет, а речь идёт про добавление маршрутов на клиентское устройство средствами DHCP-сервера, маршруты, соответственно, добавляются с привязкой к сетевому интерфейсу на уровне ОС клиента и ведут на перехватывающий узел в той же локальной сети. Дальше работает more-specific, потому что для интерфейса VPN прописано, предположим, 0.0.0.0/0. Понятно, что таким способом можно перенаправить произвольный IP-трафик на промежуточный узел до того, как этот трафик уехал на клиенте в туннельный интерфейс, поднятый приложением VPN. Трафик поэтому будет в открытом виде. Это, собственно, всё.

DHCP-команда, которая позволяет прописать маршруты в интерфейс клиенту – известна, это никакая не уязвимость, а штатная функция DHCP. Работает, конечно, если устройство не только обрабатывает данную команду, но и реально маршруты устанавливает (Android – игнорирует, поэтому атака не работает для Android). Если локально маршруты от DHCP фильтровать или игнорировать, то тоже атака не сработает (интересно, что это очередной раз показывает, насколько правильным является использование виртуализации: если доступ через виртуальную машину, то, скорее всего, навязанные маршруты через виртуальный интерфейс сами не пройдут; то же самое относится и к сетевой “виртуализации” вообще – если подключаться со своим локальным сегментом, например, через свою точку доступа, то атака опять не сработает).

Собственно, авторы исходного сообщения прямо пишут, что вопрос, является ли TunnelVision уязвимостью – спорный, а дальше объясняют, что публикация направлена на противодействие массовым маркетинговым уловкам провайдеров VPN-сервисов, когда заявляется, что какой-то VPN-клиент защищает трафик при подключении к “недоверенной сети”.



Комментировать »

Снова пишут про то, что в TLS браузера Chrome длинное ClientHello с ключом Kyber768 ломает обработчики TLS-трафика на каких-то “специальных” веб-серверах и на промежуточных фильтрах. Между тем, чтобы разобраться, как там и что происходит, достаточно посмотреть на конкретное ClientHello, но в некоторых деталях. В качестве примера я взял сообщение от браузера Chrome 124 в том виде, как оно отображается на тестовом сервере TLS. Чтобы просмотр дампа не был скучным, листинг перебивается техническими пояснениями.

Итак, ClientHello TLS 1.3 с постквантовой криптосистемой Kyber768 внутри. CH здесь уже извлечено из TLS-записей и разобранно на элементы: то есть, здесь не учитываются и не упоминаются дополнительные байты, которые расходуются внутри структуры CH на представление полей – идентификаторы, длина записи; обычно – это несколько дополнительных байтов на один элемент структуры. Если бы разбирать и эти байты, то описание излишне усложнилось бы (подробности – можно прочитать в техническом описании TLS).

Version: 0x0303
Cipher suites:
 0xBABA,0x1301,0x1302,0x1303,0xC02B,0xC02F,0xC02C,0xC030
 0xCCA9,0xCCA8,0xC013,0xC014,0x009C,0x009D,0x002F,0x0035

Начальная часть сообщения ClientHello (далее – CH) содержит “исторический” номер версии (здесь указано 0x0303) и перечень шифронаборов. Полезных данных: два байта – номер версии, 32 байта (16*2) – идентификаторы шифронаборов.

 
Client Random: 
85:32:22:08:24:07:B2:98:F3:23:08:4D:A5:FB:E4:59:41:93:13:88:AA:58:53:4E:B4:EF:E7:DA:E8:78:FE:71
Client SessionID: 
C0:39:BC:CE:BB:60:5F:76:D8:75:F9:84:69:E9:9F:C2:AE:7B:8F:D5:9C:E8:01:51:71:9D:21:D2:13:26:DB:5A

Случайное значение от клиента (Client Random). А также клиентский “идентификатор сессии” – в TLS 1.3 этот идентификатор играет роль простого сигнала и ни на какую сессию не указывает.
Здесь всего 64 байта данных, по 32 на каждое поле.

Далее идёт важная часть, которая, собственно, определяет значимые параметры TLS-соединения – набор расширений CH.

Extensions:
 Type: 14906 (0x3A3A); "_undef_ (GREASE)"
 Type: 35 (0x0023); /non-TLS-1.3/
 Type: 23 (0x0017); /non-TLS-1.3/
 Type: 16 (0x0010); "application_layer_protocol_negotiation"
  00:0C:02:68:32:08:68:74:74:70:2F:31:2E:31
 Type: 65281 (0xFF01); /non-TLS-1.3/
  00

Здесь 0x3A3A (тип 14906, первое расширение) – это пример того, что называется GREASE, а именно – специальных, заведомо неподдерживаемых, значений и идентификаторов, которые Chrome дописывает в TLS-сообщения с целью (как заявлено) проверки корректной работы парсеров и прочего программного обеспечения, задействованного в обработке TLS. Такие обработчики, согласно спецификации, должны успешно игнорировать неизвестные расширения и параметры (если контекст позволяет, конечно). Так что, вообще говоря, добавление разных там новых “постквантовых ключей” не является чем-то особенным – всякие фиктивные элементы писались в браузерные сообщения и раньше, именно для того, чтобы обновления не оказывались полной неожиданностью (ниже нам встретятся и другие GREASE). Другие расширения из этого фрагмента, с типами 35 (session_ticket), 23 (extended_master_secret), 16 (ALPN) и 65281 можно не рассматривать: они небольшие по объёму (например, extended_master_secret – это всего лишь сигнал, вообще не содержащий байтов данных), часть из них не поддерживается в TLS 1.3. Поэтому – переходим дальше.

Как говорится, а вот и он – постквантовый элемент. Клиентский открытый ключ Kyber768 содержится уже в следующем расширении – key_share. Оцените огромный размер данных, которые тут приводятся без сокращений.

 Type: 51 (0x0033); "key_share"
  _undef_ (GREASE) (0xAAAA)
   Unsupported group: 0xAAAA (_undef_ (GREASE))
  X25519Kyber768Draft00 (0x6399)
   Hybrid: X25519 + Kyber
   Len (octets, dec.): 1216
   Key share data:
    X25519
     x = 0xF2C744A07B3BC36F6C427620351A009D29BB36E6EF259A177A3881ECEB22100D
    Kyber768 client public key:
     Vpoly_1 (packed):
      6CA39FB332275395989A56958E6B61A7B3B447D6A2C9062837E39695B44E4A5B
      36C9A7B06F4A912ED6ABC2E3BD2FD8584BE42F5822A3A54A4CC14812F3D87A05
      5371F2E1222817A63FAA531CD7691DE59694F9B4ACD3B8CD638A44B9B566C094
      3A95B7DCB186CC840C53A90041FB15FFBB214E3BCE8AB0C3D278897A61992601
      BB88427608A8AEC6385C0C6319A56B8B47CA240F3A134DD6AF4B56A6333158A9
      D391B495A76EA0C5F67C49457042AFFB508766414C88A8EA23B1328723FC9199
      8BA78414527F2DC234C0213CF5DAB976910EA3DC641C8B818FF73F4CEB53C929
      C03F61CFD8A04CE88A3EB16CCAE02C9541438A16D4A7FE8129F7F04C0C0A9E14
      60ACA4049F84C2C4E5DB1B4185CF0FE8C305333CBC7B3970A27E42C23F47F003
      E3815FDE20830B912501E388BEB9B14399ADD2EA174E3C040810917E555084E1
      5B75B9599914523799B6885721D08A46741501EBACA747C905B7AA31E3D3137C
      718B50A908DC111E49161448B102D3F0411EA70D9F91CFF6F50D5D54B9AB7B11
     Vpoly_2 (packed):
      1356BAA03CAD6E2730C334C24D492E6A11088F7B036A7ACBEF26407C1A9DCDFA
      473D677C3447915AE28EB094326093668FC27DCB85086219A1A0E6A6FC367CE0
      9A4396EA75FAFA1CD336311DE505BE5075A36C436B58673CF6387AF45BDBD523
      C082864EB6BD20E6A587C99976FA04C9548FB9731BC5B80D483984D8E84D89A3
      8A0D210D58C22C9DA0316D9214B45B46C7353228C67A62F101DD79267C071CEE
      9C1FA2DA976294AD6031C245397BDFB11A3AF012DF154B6D126439F579F85C38
      77AB844586159ECCAD0D468A3D94A5DABA43B26722B4C24FEFDC19FC62355341
      29B1FBABC7D242DDEB59DB00C564546DBD384653CCB55436BCCA4B7C4BA585E3
      50B078A48B8F02C9BA79154DF463E42538DB7616AC04C9C1284F0E2918009CAE
      49EB18708A2BD322A3A613CCCF43B3CA288780546FEBF03B6FC3394816359406
      5642DC4930B4B36D5B5122A90871006975496515650608E632414B5054019BB5
      CB280DF34DA9087AB2FA2ADB94588AB2A8C8D3CA3DAB7248357001D0C175269C
     Vpoly_3 (packed):
      AAF30D9EA1ADEF802799581653A0A0D4D692EB2B644F6C84059388947838138A
      1D24464054A9A3E9385FD3E4A6C0C56D09D80F984705B2E4B4244A4D67C3CD58
      7739688170695AC9AA4C354A349AB04ACBD4753E6B519468EB900A290C3AD255
      A004307B1572C0072946B73639F897D434086C515F6BBA53BB10B6A3D4B4AC86
      58E4A4C3EE452C3D7442536756D4F7041775897C2240C4B437CC97CC5E4270FD
      986DEE9842831B1F233B543F724A9E5B0446BB22CF6C8AC278CD4E275482F61B
      A3461582291443967ED0AA78723A2EBE448AC24726D8EA8F5264BC45A4A7D8B4
      C04EFC7A7271AA361B454EE43365644E5DA9A5F8A5A838D4C93EB6970716B98D
      5617F4E4829E93A816432C9B7621ECF2CB5A75BDD4446F58BC57F1A36215467F
      1722A31FFA2432574F028848A92A0FC5C48C4F391FDF2214429454A6015DD9E6
      496A3B1D5F9768C5326AB2997E038CA5E7E34347D5C5C8E7AE00A9CB48FA4A43
      54768F3C586430B8C4E8C3CAE13EE0265910A0B01FA037CAE333B13B63601397
     Rho (bytes):
      44D2E20D0D57AA501ED3DE916106FF5DA95E4BE2AD4335034F2C757352305980
  X25519 (0x001D)
   x = 0xFB6C61B9A2E5323674FD2C49FA02DF5E1335F52EFBF984C9FC2401F01B1F7C5E

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

В данном случае браузер Chrome прислал нам значение X25519 (внизу) и гибридный набор из X25519 и Kyber768 – то есть, X25519Kyber768draft0 (идентификатор 0x6399 – в начале). Важно не запутаться: криптосистема с постквантовой стойкостью тут одна, она называется Kyber768 (“на научном языке” это KEM – Key Encapsulation Mechanism). Однако в TLS эта криптосистема внедряется в гибридном варианте, то есть, на прицепе к классической, хорошо отработанной, криптосистеме X25519, которая есть разновидность реализации протокола Диффи-Хеллмана. Данный гибрид всё ещё считается “черновым вариантом” – draft. Поэтому полное название X25519Kyber768draft0.

Если приглядеться, то в этом же расширении есть ещё один, не столь массивный, блок, названный X25519. Это другое, отдельное открытое значение X25519, которое может быть использовано сервером, если сервер не поддерживает X25519Kyber768draft0. К входящему в гибридный вариант значению X25519 свободный вариант отношения не имеет. Это та же криптосистема X25519, в гибриде она работает абсолютно и точно так же, как и без “гибридизации”, но название отличается, как отличаются и значения ключей (обозначены “x”).

Постквантовая часть ключей указана в блоке “Kyber768 client public key”. Ключ Kyber768 состоит из четырёх обособленных значений: это три полинома (Vpoly_N) и параметр Rho. И только лишь ключ Kyber768 занимает уже 1216 байтов. X25519 добавляет лишь 32 байта (в составе гибрида).

Другие элементы расширения key_share, которые тоже отмечены GREASE, это, опять, фиктивные значения, как и в следующем расширении – supported_groups.

 Type: 10 (0x000A); "supported_groups"
  0xAAAA (_undef_ (GREASE))
  0x6399 (X25519Kyber768Draft00)
  0x001D (X25519)
  0x0017 (Secp256r1)
  0x0018 (Secp384r1)

В этом расширении – поддерживаемые клиентом схемы криптосистем. Расширение называется “Поддерживаемые группы” (supported_groups). “Группы” здесь – это технический термин, обозначающий математическую структуру (группу), которая применяется в той или иной криптосистеме (кстати, можно сказать, что “схема”, с математической точки зрения, даже более технический термин, который вполне можно так применить, но, конечно, это лишь случайное совпадение).

Данное расширение всего лишь перечисляет идентификаторы параметров, которые клиент готов использовать. Часть ключей – уже передана в составе key_share. Поэтому тут и присутствуют X25519Kyber768Draft00 и X25519. Однако сервер может не поддерживать ни X25519Kyber768Draft00, ни X25519. В таком случае предстоит выбрать что-то из оставшихся вариантов: Secp256r1 и Secp384r1, под которыми подразумевается протокол Диффи-Хеллмана (DH) на кривых P-256 и P-384. А GREASE – выбрать нельзя. Для перехода к другой криптосистеме сервер, в ответ на CH, отправляет сигнальное сообщение HRR (HelloRetryRequest), указывая в расширениях к нему предпочитаемую криптосистему. Пересогласование криптосистемы для DH поддерживается на тестовом сервере tls13.1d.pw – так что эффект нетрудно увидеть, понажимав Ctrl+F5 (Refresh) в браузере: при пересогласовании клиент пришлёт новое CH, уже с другим составом key_share.

Возникает резонный вопрос: поддержка Kyber768 на серверной стороне не очень-то распространена, нужно ли пересогласование при каждом CH от Chrome с Kyber768? Нет, в типовом случае, серверу не нужно ничего пересогласовывать – сервер может проигнорировать гибридный постквантовый набор и сразу использовать X25519 (поддержка есть практически повсеместно), потому что ключ этой криптосистемы указан в CH от Chrome (не гибридный, а отдельный). Если, конечно, сервер не поддерживает X25519, тогда пересогласовать криптосистему потребуется, но не из-за наличия Kyber768.

Следующее расширение – это фиктивное ECH (Encrypted Client Hello).

 Type: 65037 (0xFE0D); "ECH /DRAFT/"
  Type: 0x00 (Outer)
  HKDF: 0x0001 (HKDF-SHA256)
  AEAD: 0x0001 (AES-128-GCM)
  Config id: 0x04
  Encapsulated key (bytes):
   08FC1E6C6A441874D38689375F9C906827516F2F306BBD8B2376569F99CF0069
  Payload (dummy):
   ECADC2C291D6311FCD925306392EE88CD057D42178C0B60EF5B14814F2CF669E
   05230A0F3D6AABADA0A3EB78D240E22BE2DE5893A50B3AEC4056B77B5CACF7C9
   07F5E6EE853268C23595E22F59E9D190BE9ECCD05B76092CBA00FCCE1C072283
   7CBE371C871817540D8E9429CB10F4CCA3089AB36154D7AE2578FF5D12884F3D
   437AB7A97E0FDA19DCC4B423A4DFD2CF

ECH служит для доступа к скрытым сервисам. Базовое применение: сокрытие имени узла, с которым устанавливается TLS-соединение. Chrome включает фиктивное расширение в CH даже для узлов, которые ECH не объявляли. Это метод придания единообразия TLS-трафику. Расширение ECH устроено довольно сложно, содержит внутри дополнительную структуру и большое по объёму данных поле Payload, которое, в случае фиктивного расширения, имитирует полезные данные ECH (зашифрованное CH). ECH, в данном случае, добавляет ещё 182 байта.

 Type: 00 (0x0000); "server_name"
  00:00:0E:00:00:0B:74:6C:73:31:33:2E:31:64:2E:70:77
  hostname: tls13.1d.pw

Расширение SNI, содержащее имя узла, с которым устанавливается TLS-соединение. Именно данные этого расширения и должно скрывать ECH (в данном случае – ECH не поддерживается). Обычно, это расширение не очень большое по объёму (но зависит от используемого имени).

 Type: 45 (0x002D); "psk_key_exchange_modes"
  01:01
 Type: 17513 (0x4469); /non-TLS-1.3/
  00:03:02:68:32
 Type: 43 (0x002B); "supported_versions"
  0x8A8A (_undef_ (GREASE))
  0x0304 (TLS 1.3)
  0x0303 (TLS 1.2)
 Type: 05 (0x0005); "status_request"
  01:00:00:00:00
 Type: 13 (0x000D); "signature_algorithms"
  00:10:04:03:08:04:04:01:05:03:08:05:05:01:08:06
  06:01
 Type: 11 (0x000B); /non-TLS-1.3/
  01:00
 Type: 27 (0x001B); /non-TLS-1.3/
  02:00:02
 Type: 18 (0x0012); "signed_certificate_timestamp"
 Type: 10794 (0x2A2A); "_undef_ (GREASE)"
  00

Из оставшихся расширений в контексте этой записки интерес представляет только supported_versions (тип 43): в TLS 1.3 именно это расширение содержит настоящий список поддерживаемых клиентом версий TLS. Chrome, помимо очередного GREASE, передаёт здесь идентификаторы версий 1.3 и 1.2. Наличие supported_versions и делает это CH сообщением версии TLS 1.3.

А заканчивается набор расширений всё тем же GREASE.

Итак, на примере конкретного ClientHello хорошо видно, что ключ Kyber768, действительно, занимает основную часть сообщения. Обычный вариант CH, без “постквантовой стойкости”, будет отличаться только отсутствием ключа X25519Kyber768Draft00, всё остальные поля – применяются точно так же.



Комментировать »

Кстати, про ноутбуки ASUS Zenbook 14 и линуксы. В свежем ядре Linux 6.8, помимо прочего, исправили дефект, относившийся к воспроизведению звука через встроенные динамики на некоторых моделях упомянутых ноутбуков. Это была распространённая проблема: через выход наушников звук воспроизводился нормально, а через встроенные динамики – нет. А теперь под линуксами с ядром свежей линейки всё заработало. То есть, и новый выпуск Ubuntu LTS (24.04), и, например, Fedora 40, успешно звучат на Zenbook 14 серии UM3402Y в разных вариантах непосредственно через динамики (я проверил на двух ноутбуках – и в комплектации на процессоре Intel, и на процессоре AMD). Не то чтобы для ноутбука это было как-то особенно важно, но всё же.



Комментировать »

В новостях про DARPA, которое внедрило ИИ на борт истребителя для “полного” им, истребителем, управления, главный посыл в том, что, мол, давайте уже разрешим использовать “недетерминированные” (non-deterministic) “алгоритмы” даже для управления самолётами – это “безопасно” и “проверено” опытом. В самолёте много чего есть загадочного и недетерминированного, начиная с механизма образования подъёмной силы крыла – спросите любого лётчика или авиационного инженера. Но, вообще-то, одно дело, когда речь идёт действительно об алгоритме, выдающем труднопредсказуемый для внешнего наблюдателя результат, но, при этом, сам алгоритм вполне себе может быть записан и задокументирован, а совсем другое дело – когда в “недетерминированность” превращается принципиальная недоступность внутреннего устройства системы ИИ для понимания даже разработчиком.

“Недетерминированный” алгоритм, но в классическом понимании, может выдавать такую последовательность отклонений органов управления летательного аппарата, которая приводит к движению по сложной, псевдослучайной траектории, ведущей, тем не менее, в заранее заданную точку – давно известный подход, применяемый на практике. Кстати, применяется не только для управления полётом, но и в случае радиосигналов, как для защиты от помех, так и для затруднения обнаружения. В качестве другого примера алгоритма можно взять любой современный шифр, рассмотрев ситуацию, когда он используется со случайным ключом.

Понятно, что если траектория и манёвры некоторого робота предсказуемы заранее, то перехватить такого робота сильно проще. Поэтому и требуется некоторая степень недетерминированности. Однако подобные алгоритмы имеют вполне конкретное, – детерминированное, так сказать, – описание. А если описание конкретное, то его можно превратить не только в обозримый исходный код и прикрепить к документации, но даже и попытаться реализовать формальное доказательство корректности: для практических систем это вполне возможно, если, конечно, там не десять миллиардов коэффициентов, как в продвигаемых ИИ-решениях. Так и возникают разумные ограничения на использование некоторых систем, – а именно, “ИИ с LLM и пр.”, – на важных направлениях: не из того, что такие системы умеют выдавать “недетерминированный” результат (это и так возможно, без ИИ), а из того, что тут нельзя “детерминировать” общее описание поведения.

Однако в ближайшем будущем с системами ИИ/LLM всё может сложиться иначе: вместо обозримого кода и понятных параметров – миллиарды коэффициентов, подменяющие осознаваемую “недетерминированность” результата.



Комментировать »

Многие используют PuTTY, а также – ключи на кривой NIST P-521, потому что считают (не без оснований), что здесь бо́льшая разрядность (например, по сравнению с кривой P-256) обеспечивает бо́льшую стойкость. В PuTTY выявлен дефект реализации ECDSA на данной кривой, который приводит к раскрытию секретного ключа по набору подписей, полученных от него – то есть, большее количество разрядов не только не помогло, но и сыграло в сторону ухудшения. Это CVE-2024-31497.

Математический смысл уязвимости следующий. Алгоритм вычисления подписи в ECDSA использует nonce – это секретный, (псевдо)случайный параметр, который обычно обозначают k. Здесь в nonce, из-за ошибки в коде, зафиксировали девять битов в начале (или в конце) записи. (Девять, видимо, потому, что 521-512 == 9.) Речь тут не про секретный ключ, а про дополнительное значение: секретный ключ в обычной ECDSA не меняется от подписи к подписи, что для данной атаки имеет определяющее значение, а вот параметр/nonce, при этом, меняется. Однако, если известно дополнительное распределение для k, как в случае данного дефекта, то часто можно вычислить секретный ключ, задействовав некоторое количество значений подписей. В случае CVE-2024-31497, девять фиксированных последовательных битов позволяют раскрыть секретный ключ за, как пишут, примерно, 60 подписей.



Комментарии (2) »

Утечки по побочным каналам (ПЭМИН) в видеокамерах смартфонов, веб-камерах и в прочих цифровых камерах, вызванные работой интерфейса передачи данных от приёмной матрицы. Не то чтобы это было неожиданностью: канал известен, для компьютерных мониторов аналогичный канал является типовым при оценке защищённости помещений и рабочих мест с ПК. Однако тут исследователи пишут об успешном приёме и декодировании утечки видеосигнала, – иногда, на расстоянии в несколько метров, – с использованием самого рядового оборудования: ноутбука и недорогого SDR-приёмника. Есть сайт EM Eye с подробным описанием и примерами кода, а также исходная публикация.

Методы защиты всё те же: шумогенератор, экранирование, ну и переход на не столь “прозрачные” протоколы передачи данных – тут эффективно внесение псевдослучайного “шума” на уровне кодирования прямо в аппаратный интерфейс.

(via)



Комментировать »

Записка про процесс валидации TLS-сертификатов, сопоставления сертификата с TLS-узлом и аутентификации этого узла; всё – на примере TLS для веба (то есть, “HTTPS в браузерах”).

Валидация – это проверка и подтверждение того, что сертификат действует, соответствует сценарию использования ключа и подписан доверенным Удостоверяющим Центром (УЦ или CA в английском варианте). Аутентификация, в данном случае, состоит в проверке соответствия имён (в сертификате и в параметрах соединения) и получении подтверждения, что аутентифицируемый узел имеет доступ к секретному ключу, соответствующему открытому ключу из сертификата.

В самом первом приближении, процесс может быть описан весьма просто, однако внутри есть большое количество важных деталей. Некоторые из этих деталей рассмотрены в данной записке. В качестве примера здесь используется типичный сценарий работы с веб-сайтом по HTTPS: то есть, современный веб-браузер в качестве клиента, а современный веб-сервер – в качестве, как нетрудно угадать, сервера.

Для описания процесса, прежде всего, важны три типа сертификатов:

1) сертификат доверенного УЦ; обычно, это самоподписанный сертификат (см. ниже), который содержит открытый ключ корневого доверенного УЦ, список таких сертификатов входит либо в дистрибутив браузера, либо в дистрибутив операционной системы;

2) сертификат промежуточного УЦ; это как раз пункт, который традиционно является источником многих хитрых деталей; промежуточный УЦ возникает потому, что непосредственно от корневых ключей “обычные” (оконечные) сертификаты сейчас на практике не выпускают, а выпускают сертификаты промежуточных УЦ – секретные ключи, соответствующие открытым ключам из этих сертификатов, служат для подписи оконечных сертификатов, которые описаны в следующем пункте;

3) оконечный, серверный сертификат – это сертификат, который является, так сказать, целью проверки; он выпущен для сетевого имени, соответствующего параметрам (контексту) соединения, а секретный ключ, соответствующий открытому, должен быть известен серверу (либо должен быть доступ к операциям с этим ключом); именно оконечный сертификат непосредственно используется при установлении соединения для аутентификации сервера клиентом (бывают ещё клиентские оконечные сертификаты, схема валидации там такая же, но работает на стороне сервера; здесь случай клиентского сертификата не рассматриваем).

В ходе валидации выстраивается так называемая “цепочка доверия”. Цепочка выстраивается при помощи проверки подписей на сертификатах, но не только. Эта цепочка – иерархия сертификатов, в которой они соединяются по соответствию имён и открытых ключей. В сертификатах есть поля Issuer/Subject. Issuer – “Издатель”, название того УЦ, который этот сертификат выпустил. Subject – “Субъект”, название, к которому этот сертификат привязывает опубликованный в нём открытый ключ при помощи подписи от ключа Issuer (“Издателя”).

Например, для dxdt.ru цепочка может быть такой (здесь корневой сертификат – слева, ISRG Root X1, а “доверие” распространяется справа налево): ISRG Root X1 — R3 — dxdt.ru. Открытые ключи привязываются в этой цепочке к именам при помощи проверки подписей. Если проверка удалась, то ключ – верный. Ключи и имена обычно используются парой (в принципе, в списке может оказаться несколько одинаковых имён с разными ключами, хоть так быть и не должно, – в таком случае, приоритет будет у значения ключа).

Для корневого УЦ сертификат является просто контейнером ключа, этот сертификат “самоподписанный” – то есть, подпись от того же ключа, открытое представление которого указано в сертификате, совпадающие значения Issuer и Subject. На других сертификатах подпись вычисляется от ключа, соответствующего другому сертификату (на него тоже указывает имя из Issuer).

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

Все сертификаты в цепочке содержат указания на то, как можно использовать ключи, указанные в этих сертификатах. Например, сертификаты УЦ содержат флаг, который обозначает, что (секретный) ключ может использоваться для подписывания других сертификатов и, например, для подписывания списков отзыва (см. ниже). Это всё помимо отдельного флага, обозначающего, что данный сертификат – сертификат УЦ. Использование ключа должно соответствовать схеме проверки – например, валидатор не должен принимать сертификат, подписанный от ключа, (доверенный) сертификат которого не содержит флага УЦ или флагов, разрешающих подписывание.

Оконечный сертификат сопоставляется по имени с именем узла, с которым браузер пытается установить соединение. Это часть процесса аутентификации узла, использующая сертификат существенным образом. Современные спецификации таковы, что тут учитывается не имя узла из поля Subject, как можно подумать. В TLS-сертификатах есть специальное расширение SAN (Subject Alternative Name), где могут быть перечислены дополнительные имена. Именно тут должно быть указано имя сервера. Например, dxdt.ru. Иначе, согласно спецификациям валидации для современного веба, которым следуют браузеры, сертификат будет невалидным для заданного имени (даже если имя указано в Subject).

Сертификаты могут быть отозваны до достижения ими срока окончания действия. Поэтому, в теории, для каждого сертификата в цепочке валидации должен быть проверен его статус (отозван или нет). В практике веба отзыв проверяется далеко не всегда. Есть два базовых способа проверки статуса сертификата – файл со списком серийных номеров отозванных сертификатов (CRL – Certificate Revocation List) и респондер протокола OCSP (Online Certificate Status Protocol); а есть специальные способы, поддерживаемые современными браузерами, например, Chrome/Chromium, и серверами. Специальные способы возникли потому, что всякое обращение к сервисам проверки статусов сертификатов раскрывает некоторую информацию о сессии браузера в сторону УЦ. Вести сервисы статуса непосредственно могут только либо сами УЦ, либо организации, которым УЦ прямо поручили реализацию такой функции, это связано с необходимым доверием, чтобы сертификаты не могли “отзывать” произвольные участники системы. Поэтому, при типовых схемах, УЦ будет узнавать о проверках статуса и видеть имена, к которым были обращения. Но можно предложить способы различного “проксирования” статусов сертификатов: сюда относятся “концентраторы” списков отзывов – пример: OneCRL, – записи “слепков” ответов OCSP – OCSP stapling, – и включение статичных списков отзыва в состав обновлений браузера (это, прежде всего, Chrome, но для важных сертификатов используют и другие браузеры, например, Firefox).

О том, где можно проверить статус сертификата, валидатор может узнаёт из состава сертификата. Адреса узлов, публикующих CRL (списки отзыва), адреса OCSP-респондеров – прямо указаны в специальных расширениях.

С отзывом сертификатов связаны два практических вывода: 1) отзыв сертификатов и корректное “оборачивание” его в необходимые сервисы – одна из больших проблем для всякого УЦ; 2) в современном вебе отзыв сертификатов сайтов, фактически, не работает (но эту неработоспособность уже несколько лет активно пытаются компенсировать внедрением сертификатов с коротким сроком действия).

Если все подписи цепочки сошлись, то, в результате успешной валидации, браузер получает доверенный открытый ключ сервера – этот ключ содержится в оконечном сертификате. Остаётся ещё один важнейший шаг аутентификации узла: нужно проверить, что узел, приславший валидный сертификат, имеет доступ к соответствующему секретному ключу. В современных версиях TLS это реализуется при помощи подписывания сервером сообщения, состав которого определяется клиентом (чтобы нельзя было подготовить заранее подписанное сообщение). Если клиент успешно проверил подпись, полученную от сервера, при помощи ключа из сертификата, то сервер считается аутентифицированным (соответствие имён проверено раньше).

Ссылка по теме: техническое описание TLS (где про сертификаты не так много, поскольку их техническое значение в TLS не очень велико, так как основное их значение – административное).



Комментировать »

Касательно свежей истории с обнаружением закладки/бэкдора (CVE-2024-3094) в пакете xz (liblzma), которая на системах с systemd/glibc, потенциально, протягивалась в sshd: понятно, что такого может быть ещё много в уже массово используемых библиотеках, но всё равно это весьма неплохая и практическая демонстрация того, что подобное удаётся быстро обнаружить силами сообщества. По этой теме я не так давно писал, что, во-первых, добавление закладок и прочего вредоносного кода – это совсем не какая-то особенность Open Source; во-вторых – доступность исходников связана с возможностями по добавлению и обнаружению вредоносного кода, но вовсе не так прямо, как часто говорят и пишут.



Комментировать »

В продолжение предыдущей записки. Различные “аппаратурные” атаки, типа разновидностей Spectre/Meltdown, которые преодолевают механизмы разграничения доступа современных процессоров, имеют интересную связь с концепцией “диагонализации”: то есть, такие атаки всегда возможны, если только процессор пытается оптимизировать использование вычислительных ресурсов достаточно сложным способом. Под “достаточно сложным” тут подразумевается наличие механизмов вида “предикторов” (упреждающего анализа потока команд), задействованных на уровне над “межпотоковым” взаимодействием.

Вообще, в x86 “префетчинг” (предварительное извлечение) кодов команд появился ещё в микропроцессоре 8086. Но тогда соответствующая схема считалась просто конвейером команд. Это был отдельный компонент, со своими регистрами и системой счётчиков, который асинхронно считывал коды команд с внешней шины, когда та была свободна, что существенно ускоряло работу процессора. Понятно, что в 8086 не было ни каких-то особых механизмов аппаратного разграничения потоков команд и адресного пространства, ни обособленных полноценных ядер, исполняющих код, так что и проблем с побочными эффектами от работы схем конвейера тоже быть ещё не могло. Однако состояние этого конвейера, вмещавшего всего несколько кодов (четыре 8-битных регистра), изменяло состояние процессора вне зависимости от исполняемой основным “протоядром” команды, поскольку конвейер содержал пару указателей, несколько флагов и т.д. Впрочем, технические детали устройства исторического микропроцессора тут не важны – важно, что, во-первых, этот простой конвейер работал только на уровне последовательности кодов команд (не со свойствами самих команд); во-вторых, не было потоков и общих элементов, совместно используемых этими потоками.

Отличие “уязвимых” схем современных процессоров в том, что здесь добавляется новый уровень – те самые “предикторы”, оснащённые логикой, которая учитывает уже не порядок кодов команд, а свойства этих команд и состояние процессора, а кроме того, добавляются общие для нескольких потоков элементы (схемы кэширования и пр.) на работу которых прямо влияют предикторы. И, конечно, возникает аппаратное разграничение доступа, которое и предлагается преодолевать при помощи атак, использующих аппаратные уязвимости.

Базовая логика таких атак – использование “оракулов”, сигналы которых пробивают границы, устанавливаемые (формально) аппаратной архитектурой процессора для фрагментов программного кода. Тут нужно учитывать, что границы эти только декларируются, а в реальности – сигналы через них проходят (иначе тут не было бы предмета), потому что процессору необходимо оптимизировать исполнение кода и доступ к памяти. Эти сигналы обязательно будут возникать именно потому, что в процессоре появился уровень, исполняющий “программу над программой”: упреждающий анализ команд работает по собственной программе (пусть и записанной непосредственно в аппаратуре); эта программа не только использует все потоки и фрагменты кода в качестве входных данных, но и влияет на состояние общих для изолируемых фрагментов кода элементов (кэш и очереди команд). То есть, схема аппаратной оптимизации тут всегда будет сквозной, можно сказать, что неустранимой. Вопрос в том, нужно ли считать такую архитектурную черту уязвимостью. Получается, что общая программа смотрит на команды в разных потоках и переключает состояние общих элементов, чтобы оптимизировать процесс. Изолируемые процессы находят способ измерения времени переключения состояний и – строится очередная уязвимость.

Если попробовать бороться с возникающими по описанным только что принципам сигналами, но попытаться сохранять общие элементы процессора, то каждый новый слой просто будет приводить к появлению более хитрых способов измерения: многими “атакующими” потоками, по накопленной статистике, ещё как-то. Если в архитектуру процессора, предположим, введут некоторое зашумление переключений кеша и предикторов, то носителем сигнала окажется схема, реализующая зашумление. Всякое подобное усложнение, добавление новых уровней, приводит к тому, что появляются и носители новых сигналов (это и есть “диагонализация”). При этом защита от “уязвимостей” программными методами, снижающими общее быстродействие, выглядит несколько странно, потому что предлагается прилагать дополнительные усилия для создания затруднений в работе оптимизирующих схем, которые и в процессоре уже встроены (то есть, потрачена площадь подложки и элементарные логические узлы), и само ПО при этом всё равно работает на общей аппаратуре.

Радикальное решение предполагает либо полную и точную аппаратную изоляцию уровней и ядер, когда все компоненты продублированы и работают независимо, либо полную замену системы команд (не стоит списывать со счетов, что в x86 уже и некоторые отдельные команды обладают тьюринг-полной реализацией). Однако это противоречит самой идее аппаратурной оптимизации на границе между логическим представлением команд процессора и машинным микрокодом. Да и приведёт внедрение таких методов только к тому, что очередной “пробой изоляции” между потоками выявят на стороне шин и контроллеров, взаимодействующих с ОЗУ и периферийными устройствами.



Комментировать »