Skip to content
Longterm Wiki
Back

demonstrated creating a fully AI-generated exploit for CVE-2025-32433

web

A concrete case study relevant to AI uplift in offensive cybersecurity; illustrates how frontier LLMs can accelerate exploit development, a key concern in AI risk and governance discussions around dual-use capabilities.

Metadata

Importance: 62/100blog postprimary source

Summary

A security researcher demonstrates using GPT-4 to autonomously generate a functional exploit for a critical Erlang/OTP SSH vulnerability (CVE-2025-32433) before any public proof-of-concept code was released. The AI identified the vulnerable commit, diffed patched vs. unpatched code, located the flaw, and iteratively debugged a working exploit. This serves as a concrete real-world example of AI-assisted offensive security research.

Key Points

  • GPT-4 independently identified the vulnerable code diff between Erlang SSH 5.2.9 and 5.2.10 and wrote a functional exploit with minimal human guidance.
  • The AI not only wrote the initial PoC but also debugged and fixed it when it failed, demonstrating iterative autonomous offensive capability.
  • The exploit was produced before any public PoC existed, compressing the typical vulnerability-to-exploit timeline significantly.
  • CVE-2025-32433 is a critical unauthenticated RCE vulnerability in Erlang/OTP SSH, making this a high-stakes demonstration of AI uplift.
  • Demonstrates that AI tools can lower the skill threshold for exploit development, raising concerns about democratization of cyberattack capabilities.

Cited by 1 page

PageTypeQuality
Cyberweapons RiskRisk91.0

Cached Content Preview

HTTP 200Fetched Apr 7, 202611 KB
How I Used AI to Create a Working Exploit for CVE-2025-32433 Before Public PoCs Existed | PlatformSecurity cd ../blog How I Used AI to Create a Working Exploit for CVE-2025-32433 Before Public PoCs Existed

 Vulnerability Research Matthew Keeley Apr 17, 2025 7 min read Writing the Proof of Concept for CVE-2025-32433

 Let's go on a little journey.

 I'm drinking my coffee, scrolling through Twitter, and there it is — this tweet from Horizon3:

 👉 https://x.com/Horizon3Attack/status/1912945580902334793 

 They've got a proof of concept for CVE-2025-32433. They say it was "surprisingly easy." But they didn't drop the code. Hmm.

 Naturally, I thought: If it's that easy… can AI just write it for me?

 🤖 AI-Driven Exploits?

 Turns out — yeah, it kinda can.

 GPT-4 not only understood the CVE description, but it also figured out what commit introduced the fix, compared that to the older code, found the diff, located the vuln, and even wrote a proof of concept. When it didn't work? It debugged it and fixed it too.

 Let's walk through how I got there.

 📸 The Initial Clue

 The first thing I did was grab the python output code in Horizon's animated GIF. It wasn't much, but it felt useful to hand to GPT.

 Horizon3 Tweet 
 A little nudge in the right direction never hurts.

 📎 Finding the Versions

 Next up: I checked out the official Erlang advisory on GitHub to find both an affected version and a patched one.

 Affected and Patched Versions 
 I knew I'd want to diff these versions. So I gave GPT this basic prompt, and here's what it spat out:

 ❯ 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/
 
 It even explained what was happening in each step. Helpful! At this point, I had two snapshots: ssh_5_2_9 (vulnerable) and ssh_5_2_10 (patched). Time to diff.

 🔍 diff.py — Our Code Archaeologist

 GPT gave me this small but mighty Python script to recursively diff the two versions:

 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]) a

... (truncated, 11 KB total)
Resource ID: 2f29463c92fb1ee1 | Stable ID: sid_pb8pYH8nbf