<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Заметки Lizard'а</title><subtitle>Криптография, RFID, Sub-GHz и прочее...

TG - https://t.me/li0ard_notes</subtitle><author><name>Заметки Lizard'а</name></author><id>https://teletype.in/atom/li0ard</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/li0ard?offset=0"></link><link rel="alternate" type="text/html" href="https://blog.li0ard.rest/?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=li0ard"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/li0ard?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-23T08:38:41.410Z</updated><entry><id>li0ard:blazorpack</id><link rel="alternate" type="text/html" href="https://blog.li0ard.rest/blazorpack?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=li0ard"></link><title>Получаем HTML из Blazorpack</title><published>2025-10-25T09:46:31.526Z</published><updated>2025-11-08T18:40:39.533Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/46/26/46267e9f-f5bf-408d-ace8-9f195a9ff832.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/c0/8f/c08f94dc-2250-453f-bd1e-03dbff72cbe7.png&quot;&gt;Одним вечером у меня появилась необходимость написать парсер HTML одного сайта, но при просмотре содержимого страницы вместо нужных мне данных я увидел данный комментарий:</summary><content type="html">
  &lt;nav&gt;
    &lt;ul&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#bljn&quot;&gt;Как это работает?&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#UIKA&quot;&gt;Установка соединения&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#1qWH&quot;&gt;Обмен данными (BlazorPack)&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#Vo1f&quot;&gt;Получаем HTML&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#lWZX&quot;&gt;Формат DOM&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#hMRf&quot;&gt;Таблица строк&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#txRS&quot;&gt;Процесс восстановления HTML&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/nav&gt;
  &lt;p id=&quot;kjrt&quot;&gt;Одним вечером у меня появилась необходимость написать парсер HTML одного сайта, но при просмотре содержимого страницы вместо нужных мне данных я увидел данный комментарий:&lt;/p&gt;
  &lt;figure id=&quot;snJc&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c0/8f/c08f94dc-2250-453f-bd1e-03dbff72cbe7.png&quot; width=&quot;632&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;HY4h&quot;&gt;Я подумал: &amp;quot;Ага, значит данные подгружаются динамически, следовательно должен быть запрос на сервер&amp;quot;, однако открыв DevTools я увидел WebSocket, который судя по всему получал HTML от сервера&lt;/p&gt;
  &lt;figure id=&quot;VEMg&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ac/c0/acc00ff7-88a0-4ee3-a064-006989514529.png&quot; width=&quot;532&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;bljn&quot;&gt;Как это работает?&lt;/h2&gt;
  &lt;figure id=&quot;QgFt&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/27/f9/27f9e8af-d348-4cc4-82ea-0f5c29af3c16.png&quot; width=&quot;1838&quot; /&gt;
    &lt;figcaption&gt;Полная схема установки соединения и согласования протоколов&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;vCDi&quot;&gt;Делать полный разбор протокола я не буду, поэтому кратко пройдёмся по основным этапам:&lt;/p&gt;
  &lt;h3 id=&quot;UIKA&quot;&gt;Установка соединения&lt;/h3&gt;
  &lt;p id=&quot;yoFt&quot;&gt;После того как браузер загрузил страницу происходит POST запрос на &lt;code&gt;/_blazor/negotiate&lt;/code&gt;, который возвращает:&lt;/p&gt;
  &lt;ul id=&quot;Wza4&quot;&gt;
    &lt;li id=&quot;x26V&quot;&gt;список поддерживаемых транспортных протоколов (WebSockets, Server-Sent Events, Long Polling);&lt;/li&gt;
    &lt;li id=&quot;6Qig&quot;&gt;ID соединения (&lt;code&gt;connectionId&lt;/code&gt;);&lt;/li&gt;
    &lt;li id=&quot;Gapb&quot;&gt;Токен доступа (&lt;code&gt;connectionToken&lt;/code&gt;).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;HOTV&quot;&gt;Браузер перебирает список протоколов, и пытается установить соединение.&lt;br /&gt;Если первый вариант не удался, то пробуется следующий и так далее.&lt;/p&gt;
  &lt;h3 id=&quot;1qWH&quot;&gt;Обмен данными (BlazorPack)&lt;/h3&gt;
  &lt;p id=&quot;WCCk&quot;&gt;В качестве протокола обмена сообщениями между сервером и браузером используется протокол &lt;strong&gt;SignalR&lt;/strong&gt;, который в свою очередь использует &lt;strong&gt;MessagePack&lt;/strong&gt; (бинарный формат сериализации)&lt;/p&gt;
  &lt;p id=&quot;bOye&quot;&gt;Также поверх этого используется ещё 1 слой - &lt;strong&gt;Binary Message Format (BMF)&lt;/strong&gt;.&lt;br /&gt;К данным добавляются префикс длины, что позволяет передать несколько сообщений за один раз.&lt;/p&gt;
  &lt;p id=&quot;XsTV&quot;&gt;Получается такая &amp;quot;матрёшка&amp;quot; из кодировок:&lt;/p&gt;
  &lt;p id=&quot;Lpl4&quot; data-align=&quot;center&quot;&gt;&lt;code&gt;BMF -&amp;gt; SignalR -&amp;gt; MessagePack&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;iFxl&quot;&gt;Каждый слой решает свою задачу:&lt;/p&gt;
  &lt;ul id=&quot;BSBV&quot;&gt;
    &lt;li id=&quot;QWAF&quot;&gt;&lt;strong&gt;MessagePack&lt;/strong&gt; - компактное представление данных;&lt;/li&gt;
    &lt;li id=&quot;3nuw&quot;&gt;&lt;strong&gt;SignalR&lt;/strong&gt; - вызов методов и маршрутизация сообщений (Ядро BlazorPack);&lt;/li&gt;
    &lt;li id=&quot;QolB&quot;&gt;&lt;strong&gt;Binary Message Format (BMF)&lt;/strong&gt; - framing сообщений (Передача нескольких сообщений за раз)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;62wq&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f7/d4/f7d474fd-f177-4797-b509-3a4e03cde1d3.png&quot; width=&quot;807&quot; /&gt;
    &lt;figcaption&gt;Пример сообщения&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;Vo1f&quot;&gt;Получаем HTML&lt;/h2&gt;
  &lt;p id=&quot;ub9u&quot;&gt;Данный этап можно назвать самым сложным, так как Blazor &lt;u&gt;не отдаёт HTML в &amp;quot;голом&amp;quot; виде&lt;/u&gt; , вместо этого &lt;u&gt;он отдаёт представление DOM в бинарном пакете&lt;/u&gt; (&lt;code&gt;RenderBatch&lt;/code&gt;) разделённым на секции:&lt;/p&gt;
  &lt;ul id=&quot;5I1K&quot;&gt;
    &lt;li id=&quot;kbt3&quot;&gt;&lt;code&gt;UpdatedComponents&lt;/code&gt; (&lt;code&gt;ArrayRange&amp;lt;Diff&amp;gt;&lt;/code&gt;);&lt;/li&gt;
    &lt;li id=&quot;OqOJ&quot;&gt;&lt;code&gt;ReferenceFrames&lt;/code&gt; (&lt;code&gt;ArrayRange&amp;lt;Frame&amp;gt;&lt;/code&gt;);&lt;/li&gt;
    &lt;li id=&quot;vbap&quot;&gt;&lt;code&gt;DisposedComponentIds&lt;/code&gt; (&lt;code&gt;ArrayRange&amp;lt;int&amp;gt;&lt;/code&gt;);&lt;/li&gt;
    &lt;li id=&quot;Bqcy&quot;&gt;&lt;code&gt;DisposedEventHandlerIds&lt;/code&gt; (&lt;code&gt;ArrayRange&amp;lt;long&amp;gt;&lt;/code&gt;);&lt;/li&gt;
    &lt;li id=&quot;Ysgc&quot;&gt;&lt;code&gt;StringTable&lt;/code&gt; (&lt;code&gt;ArrayRange&amp;lt;string offsets&amp;gt;&lt;/code&gt;).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;i66J&quot;&gt;В конце пакета находятся 5 чисел (&lt;code&gt;int32&lt;/code&gt;) — это смещения каждой секции в байтах (от начала массива).&lt;/p&gt;
  &lt;h3 id=&quot;lWZX&quot;&gt;Формат DOM&lt;/h3&gt;
  &lt;p id=&quot;YbF7&quot;&gt;Сами узлы DOM хранятся в структуре под названием &lt;code&gt;RenderTreeFrame&lt;/code&gt;, одна структура может описывать:&lt;/p&gt;
  &lt;ul id=&quot;fvVX&quot;&gt;
    &lt;li id=&quot;Xzar&quot;&gt;HTML-тег;&lt;/li&gt;
    &lt;li id=&quot;vwKA&quot;&gt;текстовое значение;&lt;/li&gt;
    &lt;li id=&quot;wtOv&quot;&gt;атрибут;&lt;/li&gt;
    &lt;li id=&quot;02CK&quot;&gt;компонент Blazor;&lt;/li&gt;
    &lt;li id=&quot;rjgc&quot;&gt;&amp;quot;голый&amp;quot; HTML-фрагмент.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;lXmG&quot;&gt;Сам &lt;code&gt;RenderTreeFrame&lt;/code&gt; выглядит так:&lt;/p&gt;
  &lt;pre id=&quot;ZmRh&quot;&gt;[Тип фрейма][Параметр 1][Параметр 2][Параметр 3][Параметр 4]&lt;/pre&gt;
  &lt;p id=&quot;Y8AP&quot;&gt;Тип фрейма определяет, что это за узел:&lt;/p&gt;
  &lt;ul id=&quot;XuGh&quot;&gt;
    &lt;li id=&quot;AwWs&quot;&gt;1 - HTML-тег (&lt;code&gt;Element&lt;/code&gt;);&lt;/li&gt;
    &lt;li id=&quot;eCKh&quot;&gt;2 - текст (&lt;code&gt;Text&lt;/code&gt;);&lt;/li&gt;
    &lt;li id=&quot;7s2a&quot;&gt;3 - атрибут (&lt;code&gt;Attribute&lt;/code&gt;);&lt;/li&gt;
    &lt;li id=&quot;VqoK&quot;&gt;4 - Компонент Blazor (&lt;code&gt;Component&lt;/code&gt;);&lt;/li&gt;
    &lt;li id=&quot;Rc5z&quot;&gt;5 - Регион (Служебные данные) (&lt;code&gt;Region&lt;/code&gt;);&lt;/li&gt;
    &lt;li id=&quot;psSN&quot;&gt;8 - &amp;quot;Голый&amp;quot; HTML (&lt;code&gt;Markup&lt;/code&gt;).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;hMRf&quot;&gt;Таблица строк&lt;/h3&gt;
  &lt;p id=&quot;iyB3&quot;&gt;Чтобы не дублировать текст, все строки (имена тегов, атрибуты, значения, текст)&lt;br /&gt;хранятся в конце пакета в таблице строк.&lt;/p&gt;
  &lt;p id=&quot;tqT0&quot;&gt;Каждая запись содержит смещение на строку, а сами строки записаны как:&lt;/p&gt;
  &lt;pre id=&quot;C2yU&quot;&gt;[LEB128-длина][UTF-8 байты строки]&lt;/pre&gt;
  &lt;h3 id=&quot;txRS&quot;&gt;Процесс восстановления HTML&lt;/h3&gt;
  &lt;ol id=&quot;13xH&quot;&gt;
    &lt;li id=&quot;DcYH&quot;&gt;Берём &lt;code&gt;RenderBatch&lt;/code&gt; полученный от SignalR&lt;/li&gt;
    &lt;li id=&quot;tjGq&quot;&gt;Читаем 5 чисел в конце файла - получаем смещение секций&lt;/li&gt;
    &lt;li id=&quot;MufW&quot;&gt;Переходим в секцию &lt;code&gt;ReferenceFrames&lt;/code&gt; - получаем все узлы дерева (&lt;code&gt;RenderTreeFrame&lt;/code&gt;)&lt;/li&gt;
    &lt;li id=&quot;hY2k&quot;&gt;Последовательно читаем фреймы:&lt;br /&gt;- если &lt;code&gt;Element&lt;/code&gt; - создаём элемент;&lt;br /&gt;- если &lt;code&gt;Attribute&lt;/code&gt; - добавляем к предыдущему тегу;&lt;br /&gt;- если &lt;code&gt;Text&lt;/code&gt; - вставляем текстовое содержимое в предыдущий тег;&lt;br /&gt;- если &lt;code&gt;Markup&lt;/code&gt; - вставляем HTML как есть;&lt;br /&gt;- если &lt;code&gt;Region&lt;/code&gt; - рекурсивно обрабатываем последующие фреймы;&lt;/li&gt;
    &lt;li id=&quot;UQD3&quot;&gt;Используем свойство subtreeLength, чтобы понять, где заканчивается элемент;&lt;/li&gt;
    &lt;li id=&quot;HI3g&quot;&gt;Склеиваем всё в строку и получаем HTML.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;i6lS&quot;&gt;&lt;strong&gt;P.S Реализация TS библиотеки доступна &lt;a href=&quot;https://github.com/li0ard/renderbatch&quot; target=&quot;_blank&quot;&gt;здесь&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

</content></entry><entry><id>li0ard:rutoken_export_p2</id><link rel="alternate" type="text/html" href="https://blog.li0ard.rest/rutoken_export_p2?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=li0ard"></link><title>Тащим ключи с Рутокен Lite ч.2</title><published>2025-08-09T16:59:07.277Z</published><updated>2025-08-13T11:15:09.660Z</updated><category term="kriptografiya" label="Криптография"></category><summary type="html">&lt;img src=&quot;https://img2.teletype.in/files/1b/40/1b40aa91-6c20-4034-a705-f1fcf4d68cf9.png&quot;&gt;В предыдущей статье, я описал способ экспорта ключей с Рутокен Lite вручную, в этой же статье будет инструкция по экспорту автоматизированным способом.</summary><content type="html">
  &lt;p id=&quot;AkKu&quot;&gt;В &lt;a href=&quot;https://teletype.in/@li0ard/rutoken_export&quot; target=&quot;_blank&quot;&gt;предыдущей статье&lt;/a&gt;, я описал способ экспорта ключей из Рутокен Lite вручную, в этой же статье будет инструкция по экспорту автоматизированным способом.&lt;/p&gt;
  &lt;p id=&quot;O7zM&quot;&gt;Нам понадобится:&lt;/p&gt;
  &lt;ol id=&quot;NQkI&quot;&gt;
    &lt;li id=&quot;F1Ed&quot;&gt;&lt;a href=&quot;https://github.com/li0ard/rutoken_export&quot; target=&quot;_blank&quot;&gt;Моя утилита&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;4VqY&quot;&gt;Сам Рутокен Lite и PIN-код пользователя&lt;/li&gt;
  &lt;/ol&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;1btQ&quot;&gt;&lt;strong&gt;Важно&lt;/strong&gt;: Данная статья предполагает, что у вас уже установлен компилятор Go&lt;/p&gt;
  &lt;/section&gt;
  &lt;ol id=&quot;OTJu&quot;&gt;
    &lt;li id=&quot;CuSn&quot;&gt;Клонируем репозиторий и переходим в папку с кодом&lt;/li&gt;
    &lt;li id=&quot;zsTS&quot;&gt;Собираем утилиту с помощью &lt;code&gt;go build&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;qjyh&quot;&gt;Запускаем утилиту, вводим PIN-код пользователя, и вводим метку (см. ниже) нужного контейнера&lt;/li&gt;
  &lt;/ol&gt;
  &lt;figure id=&quot;qa7l&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/1b/40/1b40aa91-6c20-4034-a705-f1fcf4d68cf9.png&quot; width=&quot;593&quot; /&gt;
    &lt;figcaption&gt;Пример работы&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;QFf5&quot;&gt;В указанной утилитой папке будет лежать экспортированный контейнер&lt;/p&gt;
  &lt;figure id=&quot;mWmC&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/0c/b2/0cb28bae-f772-41ef-98a3-d60c71834c66.png&quot; width=&quot;618&quot; /&gt;
  &lt;/figure&gt;

</content></entry><entry><id>li0ard:rutoken_export</id><link rel="alternate" type="text/html" href="https://blog.li0ard.rest/rutoken_export?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=li0ard"></link><title>Тащим ключи с Рутокен Lite</title><published>2025-08-03T17:23:14.015Z</published><updated>2025-08-05T16:41:39.875Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/98/bc/98bc0167-357c-4188-b336-7b6de337e139.png"></media:thumbnail><category term="kriptografiya" label="Криптография"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/b8/8b/b88b54ca-631e-4511-887e-f583e59a7d39.png&quot;&gt;Думаю многим знакома ситуация, когда ФНС (или любой другой УЦ) записывает контейнер с ЭЦП на Рутокен, а в процессе использования возникает необходимость использования ЭЦП без самого Рутокена (например из файловой системы) и т.д.</summary><content type="html">
  &lt;figure id=&quot;AaR9&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b8/8b/b88b54ca-631e-4511-887e-f583e59a7d39.png&quot; width=&quot;1280&quot; /&gt;
    &lt;figcaption&gt;Суть такова&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;tEny&quot;&gt;Думаю многим знакома ситуация, когда ФНС (или любой другой УЦ) записывает контейнер с ЭЦП на Рутокен, а в процессе использования возникает необходимость использования ЭЦП без самого Рутокена (например из файловой системы) и т.д.&lt;/p&gt;
  &lt;p id=&quot;yaXO&quot;&gt;Однако та же ФНС &lt;strong&gt;&amp;quot;отключает&amp;quot; флаг экспортируемости&lt;/strong&gt; контейнера и при попытке экспорта ключа мы получаем ошибку, а в Центре управления Рутокен&amp;#x27;ом есть возможность только экспортировать сертификат.&lt;/p&gt;
  &lt;figure id=&quot;gDcM&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/79/7c/797c65f7-1f7f-4990-acbd-19014118a520.png&quot; width=&quot;1019&quot; /&gt;
    &lt;figcaption&gt;Скриншот из Центре управления Рутокен&amp;#x27;ом&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;6SJl&quot;&gt;Также следует упомянуть, что существует популярная утилита Tokens.exe от СКБ Контур, однако у неё есть ряд недостатков:&lt;/p&gt;
  &lt;ol id=&quot;OCrr&quot;&gt;
    &lt;li id=&quot;jLy2&quot;&gt;Утилита работает только на Windows&lt;/li&gt;
    &lt;li id=&quot;b6BM&quot;&gt;Написана на HTML с использованием устаревшего ActiveXObject с связке с DLL&lt;/li&gt;
    &lt;li id=&quot;N26s&quot;&gt;Утилиту благополучно &amp;quot;выпилили&amp;quot; с сайта, поэтому приходится искать по всему интернету&lt;/li&gt;
  &lt;/ol&gt;
  &lt;h2 id=&quot;IlRW&quot;&gt;Тащим ключи&lt;/h2&gt;
  &lt;h3 id=&quot;Byue&quot;&gt;1. Ищем контейнер&lt;/h3&gt;
  &lt;p id=&quot;fFlw&quot;&gt;Рутокен Lite - не совсем флешка в привычном понимании, у него максимально облегченная файловая система, поэтому просто открыть его в проводнике не получится&lt;/p&gt;
  &lt;p id=&quot;cWsB&quot;&gt;Однако для этих целей можно воспользоваться утилитами от проекта &lt;a href=&quot;https://github.com/OpenSC/OpenSC&quot; target=&quot;_blank&quot;&gt;OpenSC&lt;/a&gt;&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;lOiM&quot;&gt;&lt;strong&gt;Важно&lt;/strong&gt;: Данная статья предполагает, что у вас уже установлены &lt;code&gt;opensc-tool&lt;/code&gt; и &lt;code&gt;opensc-explorer&lt;/code&gt;&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;Z50H&quot;&gt;Поэтому подключаем Рутокен, открываем консоль и вводим &lt;code&gt;opensc-tool --list-files&lt;/code&gt;&lt;/p&gt;
  &lt;figure id=&quot;2JAE&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/49/41/49411806-5802-4a2c-b4c5-fa5e01e54a8d.png&quot; width=&quot;815&quot; /&gt;
    &lt;figcaption&gt;Файловая система Рутокена&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;tMMJ&quot;&gt;Среди всего списка необходимо найти директорию с 6 файлами, часть из которых доступна для чтения только после авторизации (&lt;code&gt;read[CHV2]&lt;/code&gt;). Сделать это легче всего по имени контейнера в КриптоПро, поскольку &lt;code&gt;opensc-tool&lt;/code&gt; декодирует ASCII текст:&lt;/p&gt;
  &lt;figure id=&quot;aGlN&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/21/1d/211de796-f6e7-4ba2-8ae7-ffb7b5ad25c3.png&quot; width=&quot;1366&quot; /&gt;
    &lt;figcaption&gt;Совпадение имени контейнера с содержимым файла на Рутокене&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;zCiG&quot;&gt;Файл на скриншоте это &lt;code&gt;name.key&lt;/code&gt;, а директория с контейнером (выделена жёлтым) в нашем случае будет &lt;code&gt;3f00100010030a00&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;9R9N&quot;&gt;&lt;strong&gt;UPD от 05.08&lt;/strong&gt;: Вероятнее всего все контейнеры действительно лежат по пути &lt;code&gt;1000/1003&lt;/code&gt;. Соответственно при помощи команды asn1 искать по имени контейнера:&lt;/p&gt;
  &lt;figure id=&quot;aHQk&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d2/ee/d2ee69b4-f56d-4cbb-9d23-fe171bf9f709.png&quot; width=&quot;809&quot; /&gt;
    &lt;figcaption&gt;name.key и header.key второго контейнера на Рутокене&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;3San&quot;&gt;2. Выгрузка&lt;/h3&gt;
  &lt;p id=&quot;3k7m&quot;&gt;Запускаем &lt;code&gt;opensc-explorer&lt;/code&gt; и переходим в директорию контейнера с помощью команды &lt;code&gt;cd &amp;lt;путь&amp;gt;&lt;/code&gt;&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;Yzxm&quot;&gt;&lt;strong&gt;Важно&lt;/strong&gt;: Необходимо разделить путь директории на группы по 4 символа и убрать &lt;code&gt;3f00&lt;/code&gt;, в нашем случае это будет &lt;code&gt;1000&lt;/code&gt;, &lt;code&gt;1003&lt;/code&gt;, &lt;code&gt;0a00&lt;/code&gt;&lt;/p&gt;
  &lt;/section&gt;
  &lt;figure id=&quot;dGCj&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7e/bd/7ebd7d39-532a-4133-af66-95cf2bc5ac2f.png&quot; width=&quot;457&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;hV8A&quot;&gt;В директории файлы лежат в следующем порядке: &lt;code&gt;name.key&lt;/code&gt;, &lt;code&gt;header.key&lt;/code&gt;, &lt;code&gt;primary.key&lt;/code&gt;, &lt;code&gt;masks.key&lt;/code&gt;, &lt;code&gt;primary2.key&lt;/code&gt;, &lt;code&gt;masks2.key&lt;/code&gt;&lt;/p&gt;
  &lt;figure id=&quot;wQ2G&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/a3/72/a3728a84-797b-4b8a-af1d-808bbd4f3bcf.png&quot; width=&quot;357&quot; /&gt;
    &lt;figcaption&gt;Файлы контейнера&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;PMVf&quot;&gt;Теперь самый важный пункт - необходимо авторизоваться по PIN-коду пользователя (в противном случае Рутокен даст выгрузить только &lt;code&gt;name.key&lt;/code&gt; и &lt;code&gt;header.key&lt;/code&gt;). Сделать это можно с помощью команды &lt;code&gt;verify CHV2 &amp;quot;PIN-код&amp;quot;&lt;/code&gt;&lt;/p&gt;
  &lt;figure id=&quot;Inqq&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/24/6c/246c2b0d-8fc6-4df7-8a1c-cece3675eab1.png&quot; width=&quot;438&quot; /&gt;
    &lt;figcaption&gt;Успешная авторизация&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;dIOi&quot;&gt;Теперь же просто копируем файлы контейнера в память компьютера с помощью команды &lt;code&gt;get File_ID путь_назначения&lt;/code&gt;&lt;/p&gt;
  &lt;figure id=&quot;8fHq&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c6/df/c6dfa3e9-8ad7-4ae5-8ef0-b4e351dac4a8.png&quot; width=&quot;609&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;JpuC&quot;&gt;На этом всё, мы успешно скопировали контейнер с Рутокен Lite в память нашего компьютера. Далее желательно &amp;quot;пролечить&amp;quot; контейнер, чтобы &amp;quot;включить&amp;quot; флаг экспортируемости, но на текущий момент решение ещё в разработке (оповещение о релизе будет в Telegram канале). &lt;em&gt;To be continued...&lt;/em&gt;&lt;/p&gt;
  &lt;h2 id=&quot;Hybq&quot;&gt;Бонус. Экспорт приватного ключа&lt;/h2&gt;
  &lt;p id=&quot;l7us&quot;&gt;Для удобства использования ключа подписи, его можно экспортировать в формат &lt;code&gt;.pem&lt;/code&gt; (с которым умеет работать OpenSSL и прочие утилиты) с помощью моей онлайн-утилиты&lt;br /&gt;В утилиту загружаем файлы &lt;code&gt;header.key&lt;/code&gt;, &lt;code&gt;masks.key&lt;/code&gt; и &lt;code&gt;primary.key&lt;/code&gt;, поле &amp;quot;Пароль&amp;quot; оставляем пустым (поскольку контейнеры на Рутокенах не имеют пароля т.к происходит авторизация по PIN-коду) и нажимаем &amp;quot;Извлечь&amp;quot;, через несколько секунд скачается &lt;code&gt;.pem&lt;/code&gt; файл с приватным ключом.&lt;/p&gt;
  &lt;figure id=&quot;qvCN&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/0c/7c/0c7ce9c1-2f98-4f27-b65c-7bd45e5d62a2.png&quot; width=&quot;1344&quot; /&gt;
  &lt;/figure&gt;

</content></entry><entry><id>li0ard:wtfiskeeloq</id><link rel="alternate" type="text/html" href="https://blog.li0ard.rest/wtfiskeeloq?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=li0ard"></link><title>KeeLoq и с чем его едят</title><published>2025-05-27T20:27:42.908Z</published><updated>2025-07-08T06:50:33.706Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/d2/31/d231606d-6bef-4de9-9ebc-c2d8b9f57b54.png"></media:thumbnail><category term="kriptografiya" label="Криптография"></category><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/e4/f3/e4f33756-7577-44fd-9681-ecc6ab3684e8.png&quot;&gt;KeeLoq - блочный шифр, основанный на NLFSR...</summary><content type="html">
  &lt;nav&gt;
    &lt;ul&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#XZoD&quot;&gt;Принцип работы&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#iRjJ&quot;&gt;Режимы безопасности&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#kATQ&quot;&gt;Теоретические атаки&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#LK6k&quot;&gt;Слайд-атака&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#xUzg&quot;&gt;Корреляционный подход&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#UXF8&quot;&gt;Линейный шаг&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#MlSn&quot;&gt;Практические атаки&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#QeWA&quot;&gt;Replay-атака&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#hrtX&quot;&gt;Клонирование пульта&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#EVpD&quot;&gt;Future-атака&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#tacj&quot;&gt;Rollback-атака&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#jCpe&quot;&gt;Rolljam-атака&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#ckqu&quot;&gt;Атака на мануфактурные ключи (KGB attack)&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#tLCW&quot;&gt;Enc00-атака&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#wSBY&quot;&gt;Unknown-атака&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#5cd7&quot;&gt;Заключение&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#34Ux&quot;&gt;Использованные материалы&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/nav&gt;
  &lt;p id=&quot;kioG&quot;&gt;Итак, начнём с выдержки из Википедии:&lt;/p&gt;
  &lt;blockquote id=&quot;zIMz&quot;&gt;&lt;strong&gt;KeeLoq&lt;/strong&gt; - блочный шифр, основанный на NLFSR (регистр сдвига с нелинейной обратной связью), разработан компанией Nanoteq Pty Ltd. и продан компании Microchip Technology Inc. Шифрование происходит блоками по 32 бита с помощью 64 битного ключа за 528 итераций. Ранее использовался в автомобильных сигнализациях, а ныне используется в автоматических воротах, гаражных дверях и т.п&lt;/blockquote&gt;
  &lt;figure id=&quot;j3FI&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/e4/f3/e4f33756-7577-44fd-9681-ecc6ab3684e8.png&quot; width=&quot;675&quot; /&gt;
    &lt;figcaption&gt;Картинка для привлечения внимания &lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;XZoD&quot;&gt;Принцип работы&lt;/h2&gt;
  &lt;p id=&quot;96Cs&quot;&gt;KeeLoq реализует так называемый &lt;em&gt;code hopping&lt;/em&gt; (переключение кода), то есть генерирует уникальный пакет данных для каждой передачи.&lt;/p&gt;
  &lt;figure id=&quot;ZBv5&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/8e/87/8e8716b1-06de-449b-aca1-f2847a954798.png&quot; width=&quot;1050&quot; /&gt;
    &lt;figcaption&gt;Структура пакета данных&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Pfu4&quot;&gt;Разберём на примере:&lt;/p&gt;
  &lt;p id=&quot;T1Gp&quot; data-align=&quot;center&quot;&gt;&lt;code&gt;&lt;strong&gt;239B3DEB&lt;/strong&gt;F16C47A6&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;Gmjp&quot;&gt;Первые 4 байта - это фиксированная часть (т.н &lt;code&gt;fix&lt;/code&gt;), содержит в себе ID нажатой кнопки на пульте (в нашем случае &lt;code&gt;2&lt;/code&gt;) и 28&amp;#x27;ми битный серийный номер пульта (&lt;code&gt;&lt;strong&gt;39B3DEB&lt;/strong&gt;&lt;/code&gt;)&lt;/p&gt;
  &lt;p id=&quot;3RFP&quot;&gt;Следующие 4 байта - динамическая часть (т.н &lt;code&gt;hop&lt;/code&gt;), зашифрована мануфактурным ключом (ключом производителя). В расшифрованном виде выглядит так:&lt;/p&gt;
  &lt;p id=&quot;CuTc&quot; data-align=&quot;center&quot;&gt;&lt;code&gt;21EB000A&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;xhAC&quot;&gt;Здесь мы видим всё тот же ID нажатой кнопки (&lt;code&gt;2&lt;/code&gt;), 12 бит дополнительной информации (зачастую это &lt;code&gt;serial &amp;amp; 0x3FF&lt;/code&gt;) и сам 16 битный счётчик нажатий (&lt;code&gt;000A&lt;/code&gt;)&lt;/p&gt;
  &lt;p id=&quot;Sa0P&quot;&gt;Логика работы счётчика такая:&lt;/p&gt;
  &lt;ul id=&quot;O522&quot;&gt;
    &lt;li id=&quot;nH51&quot;&gt;Если переданное значение счётчика соответствует значению в EEPROM приёмника то приёмник подаёт сигнал контроллеру, что всё хорошо (и контроллер например открывает ворота)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;lA81&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/07/44/07446e47-580e-4043-a0c0-37b32b7283f7.png&quot; width=&quot;796&quot; /&gt;
    &lt;figcaption&gt;Штатная работа приёмника&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;ul id=&quot;kL84&quot;&gt;
    &lt;li id=&quot;iVC0&quot;&gt;Если переданное значение больше значения в EEPROM то приёмник синхронизируется с переданным значением и соответственно после следующей передачи значения начнёт работать штатно&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;fd8Y&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/59/66/5966eef6-7b9d-4930-ab26-e9e21b95497c.png&quot; width=&quot;784&quot; /&gt;
    &lt;figcaption&gt;Процесс сихронизации приёмника&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;ul id=&quot;Q5S6&quot;&gt;
    &lt;li id=&quot;sY2m&quot;&gt;Если переданное значение меньше значения в EEPROM то приёмник игнорирует переданную команду, а в некоторых случаях после нескольких отправок &amp;quot;устаревшего&amp;quot; значения и вовсе отвязывает пульт. (Собственно говоря это и есть опасность при экспериментах с KeeLoq)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;vsj9&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/6b/9c/6b9c0e69-07be-4a82-a569-4ecb7ecb1dcc.png&quot; width=&quot;860&quot; /&gt;
    &lt;figcaption&gt;Реакция на устаревшее значение счётчика и отвязка пульта&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;iRjJ&quot;&gt;Режимы безопасности&lt;/h2&gt;
  &lt;p id=&quot;S5EC&quot;&gt;В стандарте KeeLoq есть 3 режима безопасности (также известны как KDF, learnings):&lt;/p&gt;
  &lt;ul id=&quot;gAD1&quot;&gt;
    &lt;li id=&quot;AWTH&quot;&gt;&lt;strong&gt;Простой режим (Simple learning)&lt;/strong&gt;&lt;br /&gt;Наименее защищённый режим, при котором мануфактурный ключ никак не преобразуется и используется в шифровании as is.&lt;/li&gt;
    &lt;li id=&quot;O4Oo&quot;&gt;&lt;strong&gt;Классический режим (Normal learning)&lt;/strong&gt;&lt;br /&gt;Улучшенная версия, где мануфактурный ключ изменяется с помощью серийного номера пульта с помощью побитовых операций&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;kanv&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/e6/56/e656f372-c5a5-4c28-ab78-1bb3a872f9fe.png&quot; width=&quot;525&quot; /&gt;
    &lt;figcaption&gt;Примерная запись алгоритма&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;ul id=&quot;qKp3&quot;&gt;
    &lt;li id=&quot;C09x&quot;&gt;&lt;strong&gt;Безопасный режим (Secure learning)&lt;/strong&gt;&lt;br /&gt;Модифицированная версия классического режима, использующая вместо побитовых операций над серийным номером, дополнительное значение (он же seed), уникальное для каждого пульта и передающееся при первоначальной привязке пульта к приёмнику. На данный момент самый защищённых режим из представленных в стандарте&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;jZiQ&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/4a/55/4a5598d6-fbf5-4438-b411-f3f1b0d80c3f.png&quot; width=&quot;496&quot; /&gt;
    &lt;figcaption&gt;Примерная запись алгоритма&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;N8p0&quot;&gt;Однако некоторые производители отклоняются от стандартных режимов безопасности и реализуют свои собственные, давайте рассмотрим некоторые из них:&lt;/p&gt;
  &lt;ul id=&quot;nUV6&quot;&gt;
    &lt;li id=&quot;YvOw&quot;&gt;&lt;strong&gt;Magic XOR Type-1 learning&lt;/strong&gt;&lt;br /&gt;Используется производителем Beninca, представляет из себя XOR серийного номера пульта на мануфактурный ключ&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;0wgO&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d8/8a/d88a7eb1-9a74-4566-8aa7-0f3984286a8e.png&quot; width=&quot;357&quot; /&gt;
    &lt;figcaption&gt;Примерная запись алгоритма&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;ul id=&quot;gLs7&quot;&gt;
    &lt;li id=&quot;lKNt&quot;&gt;&lt;strong&gt;FAAC SLH (SPA) learning&lt;/strong&gt;&lt;br /&gt;Как понятно из названия, данный алгоритм используется производителем FAAC и по моему мнению является самым продуманным. Представляет из себя серию побитовых операций и шифрования&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;RRK3&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/eb/26/eb26511a-62ba-4234-9467-15d55ee36454.png&quot; width=&quot;360&quot; /&gt;
    &lt;figcaption&gt;Примерная запись алгоритма&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;kATQ&quot;&gt;Теоретические атаки&lt;/h2&gt;
  &lt;h3 id=&quot;LK6k&quot;&gt;Слайд-атака&lt;/h3&gt;
  &lt;p id=&quot;bolB&quot;&gt;Атака применима, преимущественно, к многораундовым кодам, каждый раунд которых представляет собой несложное преобразование исходного блока с использованием лишь одного ключа.&lt;/p&gt;
  &lt;p id=&quot;H8XD&quot;&gt;На первом этапе набрать порядка 2^32 пар открытый-зашифрованный текст&lt;br /&gt;Далее &lt;code&gt;(M,C)&lt;/code&gt; - одна из таких пар, &lt;code&gt;F&lt;/code&gt; - функция преобразования. Суть такова:&lt;br /&gt;если &lt;code&gt;(M’,C’)&lt;/code&gt; такая, что &lt;code&gt;P’= F(K,M)&lt;/code&gt; и &lt;code&gt;C’= F(K,C)&lt;/code&gt;, то &lt;code&gt;K&lt;/code&gt; и есть искомый ключ.&lt;/p&gt;
  &lt;p id=&quot;xXtN&quot;&gt;В теории данная атака позволяет получить первые 32 бита ключа.&lt;/p&gt;
  &lt;h3 id=&quot;xUzg&quot;&gt;Корреляционный подход&lt;/h3&gt;
  &lt;p id=&quot;pbUD&quot;&gt;Атака базируется на свойстве NLFSR - &lt;code&gt;Cor(F) = 1&lt;/code&gt;&lt;br /&gt;Оказывается, что для равномерно распределенных &lt;code&gt;x2,x3,x4&lt;/code&gt; имеет место следующее:&lt;/p&gt;
  &lt;ul id=&quot;FylO&quot;&gt;
    &lt;li id=&quot;jusg&quot;&gt;&lt;code&gt;{NLFSR(x4, x3, x2, x1, x0) = 0 | x0 ^ x1 = 0} = 5/8&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;DHFP&quot;&gt;&lt;code&gt;{NLFSR(x4, x3, x2, x1, x0) = 1 | x0 ^ x1 = 1} = 5/8&lt;/code&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;50G9&quot;&gt;Используя это и аппроксимируя NLFSR вероятности, можно добиться определения очередной части ключа.&lt;/p&gt;
  &lt;h3 id=&quot;UXF8&quot;&gt;Линейный шаг&lt;/h3&gt;
  &lt;p id=&quot;DRsM&quot;&gt;Последние 16 бит ключа определяются, если известны все предыдущие. Основываясь на том, что если мы знаем полностью 48 состояние в цикле,то можем записать:&lt;/p&gt;
  &lt;figure id=&quot;d9uN&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/4b/c1/4bc11943-61af-4270-8db5-855441752ef3.png&quot; width=&quot;499&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;QhAw&quot;&gt;Отсюда находим &lt;code&gt;key^48&lt;/code&gt; и аналогично &lt;code&gt;key^49 ... key^63&lt;/code&gt;&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;GNb7&quot;&gt;Общая сложность всех теоретических атак - ≈2^52 (≈4503599627370496)&lt;/p&gt;
  &lt;h2 id=&quot;MlSn&quot;&gt;Практические атаки&lt;/h2&gt;
  &lt;p id=&quot;N1Bb&quot;&gt;Здесь я хочу поблагодарить &lt;a href=&quot;https://github.com/jamisonderek&quot; target=&quot;_blank&quot;&gt;Derek Jamison&lt;/a&gt; за прекрасные материалы по практическим атакам на KeeLoq&lt;/p&gt;
  &lt;h3 id=&quot;QeWA&quot;&gt;Replay-атака&lt;/h3&gt;
  &lt;figure id=&quot;VXZr&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f1/49/f149c351-07ba-4de2-ad91-7b1c8a2f9661.png&quot; width=&quot;1236&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;SjbV&quot;&gt;Очень распространённая атака работающая, преимущественно, для статических кодов, и для уявизмых приёмников, которые не проверяют значение счётчика&lt;/p&gt;
  &lt;h3 id=&quot;hrtX&quot;&gt;Клонирование пульта&lt;/h3&gt;
  &lt;figure id=&quot;qYAy&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/5a/2f/5a2f5185-87fd-4498-b619-680a4da622fc.png&quot; width=&quot;1200&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;esSo&quot;&gt;Если мы знаем мануфактурный ключ пульта то без проблем можем сделать копию, которая будет работать, однако делать так не рекомендуется т.к будет конфликт значения счётчика у оригинального пульта и у копии, и в результате при использования двух пультов (оригинального и копии) приёмник может просто отвязать ваш пульт&lt;/p&gt;
  &lt;h3 id=&quot;EVpD&quot;&gt;Future-атака&lt;/h3&gt;
  &lt;figure id=&quot;IDuB&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/6f/47/6f478059-d942-4e1a-abaf-e7f14b29efd1.png&quot; width=&quot;1216&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;LebV&quot;&gt;Если мы знаем мануфактурный ключ пульта то можно воспользоваться логикой работы счётчика и отправить &amp;quot;будущее&amp;quot; значение счётчика (было &lt;code&gt;0001&lt;/code&gt; - стало &lt;code&gt;3E91&lt;/code&gt;), приёмник может подумать, что пульт &amp;quot;убежал&amp;quot; далеко вперёд и синхронизироваться с переданным значением и штатно работать со следующими значениями (&lt;code&gt;3E92&lt;/code&gt;, &lt;code&gt;3E93&lt;/code&gt; и т.п). При данной атаке оригинальный пульт полностью рассинхронизируется и дальнейшее его использования не рекомендуется &lt;a href=&quot;#esSo&quot;&gt;по описанным выше причинам&lt;/a&gt;. &lt;/p&gt;
  &lt;h3 id=&quot;tacj&quot;&gt;Rollback-атака&lt;/h3&gt;
  &lt;figure id=&quot;aopX&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/dc/8a/dc8ada19-3fb1-4e2a-83fc-4364837e1689.png&quot; width=&quot;1233&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;FJ7C&quot;&gt;Данная атака весьма редкая, однако всё же возможна с некоторыми приёмниками. Она похожа на Future-атаку, однако вместо последующих значений, мы откатываем состояние счётчика после нескольких использований и приёмник может заново синхронизироваться с этими значениями.&lt;/p&gt;
  &lt;h3 id=&quot;jCpe&quot;&gt;Rolljam-атака&lt;/h3&gt;
  &lt;figure id=&quot;66PT&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/0e/89/0e89ffba-3d7d-4ee7-9c34-4172190432d0.png&quot; width=&quot;1231&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;KfTJ&quot;&gt;Вся суть атаки в том, что вы записываете сигналы с оригинального пульта и не даёте приёмнику получить их (например создавая помехи рядом с приёмником), после чего вы можете использовать записанные сигналы.&lt;/p&gt;
  &lt;p id=&quot;Ok8c&quot;&gt;Однако следует учесть, что почти во всех странах (&lt;a href=&quot;https://www.fcc.gov/general/jammer-enforcement&quot; target=&quot;_blank&quot;&gt;например в США&lt;/a&gt;, странах ЕС, &lt;a href=&quot;https://www.consultant.ru/document/cons_doc_LAW_34661/acaefaec257669702f20b2a36e96381e17d50f52/&quot; target=&quot;_blank&quot;&gt;РФ&lt;/a&gt;) глушение сигналов является незаконным.&lt;/p&gt;
  &lt;h3 id=&quot;ckqu&quot;&gt;Атака на мануфактурные ключи (KGB attack)&lt;/h3&gt;
  &lt;figure id=&quot;pPGX&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/ff/f5/fff5633b-1266-47a8-98ac-9a313ce4db9f.png&quot; width=&quot;1218&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Q0cY&quot;&gt;Идея заключается в том, что, возможно, приёмник умеет работать с несколькими мануфактурными ключами, а не только с одним. Если мы отправим &lt;code&gt;fix&lt;/code&gt; от оригинального пульта, но закодируем счётчик с помощью другого мануфактурного ключа, то, возможно, оно откроется (обычно эту атаку комбинируют с Future-атакой, потому что вы не знаете, каким должно быть значение счётчика).&lt;/p&gt;
  &lt;h3 id=&quot;tLCW&quot;&gt;Enc00-атака&lt;/h3&gt;
  &lt;figure id=&quot;me8y&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/a2/d2/a2d2f01c-d90c-437a-abb8-579a9f901322.png&quot; width=&quot;1408&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;GkM9&quot;&gt;Атака представляет собой подмену &lt;code&gt;fix&lt;/code&gt; оригинального пульта на &lt;code&gt;fix&lt;/code&gt; другого пульта (также привязанного к приёмнику) и использование &lt;code&gt;hop&lt;/code&gt; с оригинального пульта. &lt;/p&gt;
  &lt;p id=&quot;4hTT&quot;&gt;&lt;strong&gt;Важно, что после подмены, пульт, &lt;code&gt;fix&lt;/code&gt; которого использовали, рассинхронизируется и перестаёт работать&lt;/strong&gt;&lt;/p&gt;
  &lt;h3 id=&quot;wSBY&quot;&gt;Unknown-атака&lt;/h3&gt;
  &lt;figure id=&quot;BxwY&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/1b/99/1b9931cd-d718-4d16-8d36-ac5238574bfc.png&quot; width=&quot;1216&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;da9s&quot;&gt;Суть в том, что, когда приёмник не может декодировать &lt;code&gt;hop&lt;/code&gt;, он использует значение 0. Для универсальных приёмников есть вероятность, что они откроются при значении 0.&lt;/p&gt;
  &lt;h2 id=&quot;5cd7&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;LRM8&quot;&gt;Не смотря на все описанные выше уязвимости, KeeLoq, также как и Mifare Classic (чей шифр Crypto-1 был взломан в далёких 2000x) остаётся популярным выбором для бюджетных систем безопасности (автоматические ворота, гаражные двери и т.п). Возможно в будущем все производители перейдут на более стойкие алгоритмы шифрования (например на AES), как это сделали Beninca и Hormann&lt;/p&gt;
  &lt;p id=&quot;3kdg&quot;&gt;Кстати, имея на руках мануфактурный ключ вы можете &amp;quot;поиграться&amp;quot; с KeeLoq онлайн в &lt;a href=&quot;http://li0ard.rest/apps/keeloq&quot; target=&quot;_blank&quot;&gt;моём мини-приложении&lt;/a&gt;.&lt;/p&gt;
  &lt;h3 id=&quot;34Ux&quot;&gt;Использованные материалы&lt;/h3&gt;
  &lt;ol id=&quot;k2eR&quot;&gt;
    &lt;li id=&quot;4Jp7&quot;&gt;&lt;a href=&quot;https://github.com/li0ard/keeloq/&quot; target=&quot;_blank&quot;&gt;Моя собственная библиотека для работы с KeeLoq&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;vDmX&quot;&gt;&lt;a href=&quot;https://github.com/DarkFlippers/unleashed-firmware/&quot; target=&quot;_blank&quot;&gt;Исходный код Unleashed Firmware для Flipper Zero&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;oj28&quot;&gt;&lt;a href=&quot;https://github.com/jamisonderek/flipper-zero-tutorials/tree/main/subghz/apps/rolling-flaws&quot; target=&quot;_blank&quot;&gt;Материалы Derek Jamison по KeeLoq и его приложение &amp;quot;SubGHZ Rolling Flaws&amp;quot;&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;

</content></entry><entry><id>li0ard:reviving_t5577</id><link rel="alternate" type="text/html" href="https://blog.li0ard.rest/reviving_t5577?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=li0ard"></link><title>Чиним T5577 с помощью proxmark3</title><published>2025-04-09T21:27:32.942Z</published><updated>2025-04-26T19:25:14.219Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/42/99/429977fd-5669-48e4-bde1-b429a5eac76c.png"></media:thumbnail><category term="proxmark-3" label="proxmark3"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/77/8c/778c5307-c3eb-4b33-ab76-bef2cb61069c.png&quot;&gt;Однажды экспериментировав с конфигурацией метки T5577, я получил в результате метку (даже две), которая нормально не определялась через lf search, либо определялась как Valid Indala ID found!.</summary><content type="html">
  &lt;p id=&quot;6PXB&quot;&gt;Однажды экспериментировав с конфигурацией метки T5577, я получил в результате метку (даже две), которая нормально не определялась через &lt;code&gt;lf search&lt;/code&gt;, либо определялась как &lt;code&gt;Valid Indala ID found!&lt;/code&gt;.&lt;/p&gt;
  &lt;figure id=&quot;j9qu&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/77/8c/778c5307-c3eb-4b33-ab76-bef2cb61069c.png&quot; width=&quot;678&quot; /&gt;
    &lt;figcaption&gt;Valid Indala ID found!, а ведь метка была EM-Marine....&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;bxEK&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b5/97/b5977b3a-c02b-4835-ad66-11eb4dda1698.png&quot; width=&quot;1041&quot; /&gt;
    &lt;figcaption&gt;А теперь определяется как ASK и PSK одновременно...&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;lNf3&quot;&gt;Скорее жив чем мёртв?&lt;/h2&gt;
  &lt;p id=&quot;4tlB&quot;&gt;Учитывая, что метка всё-таки как-то определялась, то необходимость использования команды &lt;code&gt;lf tune&lt;/code&gt; отпадала сама собой.&lt;/p&gt;
  &lt;p id=&quot;UwNK&quot;&gt;Поэтому необходимо было определить, может ли proxmark3 считать конфигурацию чипа через &lt;code&gt;lf t55xx [detect / p1detect]&lt;/code&gt;. Введя команду, я получил следующий ответ:&lt;/p&gt;
  &lt;pre id=&quot;lnnA&quot;&gt;[!] Could not detect modulation automatically. Try setting it manually with &amp;#x27;lf t55xx config&amp;#x27;&lt;/pre&gt;
  &lt;p id=&quot;jqyi&quot;&gt;Что ж, ещё не всё потеряно...&lt;/p&gt;
  &lt;h2 id=&quot;zqOZ&quot;&gt;Принудительное оживление&lt;/h2&gt;
  &lt;p id=&quot;9g9H&quot;&gt;Следующим шагом была попытка перезаписать нулевой блок метки, отвечающий за конфигурацию. Я делал это следующими командами:&lt;/p&gt;
  &lt;pre id=&quot;iDxQ&quot;&gt;lf t55xx write -b 0 -d 000880E0 -t
lf t55xx write -b 0 -d 000880E0 --r0 -t
lf t55xx write -b 0 -d 000880E0 --r1 -t
lf t55xx write -b 0 -d 000880E0 --r2 -t
lf t55xx write -b 0 -d 000880E0 --r3 -t&lt;/pre&gt;
  &lt;p id=&quot;3L7P&quot;&gt;После чего я проверил метку командой &lt;code&gt;lf t55xx detect&lt;/code&gt; и... видимо, одна из команд сработала:&lt;/p&gt;
  &lt;figure id=&quot;XJp7&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/a9/f4/a9f49b9a-bbc3-4a61-8a0e-be40e6e6155b.png&quot; width=&quot;402&quot; /&gt;
    &lt;figcaption&gt;Метку удалось вернуть к работе на конфигурации по умолчанию&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;VPXN&quot;&gt;После чего я попробовал записать на метку какой нибудь рандомный EM-Marine ID и считать его, это сработало!&lt;/p&gt;
  &lt;figure id=&quot;V1GQ&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/3a/fb/3afb5452-b162-49c7-b6c7-71f2952fec5b.png&quot; width=&quot;635&quot; /&gt;
    &lt;figcaption&gt;Метка заработала в стандарте EM-Marine&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;QRWu&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;9a3T&quot;&gt;Получилась весьма короткая статья, но я думаю, она кому-нибудь да пригодится.&lt;/p&gt;
  &lt;p id=&quot;8uxe&quot;&gt;Вообще, восстановление работоспособности T5577 - это довольно-таки индивидуальная тема. То, что работает в одних случаях, может не работать в других.&lt;/p&gt;
  &lt;figure id=&quot;MIwg&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/78/62/78621bca-cc25-443c-a549-36d4ce69c489.png&quot; width=&quot;764&quot; /&gt;
    &lt;figcaption&gt;Многообразие решений на форуме Dangerous Things :)&lt;/figcaption&gt;
  &lt;/figure&gt;

</content></entry><entry><id>li0ard:blindedid</id><link rel="alternate" type="text/html" href="https://blog.li0ard.rest/blindedid?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=li0ard"></link><title>Blinded ID в Session и что с ними не так</title><published>2024-08-20T10:30:28.968Z</published><updated>2025-06-29T21:47:51.111Z</updated><category term="kriptografiya" label="Криптография"></category><summary type="html">Blinded ID (aka &quot;слепые&quot; айди и т.п) - алгоритм деривации публичного ключа (ID) пользователя для открытых групп в Session, для того чтобы скрыть настоящий ID пользователя, тем самым обеспечить некую приватность.</summary><content type="html">
  &lt;p id=&quot;fqfi&quot;&gt;Blinded ID (aka &amp;quot;слепые&amp;quot; айди и т.п) - алгоритм деривации ID пользователя, который является публичным ключом Curve25519, для открытых групп в &lt;a href=&quot;http://getsession.org&quot; target=&quot;_blank&quot;&gt;Session&lt;/a&gt;, для того чтобы скрыть настоящий ID пользователя.&lt;/p&gt;
  &lt;p id=&quot;8uQF&quot;&gt;Всего существует две версии данного алгоритма:&lt;/p&gt;
  &lt;ol id=&quot;6jQf&quot;&gt;
    &lt;li id=&quot;ugY5&quot;&gt;Legacy версия (ID начинается с префикса 15)&lt;/li&gt;
    &lt;li id=&quot;PKVB&quot;&gt;Новая версия (ID начинается с префикса 25)&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;dMlP&quot;&gt;На данный момент полностью реализованной является legacy версия, а поддержка новой версии есть только в &lt;a href=&quot;https://github.com/oxen-io/libsession-util/blob/dev/src/blinding.cpp&quot; target=&quot;_blank&quot;&gt;libsession&lt;/a&gt; и вроде как планируется в &lt;a href=&quot;https://github.com/oxen-io/session-pysogs/pull/220&quot; target=&quot;_blank&quot;&gt;pysogs&lt;/a&gt;.&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;jNcZ&quot;&gt;&lt;strong&gt;Важно&lt;/strong&gt;: Все математические операции выполняются в поле &lt;em&gt;F&lt;/em&gt;p кривой ed25519, манипуляции со скалярами (редуцирование, инвертирование) выполняются в поле &lt;em&gt;F&lt;/em&gt;n (order field)&lt;/p&gt;
  &lt;/section&gt;
  &lt;h2 id=&quot;EQRZ&quot;&gt;Один ключ -&amp;gt; два ключа. Legacy версия.&lt;/h2&gt;
  &lt;h3 id=&quot;4Id9&quot;&gt;Алгоритм&lt;/h3&gt;
  &lt;p id=&quot;751h&quot;&gt;Для работы алгоритма нам понадобится:&lt;/p&gt;
  &lt;ul id=&quot;JwS8&quot;&gt;
    &lt;li id=&quot;FDkU&quot;&gt;ID пользователя&lt;/li&gt;
    &lt;li id=&quot;m5M4&quot;&gt;Публичный ключ сервера&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;mV2l&quot;&gt;Сам алгоритм:&lt;/p&gt;
  &lt;ol id=&quot;f5SJ&quot;&gt;
    &lt;li id=&quot;BCUN&quot;&gt;Генерируем т.н &amp;quot;blinding factor&amp;quot;: хэшируем с помощью Blake2B публичный ключ сервера и редуцируем результат.&lt;br /&gt;Обозначим, как &lt;code&gt;k&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;Njow&quot;&gt;Из ID пользователя убираем префикс 05 и переводим его в ed25519.&lt;br /&gt;Обозначим, как &lt;code&gt;A&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;8RHt&quot;&gt;Умножаем &lt;code&gt;k&lt;/code&gt; на &lt;code&gt;A&lt;/code&gt; и получаем ключ ed25519, который является одним из возможных &amp;quot;слепых&amp;quot; id.&lt;br /&gt;Обозначим, как &lt;code&gt;kA&lt;/code&gt;.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;figure id=&quot;1mos&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/78/69/78693505-fa28-4cc3-852c-418b9b00d683.png&quot; width=&quot;661&quot; /&gt;
    &lt;figcaption&gt;Примерная запись алгоритма&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;uY6p&quot;&gt;Сломанное условие&lt;/h3&gt;
  &lt;p id=&quot;eCpq&quot;&gt;Как следует из заголовка, legacy версия генерирует 2 возможных &amp;quot;слепых&amp;quot; ID.&lt;/p&gt;
  &lt;p id=&quot;Bgil&quot;&gt;Второй возможный ID (&lt;code&gt;kA2&lt;/code&gt;) генерируется на основе &lt;code&gt;kA&lt;/code&gt;, только с &lt;a href=&quot;https://github.com/theinfinityway/session_id/blob/main/src/index.ts#L98&quot; target=&quot;_blank&quot;&gt;изменённым&lt;/a&gt; (XOR на 128) sign битом.&lt;/p&gt;
  &lt;p id=&quot;T5D0&quot;&gt;И для того чтобы выяснить какой из двух ключей следует использовать, pysogs &lt;a href=&quot;https://github.com/oxen-io/session-pysogs/blob/dev/sogs/crypto.py#L101-L117&quot; target=&quot;_blank&quot;&gt;предлагает&lt;/a&gt; следующий код:&lt;/p&gt;
  &lt;pre id=&quot;sU4t&quot; data-lang=&quot;python&quot;&gt;if kA[31] &amp;amp; 0x80:
    return kA[0:31] + bytes([kA[31] &amp;amp; 0x80])&lt;/pre&gt;
  &lt;p id=&quot;O6vu&quot;&gt;Однако это условие &lt;a href=&quot;https://github.com/oxen-io/session-pysogs/issues/221&quot; target=&quot;_blank&quot;&gt;совершенно не работает&lt;/a&gt;, поэтому в реализации клиентов пошли другим путём - &lt;a href=&quot;https://github.com/oxen-io/session-desktop/blob/eb463a49baa79ffcb6a54362d34860f7fc358e11/ts/session/apis/open_group_api/sogsv3/sogsBlinding.ts#L161-L190&quot; target=&quot;_blank&quot;&gt;получение&lt;/a&gt; &amp;quot;слепого&amp;quot; id из приватного ключа, вместо того чтобы получать его из публичного ключа. Таким образом сервер не знает наверняка, какой ключ из двух следует использовать, и надеется на клиент в результате чего в теории может произойти раздвоение пользователя.&lt;/p&gt;
  &lt;figure id=&quot;Q2Qv&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/91/04/91042e9b-b7d9-4a6b-a68a-734b943df30a.png&quot; width=&quot;683&quot; /&gt;
    &lt;figcaption&gt;Примерная запись условия&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;nIr1&quot;&gt;Обратимая необратимость&lt;/h3&gt;
  &lt;p id=&quot;hhGD&quot;&gt;Так же немало важным является то, что legacy версия (а фактически единственная версия на момент написания статьи) является обратимой вопреки всем заявлениям.&lt;/p&gt;
  &lt;p id=&quot;C1xo&quot;&gt;Для этого достаточно инвертировать полученный ранее &amp;quot;blinding factor&amp;quot;, умножить его на слепой id, полученный ключ перевести в Curve25519 и в результате мы имеем ID пользователя.&lt;/p&gt;
  &lt;figure id=&quot;4HQ6&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/20/fd/20fd6a13-f4fb-4996-bd6a-677ab853c674.png&quot; width=&quot;670&quot; /&gt;
    &lt;figcaption&gt;Примерная запись алгоритма&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;4XKD&quot;&gt;Один ключ -&amp;gt; один ключ. Новая версия&lt;/h2&gt;
  &lt;p id=&quot;Rc2T&quot;&gt;На момент написания статьи эта версия реализована только в libsession, и поэтому может поменяться.&lt;/p&gt;
  &lt;p id=&quot;gYKy&quot;&gt;Самое главное отличие этой версии от legacy в том, что в процессе генерации &amp;quot;blinding factor&amp;quot; принимает участие ID пользователя вместе с публичным ключом сервера, что, в свою очередь, исключает возможность обратимости, как это было с legacy версией.&lt;/p&gt;
  &lt;p id=&quot;E64O&quot;&gt;Т.е алгоритм следующий:&lt;/p&gt;
  &lt;ol id=&quot;pZRm&quot;&gt;
    &lt;li id=&quot;4AOy&quot;&gt;Генерируем &amp;quot;blinding factor&amp;quot;: хэшируем с помощью Blake2B ID пользователя (вместе с префиксом) и публичный ключ сервера и редуцируем результат.&lt;br /&gt;Обозначим, как &lt;code&gt;k&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;uYJ3&quot;&gt;Переводим ID пользователя из Curve25519 в ed25519.&lt;br /&gt;Обозначим, как &lt;code&gt;A&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;3yYP&quot;&gt;Умножаем скаляр &lt;code&gt;k&lt;/code&gt; на &lt;code&gt;A&lt;/code&gt; &lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;DnGh&quot;&gt;На выходе получаем единственный Blinded ID для конкретного пользователя на конкретном сервере.&lt;/p&gt;
  &lt;figure id=&quot;e2eb&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b2/12/b212990b-309b-41a2-b944-bc9c45a51a9e.png&quot; width=&quot;677&quot; /&gt;
    &lt;figcaption&gt;Примерная запись алгоритма&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;1g9d&quot;&gt;Ссылки&lt;/h2&gt;
  &lt;p id=&quot;MsGC&quot;&gt;&lt;a href=&quot;https://github.com/theinfinityway/session_id&quot; target=&quot;_blank&quot;&gt;Моя библиотека &amp;quot;Session ID&amp;quot;&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;MZUq&quot;&gt;&lt;a href=&quot;https://github.com/sessionjs&quot; target=&quot;_blank&quot;&gt;Проект Session.js&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;DAGm&quot;&gt;&lt;a href=&quot;https://github.com/VityaSchel/bunsogs&quot; target=&quot;_blank&quot;&gt;Проект bunsogs&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>li0ard:findkey</id><link rel="alternate" type="text/html" href="https://blog.li0ard.rest/findkey?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=li0ard"></link><title>Расчёт параметров МСК</title><published>2024-07-26T06:31:02.435Z</published><updated>2024-08-19T13:54:02.776Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/c7/f3/c7f349bb-bfdf-4d23-871f-a079a0eca839.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/a6/98/a698fc32-0b84-4d31-bed8-f5976aebc4ee.png&quot;&gt;Под МСК (Местная система координат) подразумевается система координат построенная независимо от государственной системы координат (чаще всего на основе СК-42 или СК-63) и для конкретного субъекта Российской Федерации.</summary><content type="html">
  &lt;p id=&quot;Aw6b&quot;&gt;Под МСК (Местная система координат) подразумевается система координат построенная независимо от государственной системы координат (чаще всего на основе СК-42 или СК-63) и для конкретного субъекта Российской Федерации.&lt;/p&gt;
  &lt;blockquote id=&quot;MwJ3&quot;&gt;Многие программы ГИС позволяют реализовать работу в МСК непосредственно. Так, в QGIS и в MapInfo Pro любая проекция может быть дополнена аффинным преобразованием, а в Global Mapper конформные проекции дополняются разворотом.&lt;/blockquote&gt;
  &lt;h2 id=&quot;lR1F&quot;&gt;Постановка задачи&lt;/h2&gt;
  &lt;p id=&quot;yafh&quot;&gt;Имеется 6-7 пунктов, для которых известны координат X и Y в ГСК и в МСК. Необходимо подобрать параметры проекции представляющую МСК в ГИС.&lt;/p&gt;
  &lt;blockquote id=&quot;dQzV&quot;&gt;При подборе параметров предполагается использовать один из пунктов в качестве центральной точки преобразования.&lt;/blockquote&gt;
  &lt;h2 id=&quot;oAb7&quot;&gt;Подготовка данных&lt;/h2&gt;
  &lt;p id=&quot;0W1q&quot;&gt;Имеем 2 каталога координат. Один содержит координаты пунктов в государственной системе, а именно в СК-42, 4 зона (EPSG:28404) в формате &lt;code&gt;Y X&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;f8wC&quot;&gt;4645997.49 5768521.60
4661392.15 5770068.91
4650059.09 5783332.41
4634241.37 5778952.22
4631481.69 5764570.61
4642125.18 5754643.12
4655952.19 5757337.28&lt;/pre&gt;
  &lt;p id=&quot;bBPW&quot;&gt;А второй координаты в местной системе:&lt;/p&gt;
  &lt;pre id=&quot;bv3g&quot;&gt;67266.64 30088.40
82697.29 31184.27
71759.40 44771.50
55822.67 40857.06
52643.65 26564.42
62990.64 16331.35
76888.20 18619.57&lt;/pre&gt;
  &lt;p id=&quot;i43U&quot;&gt;Каждая строка в обоих файлах соответствует одному и тому же пункту. В первой строке центральный пункт системы.&lt;/p&gt;
  &lt;blockquote id=&quot;xBbz&quot;&gt;Очень важно помнить, что с точки зрения математической картографии МСК остаётся проекцией Гаусса-Крюгера и наследует её искажения. Поэтому важно знать, на какой именно ГСК основана МСК. Зачастую это заранее неизвестно, и приходится проводить предварительное исследование для выяснения этого вопроса.&lt;/blockquote&gt;
  &lt;p id=&quot;yjkL&quot;&gt;В нашем примере мы предполагаем, что это либо СК-42, 4 зона, либо СК-63, район C. Создадим также каталог в СК-63:&lt;/p&gt;
  &lt;figure id=&quot;yAdU&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/a6/98/a698fc32-0b84-4d31-bed8-f5976aebc4ee.png&quot; width=&quot;1191&quot; /&gt;
    &lt;figcaption&gt;cs2cs online by MyGeodata Cloud&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;pre id=&quot;nka5&quot;&gt;330797.453706 5755981.4752
346208.044264 5757327.09534
335051.738244 5770735.14419
319180.795365 5766563.18288
316233.724465 5752221.19702
326744.900981 5742157.23182
340603.316544 5744670.19105&lt;/pre&gt;
  &lt;h2 id=&quot;Q4vH&quot;&gt;Получение параметров&lt;/h2&gt;
  &lt;p id=&quot;I2Jt&quot;&gt;Для вычислений воспользуемся моей &lt;a href=&quot;https://geo.li0ard.rest/keys&quot; target=&quot;_blank&quot;&gt;утилитой&lt;/a&gt;.&lt;/p&gt;
  &lt;p id=&quot;RKDq&quot;&gt;Для начала необходимо определить базовую ГСК, сделаем это с помощью координатных невязок.&lt;/p&gt;
  &lt;p id=&quot;I64Q&quot;&gt;Загружаем каталог в СК-42 и в МСК в утилиту, и получаем значение невязок:&lt;/p&gt;
  &lt;figure id=&quot;UaNY&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/5d/6c/5d6cb960-ef51-47d1-acf3-9663cabbcacd.png&quot; width=&quot;553&quot; /&gt;
    &lt;figcaption&gt;Невязки для СК-42&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;6wRz&quot;&gt;Теперь вычислим невязки аналогичным способом для СК-63:&lt;/p&gt;
  &lt;figure id=&quot;31Tt&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/9f/a1/9fa1830a-5eef-4dcb-b3ba-68fcbd7d8a4e.png&quot; width=&quot;562&quot; /&gt;
    &lt;figcaption&gt;Невязки для СК-63&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;aYAm&quot;&gt;Сравнив невязки мы понимаем, что базовая ГСК - СК-63&lt;/p&gt;
  &lt;p id=&quot;Ho4F&quot;&gt;Получаем параметры 2D преобразования Гельмерта:&lt;/p&gt;
  &lt;figure id=&quot;wkIL&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7b/8e/7b8e85ad-b303-4c69-9679-979e5bd22b97.png&quot; width=&quot;564&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;RfmG&quot;&gt;А также параметры Аффинного параметрического преобразования:&lt;/p&gt;
  &lt;figure id=&quot;BeQr&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/87/c3/87c3aab6-23ac-4af7-9f55-127a0215b17d.png&quot; width=&quot;550&quot; /&gt;
  &lt;/figure&gt;

</content></entry><entry><id>li0ard:anticryptopro_p3</id><link rel="alternate" type="text/html" href="https://blog.li0ard.rest/anticryptopro_p3?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=li0ard"></link><title>Побег из КриптоПро (ч.3)</title><published>2024-06-23T12:06:45.108Z</published><updated>2024-06-23T12:06:45.108Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/56/b9/56b95756-5be1-44d6-be7a-8b423726351e.png"></media:thumbnail><category term="kriptografiya" label="Криптография"></category><summary type="html">&lt;img src=&quot;https://img2.teletype.in/files/9d/d5/9dd5b7e8-5018-4f4b-bfdc-c2b32875e02b.png&quot;&gt;В прошлых частях я разбирался с транспортным ключевым контейнером от КриптоПро (он же PFX, PKCS12, P12). В этой статье пойдёт речь о собственном формате ключевого контейнера КриптоПро (те самые 6 файлов .key)</summary><content type="html">
  &lt;p id=&quot;7ST7&quot;&gt;В прошлых частях (&lt;a href=&quot;/anticryptopro&quot;&gt;клик&lt;/a&gt;, &lt;a href=&quot;/anticryptopro_p2&quot;&gt;клик&lt;/a&gt;) я разбирался с транспортным ключевым контейнером от КриптоПро (он же PFX, PKCS12, P12). В этой статье пойдёт речь о собственном формате ключевого контейнера КриптоПро (те самые 6 файлов .key)&lt;/p&gt;
  &lt;figure id=&quot;GY2O&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/9d/d5/9dd5b7e8-5018-4f4b-bfdc-c2b32875e02b.png&quot; width=&quot;598&quot; /&gt;
    &lt;figcaption&gt;Проприетарный контейнер КриптоПро&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;cZkW&quot;&gt;Вообще тема данной статьи не нова, ещё в далёком 2016 года Михаил Куликов (он же shukan) написал &lt;a href=&quot;https://habr.com/ru/articles/275039/&quot; target=&quot;_blank&quot;&gt;статью&lt;/a&gt; на Хабре в которой он предоставил программу на C, которая вытаскивала ключ для ГОСТ 34.10-2001. Чуть позже благодаря сообществу появилась версия и для ГОСТ 34.10-2012. Однако пробуя запустить все эти утилиты для контейнера ГОСТ 34.10-2012 512 бит сгенерированного в КриптоПро CSP 5.0, утилиты выдавали ошибку. Собственно это и стало мотивацией разобраться как там всё устроено и написать свою программу.&lt;/p&gt;
  &lt;h2 id=&quot;bApX&quot;&gt;Как там всё устроено&lt;/h2&gt;
  &lt;h3 id=&quot;naQk&quot;&gt;Файл masks.key&lt;/h3&gt;
  &lt;figure id=&quot;GQHb&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/58/86/58863e2a-852e-432a-a347-ccb0a4fdd410.png&quot; width=&quot;812&quot; /&gt;
    &lt;figcaption&gt;Содержимое masks.key&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;MkTb&quot;&gt;Содержит в себе три Octet String, которые в свою очередь являются маской ключа (32 байта для 256 бит, 64 для 512), солью для деривации пароля и контрольной суммы маски соответственно.&lt;/p&gt;
  &lt;h3 id=&quot;vjGc&quot;&gt;Файл primary.key&lt;/h3&gt;
  &lt;figure id=&quot;qmTL&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/19/b7/19b7ab2d-7ea5-42dc-9f32-49447d9dfef1.png&quot; width=&quot;822&quot; /&gt;
    &lt;figcaption&gt;Содержимое primary.key&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;MEyb&quot;&gt;Содержит зашифрованный приватный ключ (32 байта для 256 бит, 64 для 512), который после расшифровки надо разделить по модулю на поле Q эллиптической кривой ключа.&lt;/p&gt;
  &lt;h3 id=&quot;auGh&quot;&gt;Файл header.key&lt;/h3&gt;
  &lt;figure id=&quot;3mQn&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/91/6a/916ad450-13e0-4c25-8b99-72ad41482b51.png&quot; width=&quot;848&quot; /&gt;
    &lt;figcaption&gt;Содержимое header.key&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;7Y70&quot;&gt;Содержит всю информацию о контейнере: Сертификат, свойства ключа, параметры эллиптической кривой и алгоритма хэширования, первые 8 байт публичного ключа, а также контрольные суммы.&lt;/p&gt;
  &lt;h2 id=&quot;XLcJ&quot;&gt;Получаем приватный ключ&lt;/h2&gt;
  &lt;p id=&quot;Mvlh&quot;&gt;Для получения приватного ключа необходимо выполнить следующие шаги:&lt;/p&gt;
  &lt;ol id=&quot;FOPy&quot;&gt;
    &lt;li id=&quot;yeOC&quot;&gt;Получение так ключа хранения с помощью CPKDF (CryptoPro Key Derivation Function) в которую передаётся пароль и соль из файла masks.key.&lt;/li&gt;
    &lt;li id=&quot;PJTR&quot;&gt;Расшифровка основного ключа с помощью ГОСТ 28147-89 (Магма) в ECB режиме с параметрами набора Z от ТК-26&lt;/li&gt;
    &lt;li id=&quot;bZZo&quot;&gt;Деление по модулю расшифрованного ключа на маску&lt;/li&gt;
    &lt;li id=&quot;9u5A&quot;&gt;Подстановка результата в ASN.1 конструкцию приватного ключа&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;csSv&quot;&gt;Подводя итоги могу сказать, что это была достаточно сложная работа, отнявшая у меня годовой запас кофе и не только :) Однако я полностью доволен результатом.&lt;/p&gt;
  &lt;p id=&quot;UHAM&quot;&gt;Также хочу выразить благодарность Савелию Красовскому за его утилиту go-decrypto-pro, которая стала основной для моей программы, и VovkaTM за консультации и прочую помощь.&lt;/p&gt;
  &lt;h2 id=&quot;0Kh6&quot;&gt;Ссылки&lt;/h2&gt;
  &lt;p id=&quot;uTre&quot;&gt;Программа - &lt;a href=&quot;https://github.com/li0ard/ckey&quot; target=&quot;_blank&quot;&gt;https://github.com/li0ard/ckey&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;8yLV&quot;&gt;Утилита go-decrypto-pro - &lt;a href=&quot;https://github.com/savely-krasovsky/go-decrypto-pro&quot; target=&quot;_blank&quot;&gt;https://github.com/savely-krasovsky/go-decrypto-pro&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>li0ard:dump_l3_cdm</id><link rel="alternate" type="text/html" href="https://blog.li0ard.rest/dump_l3_cdm?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=li0ard"></link><title>Дампим L3 CDM из AVD</title><published>2023-12-28T18:22:08.704Z</published><updated>2024-04-22T19:27:16.966Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/e8/19/e819e595-bef4-4a3c-a4be-d0464621a394.png"></media:thumbnail><category term="kriptografiya" label="Криптография"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/75/21/7521468a-4237-40c3-9826-c65d9a3e506b.png&quot;&gt;Автор статьи не несёт ответственности за всё ниже сказанное. Вся информация ниже опубликована в учебно-ознакомительных целях. Все действия выполняйте на свой страх и риск.</summary><content type="html">
  &lt;blockquote id=&quot;I4bS&quot;&gt;Автор статьи не несёт ответственности за всё ниже сказанное. Вся информация ниже опубликована в учебно-ознакомительных целях. Все действия выполняйте на свой страх и риск.&lt;/blockquote&gt;
  &lt;p id=&quot;Vz0r&quot;&gt;Если вы решили получить 2 магических файла для расшифровки DRM контента и у вас нету Android устройства с root, как в моём случае, то можно использовать эмулятор, который встроен в обычную Android Studio.&lt;/p&gt;
  &lt;p id=&quot;B4Rw&quot;&gt;Для начала нам необходимо создать конфигурацию нашего устройства, для это заходим в Device manager и нажимаем Create Device&lt;/p&gt;
  &lt;p id=&quot;1aZM&quot;&gt;&lt;/p&gt;
  &lt;figure id=&quot;p6Pq&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/75/21/7521468a-4237-40c3-9826-c65d9a3e506b.png&quot; width=&quot;1365&quot; /&gt;
    &lt;figcaption&gt;Изображения взято с forum.videohelp.com&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;TjNo&quot;&gt;Далее выбираем марку нашего устройства (например я выбирал Pixel 6)&lt;/p&gt;
  &lt;figure id=&quot;MmWO&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7c/24/7c246c84-09fe-4693-b70e-17c85176469e.png&quot; width=&quot;1365&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;15Bx&quot;&gt;Сейчас нам необходимо сделать первый важный шаг: выбрать версию Android с Google APIs и без Google Play (иначе у вас не будет рута в adb). Лично я выбрал Android 9.0 Pie&lt;/p&gt;
  &lt;figure id=&quot;7IQ9&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/93/7d/937dca24-d99b-454e-9f89-cc0b91ab33e4.png&quot; width=&quot;1365&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;tWGu&quot;&gt;Далее идут настройки, которые можно оставить без изменений. Запускаем наше устройство.&lt;/p&gt;
  &lt;figure id=&quot;KDNN&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/2c/1c/2c1c2bd3-4b3b-44a3-9d5a-d75b48653b25.png&quot; width=&quot;1365&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;Wgen&quot;&gt;Установка Frida&lt;/h3&gt;
  &lt;p id=&quot;RHMC&quot;&gt;Открывыем терминал и пишем:&lt;/p&gt;
  &lt;pre id=&quot;sv2s&quot;&gt;pip install frida frida-tools&lt;/pre&gt;
  &lt;figure id=&quot;PDb6&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/37/4f/374f137b-4055-411c-8c4f-683bcd18d466.png&quot; width=&quot;1349&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;BveF&quot;&gt;Далее &lt;a href=&quot;https://github.com/frida/frida/releases&quot; target=&quot;_blank&quot;&gt;заходим на официальную страницу проекта&lt;/a&gt; и скачиваем frida-server для вашей версии клиента на компьютере&lt;/p&gt;
  &lt;p id=&quot;3I90&quot;&gt;В терминале пишем:&lt;/p&gt;
  &lt;pre id=&quot;3ZHt&quot;&gt;adb devices&lt;/pre&gt;
  &lt;p id=&quot;bXmS&quot;&gt;Если у вас всё хорошо то отобразится примерно следующая картина:&lt;/p&gt;
  &lt;figure id=&quot;utCZ&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/bd/92/bd92d226-dee7-4643-ac94-9f7fc0573754.png&quot; width=&quot;1365&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;GxAe&quot;&gt;Теперь настала очередь загрузить frida-server на наше устройство через терминал:&lt;/p&gt;
  &lt;pre id=&quot;iPW0&quot;&gt;adb push frida-server /sdcard
adb shell
su
mv /sdcard/frida-server /data/local/tmp
chmod +x /data/local/tmp/frida-server
/data/local/tmp/frida-server&lt;/pre&gt;
  &lt;figure id=&quot;Y30u&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/af/e6/afe6aac8-6a0e-4419-96be-e4afe6735a4f.png&quot; width=&quot;1352&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;w7Ra&quot;&gt;Теперь не закрывайте этот терминал и можете приступать к следующему шагу.&lt;/p&gt;
  &lt;h3 id=&quot;lvvo&quot;&gt;Установка дампера и получение ключей&lt;/h3&gt;
  &lt;p id=&quot;lCqu&quot;&gt;Переходим по &lt;a href=&quot;https://github.com/lollolong/dumper&quot; target=&quot;_blank&quot;&gt;ссылке&lt;/a&gt;, скачиваем ZIP архив и разархивируем его.&lt;/p&gt;
  &lt;figure id=&quot;nVk7&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b6/31/b631c2f1-cebb-4500-a15d-dc27e89a5e03.jpeg&quot; width=&quot;452&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Bkjd&quot;&gt;После в терминале пишем:&lt;/p&gt;
  &lt;pre id=&quot;NMf8&quot;&gt;python dump_keys.py&lt;/pre&gt;
  &lt;p id=&quot;k3jI&quot;&gt;Должно написать &amp;quot;Hooks completed&amp;quot; и после этого необходимо начать просмотр, какого нибудь защищенного через Widevine контента (например &lt;a href=&quot;https://bitmovin.com/demos/drm&quot; target=&quot;_blank&quot;&gt;демо страница BitMovin&lt;/a&gt;). Во время просмотра будут сообщения в консоли и в результате появится директория key_dumps в которой будут 2 файла с приватным ключом и идентификатором устройства.&lt;/p&gt;
  &lt;figure id=&quot;ifH9&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/65/0d/650d4fb1-a3da-457e-b8e8-62b430b8e76d.png&quot; width=&quot;1365&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;brpQ&quot;&gt;Ссылки&lt;/h3&gt;
  &lt;p id=&quot;NhFJ&quot;&gt;Оригинальная статья - https://forum.videohelp.com/threads/408031-Dumping-Your-own-L3-CDM-with-Android-Studio&lt;/p&gt;
  &lt;p id=&quot;tT8H&quot;&gt;Мой телеграм канал - https://t.me/li0ard_notes (полумёртвое создание однако)&lt;/p&gt;

</content></entry><entry><id>li0ard:gia9_pseudosecurity</id><link rel="alternate" type="text/html" href="https://blog.li0ard.rest/gia9_pseudosecurity?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=li0ard"></link><title>Безопасность устного собеседования (ГИА-9)</title><published>2023-04-03T14:53:40.734Z</published><updated>2023-10-02T04:45:17.587Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/0d/92/0d92ce57-388b-4ebe-9ab0-503a3b1d865f.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img2.teletype.in/files/d8/4f/d84ff49c-af86-4f57-b0f8-f43af82ca6b2.png&quot;&gt;Все ниже сказанное является мнением автора и ни к чему не призывает даже если вам так показалось. Вас предупредили :)</summary><content type="html">
  &lt;blockquote id=&quot;EVVc&quot;&gt;Все ниже сказанное является мнением автора и ни к чему не призывает даже если вам так показалось. Вас предупредили :)&lt;/blockquote&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;G1et&quot;&gt;В этой статье пойдет речь о том, как устроен один из экзаменов ГИА-9, об устном собеседовании по русскому языку, а именно про так называемую безопасность, ведь в описании программы сказано, что подменить аудиозапись экзамена невозможно.&lt;/p&gt;
  &lt;h3 id=&quot;mDIQ&quot;&gt;Программное обеспечение&lt;/h3&gt;
  &lt;p id=&quot;O6hL&quot;&gt;В моем регионе используется программа Russo, которую я добыл с сайта одного образовательного учреждения&lt;/p&gt;
  &lt;figure id=&quot;gIcC&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d8/4f/d84ff49c-af86-4f57-b0f8-f43af82ca6b2.png&quot; width=&quot;1280&quot; /&gt;
    &lt;figcaption&gt;Главный экран с тестовыми данными&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;i3ZM&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/5a/94/5a94c292-074d-49ef-978c-d7c917f914ce.png&quot; width=&quot;1280&quot; /&gt;
    &lt;figcaption&gt;Экран самого собеседования&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;20oQ&quot;&gt;После нажатия на кнопку программа создает папку и ZIP архив с идентичным названием и содержимым. Структура названия папки/архива: &lt;code&gt;01-ДДММГГГГ-000000-код школы-номер аудитории&lt;/code&gt;.&lt;/p&gt;
  &lt;figure id=&quot;bdYt&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/aa/3a/aa3afc53-0859-47d3-b611-4fed52c65143.png&quot; width=&quot;552&quot; /&gt;
    &lt;figcaption&gt;Содержимое архива&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;7cy4&quot;&gt;В архиве мы можем видеть заголовочный файл и аудиозаписи участников по их порядковым номерам.&lt;/p&gt;
  &lt;h3 id=&quot;Wiv9&quot;&gt;Псевдобезопасность&lt;/h3&gt;
  &lt;p id=&quot;sTW7&quot;&gt;Файлы mp3 мы рассматривать не будем, т.к это самые обычные mp3&amp;#x27;шки. Меня интересует заголовочный csv&amp;#x27;шный файл. Открыв его, мы можем увидеть следующие данные:&lt;/p&gt;
  &lt;figure id=&quot;sAv7&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/8c/03/8c03159b-d0b5-44eb-b6be-1f51746aa07e.png&quot; width=&quot;358&quot; /&gt;
    &lt;figcaption&gt;Содержимое 01-03042023-000000-111111-001.csv&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;pGTn&quot;&gt;Первая строка тут что то вроде magic заголовка, потом на следующей строке идет дата проведения, город, код учреждения, название учреждение, номер аудитории. Потом идет перечисление файлов участников и кол-во участников, я бы хотел остановиться на перечислении файлов. Как мы можем видеть тут записано название файла, дата и время (с точностью до секунд) создания, длина файла и CRC-32 сумма и всё. Лично я считаю, что это не спасает от подмены файлов, ведь можно оставить имя и отметку о создании файла, подменить файл и вписать новую длину и контрольную сумму, которая рассчитывается очень легко.&lt;/p&gt;
  &lt;figure id=&quot;j8my&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/8a/e2/8ae2b934-319d-4c01-99ee-46f4d9d93384.png&quot; width=&quot;712&quot; /&gt;
    &lt;figcaption&gt;Сайт из первой ссылки в гугле&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;IRR9&quot;&gt;Что же делать?&lt;/h3&gt;
  &lt;p id=&quot;F9a0&quot;&gt;Я считаю, что необходимо переработать данную систему и сделать например так, чтобы программа подписывала detached подписью (например тем же ГОСТ&amp;#x27;овским сертификатом &lt;a href=&quot;https://open-dpo.obrnadzor.gov.ru/data/manual/ceritficate_install_man.pdf&quot; target=&quot;_blank&quot;&gt;подписанным УЦ ФРДО&lt;/a&gt;) файл аудиозаписи, а в заголовочный файл можно было бы вносить значение этой самой подписи. Позже при проверке программа бы проверяла подпись на то кем она сделана и сравнивала бы её значение с заголовочным файлом.&lt;/p&gt;

</content></entry></feed>