A SSRF vulnerability in gleezcms 1.20.
If ://
is present in the URL path, GleezCMS will use the cURL library to send a request specified by the attacker.
POC:
https://gleezcms.org/http%3A%2F%2Fwww.google.com
https://gleezcms.org/gopher%3A%2F%2F127%2E0%2E0%2E1%3A9000%2F%5Ftest
This vulnerability is far more dangerous than it looks like because curl supports gopher protocol, which is always used to attack php-fpm, redis, memecached and so on. If these application exists, this ssrf may cause remote code execution.
- In https://github.com/gleez/cms/blob/222a29a3de705ed912492c074447b72c4dd955ff/index.php#L140,
Request::factory
is called.
echo Request::factory()
->execute()
->send_headers()
->body();
- In https://github.com/gleez/cms/blob/222a29a3de705ed912492c074447b72c4dd955ff/modules/gleez/classes/request.php#L197C73-L197C87,
$allow_external
parameter is set toTRUE
by default. This enables support for external proxies in theRequest::__construct
.
public static function factory($uri = TRUE, $client_params = array(), $allow_external = TRUE, $injected_routes = array())
{
//......
Request::$initial = $request = new Request($uri, $client_params, $allow_external, $injected_routes);//
//......
}
public function __construct($uri, $client_params = array(), $allow_external = TRUE, $injected_routes = array())
{
// Initialise the header
$this->_header = new HTTP_Header(array());
// Assign injected routes
$this->_routes = $injected_routes;
// Cleanse query parameters from URI (faster that parse_url())
$split_uri = explode('?', $uri);
$uri = array_shift($split_uri);
// Initial request has global $_GET already applied
if (Request::$initial !== NULL)
{
if ($split_uri)
{
parse_str($split_uri[0], $this->_get);
}
}
// Detect protocol (if present)
// $allow_external = FALSE prevents the default index.php from
// being able to proxy external pages.
if ( ! $allow_external OR strpos($uri, '://') === FALSE)
{
// Remove trailing slashes from the URI
$this->_uri = trim($uri, '/');
// Apply the client
$this->_client = new Request_Client_Internal($client_params);
}
else
{
// Create a route
$this->_route = new Route($uri);
// Store the URI
$this->_uri = $uri;
// Set the security setting if required
if (strpos($uri, 'https://') === 0)
{
$this->secure(TRUE);
}
// Set external state
$this->_external = TRUE;
// Setup the client
$this->_client = Request_Client_External::factory($client_params);
}
}
- Eventually, the specified URL is accessed in
Kohana_Request_Client_Curl::_send_message
.