第四屆上海大學生資訊保安比賽----- web3
這道是原始碼題,
原始碼:
原始碼很簡單,我覺得考得主要是細心
直接看第一個if,
判斷是否上傳了一個檔案,然後進去判斷是否POST了一個名為file的引數,如果有上傳這個引數,那麼$filename就等於這個POST上去的值,否則就等於上傳上去的檔名
然後下面判斷$filename是否是一個array ,
如果是,就對$filename 進行 explode ,切割成一個數組
否則,。。。沒有判斷(這就是第一個考點)
$ext = end($filename)
如果$filename 不是array,那麼$ext 就等於上傳的檔案的字尾
那麼如果是陣列呢,那麼就等於
繼續判斷$ext是否和$filename[count($filename)-1]的值相等
如果count($filename)為2,那麼就是判斷
$ext === $filename[1]
這裡就有一個問題了,那麼end($filename),到底是哪一個 (我覺得這裡也是一個考點)
測試一下
可以很簡單地繞過。
然後下面新生成一個檔案,字尾我們可以控制為php
然後將剛才上傳的檔案,儲存進去
下面在POST一個引數hehe,
首先將這個檔案的內容讀取出來,判斷前
然後判斷上傳的檔案不能和新生成的檔名一樣,這個隨便就可以過
成功了就包含這個php檔案
可怕的是下面有一個unlink() ,將剛才生成的檔案全部刪除了,但是這個繞過去也很簡單
首先想到的是,資源競爭。
開多執行緒,如果這個檔案剛生成,還沒有執行到unlink()的時候,被另外一個執行緒訪問到,那麼就會執行這個檔案,如果這個檔案的程式碼再生成了一個檔案,那麼這個檔案就不會被刪除了。事實證明是可以的。
還有一種方法,我們控制字尾為 php/.
那麼生成的檔案就會一直儲存著,不會被刪除
(這種方法,我不是很理解,我沒有想到可以這樣子來繞過
兩種方法都來試一下
第一種方法,資源競爭,這個比較耗時間,但是容易想到
第二種,
修改file[0]為php/. 就可以了
做到這裡,全部完成了,讀取flag的話,修改一下里面內容,就可以讀到