Exploit-DB #8958
Description: TorrentTrader Classic 1.09 - Multiple Vulnerabilities
Type: webapps
Platform: php
Date: 2009-06-15
Author: waraxe

Exploit:
[waraxe-2009-SA#074] - Multiple Vulnerabilities in TorrentTrader Classic 1.09
===============================================================================

Author: Janek Vind "waraxe"
Date: 15. June 2009
Location: Estonia, Tartu
Web: http://www.waraxe.us/advisory-74.html


Description of vulnerable software:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

TorrentTrader is a feature packed and highly customisable PHP/MySQL Based
BitTorrent tracker. Featuring integrated forums and plenty of administration
options. Please visit www.torrenttrader.org for the support forums.

http://sourceforge.net/projects/torrenttrader 


List of found vulnerabilities
===============================================================================

1. Sql Injection vulnerability in "account-inbox.php"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Reasons:
  1. unsanitized user submitted parameter "origmsg" is used in sql query
Preconditions:
  1. attacker must be logged in as valid user

Test:

http://localhost/torrenttrader109/account-inbox.php?msg=1&receiver=waraxe&origmsg=foobar&delete=yes

Result: "MYSQL Error has occurred!"

-----------------------------[source code start]-------------------------------
if ($msg) {
  $msg = trim($msg);

  $res = mysql_query("SELECT id, acceptpms, notifs, email, UNIX_TIMESTAMP(last_access) as la FROM users WHERE username=".sqlesc($receiver)."");
  $user = mysql_fetch_assoc($res);
  if (!$user)
    $message = "Username not found.";
...

    if ($origmsg && $delete == "yes")
       mysql_query("DELETE FROM messages WHERE id=$origmsg") or sqlerr();
-----------------------------[source code end]---------------------------------


2. Weak password generation algorithm in "account-recover.php"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Reasons:
  1. generated password is weak and can be easily bruteforced
Preconditions:
  1. attacker must know email address associated with target's account

Torrenttrader contains password reseting functionality:

http://localhost/torrenttrader109/account-recover.php

Anyone can initiate password reset, only condition is, that target's email
address must be know. Torrenttrader will check email address and after successful
validation new, temporal password will be generated and sent to that email address.
Specific autogenerated password appears to be random number between 10000 and 50000,
so basically there can be only 40000 possible temporal passwords. It's easy to
write bruteforce script, which will try all possible password combinations.
This process can take couple of hours or more, but eventually the password will
be guessed and target account becomes compromised.

-----------------------------[source code start]-------------------------------
if ($HTTP_SERVER_VARS["REQUEST_METHOD"] == "POST") {
  $email = trim($_POST["email"]);
  if (!validemail($email)) {
	$msg = "" . NOT_VAILD_EMAIL . "";
	$kind = "Error";
  }
  else {
	  $res = mysql_query("SELECT * FROM users WHERE email=" . sqlesc($email) . " LIMIT 1");
	  $arr = mysql_fetch_assoc($res);

	  if (!$arr) {
	    $msg = "" . EMAIL_INVALID . "";
	    $kind = "Error";
	  }
...
	  if ($arr) {
	  	$newpassword = rand(10000, 50000);
	  	$md5pass = md5($newpassword);
-----------------------------[source code end]---------------------------------


3. Unauthorized database backup vulnerability in "backup-database.php"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Reasons:
  1. missing access control
Preconditions:
  1. mysqldump utility must be available
  2. gzip utility must be available
  3. target directory must be writable
  4. database name must be known in order to successfully guess archive filename

Test:

http://localhost/torrenttrader109/backup-database.php

Resulting message: "Database backup successful, entry inserted into database."

-----------------------------[source code start]-------------------------------
system(sprintf(    
  'mysqldump --opt -h %s -u %s -p%s %s | gzip > %s/%s/%s-%s-%s-%s.gz',                                    
  $host,
  $user,
  $pass,
  $db,
  getenv('DOCUMENT_ROOT'),
  $backupdir,
  $db,
  $day,
  $month,
  $year
 )); 
-----------------------------[source code end]---------------------------------

Attacker is able to create database backup and resulting "gz" archive's
filename can be guessed, if attacker knows database name. This file is also
directly downloadable from website. Example download URI:

http://localhost/torrenttrader109/backups/torrenttrader109-10-06-2009.gz

As result information leakage exists. For example, attacker can fetch admin
credentials from backed up database.


4. Sql Injection vulnerability in "browse.php"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Reasons:
  1. uninitialized variable "wherecatin" is used in sql query
Preconditions:
  1. none

Test:

http://localhost/torrenttrader109/browse.php?wherecatin=waraxe

Result:

Unknown column 'waraxe' in 'where clause'

-----------------------------[source code start]-------------------------------
if (count($wherecatina) > 1)
$wherecatin = implode(",",$wherecatina);
elseif (count($wherecatina) == 1)
$wherea[] = "category = $wherecatina[0]";
...
if ($wherecatin)
$where .= ($where ? " AND " : "") . "category IN(" . $wherecatin . ")";

if ($where != "")
$where = "WHERE $where";

$res = mysql_query("SELECT COUNT(*) FROM torrents $where") or die(mysql_error());
-----------------------------[source code end]---------------------------------

This specific sql injection vulneraility can be exploited using blind attack
methods. If there is one or more active torrents in database, then usable is
attack pattern below:

http://localhost/torrenttrader109/