PHP代码审计——ThinkPHP基础

admin 2023年5月21日01:19:43评论22 views字数 6260阅读20分52秒阅读模式

一、ThinkPHP概述

1. ThinPHP是一个轻量级的PHP框架,旨在提供快速开发Web应用程序的工具和资源。它采用了MVC(Model-View-Controller)架构,使开发人员可以更好地组织和管理代码。ThinPHP还提供了许多有用的功能,如路由、数据库抽象层、模板引擎等,使开发人员可以更快地构建Web应用程序。相比其他PHP框架,ThinPHP的优点在于它的轻量级和易用性。它的代码库非常小,因此可以快速下载和安装。它支持多种数据库(MySQL、PostgreSQL、SQLite等),同时还支持多种模板引擎(Smarty、Twig等)。此外,它还具有强大的缓存机制和安全性,提供了一些内置的安全功能,如防止SQL注入、XSS攻击、CSRF攻击等。

2. MVC是一种常见的软件设计模式,用于将应用程序分为三个主要组件:模型、视图和控制器。在ThinkPHP中,MVC是框架的核心,它使开发人员可以更好地组织和管理代码。 

    • 模型是应用程序的数据层,用于处理与数据库交互的所有操作。在ThinkPHP中,模型通常是一个继承自thinkModel类的PHP类。模型类包含与数据库表对应的属性和方法,例如find、save和delete等方法。 

    • 视图是应用程序的表示层,用于呈现数据和用户界面。在ThinkPHP中,视图通常是一个包含HTML和PHP代码的模板文件。模板文件可以使用模板引擎来动态生成HTML代码,例如ThinkPHP的内置模板引擎ThinkTemplate。 

    • 控制器是应用程序的业务逻辑层,用于处理用户请求并返回响应。在ThinkPHP中,控制器通常是一个继承自thinkController类的PHP类。控制器类包含与用户请求对应的方法,例如index、login和register等方法。当用户发出请求时,控制器将根据请求的URL调用相应的方法,并将结果返回给用户。控制器还可以使用模型来访问数据库,并使用视图来呈现数据和用户界面。


3. 在MVC模式下,Web程序的功能通常在控制器部分实现。控制器是应用程序的业务逻辑层,用于处理用户请求并返回响应。它们是MVC架构的一部分,用于将应用程序的业务逻辑与其表示层分离。控制器通常包含与用户请求对应的方法,例如index、login和register等方法。当用户发出请求时,控制器将根据请求的URL调用相应的方法,并将结果返回给用户。控制器还可以使用模型来访问数据库,并使用视图来呈现数据和用户界面。因此,控制器是Web程序中实现功能的关键部分。这也说明,MVC模式的应用程序,其漏洞也通常在控制器下产生

二、ThinkPHP的目录结构与入口文件

1. 初始目录结果如下

www  WEB部署目录(或者子目录)  ├─application           应用目录  │  ├─common             公共模块目录(可以更改)  │  ├─module_name        模块目录  │  │  ├─config.php      模块配置文件  │  │  ├─common.php      模块函数文件  │  │  ├─controller      控制器目录  │  │  ├─model           模型目录  │  │  ├─view            视图目录  │  │  └─ ...            更多类库目录  │  │  │  ├─command.php        命令行工具配置文件  │  ├─common.php         公共函数文件  │  ├─config.php         公共配置文件  │  ├─route.php          路由配置文件  │  ├─tags.php           应用行为扩展定义文件  │  └─database.php       数据库配置文件  ├─public                WEB目录(对外访问目录)  │  ├─index.php          入口文件  │  ├─router.php         快速测试文件  │  └─.htaccess          用于apache的重写  ├─thinkphp              框架系统目录  │  ├─lang               语言文件目录  │  ├─library            框架类库目录  │  │  ├─think           Think类库包目录  │  │  └─traits          系统Trait目录  │  │  │  ├─tpl                系统模板目录  │  ├─base.php           基础定义文件  │  ├─console.php        控制台入口文件  │  ├─convention.php     框架惯例配置文件  │  ├─helper.php         助手函数文件  │  ├─phpunit.xml        phpunit配置文件  │  └─start.php          框架入口文件  ├─extend                扩展类库目录  ├─runtime               应用的运行时目录(可写,可定制)  ├─vendor                第三方类库目录(Composer依赖库)  ├─build.php             自动生成定义文件(参考)  ├─composer.json         composer 定义文件  ├─LICENSE.txt           授权说明文件  ├─README.md             README 文件  ├─think                 命令行入口文件
    • router.php用于php自带webserver支持,可用于快速测试

    • 切换到public目录后,启动命令: php -S localhost:8888  router.php

    • 上面的目录结构和名称是可以改变的,这取决于你的入口文件和配置参数。

2. ThinkPHP的入口文件为public/index.php,实际部署网站的时候对外的访问目录为public,它负责处理所有进入应用程序的Web请求。每个请求都必须经过该文件进行路由和分发。以下是该文件的基本结构:

<?php  define('APP_PATH', __DIR__ . '/../app/');  //定义应用程序运行时目录路径  define('RUNTIME_PATH', __DIR__ . '/../runtime/');  //加载框架的入口文件  require __DIR__ . '/../thinkphp/start.php';
    • 第一行定义了应用程序根目录的路径。默认情况下,该路径设置为public目录的父目录,即应用程序的根目录。 

    • 第二行定义了应用程序运行时目录的路径。该目录用于存储框架生成的缓存文件和日志文件等运行时数据。这一行代码有可能没有。

    • 第三行加载框架的入口文件。该文件包含了所有必要的类和函数,以及自动加载器和错误处理程序等功能。 

    • 在入口文件加载完成后,它会调用框架核心的启动程序thinkApp::run()方法。该方法负责初始化应用程序,并将请求传递给路由处理程序进行路由匹配和分发。路由和分发过程完成后,应用程序执行对应的控制器和动作方法,并输出结果。

三、ThinkPHP的调试模式

1. 在应用程序的配置文件config/app.php中,修改debug选项为true,修改app_trace选项为true:

'debug' => true,
'app_trace' => true,

2. 然后当我们访问一个不存在或不正确的路由时,就会出现如下报错界面

PHP代码审计——ThinkPHP基础

四、ThinkPHP的URL访问模式

1. ThinkPHP在没有启用强制路由的情况下的典型访问URL为

http://serverName/index.php(或者其它应用入口文件)/模块/控制器/操作/[参数名/参数值...]

2. 支持切换到命令行访问,如果切换到命令行模式下面的访问规则是

php.exe index.php(或者其它应用入口文件) 模块/控制器/操作/[参数名/参数值...]

3. ThinkPHP5取消了URL模式的概念,普通的URL模式访问不再被支持,但参数可以通过普通URL模式传递

php.exe index.php(或者其它应用入口文件) 模块/控制器/操作?参数名=参数值&..
http://serverName/index.php(或者其它应用入口文件)?s=/模块/控制器/操作/[参数名/参数值...]

五、ThinkPHP的控制器

1. ThinkPHP的控制器是用于处理用户请求并返回响应的重要组成部分。它们是MVC架构的一部分,用于将应用程序的业务逻辑与其表示层分离。

    • ThinkPHP的控制器负责处理请求并将响应数据返回给客户端。控制器是一个类,它继承了框架的基础控制器类。每个控制器都映射到一个URL路由,并包含一组动作方法来处理不同的请求。当请求发送到特定路由时,相应的控制器和动作方法将被调用。 

    • 在控制器中,开发者可以定义其控制器逻辑并与模型或应用程序的其他组件交互。控制器可以访问请求参数、会话数据和其他应用程序资源。

    • - ThinkPHP还提供了一种名为“约定优于配置”的特性,这意味着如果遵循一定的控制器和动作方法的命名约定,框架将自动路由请求到正确的控制器和动作方法。

2.ThinkPHP默认的控制器为application/index/controller/index.php,我们可以在该文件中新建一个test方法

public function test(){   echo 'Hello, ThinkPHP!';}
    • 访问该方法需要定位到该函数的路由,否则直接访问将会报错,正确的路由如下

http://localhost/index.php/index/index/test
    • 如下,成功访问application/index/controller/index.php中的test()方法

PHP代码审计——ThinkPHP基础

3.要在ThinkPHP中创建一个控制器,只需要在application/index/controller目录下新建一个php文件,创建新的函数即可

    • 例如,新建一个hello.php文件,写入如下代码

<?php  namespace appindexcontroller;    class Hello{      public function index(){          echo 'Hello, world!';      }        public function hello(){          echo 'Hello, Web Security!';      }  }
    • 访问控制器路由

http://localhost/index.php/index/hello/hello
    • 如下,成功访问hello.php中的hello方法

PHP代码审计——ThinkPHP基础

4. 标准的ThinkPHP的URL访问格式

http://domainName/index.php/模块/控制器/操作/[参数名/参数值...]

六、ThinkPHP的路由

1. 路由是指在应用程序中定义URL和请求处理程序之间的映射关系。在ThinkPHP中,路由是由应用程序的路由表配置文件定义的。路由表指定了不同的URL模式以及在处理不同URL时应该调用哪个控制器和方法。ThinkPHP支持多种路由风格,例如传统的PathInfo模式、兼容模式(支持PathInfo和查询字符串)、路由模式(支持正则表达式)等。这些路由风格可以通过应用程序配置文件进行设置。通过路由,您可以将URL重定向到特定的控制器和动作方法。此外,您还可以使用路由变量来匹配特定的URL模式,并将URL参数传递到控制器中。总之,路由在ThinkPHP中是非常重要的,因为它指定了应用程序的URL结构和请求处理方式。通过设置路由,您可以实现可读性更好的URL,并促进应用程序的可维护性和可扩展性。

2. 详细说明介绍ThinkPHP的路由

    • 首先,打开应用程序的路由配置文件config/route.php,添加以下内容:

use thinkRoute;Route::get('user/:id', 'index/User/index');
    • 在该例子中,我们创建了一条路由规则,该规则指定HTTP GET请求的URL必须由路由/user/:id匹配,并将匹配的请求转发到index控制器的User方法。接下来,我们打开index控制器类的文件appindexcontrollerUser.php,添加以下代码:

namespace appindexcontroller;use thinkController;    class User extends Controller{  public function index($id){    echo 'User ID: '.$id;  }}
    • 在该例子中,我们创建了名为User的控制器类,并在该类中创建了名为index的动作方法。该方法使用$id变量来接收通过路由传递的参数,并输出用户ID。

    • 最后,打开Web浏览器并输入http://localhost/index.php/user/123,应用程序将输出“User ID: 123”。

PHP代码审计——ThinkPHP基础

七、ThinkPHP的参数传入

1. 首先,在路由配置文件config/route.php中添加以下代码:

use thinkRoute;Route::get('blog/:id', 'blog/read', ['ext' => 'html'], ['id' => 'd+']);

2. 在该例子中,我们定义了一个路由规则,它允许HTTP GET请求匹配以“/blog/”开头,后跟数字参数的URL。规则将该请求传递到名为blog的控制器的名为read的动作方法。我们还指定了一个扩展名为“html”的参数,并使用正则表达式指定该参数必须是数字。然后,我们在控制器文件app/controller/blog.php中添加以下代码:

<?php  namespace appindexcontroller;  use thinkController;  use thinkRequest;    class Blog{      public function read($id){          $request = Request::instance();          echo 'Blog ID: ' . $id . '<br/>';          echo 'Extension: ' . $request->ext() . '<br/>';          echo 'URL: ' . $request->url() . '<br/>';      }  }

4. 在该例子中,我们创建了一个名为Blog的控制器类,并在该类中创建了一个名为read的动作方法,该方法使用$id变量接收从路由传递的参数,并输出该参数,以及请求的扩展名和URL。最后,我们可以在Web浏览器中输入以下URL进行测试:http://example.com/blog/123.html,应用程序将匹配路由规则并调用Blog控制器的read方法。方法将输出以下内容:

PHP代码审计——ThinkPHP基础

八、ThinkPHP的框架执行流程

1. 首先,Web服务器(如Apache或Nginx)将请求发送到应用程序的入口文件public/index.php,它位于应用程序根目录下。 

// [ 应用入口文件 ]// 定义应用目录define('APP_PATH', __DIR__ . '/../application/');// 加载框架引导文件require __DIR__ . '/../thinkphp/start.php';

2. 入口文件初始化应用程序的核心实例化thinkphp/start.php,这将创建一个App对象并运行应用程序,最终输出响应内容。

namespace think;
// ThinkPHP 引导文件// 加载基础文件require __DIR__ . '/../thinkphp/base.php';//执行应用thinkApp::run()->send();

3. 入口文件初始化应用程序的基础设置thinkphp/base.php,包括定义应用程序的常量和自动加载机制:

    • 环境常量

    • 载入Loader类

    • 注册自动加载

    • 注册错误和异常处理机制

    • 加载惯例配置文件

4. 应用程序在运行时,先通过路由系统解析URL路径和请求方法,找到对应的控制器和方法,控制器文件和方法文件分别位于应用程序的controller和model目录下

5. thinkphp/library/think/App.php执行控制器的方法,生成响应内容


原文始发于微信公众号(菜鸟的渗透测试之路):PHP代码审计——ThinkPHP基础

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年5月21日01:19:43
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   PHP代码审计——ThinkPHP基础https://cn-sec.com/archives/1750465.html

发表评论

匿名网友 填写信息