1. 程式人生 > >【42】WEB安全學習----PHP-ThinkPHP框架1

【42】WEB安全學習----PHP-ThinkPHP框架1

前言

前不久參加了一個CTF比賽,有一道題是PHP程式碼審計,採用框架進行開發,因為從沒有接觸過框架學習,故找到了漏洞程式碼也不知道怎麼構造利用,悲慘之極,現在惡補下。

PHP框架

在PHP中,目前主流的框架有:

Zend Framework:重量級框架,由PHP官方出品,因為功能較全面,導致啟動慢比較臃腫。

YII:重量級框架,由美國華人薛強開發

Symfony:重量級框架,一款國外框架。

Laravel:輕量級框架,一款國外框架。

Codelgniter:輕量級框架,簡稱CI框架,一款國外框架。

ThinkPHP:由國人開發,有中文官網和社群,在國內使用比較普遍。

MVC

說到框架,那麼不得不說MVC設計模式了,它是強制將使用者的輸入、邏輯、輸出相分離,將整個專案分為三個部分:控制器、模型、檢視。

程式設計階段:

第一階段:混合程式設計-將PHP程式碼和前端程式碼寫在一個檔案中。

第二階段:模板引擎-典型的如smarty。將後端程式碼和前端程式碼分離開。

第三階段:框架-將使用者的輸入、邏輯、輸出相分離,維護性提高很多。

ThinkPHP框架

目前最新的是V5版,但目前使用最多的是3.2.3版本。

軟體版本的修飾詞:

  1. Alpha版本:內測版本,內部測試
  2. Beta版本:公測版本,面向使用者,由使用者找BUG
  3. RC版本:候選版本,軟體在這個階段就已經不會有太多的功能性調整,主要是排錯。
  4. R版本:release版本,發行版本,穩定的版本

目錄解釋

  • Application:應用目錄
  • Public:資原始檔,存放圖片、CSS、JS等靜態檔案
  • ThinkPHP:框架核心目錄
  • .htaccess:分散式配置檔案
  • composer.json:給composer管理軟體使用的說明文
  • index.php:專案的入口檔案
  • README.md:說明檔案

核心框架目錄:

  • Common:系統函式庫目錄,存放了functions.php
  • Conf:系統配置檔案目錄
  • Lang:語言包目錄
  • Library:thinkphp核心目錄
  • Mode:模式,一般用不著
  • Tpl:系統模板目錄,裡面包含了系統所用的模板
  • ThinkPHP.php:專案介面檔案,在後期開發的時候被專案入口檔案所引入

自動生成

在首次執行index.php入口檔案時會自動生成相應的目錄結構:

開始只需要這兩個檔案即可:

訪問入口檔案會自動生成Application目錄

應用目錄名字取決於在index.php中定義的常量APP_PATH:

目錄安全檔案:

在自動生成的目錄中都有一個空白的html檔案,這是為了防止開發者忘記在Apache配置檔案中配置了options+indexes,防止目錄遍歷攻擊。防止列出站點檔案結構。

預設訪問:

預設訪問可看到一個笑臉,這是為啥呢?

預設配置在系統配置convention.php檔案中:

預設分組/平臺:Home

預設控制器:Index

預設方法:index

 

ThinkPHP中控制器

命名規範:控制名(英文首字母大寫)+Controller關鍵詞+.class.php

如:GoodController.class.php

控制器程式碼結構:

1、聲明當前控制器(類)的名稱空間:namespace Home\Controller

2、引入父類控制器:Think\Controller

3、宣告控制器(類)並且繼承父類:class IndexController extends Controller

自己寫一個控制器:

#自己建立一個控制器:UserController.class.php
<?php
namespace Home\Controller;
use Think\Controller;
class UserController extends Controller{
	public function test(){
		echo "hello world";
	}
}

那麼怎麼構造訪問呢?http://127.0.0.1/thinkphp/index.php?m=Home&c=User&a=test

m為平臺/分組,預設為Home,C為控制器,a為方法

路由形式

路由:是指訪問專案具體某個方法的URL地址,在ThinkPHP中系統提供了4種路由形式:

  • 普通形式路由(GET形式路由)
  • Pathinfo形式路由
  • Rewrite形式路由
  • 相容形式路由

普通形式路由:

路由形式:http://網址/入庫檔案?m=分組名&c=控制器名&a=方法名&引數名=引數值

例如:訪問Home分組下的User控制器中的test方法,並且傳遞一個引數,id=1

http://127.0.0.1/index.php?m=Home&c=User&a=test&id=1

問題:既不安全也不好看

Pathinfo形式路由:thinkphp預設路由

路由形式:http://網址/入口檔案/分組名/控制器/方法/引數名1/引數值1/引數名/2引數值2

例如:訪問Home分組下的User控制器中的test方法,並且傳遞一個引數,id=1

http://127.0.0.1/thinkphp/index.php/Home/User/test/id/1

Rewrite形式路由:

路由形式:http://網址/分組名/控制器/方法/引數名1/引數值1/引數名/2引數值2

http://127.0.0.1/thinkphp/Home/User/test/id/1

注意:該路由需要配置才能使用。此路由形式很少使用。

相容形式路由:

路由形式:http://網址/入口檔案?s=/分組名/控制器/方法/引數名1/引數值1/引數名/2引數值2

http://127.0.0.1/thinkphp/index.php?s=/Home/User/test/id/1

thinkphp路由的配置:在thinkphp系統配置檔案convention.php中,預設為Pathinfo形式路由,這裡配置不影響我們在位址列輸入的形式,而是影響的是thinkphp系統封裝的URL組裝函式。

分組

一般的專案都會根據某個功能來區分程式碼,這時候放到一起就形成了分組資料夾,分組就是指的是平臺(前臺、後臺)。

預設thinkphp建立了一個Home分組,後期需要更多的分組,需要自己建立。

如何建立分組:參考Home分組的檔案結構

自己建立一個分組:

在Home分組同級目錄中建立一個Admin分組,裡面的結構參考Home分組結構

在Admin分組中建立一個控制器:TestController.class.php,並建立一個測試方法Test

<?php
namespace Admin\Controller;
use Think\Controller;
class TestController extends Controller {
	public function test(){
		phpinfo();
	}
}

訪問建立的分組:http://127.0.0.1/thinkphp/index.php/Admin/test/Test

控制器中的跳轉

URL組裝:

URL組裝就是根據某個規則,來組成一個URL地址,這個功能就叫做url組裝。

在Thinkphp中,系統提供了一個封裝函式來處理URL的組裝,這個方法叫做U方法。

U方法是系統提供的快速方法,除了U方法還有其它的快速方法:A、B、C等這些方法都定義在系統函式庫中functions.php。

測試U方法組裝:

<?php
namespace Admin\Controller;
use Think\Controller;
class TestController extends Controller {
	public function test(){
		echo U('admin');
	}
}

這裡admin後面是.html,這是偽靜態,為了優化。

用法:U('[分組名/控制器名]方法名',array('引數名1'=>引數值1,'引數名2'=>引數值2))

示例:echo U('Admin/Test/Test',array('id'=>1));

系統跳轉方法:

在Thinkphp中系統有2個跳轉方法:成功跳轉和失敗跳轉。

成功:

        $this->success(跳轉提示,跳轉地址,等待時間);

失敗:

        $this->error(跳轉提示,跳轉地址,等待時間);

跳轉引數必須要有,後面的地址和時間可以沒有,若沒有地址則跳轉到上一頁。

測試跳轉:

<?php
namespace Admin\Controller;
use Think\Controller;
class TestController extends Controller {
	public function test(){
		echo "hello world";
	}
	public function test1(){
		echo "good id";
	}
	public function jmp1(){
		$this->success("跳轉成功",U("test"),10);
	}
	public function jmp2(){
		$this->error("跳轉失敗",U("test1"),10);
	}
}

檢視

什麼是檢視:是MVC三大組成部分之一,主要負責資訊的輸出和展示。

檢視的建立:

建立的位置需要在分組目錄下的View目錄中,一般來說,一個控制器對應著一個檢視目錄 (同名),控制器中的方法對應著檢視目錄裡的一個html檔案。

示例:Test控制器中的login方法,需要有一個模板,則該模板檔案login.html需要放在View/Test/login.html。

檢視的展示:

在Thinkphp中展示檢視是通過:$this->display();展示當前控制器下與當前請求方法名稱一致的模板檔案。

測試模板:

Test控制下有一個test1方法:

public function test1(){
		$this->display();
	}

在View\Test\建立一個test1.html模板檔案,訪問即可展示test1.html。

變數的分配:

在Thinkphp中系統已封裝好了一個變數的分配方法:$this->assign('模板中變數名','php中變數名');

而在模板中通過{$模板變數名}來展示變數資料。

測試:

public function test1(){
		$date=date('Y-m-d H:i:s',time());
		$this->assign('date',$date);
		$this->display();
	}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    現在時間是:{$date}
</body>
</html>