2

https://www.vpnmentor.com/blog/critical-vulnerability-gpon-router/

Firstly, the use of 'GPON' I find misleading because this vulnerability is to do with the routers and webservers and not the access network. Someone I know whose PC firewall picked up this attack is on P2P FTTC for instance. It was also a virgin router which is interesting, so not just D-link or Dasan -- which makes sense. I mean the vulnerability was disclosed in 2018 -- is it likely that routers has stateful firewalls before then to filter out this vulnerability from http requests?.

As far as I understand, external port 8080 or port 80 needs to be being forwarded to an internal machine on the network which is running a webserver that is listening on one of those ports. The attacker then uses a (python) script which sends an http request to the victim but with ?images/ appended to the url which appears to be a malformed GET query; this, somehow allows the hacker to execute commands on the server e.g. ls whose result is returned in an http response. How exactly does appending ?images/ achieve this -- can anyone explain how the webserver interprets this such that it leads to the attacker being able to execute code on the server and such that it is returned in an http response.

2

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
.
.
.
0

I don't think this has to do with port forwarding for the following reasons:

  • A web server inside the network wouldn't (normally) have the ability to control the network or device.
  • A malformed URI would be taking advantage of a flaw in the web server, the way that request was routed seems irrelevant given the description.

I also don't think it's relevant whether you write the script in Python. The an HTTP request is just data over the wire. The receiver of the request has no way to know what sent it. There's no mention of Python in the link you provide. As far as I can tell you could do this with a browser.

It's not really clear from the description but I think the vulnerability is in the administration interface of the router. I would not expect a router to default to enable remote administration and/or not have the ability to disable it but perhaps it's GPON that is configuring them this way. Again details in the CVE are slim but that's all I can figure here.

  • Well, it can be done in the Webserver on the router that provides the router interface so that's why it's also speaking about it being a router vulnerability. The vulnerability pertains to having remote management enabled probably. I doubt any home routers would prevent passing it through to a Webserver on the internal network. I've read the source code and I don't know how sending an http request to that url (url_bypass) with that payload causes the command to be executed. github.com/f3d0x0/GPON/blob/master/gpon_rce.py – Lewis Kelsey Feb 23 at 15:13
  • I'm not sure I understand your comment. The first three sentences are just reiterating what I wrote in the answer. If you need me to clarify I can try to reword this. – JimmyJames Feb 25 at 14:12
  • All remote execution vulnerabilities are basically the result of the same design flaw: accepting input data that is then treated as executable instructions. There's nothing magic about it. The developers made a huge, stupid mistake. This one is really egregious and probably the result of laziness. It's really easy for the coders to just pass in commands and not have to bother with writing a proper API. – JimmyJames Feb 25 at 14:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.