Exploit-DB #4768
Description: Shadowed Portal 5.7d3 - Remote Command Execution
Type: webapps
Platform: php
Date: 2007-12-21
Author: The:Paradox

Exploit:
#!/usr/bin/python
#-*- coding: iso-8859-15 -*-
'''
 ____            __________         __             ____  __   
/_   | ____     |__\_____  \  _____/  |_          /_   |/  |_ 
 |   |/    \    |  | _(__  <_/ ___\   __\  ______  |   \   __\
 |   |   |  \   |  |/       \  \___|  |   /_____/  |   ||  |  
 |___|___|  /\__|  /______  /\___  >__|            |___||__|  
          \/\______|      \/     \/                           
------------------------------------------------------------------------------------------------
This is a Public Exploit. 21/12/2007 (dd-mm-yyyy)
------------------------------------------------------------------------------------------------
ÃÂ§ Shadowed Portal 5.7 and maybe lower - Remote Command Execution Vulnerabilities ÃÂ§
Vendor:	  http://www.shad0wed.com
Severity: Highest
Author:	  The:Paradox

Visit inj3ct-it.org

Proud to be Italian.
------------------------------------------------------------------------------------------------
Related Codes:

-- control.php; line 1:

<?php

require("config.php");

require("globals.php");

require("functions.php");

require("variables.php");

$return = setvar("return");

if($act == "login") {

$online = 0;

$usr = $_POST['usr'];

$pwd = $_POST['pwd'];

if(file_exists($root."/users/".strtolower($usr).".php")) {

require($root."/users/".strtolower($usr).".php");

}

-- globals.php; line 1:

<?php

define('CHECK',md5("null"));

global $viv;

global $mod;

global $act;

global $do;

global $act;

global $id;

global $tp;

global $w;

global $method;

global $board;

global $user;

global $pass;

global $cat;

global $linkback;

global $HTTP_POST_VARS;

global $_GET;

global $_POST;

global $_FILES;

global $HTTP_REFERER;

global $_SERVER;

-- /modules/fs/mod.php; line 1:

<?php

if(!defined('CHECK')) { exit; }

-- /modules/fs/mod.php; line 277:

if($do == "_upload") {

echo <<<HTML

<table width="100%" $sp_table>

<tr $sp_htr><td align="center" $sp_htd>FS: Upload</td></tr>

<tr $sp_ctr><td $sp_ctd>

HTML;

if($ls == $login_session) {

$err = 0;

$id = make_code(50);

$product = alter($_POST['product']);

$publisher = alter($_POST['publisher']);

$category = alter($_POST['category']);

$product_website = alter($_POST['product_website']);

$description = alter($_POST['description']);

$ext = substr(strrchr($_FILES['upload']['name'],"."),1);

if(blankc($_FILES['upload']['name'],"Upload")) { $err = 1; }

if(blankc($product,"Product")) { $err = 1; }

if(blankc($category,"Category")) { $err = 1; }

if(blankc($description,"Description")) { $err = 1; }

if($_FILES['upload']['size'] > FS_MAX_SIZE) { derr("File is too large. Limit: ".$fs_max_size); $err = 1; }

if($fs_ext_allow != "") {

$arr = explode(",",$fs_ext_allow);

$err = 1;

foreach($arr as $single) {

if(strtolower($ext) == strtolower($single)) { $err = 0; }

}

if($err == 1) { derr("File extension ($ext) is not allowed. Extensions allowed are: ".str_replace(",",", ",$fs_ext_allow));  }

}

else {

$arr = explode(",",$fs_ext_unallow);

foreach($arr as $single) {

if(strtolower($ext) == strtolower($single)) { derr("File extension ($single) is not allowed."); $err = 1; }

}

}

if($err == 0) {

if(move_uploaded_file($_FILES['upload']['tmp_name'],$mod_root."/uploads/".$id)) {

$fs_files = "";

require($root."/users/".strtolower($usr).".php");

$fs_files .= "||" . $id;

$name = basename($_FILES['upload']['name']);

$author = $usr;

$date_posted = $date;

$downloads = 0;

$rating = 0;

if($u_rank >= $rank_required['mod_admin']) {

$access = alter($_POST['access']);

}

else {

$access = 0;

}

define('FS_WRITE',"edit");

require($mod_root."/fs_file.php");

wf($mod_root."/files/".$id.".php","w",$fs_file);

require($root."/user_info.php");

wf($root."/users/".strtolower($usr).".php","w",$user_info);

echo <<<HTML

File successfully uploaded.<br />

<div align="center">

(<a href="$mod_url&do=view&id=$id">View File</a>)<br />

(<a href="$mod_url&do=manage">Manage Uploads</a>)<br />

(<a href="$mod_url&do=upload">Upload Another File</a>)<br />

</div>

HTML;

}

else { derr("Failed to upload file."); }

}

}

else { derr("Bad session."); }

echo <<<HTML

</td></tr>

</table>

HTML;

}

------------------------------------------------------------------------------------------------
Bug Explanation:

This Portal presents a vulnerability in the "login system" that allows us to require a page ".php" in the directory "/users/" (whatever using directory transversal ("../") we can require any page).

Additionally "Check" was defined by the required page globals.php, allowing us to bypass the "security-die" on the top of most php page (see /modules/fs/mod.php; line 1).
In this exploit we will require "/modules/fs/mod.php" to be able to upload files.
The uploader is secure but mod.php creates a "description file" of the upload, in this file the $access variabile is not correctly filtered.

Normally that var could be given only by administrators ($u_rank >= $rank_required['mod_admin']) but in our particular case $rank_required['mod_admin'] has no values (Because the "first require trick" has skipped some includes) , and a $variable_with_value is always > $variabile_without_value.

We will insert malicious php code in it, and get command execution. Whatever the "description page" won't be directly accessible, but there is no problem for us: just require it through control.php again =D (To make RCE easier, in the exploit i will create an accessibile php page in the "/" path).
------------------------------------------------------------------------------------------------
The require in control.php is extremely unsafe, it could be used with other pages to obtain other vulnerabilities.
----------------------------------------------------