download newest firmware
This is the firmwares download locations for the latest development versions, all of which contain the vulnerabilities described in this article.
https://www.dcnetworks.com.cn/ruanjian.html?title=dcme
influence range
- DCME-720-9.1.5.11
- DCME-520-9.25.5.11
- DCME-520-9.1.5.11
- DCME-320-9.3.5.26 (DCME-320-L/(DCME-320 r2)
- DCME-320-7.4.12.90 (DCME-320/(DCME-320 r1)
test enviroment
Since this is a backend RCE vulnerability, it wasn’t feasible to test network assets within legal boundaries. I purchased a second-hand DCME-320 online,
as it uses a system similar to the DCME-320-L/DCME-520/DCME-720. Unfortunately, I couldn’t (and didn’t have sufficient funds to) purchase the latter two models, so I could only perform a code audit on them (later I discovered the code is largely similar).
I used Ngrok for public network mapping to simulate real conditions as closely as possible. You may notice that the Ngrok mapping address in the report varies slightly; this is because it sometimes crashes, requiring an address change. In fact, the mapping remains consistent except for the first four characters. The format is always https://XXXX-218-19-14-194.ngrok-free.app/.“
What’s more,these below are all rce after login,please login first so that you can recur the vuln(default password:admin/admin,and i can help you to build a remote recur enviroment by ngrok if you need)
the ngrok address:
https://f0e6-218-19-14-194.ngrok-free.app
it will run at these time
1.【RCE】mon_stat_hist.php
Vuln point
/function/audit/newstatistics/mon_stat_hist.php
Vuln analysis
just let statset equal to “predef_sess_ip” or “predef_bw_if” to enter the danger function:getPrint()
user controlable args:
statset(case control)
type_name(rce place)
type(if condiction control)
control the statset we need to entry the case
then,let the first arg “$time_type”,which is delivered by $type,equal to “5mins”,so that we can manipulate the exec() function’s arg1,so it is RCE.
eth_to_pppoe define is below.Obviously it will not interupt our rce vuln using
replace_interface define is below.Obviously it will not interupt our rce vuln using
EXP
?statset=predef_sess_ip&type=5mins&type_name=|[command concatenation]|
after test i find that it is no need to submit &type=5mins,lol:
https://[website address]/function/audit/newstatistics/mon_stat_hist.php?statset=predef_sess_ip&type_name=aaa ;echo ”>>proof15.php;
Successfully wrote to proof15.php in the current path, confirming that the echo command was indeed executed.
2.【RCE】mon_stat_hist_new.php
Vuln point
/function/audit/newstatistics/mon_stat_hist_new.php
Vuln analysis
we can simply submit “inter” or “app” to control the exec words in this case,
and in fact,the time_type is no need to be 5mins,because of the else brench also have exec
replace_interface define is below.Obviously it will not interupt our rce vuln using
EXP test
/function/audit/newstatistics/mon_stat_hist_new.php?type=5mins&inter=;echo test16>>/usr/local/www/proof16.txt;
3.【RCE】license_update.php
Vuln point
/function/system/basic/license_update.php
Vuln analysis
You may encounter this prompt at the very beginning.
But this is the logic after exec, which actually doesn’t need to be considered. Also, it actually won’t restart, because it won’t reach that logic.
EXP test
Then, how should the data packet be constructed?
Although the vulnerability point is in /function/system/basic/license_update.php,
you can actually first go to /function/system/basic/license_list.php to trigger a request, allowing the system to automatically construct a valid request packet for us.
Just select any file, then capture the packet. Here, the request packet can be modified and replayed.
Then, modify the file name to a malicious command execution string. For example, here, for vulnerability verification, the file name is changed to:
aaa ;echo ‘<? phpinfo()?>’>>proof18.php;
then we sussessed in writing evil file:p
proving that we can eval any code
4.【RCE】mgmt_edit.php【320r1 has stricter checks, but after bypassing them, the validation was still successful.】
Vuln point
/function/system/basic/mgmt_edit.php
Vuln analysis
Below is the code for DCME 320r2/520/720.
However, in 320r1, the upload() function includes a check_tag() that complicates the exploitation process. We’ll continue the discussion of the exploitation based on this, as it has broader applicability—an exploit that works on 320r1 will certainly work on 320r2/520/720 as well.
Following up with
config.php in the same folder, you’ll find that
check_tag actually splits the following content (for illustration purposes only, with MD5 written randomly).
#device=Router123
#description=Q29uZmlndXJhdGlvbiBmb3Igcm91dGVy
#DCFOSversion=MS4wLjA=
#md5Value=5d41402abc4b2a76b9719d911017c592
#user=admin
#createtime=2024-10-08 12:00:00
#position=DataCenter1
#file_size=7
Later, a for loop function will be used to extract the content after each # one by one, with tmp_tip as the variable name and tmp_val as the value. file_size must equal a number. The logic within the red box means that the value of the last line (file_size) must be a number; otherwise, it will return false, causing the exploitation to fail.
md5Value is the MD5 hash of the file, and it must be correct. The following code:
It turns out that this function checks if the file content actually matches the recorded MD5 hash. Therefore, the bypass approach is that, first, the format needs to be correct, and then the MD5 hash must be forged to match the correct value. This way, the uploaded file will meet the requirements. Fortunately, we don’t need to figure out the forging step ourselves; simply exporting a real configuration will do. This way, the requirements of the check_tag() function are guaranteed to be met.
EXP test
get to /function/system/basic/mgmt_edit.php,you will see
press “选择文件”(select file)and use tools(such as burp) to catch the file uploading web request
Next, change the filename to a malicious command execution string. For example, to validate the vulnerability, change the filename to:
aaa ;echo ‘<? phpinfo()?>’>>proof19.php;
5.【RCE】traceroute.php
Vuln point
/function/system/tool/traceroute.php
Vuln analysis
First, a Mycontrol class instance will be created, and then the
actionList function defined within the class will be executed.
And during the class construction and execution of actionList, we can manipulate certain parameters.
Observe the switch branch,
exec_cmd() performs some filtering on user input; however, fetch_msg() still contains an injection vulnerability.
EXP test
Just go to the
/function/system/tool/traceroute.php
(Files created in this directory are renamed, so their content isn’t visible, but the file creation was indeed successful)
and submit:
|echo proof20 > /usr/local/www/proof20.txt|
then press:”执行”,it will excute the evil command,and we can see the file have been writed in web root
6.【RCE】mon_stat_top10.php
Vuln point
/function/audit/newstatistics/mon_stat_top10.php
Vuln analysis
In some branches, such as ‘predef_sess_app_zone’, ‘predef_bw_ip_zone’, and so on, we can control the second parameter of the fetch_data function.
This PHP file imports config.php from the same folder. Note that it has the same filename as another vulnerable config.php file but a different path,
located at /function/audit/newstatistics/config.php.
Further investigation reveals that the second parameter of the
fetch_data() method here has potential for command injection exploitation.
EXP
?statset=predef_sess_app_zone&if_value=;echo ‘test21’>>/usr/local/www/proof21.txt;
it will excute the evil command,and we can see the file have been writed in web root