A remote code execution vulnerability has been discovered in GoAhead web server version prior to 3.6.5. The issue stems from the ability to configure environment parameters for GoAhead CGI scripts via an HTTP request. An attacker can exploit this vulnerability to achieve remote code execution. In this post we will discuss how this vulnerability can be exploited and how Qualys detects vulnerable targets on the network.
Vulnerability
As mentioned earlier GoAhead accepts an HTTP request to initialize envp
for the new process. This operation is handled by cgiHandler
.
After which launchCgi
fork’s and executes the CGI script using execve
and uses the values in envp
. Essentially the parameters received via HTTP can indirectly affect the execution flow of the CGI script. So an attacker can tinker with theses parameters especially the ones that are user controlled, trusted etc. In our case apart from REMOTE_HOST and HTTP_AUTHORIZATION the remaining parameters are trusted and forwarded to envp
array without filtering.
As it so happens some envp
parameters affect the way ELF dynamic linker execution, which affects any process that is using the dynamic linker. One such parameter is LD_PRELOAD
which is a list of user-specified ELF shared objects that are loaded before others. So by setting LD_PRELOAD
parameter in the HTTP request we can inject our own shared objects in to GoAhead’s address space. At this point we can inject our shared objects in to GoAhead, the next step would be to execute code. To achieve this we can set .init and .fini sections of our (to be injected) shared object. The function in .init section will be executed before main and the functions in .fini will be executed before main returns.
Exploitation
To achieve code execution remotely, we look in to launchCgi
, this function calls dup2()
to duplicate the stdin file descriptor. This is a temporary file that contains the body of the HTTP POST request, we can abuse this behavior to place our payload on the target file system.
Now that the payload is placed on the target we can use LP_PRELOAD
to inject it in to GoAheads address space. The payload must contain proper .init
and .fini
sections this enables it to execute before main()
.
A PoC is available online. It checks if CGI scripting is enabled and proceeds to send a payload to the target and sends an HTTP POST request with LD_PRELOAD
pointing to the uploaded payload. The payload gets executed when launchCgi
executes the CGI script.
Fix
The issue was fixed in cgi.c
. Any special parameter listed in the HTTP request are skipped and the remaining parameters have been prefixed with CGI_
.
Mitigation
Upgrade GoAhead server to version 3.6.5 or later and scan your network using QID 11894 to detect vulnerable machines. The QID sends a test module to /cgi-bin/cgitest
and /cgi-bin/index.cgi
, vulnerable targets will respond with “qualysrce” in the HTTP header.
Please continue to follow Qualys Threat Protection from information on this vulnerability
References
REMOTE LD_PRELOAD EXPLOITATION
GoAhead Fix