利用 wrapper 對字串解析的不同來成功 getshell
[正文]
題目一開始就給出 source code 和 phpinfo.php!
1 | stream_wrapper_unregister('php'); |
Analysis
先觀察
phpinfo
重要的兩項,allow_url_include
和allow_url_fopen
Directive Local Value Master Value
allow_url_fopen On On
allow_url_include Off Off`再來觀察 source code,首先可以發現 Wrapper
php://
被關閉。1
stream_wrapper_unregister('php');
$mkdir
的system
有加入escapeshellarg($dir)
基本上是死路。4
5
6$mkdir = function($dir) {
system('mkdir -- '.escapeshellarg($dir));
};看起來可以透過
$_SERVER['HTTP_X_FORWARDED_FOR']
控制$userFolder
。再來會把$_SERVER
array 的內容都 dump 進$userFolder/profile
裡面。11
12
13
14
15
16$userFolder = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']);
$userFolder = basename(str_replace(['.','-'],['',''],$userFolder));
$mkdir($userFolder);
chdir($userFolder);
file_put_contents('profile',print_r($_SERVER,true));看起來可以控制
$_GET['page']
,不過allow_url_include
被關閉了不能輕鬆地 LFI18
19
20
21$_GET['page']=str_replace('.','',$_GET['page']);
if(!stripos(file_get_contents($_GET['page']),'<?') && !stripos(file_get_contents($_GET['page']),'php')) {
include($_GET['page']);
}全部跑完後會把產生的所有東西都刪除。
23
24chdir(__DIR__);
system('rm -rf users/'.$randFolder);
Get shell
allow_url_fopen on, allow_url_include off
, data warper 會有以下性質
file_get_contents( 'data:,QAQ/profile' ); |
透過前面的觀察,可以創建一個 data:,aaaa/profile
,然後 file_get_contents()
會去嘗試得到 aaaa/profile
這個不存在的檔案的內容,成功 bypass,且 include()
會成功 include data:,aaaa/profile
。至於檔案的內容 print_r($_SERVER,true)
,可以透過傳送 http header 來送進去。
payload
1 | #!/usr/bin/env python3 |
python payload.py 'ls /' |
FLAG: INS{PhP_UrL_Phuck3rY_h3h3!}