1. 程式人生 > >BUGKU welcome to bugkuctf

BUGKU welcome to bugkuctf

這裡記錄我花了一整天才理清題目意思的題目,因為接觸CTF時間還不長,水平還停留在各個方面都稍有了解,但是涉及的知識稍微深入一些就沒有思路了,這道題目涉及了php的程式碼審計,php的偽協議,php的序列化,php魔術方法。

因為我是小白一個,所以這道題目稍微把一些細節的地方說多一點,萬一有些朋友看到其他writeup沒看懂,看到我說的一些地方有可能就懂了。。。。

首先開啟題目檢視原始碼以後:

從上面的程式碼可以看出以下資訊:

通過get方法傳遞三個值:txt,file,password

讀取$user檔案的內容,並且檔案內容要與‘welcome to the bugkuctf’相同

$file經提示應該為hint.php

因為file_get_contents($user,'r')這個函式的意思是將$user這個檔案的內容寫到字串裡去,就是說$uesr檔案裡的內容會變成一個字串。那麼現在我們要考慮的是怎麼讓$uesr這個檔案的內容讀取出來就是"welcome to the bugkuctf"

這裡就涉及到一個php偽協議,就是php://input,它的大概意思就是可以讀取我們post傳遞的資料。它的詳解在這篇文章中有很好的解釋 https://blog.csdn.net/qq_27682041/article/details/73326435

所以看完了這篇文章的話,你應該就知道file_get_contents()函式裡面放的不止檔名哦,還可以放php的偽協議,如果把這個php://input作為檔名放進去的話,這個函式發現是一個偽協議,那作為一個“檔案”,它裡面肯定是沒有內容的吧,那要怎麼把它的內容變成一個字串呢,它會讀取我們post傳遞的資料作為它的”檔案內容“,然後再變成一個字串。

比如說我們現在有這麼一句 file_get_contents("php://input"),然後我們又post傳遞了一個數據的話,那這個資料就會被php://input讀取到,然後file_get_contents又把它變成字串。

所以我們構造txt=php://input,並且post一個"welcome to the bugkuctf"試試看

網頁變了,但是為什麼是一個hello friend!呢。。。。我也不知道,不過我們程式碼中的第一層已經解開了,再往下看吧。有一個include($file);//hint.php ,首先我們知道include($file)是動態讀取檔名,然後又提示我們hint.php,那豈不是說我們可以直接讓file=hint.php就可以得到下一步資訊了!

果然還是沒有那麼簡單。。。不然怎麼引出我們第二個php偽協議呢?php://filter 這個協議現在我只知道可以用來讀取網頁base64編碼後的原始碼。用這句 file=php://filter/read=convert.base64-encode/resource=hint.php

就可以得到hint.php這個網頁的base64編碼後的原始碼了。

光看這個程式碼是不是感覺資訊不是很夠呢,要不我們再看看index.php這個檔案的原始碼。

不要問我為什麼知道要看index.php裡的,因為這個一般是主頁檔案,有很重要的資訊嘛,嘿嘿嘿嘿嘿嘿嘿。

可以看到這麼多程式碼,雖然很煩,但是先從簡單的地方來理解。

第一張圖提示了我們flag.php,但是我們可以看第二張圖,如果我們設定的檔名中包含’flag‘,那麼就會跳出“不能現在就給你flag哦”然後exit();

繼續看第二張圖,第一個if告訴我們,我們之前的大前提並沒有改變,但是在這個前提下還附加了一些條件,如果檔名沒有"flag"了,就會把這個檔案包含進來,然後$password進行反序列化,再輸出$password的值。什麼是反序列化呢,那就要先知道序列化啦,在PHP中,序列化用於儲存或傳遞 PHP 的值的過程中,同時不丟失其型別和結構(這是百度的)。我們可以把它想成一種編碼嘛。

 

回到第一張圖,定義了一個類 FLAG,類裡面有一個$file屬性,並且有一個魔術方法_tostring(),這個方法的作用就是當呼叫例項化物件時就會自動執行_tostring()這個方法。簡單來說創造一個這個類的物件就會呼叫這個方法。魔術方法呢,就是一個很神奇的方法(一本正經的胡說八道),大概就是一種類裡面預設的方法,你可以對它進行改造,類似於構造方法。反正大家都要了解的,去百度看看用法和詳解吧。

_tostring()方法裡面又定義瞭如果$file這個屬性有賦值的話,那麼就會輸出這個檔案的內容(輸出成一個字串)。

所以根據上面的這些條件,我們可以讓$password為FLAG型別,並且讓FLAG中的$file就等於flag.php,這樣我們就可以得到flag.php的內容了,不過要記得,前面$password進行了反序列化的操作,所以我們要先把它序列化。寫一個php指令碼吧!

在本地的伺服器跑一下,我們就可以得到序列化的一個FLAG類咯。大家如果還沒有搭本地伺服器的話,推薦先自己學習一下怎麼搭建環境,在本地可以自己試驗各種php程式碼,可以自己瞭解資料庫一些操作等等。下一個APPSERV就可以啦,這是一個合集,也是有中文的,網上都有教程的,很簡單。

那最後我們就給$password賦值吧!

得到了flag啦。

 

感謝您的觀看,這是我的第一篇文章,沒有什麼寫作的經驗,而且自己現在的技術沒有多高,就是一個剛入門的小白,因為經常在writeup上看不懂,所以我會用自己理解的方式做下筆記,方便自己以後檢視的時候能夠看懂,在一些名詞的解釋方面可能不太正確,推薦大家去看看大佬們的解釋,我只是用自己的方式記憶。。。。如果文章中有哪裡出錯,希望您可以指出讓我改進,如果有和我一樣剛入門的小白想知道bugku上其他一些題目的思路也可以告訴我,如果我會的話,會盡力寫一篇writeup講解的,再次感謝!