Skip to content

Fix TypeError when server closes connection mid-heartbeat read - #913

Open
jbug0x wants to merge 1 commit into
threat9:masterfrom
jbug0x:fix/heartbleed-nonetype-concat
Open

Fix TypeError when server closes connection mid-heartbeat read#913
jbug0x wants to merge 1 commit into
threat9:masterfrom
jbug0x:fix/heartbleed-nonetype-concat

Conversation

@jbug0x

@jbug0x jbug0x commented Aug 23, 2026

Copy link
Copy Markdown

Problem

Running the heartbleed module (directly or via autopwn) against a
target that closes the connection between the SSL record header read
and the heartbeat payload read crashes the scanning thread:

TypeError: can't concat NoneType to bytes

Traceback:
File ".../heartbleed.py", line 312, in get_ssl_record
hdr += data

This happens because get_ssl_record() only checks recv_all() for
None on the header read, not on the payload read. Targets that are
not vulnerable to Heartbleed (or that simply drop the connection)
trigger this.

Fix

Add the same None guard to the second recv_all() call and return
None cleanly instead of letting the concatenation raise.

Testing

Encountered this crash multiple times while running autopwn
against live targets in a lab environment — different targets
closed the connection between the SSL record header read and the
heartbeat payload read, consistently triggering the TypeError and
killing the scanning thread for that target. After applying the
fix, autopwn handles these targets gracefully, reporting them as
not vulnerable instead of crashing.

get_ssl_record() only guarded against tcp_client.recv_all() returning
None for the SSL record header, but not for the heartbeat payload
read that follows. When a target closes the connection (or times
out) between the two reads -- which happens for hosts that are not
vulnerable to Heartbleed -- data comes back as None and 'hdr += data'
raises TypeError: can't concat NoneType to bytes. This crashes the
scanning thread and aborts the autopwn run for that target.

This adds the same None check for the second recv_all() call and
returns None cleanly instead of raising.

Tested against a target that closes the connection after the header
read; the module now reports 'not vulnerable' instead of crashing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant