The vulnerability (CVE-2014-4956) allows an attacker to execute JS code (the system utilizes Node.js) at a vulnerable GenieACS server, resulting in complete server compromise.
GenieACS is an open sourced implementation of an ACS (Auto Configuration Server) written in Node.js. It is popular in the ISP industry as a convenient way of cheaply implementing the TR-069 protocol.
Note: This vulnerability was found back in 2014, as part of my work at Check Point’s Research group.
This is the first time the details are released publicly.
V0.x.x – V1.0.0
GenieACS provides a REST API interface in order for the GUI front-end to communicate with the server back-end.
One of the features this API is offering to unauthenticated users is listing the names of the devices connected to the ACS. In order to properly filter the results, GenieACS allows the use of a query string, with the character ‘*’ treated as a wild card.
Upon receiving the request, the server compiles a regex string based on the user query string. Then, the system uses an “eval” call in order to execute this regex query on the list of device names.
This can be seen here:
return eval('/^' + user_query + '$/')
Of course, inserting user input into an “eval” call is never a good idea, even if it’s inside a string deceleration, as an attacker can simply escape it and append his own code to the statement.
GenieACS developers tried to defend against this kind of attack by replacing every occurrence of a character they considered dangerous – such as the “/” (slash) character used in order to escape the regex query, or the “;” (semicolon) character used in order to append more commands to the code.
The developers accomplished that by using the following code:
user_query = user_query.replace(/[\[\]\\\^\$\.\|\?\+\(\)]/, "\\$&amp;amp;")
Therefore, code execution can be achieved by sending the following request:
GET /devices?query=["./;require('util').log('lolzor');//*"] HTTP/1.1
At the end of the query the string “//*” is appended in order to force the rest of the regex query to be parsed as a comment, allowing our code to be executed without any syntax errors.
After sending this one-liner HTTP request (No headers are necessary), “lolzor” will be added to the system’s log. Obviously, binaries can be executed using the class ‘child_process’ and its method ‘exec’, which allows us to fully exploit our Unauthenticated Remote Code Execution.
This simple vulnerability shows you can never trust user input in dangerous functions, even if it appears you have already validated it.