网站架构知识点
本文最后更新于:2023年12月14日 下午
参考
mvc
- 🔗博客园、详解:https://www.awaimai.com/128.html
笔记,https://mp.weixin.qq.com/s?__biz=Mzg5MDY2MTUyMA==&mid=2247484899&idx=1&sn=88695ccf7c57ea43f45ae6dc6464de6d&chksm=cfd87a1cf8aff30a2fe6812b27f19e07e4cedcdd08cef51720a0431f08f22e5f4fd896c15579&scene=178&cur_album_id=2058889256642707457#rd
mac cms https://www.cnblogs.com/ichunqiu/p/9548754.html
知识点📂
MVC
关键字
搜索漏洞关键字
但是注意对方可能自己写函数封装
定点挖掘功能点
- 从功能点出发,找功能点对应代码段,进行代码分析
断点测试
- 对访问页面进行断点测试——》执行过程前后顺序,对应的文件列表。。
攻击⚔
seay代码审计
sql注入,搜索SELECT,有变量才有漏洞!,无变量就是写死的
魔术引号绕过
宽字节注入,二次注入(存进的数据是加上,使用数据【修改资料update】的时候产生注入)
二次注入,找功能点,注册用户一类的
文件上传
直接检查后缀比mime靠谱
xdebug断点调试能细分到各个php,而burp抓不到,它只抓网页请求,不管内部调用
对先上传后验证的--》有漏洞,抓包改后缀即可上传php
mvc与thinkphp
- 一个是思想,一个基于此
文件删除
install.lock或访问install.lock.txt会提示重新安装,重新安装=》初始化
对应函数unlink
RCE
- eval,
Metinfo-无框架-变量覆盖-自动审计或搜索
用seay工具审计,双$$可能存在变量覆盖漏洞
重点看配置文件:inc
前端显示界面可能并不是index.php而是在default【模块文件夹】以某个文件如index.html 被index.php包含,修改这个index.html前端就有变化
变量名=【get/post/cookie】参数名时,实现变量覆盖,$request==a $\(request==\)a
配合文件包含进行攻击,控制$file进行攻击 ,上传图片马,file指向图片马√
包含漏洞条件
需要有包含函数+包含的是变量【可控】,而不是固定的字符串【不能更改】
满足用到了(包含了)那个变量覆盖的配置文件
- 1包含2,2包含3 可以说 1包含3
变量覆盖还可以和sql注入搭配使用
phpmydmin-无框架-反序列化-自动审计或搜索
phpmyadmin插件==》管理自己的数据库
TP5知识点
入口文件:即访问网站的文件(首页文件 ):application.php
- 但这是对应的功能文件,若是找美观/页面==》view下对应的html
对应用的所有请求都定向到应用的入口文件
模块:application目录下的,控制器:controller下的,操作==函数(controller下的文件里的函数)、
如何访问参数?
- xiaodi/i/1或者?i=1
- xiaodi/i/1或者?i=1
TP5 自带的mysql写法有过滤,内置安全 ==》【TP 历史漏洞 绕过 过滤】
一般入口文件/index.php/可加可不加
- 入口文件在public/index.php
tp5手册
包含:include==代码包含进去,把任意代码当成php执行,可以任意格式文件
- 无需eval(include),include就能执行包含文件的代码
MVC框架
MVC各部分的职能:
- 模型Model – 管理大部分的业务逻辑和所有的数据库逻辑。模型提供了连接和操作数据库的抽象层。
- 控制器Controller - 负责响应用户请求、准备数据,以及决定如何展示数据。
- 视图View – 负责渲染数据,通过HTML方式呈现给用户。
一个典型的Web MVC流程:
- Controller截获用户发出的请求;
- Controller调用Model完成状态的读写操作;
- Controller把数据传递给View;
- View渲染最终结果并呈献给用户。
大致总结:controller根据请求调用model数据用view呈现出来
MVC框架目录结构
project WEB部署根目录
├─app 应用目录
│ ├─controllers 控制器目录
│ ├─models 模块目录
│ ├─views 视图目录 //例如页头页脚文件+各种要显示功能的文件
├─config 配置文件目录 //数据库连接参数
├─fastphp 框架核心目录
│ ├─base MVC基类/模板目录,数据库增删修改模板在此\db\sql.php
│ ├─db 数据库操作类目录
│ ├─Fastphp.php 内核文件 //规定了路由
├─static 静态文件目录
├─index.php 入口文件
MVC核心文件
入口文件index.php
<?php
// 应用目录为当前目录
define('APP_PATH', __DIR__ . '/');
// 开启调试模式
define('APP_DEBUG', true);
// 加载框架文件
require(APP_PATH . 'fastphp/Fastphp.php');
// 加载配置文件
$config = require(APP_PATH . 'config/config.php');
// 实例化框架类
(new fastphp\Fastphp($config))->run();
DIR
是PHP的魔术常量,表示当前目录的绝对路径
配置文件config.php
作用是定义数据库连接参数参数,以及配置默认控制器名和操作名:
<?php
// 数据库配置
$config['db']['host'] = 'localhost';
$config['db']['username'] = 'root';
$config['db']['password'] = '123456';
$config['db']['dbname'] = 'project';
// 默认控制器和操作名
$config['defaultController'] = 'Item';
$config['defaultAction'] = 'index';
return $config;
核心框架文件fastphp.php
核心代码:路由方法:
// 路由处理
public function route()
{
$controllerName = $this->config['defaultController'];
$actionName = $this->config['defaultAction'];
$param = array();
$url = $_SERVER['REQUEST_URI'];
// 清除?之后的内容
$position = strpos($url, '?');
$url = $position === false ? $url : substr($url, 0, $position);
// 删除前后的“/”
$url = trim($url, '/');
if ($url) {
// 使用“/”分割字符串,并保存在数组中
$urlArray = explode('/', $url);
// 删除空的数组元素
$urlArray = array_filter($urlArray);
// 获取控制器名
$controllerName = ucfirst($urlArray[0]);
// 获取动作名
array_shift($urlArray);
$actionName = $urlArray ? $urlArray[0] : $actionName;
// 获取URL参数
array_shift($urlArray);
$param = $urlArray ? $urlArray : array();
}
// 判断控制器和操作是否存在
$controller = 'app\\controllers\\'. $controllerName . 'Controller';
if (!class_exists($controller)) {
exit($controller . '控制器不存在');
}
if (!method_exists($controller, $actionName)) {
exit($actionName . '方法不存在');
}
// 如果控制器和操作名存在,则实例化控制器,因为控制器对象里面
// 还会用到控制器名和操作名,所以实例化的时候把他们俩的名称也
// 传进去。结合Controller基类一起看
$dispatch = new $controller($controllerName, $actionName);
// $dispatch保存控制器实例化后的对象,我们就可以调用它的方法,
// 也可以像方法中传入参数,以下等同于:$dispatch->$actionName($param)
call_user_func_array(array($dispatch, $actionName), $param);
}
命名空间
php文件开头的 namespace AA;
- 命名空间https://blog.csdn.net/zhanghuiqi205/article/details/84671608?utm_source=app&app_version=4.17.0,其实就是对不同文件各种起名(函数名,对象名)的一块地方汇总,避免不知道哪个是哪个文件的
- 命名空间也有根目录,没有命名空间的默认根目录下
- 空间名我们可以任意的定义,但是如果命名更有意义呢?一般我们会以==类文件所在的文件夹为空间名==。其实主要的就是方便按照某种约定成俗的规则加载文件。==tp5规范命名空间其实对应了文件的所在目录==
路由方法
主要作用:截取URL,并解析出控制器名、方法名和URL参数。
假设我们的 URL 是这样:
yoursite.com/controllerName/actionName/queryString
当浏览器访问上面的URL,route()
从全局变量
$_SERVER['REQUEST_URI']
中获取到字符串/controllerName/actionName/queryString
。
然后,会将这个字符串分割成三部分:controllerName
、actionName
和 queryString
。
例如,URL链接为:yoursite.com/item/detail/1/hello,那么route()
分割之后,
- ControllerName名就是:item
- actionName名就是:detail
- URL参数就是:array(1, hello)
分割完成后,路由方法再实例化控制器:itemController
,并调用其中的detail
方法
。
TP5
==注意! 默认情况下,URL地址中的控制器和操作名是不区分大小写的,因此下面的访问其实是等效的:/index/与/INDEX/==
目录结构
|-application 应用目录(代码的主要编写区,几乎整个项目的内容都写在这里)
|-index(这里的文件夹tp5叫做模块-----一般是前台模块,也可以根据需要需求修改成其他(例如:home),需要修改配置文件,修改默认模块、控制器、操作) 【注】:TP5默认只有一个index文件(模块)和一个控制层(conrroller),我们在写代码的时候会自己新建一个model和view,这样就组成了这个Index模块儿的MVC(controller控制层,model模型层,view视图层),如需后台(一般来说都需要),则需要新建一个后台模块(admin)
|-controller(控制层)
|-model(模型层)
|-view(视图层)
|-admin(后台模块)
|-controller(控制层)
|-model(模型层)
|-view(视图层)
|- command.php 是控制台的配置文件,当我们用命令行执行thinkphp的时候,它会读取command.php的配置
|- common.php 它是项目的公共文件,当我们编写一些通用函数的时候,比如我们写一个函数,想在所有的模块儿中都能调用,那么我们就可以把函数写在改文件中,它就可以注册到全局,在任何地方都可以调用
|- config.php 它是应用的配置文件,整个应用都读取这个配置,也就是admin模块儿和index模块儿会通用这个配置
|- database.php 它是数据库配置文件,如果我们需要连接数据库,那么我们只需要修改database.php的配置就可以了
|- route.php 它是路由文件,当我们想对URL进行美化,那么我们就可以修改此文件,对其增加一些路由配置,就可以达到美化的效果
|- tags.php 它是应用行为扩展文件,在thinkphp中,它为我们埋下了很多钩子,我们可以对框架进行扩展,而不需要修改框架本身的源码,我们需要在某一个钩子上注册某些函数,或者是注册某些行为,来通过行为来改变框架的执行流程
|-extend 扩展类库目录,这个目录是我们下载第三方库时候使用的,当然我们不是通过composer来下载的,比如说我们有一个第三方库,我们用着比较好用,但是它没有composer包,我们就可以将类库下载到extend目录,之后我们修改一下命名空间,就可以直接在我们的应用中使用
|-publiic 我们网站(WEB)的根目录,也就是说我们网站根目录下所有的这些文件都是允许访问的
|-static 主要用来放静态文件,比如说css,js,图片等等
|-index.php 整个网站或整个应用的入口文件,所有的请求都会经过index.php之后再去转发
|-router.php 它是框架快速启动的测试文件,比如你本地没有安装Apache,只安装了PHP,那么我们可以同过,PHP内置的workserver来启动,通过这个文件,我们就可以启动这个框架
|-runtime 它是网站运行中的缓存文件,它包括日志,缓存和编译文件等等。
|-thinkphp 它是框架文件,也就是说thinkphp5的框架都在里边
|-lang 里边是语言包
|-library 目录是框架的核心,它里边有think(它是整个框架的核心文件)和traits(它是类库的扩展)两个目录
|-think Think 类库包目录
|-traits 系统 Traits 目录
|-tpl 是我们框架默认的一些模板(了解知识)
|-default_index.tpl 它是我们自动生成的控制器模板文件
|-dispatch_jump.tpl它是我们网站发出成功或失败的中间跳转文件
|-page_trace.tpl它是我们调试时显示的模板文件
|-think_exception.tpl它是我们抛出异常时页面展示的文件
|-base.php 定义一些常量
|-console.php 它是控制台的入口文件
|-convention.php 是框架惯例配置文件
|-help.php 助手函数
|-start.php是框架启动文件
|-vendor 是composer安装过程中生成的目录,通过composer安装的所有类库都被安装在了这个目录中。
- application
application文件夹是TP5框架的应用层,是代码的主要编写区,你写的大部分工程代码都要在这里写,比如控制器层,服务层等
- public
public就是TP5框架默认的最先读取文件夹,里面的index文件定义了应用目录路径和框架引导文件路径【public/index.php入口文件】,一些默认页面也在这里。
入口文件位置的设计是为了让应用部署更安全,
public
目录为web可访问目录,其他的文件都可以放到非WEB访问目录下面。
- thinkphp
thinkphp就是TP5的核心框架代码,里面就是TP5框架的第一方类库,支持整个TP5框架的运行规则。
- runtime
runtime是用来存放一些写入文件的,比如说日志文件、缓存文件等等。
- extend
extend是用来存放一些你自己下的第三方类库的,在此目录下的第三方类库的命名空间可以直接访问
- vendor
vendor也是用来存放第三方类库的,和extend不一样的是,这个目录是存放通过composer命令来安装的第三方类库的默认路径
访问入口文件
- 入口文件:即访问网站的文件(首页文件 )【但这是对应的功能文件,若是找美观/页面==》view下对应的html】
没有指定模块、控制器、操作的话,将会访问默认文件
如果我们直接访问入口文件的话,由于URL中没有模块、控制器和操作,因此系统会访问默认模块(index)下面的默认控制器(Index)的默认操作(index),因此下面的访问是等效的:
http://tp5.com/index.php
http://tp5.com/index.php/index/index/index
==对应用的所有请求都定向到应用的入口文件==
模块:application目录下的,控制器:controller下的,操作==函数(controller下的文件里的函数)function
比如我们在 WWW.php下新建方法test
访问http://localhost/tp5/public/index.php/index/index/test
【此时没有隐藏入口文件】
隐藏入口文件
原:http://localhost/tp5/public/index.php/index/index/hello
修改/public/目录下.htaccess文件,phpstudy配置的话,修改倒数第二行为RewriteRule ^(.*)$ index.php?s=$1 [QSA,PT,L]
即可隐藏入口文件index.php,后直接访问http://localhost/tp5/public/index/index/hello即可
如何访问参数?
1. 方法/i/1
或者方法?i=1
- 多个参数?
PATHINFO 模式是一种url访问方式:
http://域名/项目名/入口文件/模块名/方法名/键1/值1/键2/值2
普通访问方式如下:
http://域名/项目名/入口文件?m=模块名&a=方法名&键1=值1&键2=值2
当开启了顺序绑定之后,不能使用普通方式访问。
// 按照参数顺序获取
'url_param_type' => 1,
eg:自动获取URL地址中的同名参数值作为方法的参数值,而且这个参数的传入顺序不受URL参数顺序的影响
index.php/index/index/hello/name/bob/city/shanghai
index.php/index/index/hello/city/shanghai/name/bob
index.php/index/index/hello?city=shanghai&name=bob
URL的参数传值方式就变成了严格按照操作方法的变量定义顺序来传值了,也就是说我们必须使用下面的URL地址访问才能正确传入name
和city
参数到hello
方法
http://tp5.com/index.php/index/index/hello/bob/shanghai
此时hello/name/thinkphp/city/shanghai和?=都不行
路由
路由配置文件 application/route.php
路由配置的作用:URL地址里面的index模块怎么才能省略呢,默认的URL地址显得有点长,下面就来说说如何==通过路由简化URL访问==
return [
// 添加路由规则 路由到 index控制器的hello操作方法
'hello/:name' => 'index/index/hello',
// 路由参数name为可选:
'hello/[:name]' => 'index/hello',
//以$结尾的时候就表示当前路由规则需要完整匹配。/hello/thinkphp // 正确匹配,/hello/thinkphp/val/value // 不会匹配
'hello/[:name]$' => 'index/hello',
];
该路由规则表示所有hello开头的并且带参数的访问都会路由到index控制器的hello操作方法。
路由之前的URL访问地址为
http://tp5.com/index/index/hello/name/thinkphp
定义路由后就只能访问下面的URL地址,变量name值为thinkphp
http://tp5.com/hello/thinkphp
==⚠定义路由规则后,原来的URL地址将会失效,变成非法请求。==
- 闭包定义
还支持通过定义闭包为某些特殊的场景定义路由规则(大致意思就是路由匹配到这些就会执行函数),例如:
return [
// 定义闭包
'hello/[:name]' => function ($name) {
return 'Hello,' . $name . '!';
},
];
或者:
Route::rule('hello/:name', function ($name) { //参数$name就是url中定义的变量。
return 'Hello,' . $name . '!';
});
因此,当访问http://tp5.com/hello/thinkphp 会输出 Hello,thinkphp!
路由设置
<?php
namespace app\index\controller;
class Blog
{
public function get($id)
{
return ’查看id=‘ . $id . ’的内容‘;
}
public function read($name)
{
return ’查看name=‘ . $name . ’的内容‘;
}
public function archive($year, $month)
{
return ’查看‘ . $year . ’/‘ . $month . ’的归档内容‘;
}
}
博客文章采用 CC BY-SA 4.0 协议 ,转载请注明出处,有疑问欢迎联系:)