# Talos Vulnerability Report
### TALOS-2022-1578
## Robustel R1510 web_server /action/import_authorized_keys/ OS command injection vulnerability
##### October 14, 2022
##### CVE Number
CVE-2022-34850
##### SUMMARY
An OS command injection vulnerability exists in the web_server /action/import_authorized_keys/ functionality of Robustel R1510 3.1.16 and 3.3.0. A specially-crafted network request can lead to arbitrary command execution. An attacker can send a sequence of requests to trigger this vulnerability.
##### CONFIRMED VULNERABLE VERSIONS
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
Robustel R1510 3.1.16
Robustel R1510 3.3.0
##### PRODUCT URLS
R1510 –
##### CVSSv3 SCORE
9.1 – CVSS:3.0/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
##### CWE
CWE-78 – Improper Neutralization of Special Elements used in an OS Command (OS Command Injection)
##### DETAILS
The R1510 is an industrial cellular router. It offers several advanced software features like an innovative use of Open VPN, Cloud management, data over-use guard, smart reboot and others.
The R1510s web_server offers an API to add, for the logged users, the SSH authorization keys.
Here is the `/action/import_authorized_keys/` API that manages the imports of the SSH authorization keys:
void /action/import_authorized_keys/(Webs *webs)
{
[…]
memset(admin_ssh_folder,0,0×40);
user_username = uci_get(“user_management.username”);
snprintf(admin_ssh_folder,0x40,”/home/%s/.ssh”,user_username);
iVar1 = dir_exists(admin_ssh_folder);
if (iVar1 == 0) {
sysprintf(“mkdir -p %s”,admin_ssh_folder);
sysprintf(“chmod 700 %s”,admin_ssh_folder);
}
iVar1 = scaselessmatch(webs->method,”POST”);
if (iVar1 != 0) {
for (current_file = (WebsKey *)hashFirst(webs->files); current_file != (WebsKey *)0x0;
current_file = (WebsKey *)hashNext(webs->files,current_file)) {
sysprintf(“cp -rf “%s” %s/authorized_keys”,
((current_file->content).WebsUpload)->temp_filename,admin_ssh_folder); [1]
}
}
[…]
}
This function will fetch the admin-chosen username, create the `/home//.ssh` folder and set the right permissions for it. Then it will iterate over the requests files and import those using the instruction at `[1]`. This instruction uses the `sysprintf` function that will first execute the `vsnprintf` function with the provided arguments, then use the output as argument for the `system` function. So, the instruction will copy the uploaded file from the temporary upload location to the `/home//.ssh/authorized_keys` folder, executing `cp -rf “” /home//.ssh/authorized_keys`.
The web_server offers the possibility to change the admin username. The API responsible to do so is `/ajax/webs_uci_set_super_user/`:
undefined4 /ajax/webs_uci_set_super_user/(Webs *webs)
{
[…]
new_username = websGetVar(webs,”new_username”,0);
is_not_empty = string_is_not_empty(new_username);
if ((is_not_empty == 0) ||
(does_not_match = string_reg_verify(new_username,
“^[a-zA-Z0-9@\#\.\$\*\!][a-zA-Z0-9@\#\.\$\*\!\-]{4,32 }$”
), does_not_match == 0)) { [2]
old_password = websGetVar(webs,”old_password”,0);
is_error = string_reg_verify(old_password,
“^[a-zA-Z0-9@\#\.\$\*\!][a-zA-Z0-9@\#\.\$\*\!\-]{4,32}$ “
);
if (is_error == 0) {
new_password = websGetVar(webs,”new_password”,0);
is_error = string_reg_verify(new_password,
“^[a-zA-Z0-9@\#\.\$\*\!][a-zA-Z0-9@\#\.\$\*\!\-]{4,32 }$”
);
if (is_error == 0) {
current_password = uci_get(“user_management.password”);
is_error = string_matched(old_password,current_password);
if (is_error == 0) {
websWrite(webs,”{name: “%s”, reason: “%s”}”,”old_password”,”not match”);
}
else {
is_error = string_is_not_empty(new_username);
if (((is_error == 0) ||
(is_error = uci_set(“user_management.username”,new_username), is_error == 0)) && [3]
(is_error = uci_set(“user_management.password”,new_password), iVar1 == 0)) {
res = “OK”;
[…]
}
This function will take the requests `new_username` parameter and checks at `[2]`, if it is in a valid format. The same goes for the password parameters. Then, at `[3]`, the `new_username` is committed as the new one.
Because the `new_username` valid format is `^[a-zA-Z0-9@\#\.\$\*\!][a-zA-Z0-9@\#\.\$\*\!\-]{4,32 }$`, it is allowed to use special characters that can be interpreted in the unix shell. So, crafting a specific admin username and then using the `/action/import_authorized_keys/` API would lead to a command injection at `[1]`.
##### TIMELINE
2022-07-13 – Vendor Disclosure
2022-10-14 – Public Release
##### Credit
Discovered by Francesco Benvenuto of Cisco Talos.
* * *
Vulnerability Reports Next Report
TALOS-2022-1580
Previous Report
TALOS-2022-1577Read More