The answer lies on this page: https://github.com/nixawk/labs/tree/master/CVE-2018-10562
An issue was discovered on Dasan GPON home routers. Command Injection can occur via the dest_host parameter in a diag_action=ping request to a GponForm/diag_Form URI. Because the router saves ping results in /tmp and transmits them to the user when the user revisits /diag.html, it's quite simple to execute commands and retrieve their output.
It now makes sense. It appears that Dasan routers must have a remote management feature that allows the router interface to be accessed externally over port 80/8080 and this is what is vulnerable because certain Dasan routers have a GponForm/diag_Form file which for whatever reason allows for a remote ping functionality and possibly a restricted set of other diagnostic commands. It appears that for ping, there is no sanitisation on the ip to ping, which allows for a command to appended to the end of it. Furthermore, there is also a vulnerability on the router where appending ?images bypasses authentication (checking token of accessor) such that anyone can send the post request.
A request to a webserver running on a machine behind the router will not achieve anything because it is only the Dasan webserver that is vulnerable; it may be still be picked up by WAF however.
The git repository linked at the top of the answer uses a dictionary as its payload, here is the value of the dest_host
key:
payload = "127.0.0.1;\`echo {randflag};{cmd};echo {randflag}`;".format(randflag=randflag, cmd=cmd)
It is clear that the host to ping is not sanitised as it allows for the appension of another command at the end. For some reason echo statements have been used but {cmd}
on its own would have sufficed.
Another source code uses a single string rather than a dictionary for the POST data as it uses requests.Request()
rather than requests.post()
to send the POST request:
payload = 'XWebPageName=diag&diag_action=ping&wan_conlist=0&dest_host=`' + command + '`;' + command + '&ipv=0'
This is similar to the previous example except they have not included an IP to ping and immediately inserted a command to be executed, the command output will hence be used as the target address whereas the previous example would be using 127.0.0.1;commandoutput as the IP to ping.
If I were to write it I would write:
domain = sys.argv[1]
command = sys.argv[2]
url_bypass = domain + '/GponForm/diag_Form?images/'
payload = 'XWebPageName=diag&diag_action=ping&wan_conlist=0&dest_host=127.0.0.1;`command`&ipv=0'
send_command(url_bypass, payload)
In the code above we see a url_bypass
which is the url of the vulnerable diag_Form. A POST request is then sent to that url using the payload as the POST data in the request body which will cause the command to be executed along with the ping command
Finally, Diag.html is visited using requests.get(url)
, which on Dasan routers returns the results of the ping that was performed. Because of the backticks, the command was executed and the output appended to the address as a string meaning it is obviously returned in the ping result as it was interpreted as the address to ping. The backticks are preserved by python2 because they are in quotation marks, hence not converted to repr()
.
for line in response.text.splitlines():
if 'diag_result = "ping -c 4 -s 64' in line:
output = line.replace('\\n', '\n')
break
Which (when "ls /bin/" is the command) looks like this:
diag_result = "ping -c 4 -s 64 127.0.0.1;
Console
EthMgr
GponCLI
GponSLID
.
.
.