XerCMS-1.0.3代码审计(文件名报错注入后台getshell)

链接:https://share.weiyun.com/6b98e41d036967178e1a21fb88ed340f (密码:YnNY)

文件名报错注入

index.php?m=member&a=upfiles&id=2

在这个文件夹中XerCMS\Modules\member\index.php

前台注册个用户 在头像上传处抓包reperter一下用mysql监控工具

发现有insert数据库操作 分析一下

跟进upfiles函数

   public function upfiles() {
          setformat(‘json‘);
          $config = ini(‘member/group/‘.X::$G[‘group‘]);
          if(empty($config)) {
               exit(‘Access Denied‘);
          } else {
               if($config[‘upload‘][0] == 0) {
                    error(‘upload_group_limit‘);
               } else if($config[‘upload‘][1] != 0 && X::$G[‘upload‘] > $config[‘upload‘][1]) {
                    error(‘upload_group_size‘);
               }
          }
          $id = int1(g(‘id‘));
          c(‘upload‘)->load($id);
          $image = ini(‘image‘);
          if(isset($image[‘status‘]{2})) {
               c(‘upload‘)->config[‘thumbs‘] = array(array(‘width‘=>$image[‘width‘],‘height‘=>$image[‘height‘],‘cut‘=>$image[‘cut‘],‘quality‘=>$image[‘quality‘]));
          } else {
               if(isset(c(‘upload‘)->config[‘thumbs‘])) unset(c(‘upload‘)->config[‘thumbs‘]);
          }
          c(‘upload‘)->files();
          c(‘upload‘)->show();
     }

通过c(‘upload‘)->files()完成上传操作

跟进一下files函数/XerCMS/Library/XerCMS_upload.php

    function files() {
            foreach($_FILES as $k=>$v) {
            $this->file($k);
        }
    }

继续跟进file函数

    function file($name) {
        if(isset($_FILES[$name][‘tmp_name‘]) && !empty($_FILES[$name][‘tmp_name‘])) {
            $ext = $this->ext($_FILES[$name][‘name‘]);
               if(in_array(strtolower($ext),$this->forbid) || preg_match(‘/([^a-z0-9])/i‘,$ext,$match)) {
                    $this->result[$name][‘error‘] = ‘Ext‘;return;
               }
            if(!empty($this->config[‘maxsize‘]) && $_FILES[$name][‘size‘] > $this->config[‘maxsize‘]) {
                $this->result[$name][‘error‘] = ‘Size‘;return;
            }
              $rid = $this->record($_FILES[$name]);
            $this->dir($this->config[‘path‘],$rid,$ext);
            if(is_uploaded_file($_FILES[$name][‘tmp_name‘])) {
                    if(move_uploaded_file($_FILES[$name][‘tmp_name‘],$this->name($rid)) == false) {
                         $this->delrid($rid);
                         $this->result[$name][‘error‘] = ‘Move‘;return;
                    } else {
                     //chmod($this->name($rid),0644);
                }
                if($this->config[‘local‘] == ‘0‘) {
                        if(!REMOTE::upload($this->name($rid),$this->name($rid),$this->config[‘remote‘],$this->config[‘mode‘])) {
                             $this->delrid($rid);@unlink($this->name($rid));
                             $this->result[$name][‘error‘] = $this->config[‘mode‘];return;
                        }
                   }
                //if($helper != null) {
                    $files = $this->handle($this->name($rid),$ext);
                    if($files != null && $this->config[‘local‘] == ‘0‘) {
                         foreach($files as $file) {
                                if(!REMOTE::upload($file,$file,$this->config[‘remote‘],$this->config[‘mode‘])) {
                                     $this->delrid($rid);
                                     $this->result[$name][‘error‘] = ‘extra‘;
                                break;
                                }
                        }
                        if(!empty($this->result[$name][‘error‘])) {
                             foreach($files as $file) {
                                 @unlink($file);
                            }
                             return;
                        }
                    }
                //}
               }
            $this->result[$name][‘host‘] = $this->config[‘host‘];
               $this->result[$name][‘path‘] = $this->name($rid);
               $this->setPath($rid,$this->result[$name][‘path‘]);
        } else $this->result[$name][‘error‘] = ‘Tmp‘;
    }
var $forbid = array(‘php‘,‘asp‘,‘aspx‘,‘vbs‘,‘bat‘,‘asa‘);

后缀利用的是黑名单 可以进行php3 php5 绕过 这里不是重点

继续跟进一个record函数

     function record($upfile) {
        if (X::$G[‘uid‘]) {
               DB::add(‘xercms_member_count‘,array(‘upload‘=>$upfile[‘size‘]),array(‘uid‘=>X::$G[‘uid‘]));
        }
          DB::insert(‘xercms_member_upfiles‘,
             array(‘uid‘=>X::$G[‘uid‘],
                ‘size‘=>$upfile[‘size‘],
                ‘name‘=>$upfile[‘name‘],
                ‘time‘=>X::$G[‘time‘],
                ‘ip‘=>X::$G[‘ip‘],
                ‘type‘=>$this->cid));
          return DB::lastid();
     }

可以看出有个insert操作

而前面的函数传参是文件本来的文件名

 $rid = $this->record($_FILES[$name]);

而且这套cms并没有进行全局过滤

所以导致了注入

static function insert($table,$fields) {
     if (empty ($fields)) {
          return ;
     }
     foreach ($fields as $k=>$v) {
          $content[] = ‘`‘ .DB::filter($k, ‘f‘ ).‘` = \‘‘.DB:: filter($v).‘\‘‘ ;
     }
     self ::query( ‘INSERT INTO ‘ .$table.‘ SET ‘.implode( ‘,‘,$content), self ::$connect );
     return self ::lastid();
}

其中filter函数还有一点过滤

    static function filter($str,$t = ‘‘) {
        $str = (string)$str;
        switch($t) {
            case ‘f‘:
                return preg_replace(‘/([^a-z0-9_])/i‘,‘‘,$str);
              break;
              default:
                    return trim($str,‘\\‘);
              break;
        }
      }

针对key 将不是字母和数字还有下划线的其他字符替换成了‘‘,而对value只是过滤了\,所以是可以造成注入的,接下来跟进query方法

开启了报错 导致了可以报错注入

文件名1‘ or updatexml(1,concat(0x7e,(version())),0) or ‘.jpg" 看返回

时间: 2024-07-31 17:05:56

XerCMS-1.0.3代码审计(文件名报错注入后台getshell)的相关文章

Druid “loopWaitCount 0, wait millis 6001” 报错

今天总结下自己使用Druid遇到的一个错误"loopWaitCount 0, wait millis 6001" 报错信息: Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException:  Could not get JDBC Connection; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException:  loopW

cocos2d-js 3.0 rc0 编译release报错 value for keystore is not valid. it must resolve to a single path

第一次编译是好好的,需要手工输入keystore文件地址和密码等等.第二次不需要输入,然后就直接出错了.   找了一下,发现第一步之后,cocos会记录ant信息到\frameworks\runtime-src\proj.android\ant.properties   打开这个文件发现: key.store=e:\cocos_projects\android.keystore 斜杠都少了一个,只需要改为 key.store=e:\\cocos_projects\\android.keystor

appium在android 7.0真机上运行报错command failed shell:............ps:'uiautomator"的解决方式

appium版本:1_4_16 在CSDN中找到相关解决的方案,根据此解决方案顺利的解决了让人惆怅的问题,再次记录. 1.找到appium安装目录下的adb.js文件,目录为:Appium\node_modules\appium\node_modules\appium-adb\lib 2.打开adb.js,可使用notepad++编辑器等打开文件(说明:在修改代码的时候先注释掉以前的代码,并且添加自己容易识别的标记,以防出错后还有回旋的余地,或者将代码备份也可行),找到如下代码: ADB.pro

关于Code Blocks无编译器版本及VC6.0插入、打开报错

CodeBlocks运行C成功,编译C++一直报错:fatal error:stdlib.h:no such file or directory.下载重装了几次Code Blocks无编译器版本以及MINGW.看了很多教程,并不能解决问题.据说是版本对不上,于是重置电脑,安装带有编译器的版本成功运行.至于具体原因有待探究. 另VC6.0插入.打开报错,微软官方之前给出了相应插件,不过现已失效.使用百度引擎找到免费.便捷的链接并不容易.为了方便大众,现将链接附上. https://pan.baid

i春秋——“百度杯”CTF比赛 十月场——Vld(Vulcan Logic Dumper 、php opcode、sql 报错注入)

打开题目看到提示 "do you know Vulcan Logic Dumper?" ,再查看源码看到"<!-- index.php.txt ?>",访问后发现一堆看不懂的东西 这肯定就是所谓的Vulcan Logic Dumper了,先了解下相关概念 PHP内核-Zend引擎:http://www.php.cn/php-weizijiaocheng-355597.html PHP中的opcode:https://blog.csdn.net/weiyu

使用insert、update和delete报错注入

使用insert注入 1.原理 一般我们写SQL注入的过滤器的话,重点关注的关键词就是select了,因为这个关键字可以从数据库中查询信息.所以一旦这个函数杯过滤,并且无法通过其他方法进行绕过的话,注入工作可能会变得比较困难. 如果在有用户注册的页面的话,后台SQL语句会有类似insert出现,例如 insert into user(id,name,pass) values (1,"tony","123456"); 这里是可以进行报错注入的.主要就是用到了两个Mys

SQL报错注入的十余种注入方式

报错注入原理: 由于rand和group+by的冲突,即rand()是不可以作为order by的条件字段,同理也不可以为group by的条件字段. floor(rand(0)*2) 获取不确定又重复的值造成mysql的错误 floor:向下取整,只保留整数部分,rand(0) -> 0~1 本地环境搭建数据库测试注入姿势: mysql> create database sqli; mysql> create table user ( id int(11) not null auto_

【菜鸟学注入】之MySQL报错注入详解

本文转自:http://bbs.blackbap.org/forum.php?mod=viewthread&tid=6483&highlight=mysql%2B报错注入 用SQL注入获取数据库数据,利用的方法可以大致分为联合查询.报错.布尔盲注以及延时注入,通常这些方法都是基于SELECT查询语句中的SQL注射 点来实现的.如果涉及非SELECT查询的注入,我们通常用到的就是mysql注入查询 创建一个test表 USE test; CREATE TABLE test(num int(5

mysql报错注入手工方法

以前觉得报错注入有那么一长串,还有各种concat(),rand()之类的函数,不方便记忆和使用,一直没怎么仔细的学习过.这次专门学习了一下,看了一些大牛的总结,得到一些经验,特此记录下来,以备后续巩固复习. 总体来说,报错注入其实是一种公式化的注入方法,主要用于在页面中没有显示位,但是用echo mysql_error();输出了错误信息时使用. 公式具体如下 and(select 1 from(select count(*),concat((select (select (select co