In 2023, a serious vulnerability—CVE-2023-29483—was found in two widely-used Python libraries: eventlet (before .35.2) and dnspython (before 2.6.). This flaw exposes web applications to remote attackers who can tamper with DNS name resolution by quickly sending a single, specifically crafted packet. Known in security circles as a “TuDoor” attack, this issue affects software that relies on DNS lookups, potentially redirecting traffic or disabling services. Let’s break down what this vulnerability is, how it works, why it’s dangerous—and see the code that’s affected.
What is the “TuDoor” Attack?
When a program performs DNS lookups, it usually waits for a response from a valid DNS server. Ideally, if it receives an invalid or malformed packet, it should ignore the bad packet and keep waiting the whole timeout period for a good answer, just in case. However, affected versions of eventlet and dnspython stop waiting as soon as they see *any* packet with the correct source (even if it’s invalid). This creates a window for attackers to send a quick, invalid response and disrupt DNS queries—causing service outages, misrouted requests, or even helping further attacks.
Technical Deep Dive
Both eventlet and dnspython had a logic flaw in how they implemented DNS UDP packet handling. When looking up a hostname, they would accept the *first* UDP response from the expected source port/IP—even if the content wasn’t valid.
The victim system makes a DNS query (say, for update.my-app.com).
2. The attacker quickly sends an invalid DNS packet from the right IP/port.
3. The vulnerable resolver gets the bogus packet and stops waiting for a real response, causing the lookup to fail.
Exploit Diagram
Victim App -> Internet -> Attacker
| /
|-------- DNS Query for "example.com" ------/
|<--- Invalid packet from attacker's IP ---|
| (right UDP port, garbage data) |
Fail: Resolver aborts query, never gets the real answer.
Here’s a simplified example of the Python pattern that’s broken
import eventlet
import dns.resolver
def lookup(hostname):
try:
# dnspython uses eventlet's GreenSocket
result = dns.resolver.resolve(hostname)
return result[].address
except Exception as e:
return f"Failed lookup: {e}"
# In the vulnerable setup, ANY packet from the correct IP/port closes the wait.
In the actual vulnerable eventlet code, the “recvfrom” would return as soon as a packet *from the right address* was seen, with no verification that it was a meaningful DNS packet. This is a key logic flaw.
Proof of Concept (PoC) Attack
Attackers can craft a UDP packet that looks like it’s from the DNS server’s IP/port, but contains junk:
import socket
dns_server = ('victim_ip', 53) # The IP of the DNS server the victim expects
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
invalid_data = b'\x00\x00\x00\x00THIS IS NOT A VALID DNS RESPONSE'
s.sendto(invalid_data, dns_server)
If done fast enough (before the legitimate server answers), this bogus packet causes the vulnerable resolver to abort waiting.
Who’s Affected?
- eventlet < .35.2 (get the changelog here)
- dnspython < 2.6. (changelog)
A complicated twist: dnspython 2.6. has a separate bug that made it unusable in many scenarios (fixed in 2.6.1), so upgrade *at least* to 2.6.1 or later.
Real-World Consequences
Why does this matter? Many web apps, SaaS APIs, and microservice platforms use these libraries for behind-the-scenes DNS. If you use eventlet/dnspython for DNS or as a dependency (directly or indirectly), your service could be induced to:
Upgrade dnspython to *2.6.1* or later.
For Linux admins: Ensure you’re not shipping old library versions in containers or virtualenvs.
For developers: Pin your dependencies! Use Pip’s requirements.txt to prevent old versions from sneaking in:
eventlet>=.35.2
dnspython>=2.6.1
Original References and Links
- CVE-2023-29483 on NIST NVD
- dnspython vulnerability advisory
- eventlet Changelog .35.2
- dnspython Changelog
Conclusion
CVE-2023-29483 is a subtle but powerful reminder that network libraries must handle invalid or adversarial input carefully. If you’re using eventlet or dnspython (directly or through popular frameworks), check your version *now* to avoid service outages or worse. A single fast UDB packet from an attacker shouldn't be able to break your DNS resolution—yet that was possible for a long time! Patch your pipeline, educate your team, and stay safe.
*This post is exclusive and written for clarity—feel free to share with your devs and sysadmins. Got questions about this bug or others? Post below!*
Timeline
Published on: 04/11/2024 14:15:12 UTC
Last modified on: 08/27/2024 19:35:04 UTC