title: thinkphp审计
date: 2022-09-15 09:57:30
tags:
前言
前几天一直在学习thinkphp
然后跟着b站的博主做了一个小小的demo
接下来就要审一审经过别人二次开发的代码了(因为我代码审计能使实在太差了)
前段时间学长说过一句话 如果学web安全不学开发就是空中楼阁 走不远的
并且我也有隐隐约约的意识到这个 所以还是要学开发的
突然想到一个我之前很搞笑的一个东西 在我还没有学sql的时候我竟然去学了sql注入 去刷了 sqlab
当时真的很懵 啥也不懂 就跟死记硬背差不多了 导致我现在的sql注入学的跟屎一样(其实别的洞也学的不咋地) 代码审计完了之后就去在刷一遍sqlab
好了,就写到这里把 直接开始代码审计
开始审计
index应用 index控制器的index方法
我把这个源码用phpstudy搭起来了
先把目录结构放出来吧
这个里面有我不熟悉的目录
比如extend 和addons 对于刚开始的审计应该没什么太大的干扰把 不过看字面意思应该都是一些扩展插件的意思把
看到应用模块里面有几个应用 之前都是学的单应用的 不过应该也没啥太大的影响吧
index应用(前台应用)
先看index应用把
用于index类继承类base基类
base基类里面有个构造方法 可以直接去直接构造方法 那先看构造方法把
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 控制器初始化
$this->initialize();
}
这个初始化方法利用了对象注入的方式 实例化了一个app类 对象变量为$app
把自己的app属性赋值为了APP对象
自己的request赋值为了app类的request
执行控制器初始化方法
$system为数据库里面一个值为1的数据
妈的说错了
看这个注释应该是查找所有的表数据
这个1应该相当与ture 为真
$appname为当前的应用名 也就是 index
$controllername为当前控制器名称 index
所以$system为数据表里面所有的数据
定义了一些路径把
这里结合数据表来看
这里面请求的是system数据表
里面就一条数据
$this->public = '/template/' . $this->system['template'] . '/' . $this->appName . '/';
这里$this->system['template']为default
所以综上
这个$this->public 为 /template/default/index/
$this->template 为./template/default/index/html/
把base类的初始化方法走完了 接着回到index控制器的index方法
定义了一个view数组
$view = [
'cate' => ['topid' => 0], // 栏目信息
'system' => $this->system, // 系统信息
'public' => $this->public, // 公共目录
'title' => $this->system['title'] ?: $this->system['name'], // 网站标题
'keywords' => $this->system['key'], // 网站关键字
'description' => $this->system['des'], // 网站描述
];
$this->system为数据库的信息
'title'为 空
keyword为SIYUCMS,SIYUCMS内容管理系统,php,ThinkPHP CMS,ThinkPHP建站系统
description为SIYUCMS 是一款基于 ThinkPHP + AdminLTE 的内容管理系统。后台界面采用响应式布局,清爽、极简、简单、易用,是做开发的最佳选择。
$template = $this->template . 'index.html';
$template为。/template/default/index/html/index.html
View::assign($view);
给模板定义了一些变量
$view = [
'cate' => ['topid' => 0], // 栏目信息
'system' => $this->system, // 系统信息
'public' => /template/default/index/, // 公共目录
'title' => "", // 网站标题
'keywords' => ”SIYUCMS,SIYUCMS内容管理系统,php,ThinkPHP CMS,ThinkPHP建站系统“, // 网站关键字
'description' => "SIYUCMS 是一款基于 ThinkPHP + AdminLTE 的内容管理系统。后台界面采用响应式布局,清爽、极简、简单、易用,是做开发的最佳选择", // 网站描述
];
返回到了
return View::fetch($template);
返回到了
/template/default/index/html/index.html这个页面
返回渲染到了主页面
index应用 index控制器的search方法
// 搜索
public function search()
{
$search = Request::param('search'); // 关键字
if (empty($search)) {
$this->error(lang('please input keywords'));
}
$view = [
'cate' => ['topid' => 0], // 栏目信息
'search' => $search, // 关键字
'system' => $this->system, // 系统信息
'public' => $this->public, // 公共目录
'title' => $this->system['title'] ?: $this->system['name'], // 网站标题
'keywords' => $this->system['key'], // 网站关键字
'description' => $this->system['des'], // 网站描述
];
$template = $this->template . 'search.html';
View::assign($view);
return View::fetch($template);
}
$search = Request::param('search'); // 关键字
获取到了search参数
如果search为空的话输出please input keywords
还是定义了一些变量 然后渲染了
/template/default/index/html/search.html页面
index应用 index控制器的tag方法
public function tag()
{
$tag = Request::param('t', '', 'htmlspecialchars');
if (empty($tag)) {
$this->error(lang('please input keywords'));
}
$view = [
'cate' => ['topid' => 0], // 栏目信息
'tag' => $tag, // 关键字
'system' => $this->system, // 系统信息
'public' => $this->public, // 公共目录
'title' => $this->system['title'] ?: $this->system['name'], // 网站标题
'keywords' => $this->system['key'], // 网站关键字
'description' => $this->system['des'], // 网站描述
];
$template = $this->template . 'tag.html';
View::assign($view);
return View::fetch($template);
}
....同样也是渲染一个页面
/template/default/index/html/tag.html页面
然后有一个 留言和验证码的功能
index应用user控制器
// 用户中心首页
public function index()
{
if (!Session::has('user.id')) {
return redirect('login');
}
$user = \app\common\facade\User::getUser($this->userId);
$view = [
'user' => $user,
];
View::assign($view);
return View::fetch();
}
如果不存在user.id从定向到login方法
如果存在post提交数据 进入到了checklogin()函数
验证用户名密码
这里面都是一些注册账号 修改账号密码的操作
啊 好怪 好快这么就把index应用分析完了????这个user控制器确实有点水
不过index应用的控制器确实少
现在来看admin应用
admin应用 index控制器index方法
class Index extends Base
{
// 首页
public function index()
{
// 系统信息
$mysqlVersion = Db::query('SELECT VERSION() AS ver');
$config = [
'url' => $_SERVER['HTTP_HOST'],
'document_root' => $_SERVER['DOCUMENT_ROOT'],
'server_os' => PHP_OS,
'server_port' => $_SERVER['SERVER_PORT'],
'server_ip' => isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '',
'server_soft' => $_SERVER['SERVER_SOFTWARE'],
'php_version' => PHP_VERSION,
'mysql_version' => $mysqlVersion[0]['ver'],
'max_upload_size' => ini_get('upload_max_filesize'),
'version' => App::version(),
'siyu_version' => Config::get('app.siyu_version'),
];
// 查找一周内注册用户信息
$user = \app\common\model\Users::where('create_time', '>', time() - 60 * 60 * 24 * 7)->count();
// 查找待处理留言信息
if (class_exists('\app\common\model\Message')) {
$message = \app\common\model\Message::where('status', '0')->count();
}
// 查找是否有在线留言的模型id
$messageModuleId = \app\common\model\Module::where('table_name', 'message')->value('id');
$messageCatUrl = url('Message/index');
if ($messageModuleId) {
// 查询留言模块第一个栏目ID
$messageCatId = \app\common\model\Cate::where('module_id', $messageModuleId)->value('id');
if (!is_null($messageCatId)) {
// 生成URL
$messageCatUrl = url('Message/index', ['cate_id' => $messageCatId]);
}
}
$view = [
'config' => $config,
'user' => $user,
'message' => $message ?? 0,
'messageCatUrl' => $messageCatUrl,
'indexTips' => $this->getIndexTips(),
];
View::assign($view);
return View::fetch();
}
同样定义了一些变量
$user = \app\common\model\Users::where('create_time', '>', time() - 60 * 60 * 24 * 7)->count();
利用模型 查找了一周内注册用户的数量
// 查找待处理留言信息
if (class_exists('\app\common\model\Message')) {
$message = \app\common\model\Message::where('status', '0')->count();
}
处理过的信息变为了1、
admin应用 index控制器clear方法
public function clear()
{
$path = App::getRootPath() . 'runtime';
if ($this->_deleteDir($path)) {
$result['msg'] = '清除缓存成功!';
$result['error'] = 0;
} else {
$result['msg'] = '清除缓存失败!';
$result['error'] = 1;
}
$result['url'] = (string)url('login/index');
return json($result);
}
admin应用upload控制器
先寻找upload文件上传路由看看有没有存在文件上传漏洞
这里有个上传图片的功能 然后我们具体看抓包看一看它具体是如何进行上传的,这里也可以用debug调试来寻找,但是不着地怎么搞的总是监听不了我笨的的8000端口
所以只能用burp抓包来看具体如何上传文件的
这里可以看到
路径跳转到了 admin/uplaod/index.html里面所以我们就可以去upload控制器里面寻找了
先看构造方法
定义了一些验证规则
public function __construct(App $app)
{
parent::__construct($app);
// 默认上传方式
$this->uploadType = "chunk";
// 验证规则
$this->uploadValidate = [
//如果上传图片的话
////验证规则$file['fileExt'] = 'jpg,png,gif,jpeg';并且限制图片大小
'file' => $this->uploadVal()
];
}
后面定义了上传文件的规则
这里的system为数据库中system表中的所有的信息
进入uploadval函数
private function removeExt(string $ext = '')
{
//将字符串转化成小写
$ext = strtolower($ext);
if (strpos($ext, 'php') !== false) {
$ext = str_ireplace("php", "", $ext);
return $this->removeExt($ext);
}
if (strpos($ext, 'asp') !== false) {
$ext = str_ireplace("asp", "", $ext);
return $this->removeExt($ext);
}
return $ext;
}
这个函数的逻辑就是不能上传php的后缀名
这里它先将后缀名转变为小写
然后利用 str_ireplace函数将php转换为空字符串
所以我们可以利用双写绕过 但是 这里它又调用本身一次 所以这里我们不能利用双写绕过了
标签:审计,index,search,app,system,template,thinkphp,public From: https://www.cnblogs.com/kkkkl/p/16748378.html