代码审计之YIXUNCMS

在代码审计中,看懂有问题的代码其实很简单,难的是如何从一套源码中找到那个有问题的点。每个人都有一套自己的审计方法,有的人喜欢从入口着手,通读整套系统源码,逐步排查;有的人喜欢直接找输入输出交互点,简单粗暴。我喜欢在本地搭建测试环境,用黑盒+白盒的思维来找出漏洞。
一、编辑模版getshell
发现后台修改模版处没有对$path和$filename做限制,造成任意文件编辑。


代码审计之YIXUNCMS_第1张图片
1.png

利用如下:修改要编辑的文件名


代码审计之YIXUNCMS_第2张图片
2.png

测试phpinfo()
代码审计之YIXUNCMS_第3张图片
3.png

代码审计之YIXUNCMS_第4张图片
4.png

利用成功。可以通过对路径与文件名后缀进行过滤来修补此问题

二、插配置文件getshell
在/classes/baseset.class.php中,69到124行定义了改下配置文件函数,但是并没有对用户的输入进行过滤,通过构造,可以getshell

static function writeConfig($post){
            $confile=PROJECT_PATH."config.inc.php";
            $configText = file_get_contents($confile);
            self::writeindex($post['appStyle'], $post['cstart']);
            
            $reg=array(
                    "/define\(\"CTIME\".+?;/i",
                    "/define\(\"APP_NAME\".+?;/i",
                    "/define\(\"APP_ENAME\".+?;/i",
                    "/define\(\"KEYWORD\".+?;/i",
                    "/define\(\"DESCRIPTION\".+?;/i",
                    "/define\(\"ICP\".+?;/i",
                    "/define\(\"COPY\".+?;/i",                  
                    "/define\(\"ARTICLE_PAGE_SIZE\".+?;/i",     
                    "/define\(\"PHTURE_PAGE_SIZE\".+?;/i",      
                    "/define\(\"HOME_COLUMN_SIZE\".+?;/i",      
                    "/define\(\"HOME_COLUMNPAGE_SIZE\".+?;/i",      
                    "/define\(\"POSITION\".+?;/i",
                    "/pictureSize\s*=\s*.+?;/i",    
                    "/thumbSize\s*=\s*.+?;/i",  
                    "/bannerSize\s*=\s*.+?;/i",
                    "/playSize\s*=\s*.+?;/i"    
                );
            $rep=array( 
                    "define(\"CTIME\", \"{$post['ctime']}\");",
                    "define(\"APP_NAME\", \"{$post['appname']}\");",
                    "define(\"APP_ENAME\", \"{$post['eappname']}\");",
                    "define(\"KEYWORD\", \"{$post['keyword']}\");",
                    "define(\"DESCRIPTION\", \"{$post['description']}\");",
                    "define(\"ICP\", \"{$post['icp']}\");",
                    "define(\"COPY\", \"{$post['copy']}\");",                   
                    "define(\"ARTICLE_PAGE_SIZE\", \"{$post['articlePageSize']}\");",
                    "define(\"PHTURE_PAGE_SIZE\", \"{$post['photoPageSize']}\");",
                    "define(\"HOME_COLUMN_SIZE\", \"{$post['homecolumnsize']}\");",
                    "define(\"HOME_COLUMNPAGE_SIZE\", \"{$post['homecolumnpagesize']}\");",
                    "define(\"POSITION\", \"{$post['position']}\");",
                    "pictureSize = array('maxWidth' => {$post['maxWidth']}, 'maxHeight' => {$post['maxHeight']});",
                    "thumbSize = array('width' => {$post['width']}, 'height' => {$post['height']});",
                    "bannerSize = array('bwidth' => {$post['bwidth']}, 'bheight' => {$post['bheight']});",
                    "playSize = array('pwidth' => {$post['pwidth']}, 'pheight' => {$post['pheight']});"
                );
            
            if(isset($_FILES["water"])) {
                $water=self::changeWater();
                if($water) {
                    $img="/define\(\"WATER\"\s*,\s*\"(.+?)\"\);/i";
                    preg_match($img, $configText, $arr);
                    $srcimg=PROJECT_PATH."public/uploads/".$arr[1];
                    if(file_exists($srcimg))
                        unlink($srcimg);
                    $reg[] = $img;
                    $rep[] = "define(\"WATER\",\"{$water}\");";
                }       
            }
            return file_put_contents($confile, preg_replace($reg, $rep, $configText));
        }

在版权出插入 ");?>define("a", "asdas
那么写进去后的文件就是


clipboard1.png

闭合成功,该CMS几处涉及到修改配置文件的函数都没有考虑到这个问题,实际利用中将phpinfo改为file_put_content即可getshell


代码审计之YIXUNCMS_第5张图片
clipboard2.png

修补方法,建议将写入文件的数据用addslashes转义。

三、任意文件下载、删除
在/admin/controls/databak.class.php中

//删除数据文件
        function del(){
            $filename = $_GET['file'];
            $dirname=PROJECT_PATH.'databak/'.$filename;
            unlink($dirname);
            $this->filelist();
            $this->mess("删除成功",true);
            $this->display("index");            
        }
        
        //下载数据文件
        function dow(){
            $filename=PROJECT_PATH.'databak/'.$_GET['file'];
            header("Content-disposition:filename=".$_GET['file']);
            header("Content-type:application/octetstream");
            header("Content-Length:".filesize($filename));
            header("Pragma:no-cache");
            header("Expires:0");
            readfile($filename);
        }

del()与dow()均未对$filename做出限制,导致任意文件下载和删除,此CMS所有涉及到文件下载和删除的地方均是如此。但是在利用上却有个问题,即导航的链接地址,格式为“/模块名/操作名/参数/值”,也就是说如果将文件名改为../config.inc.php,会导致系统识别参数失败。目前,我尚未找到控制识别url导航的代码。

四、安装文件SQL注入

$insert="INSERT INTO ".TABPREFIX."user(gid,username, userpwd, email,regtime) VALUES('1','".$user["ADMIN_USER"]."', '".md5($user["ADMIN_PWD"])."','".$user["ADMIN_MAIL"]."','".time()."')";
            
            if(mysql_query($insert)){
                $this->info.='添加管理员用户'.$user["ADMIN_USER"].'成功!
'; }else{ $this->info.='添加管理员用户'.$user["ADMIN_USER"].'失败!'; mysql_close(); return false; }

insert注入,可以使用admin' or updatexml(1,concat(0x7e,(version())),0) or'来报错注入,但是本环境测试失败,admin' or sleep(5) or'延时注入测试成功,虽然都没什么实际意义。

你可能感兴趣的:(代码审计之YIXUNCMS)