phpThumb Server Side Request Forgery
Recently me along with my friend "Deepankar Arora" discovered a server side request forgery vulnerability inside of the phpThumb's latest version. The vulnerability is not inside the script itself, bit it occurs due to the fact that the webmasters do not configure phpThumb properly and also due to the fact that the high security settings were not turned on by default until now, before we talk about the details, let us briefly introduce the readers to SSRF vulnerability.
What is a Server Side Request Forgery?
A server side request forgery is not a single vulnerability, however it represents different classes of vulnerability which includes attacks such as XXE, http response splitting etc. In a server side request forgery an attacker creates forged packets to communicate with the intra/internet by using the vulnerable server as a pivot point. Several other different attacks can be performed, however we will keep it at a basic level so that they can be understood easily.Explanation
The debug mode in phpThumb was introduced for trouble shooting purposes, however the debug mode when turned can result in a server side request forgery. By exploiting it a SSRF vulnerability an attacker may be able to scan local or remote ports, fingerprint services etc.
Let's take a look at the piece of code responsible for fetching an external image:
if ($rawImageData = phpthumb_functions::SafeURLread($phpThumb->src, $error, $phpThumb->config_http_fopen_timeout,
$phpThumb->config_http_follow_redirect)) {
$phpThumb->DebugMessage('SafeURLread('.$phpThumb->src.') succeeded'.($error ? ' with messsages: "'.$error.'"' :
''), __FILE__, __LINE__);
$phpThumb->DebugMessage('Setting source data from URL "'.$phpThumb->src.'"', __FILE__, __LINE__);
$phpThumb->setSourceData($rawImageData, urlencode($phpThumb->src));
} else {
$phpThumb->ErrorImage($error);
}
}
if ($rawImageData = phpthumb_functions::SafeURLread($_GET['src'], $error, $phpThumb->config_http_fopen_timeout,
$phpThumb->config_http_follow_redirect)) {
$md5s = md5($rawImageData);
}
The above code is responsible for fetching an external image file with the "src" parameter. The code doesn't checks if the image retrieved is actually a valid image i.e. .jpg, .png, .gif etc. Therefore, under debug mode set to "True" it would display the error message received from the lower layer network sockets which would enable an attacker to launch a server side request forgery attack.
Furthermore, I noticed that there was a validation being performed for protocols such as file://.
if (preg_match('#^(f|ht)tp\://#i', $phpThumb->src)) {
However, this doesn't prevent this attack completely, as an attacker may be able to leverage other protocols such as gopher://, dict:// etc in order to exploit this vulnerability.
Proof of Concept
http://site.com/phpthumb/phpThumb.php?h=32&w=32&src=http://scanme.nmap.org:22&phpThumbDebug=9 // Open Port
http://site.com/phpthumb/phpThumb.php?h=32&w=32&src=http://scanme.nmap.org:80&phpThumbDebug=9 // Open port
http://site.com/phpthumb/phpThumb.php?
h=32&w=32&src=http://scanme.nmap.org:1337&phpThumbDebug=9 // Closed port
Probing For Open-Port 80
Probing For An Open-Port 22
Probing For a Closed-Port 1337
SSRF Inside-Out
In the similar manner an attacker may be able to leverage this attack to scan ports for the intranet. Following are the most common hosts found on the intranet that is worth looking for.
1) intranet
2) webmail
3) jira
4) helpdesk
5) bugzilla
6) localhost
In case where the debug mode is disabled, the attacker would receive the following error message:
Recommendations
It is recommended to turn off the "debug" mode. The debug mode can be modifying by changing the following lines inside the PHP code.
"$PHPTHUMB_CONFIG['disable_debug']= false;"
With:
"$PHPTHUMB_CONFIG['disable_debug']= true;".
Fix
1) The authors explicitly disabled all other protocols then http/https/ftp protocols. This minimizes few of the attack vectors.
https://github.com/JamesHeinrich/phpThumb/commit/457a37d4a22ac9cdbbfe19577376622e58df81b0
2) The debug_mode has been disabled and the "High Security Mode" has been enabled by default in version phpThumb 1.7.12. Take a look at the author's note:
3) Further security improvements are to be done in the future versions.
Special thanks to "David Vieira-Kurz" from Majorsecurity for his advice on this issue.