SMF fgets off-by-one issue and filter size evasion
SMF fgets off-by-one issue and filter size evasion
Author: Jose Carlos Norte
Discovered by: Jose Carlos Norte
Risk: Medium
Type: DoS
Version: ALL
1. Introduction
Simple machines forum is a popular scalable free bulletin board system written
in php over mysql database, the url of the project:
http://www.simplemachines.org/
2. The problem
Smf can allow the users to have a remote avatar, this avatar is shown in the
topics where the user send messages.
The problem is that smf checks the remote avatar for test if the size is in a
valid range.
>From Sources/Subs.php (1578 yo 1069):
function url_image_size($url)
{
// Get the host to pester...
preg_match('~^\w+://(.+?)/(.*)$~', $url, $match);
// Can't figure it out, just try the image size.
if ($url == '' || $url == 'http://' || $url == 'https://')
return false;
elseif (!isset($match[1]))
return @getimagesize($url);
// Try to connect to the server... give it one full second.
$temp = 0;
$fp = @fsockopen($match[1], 80, $temp, $temp, 1);
// Successful? Continue...
if ($fp != false)
{
// Send the HEAD request.
fwrite($fp, 'HEAD /' . $match[2] . ' HTTP/1.1' . "\r\n" .
'Connection: close' . "\r\n" . 'Host: ' . $match[1] . "\r\n\r\n");
// Read in the HTTP/1.1 or whatever.
$test = substr(fgets($fp, 11), -1);
fclose($fp);
// See if it returned a 404/403 or something.
if ($test < 4)
return @getimagesize($url);
}
// Didn't work.
return false;
}
a remote server is modified, can send false values to head requests, and a
999999999999x9999999999 will bypass the filter,
aditionally, if the server don't do any response against head requests, php
script will stop in fgets until php kill it,
on time_limit, the result is that any topic where the malicious user send a
message becomes unreadable for all users.
3. SOlution
changue function to:
function url_image_size($url)
{
return false;
}
and don't try to check the size of remote images!
I was unable to contact smf developer team, again.