ez_curl
題目來源
攻防世界 NO.GFSJ1188
題解
是一個PHP的程式碼審計
同時還提供了一個附件app.js
,開啟後內容如下
app.js
中:
- req.query.admin.includes:要求在URL中
admin
欄位的值不包含“false"子串(必須要有admin欄位) - req.headers.admin.includes:要求在報文頭部中
admin
欄位的值包含“true”子串
解題思路:向PHP檔案發出請求,該PHP檔案從POST的資料中拿到變數$url
、$headers
,向app.js
發出請求。
繞過URL的判斷
在PHP檔案中可以看到URL由POST的params中的元素拼接而成,最後加上admin=false
。
在NodeJS中有以下知識點:express的parameterLimit預設為1000,即當引數個數大於1000時,後面的引數將被截斷。
當我們給params賦值的成員個數大於1000時,$url
中引數的個數將大於1000,因此1000以後的引數將失效,即可讓$url
中admin=false
被截斷。
繞過headers的判斷
對於php檔案中的繞過,有兩種方法。在做題時可以將兩個檔案放到本地進行除錯,有利於學習NodeJS解析的結果(本文跳過此步驟)
第一種
{"headers": ["xx:xx\nadmin: true"]}
我們可以看到admin
和true
字串都在第一個冒號後面,因此可以繞過PHP程式碼的檢測,而在NodeJS解析時,會解析得到admin
的欄位為true.
第二種
{"headers": ["admin: x", " true: y"]}
由於admin
和ture
出現在陣列的兩個元素中,因此可以繞過PHP檔案的判斷。在正常解析過程中,在鍵名中是不允許存在空格的,但NodeJS在遇到這類情況時是寬容的,會將其解析成
{"admin": "x true y"}
即NodeJS會將分隔符直接去掉。
構造body
python程式碼如下
import json
datas = {"headers": ["xx:xx\nadmin: true"],
"params": {"admin": "true"}}
for i in range(1020):
datas["params"]["x" + str(i)] = i
json1 = json.dumps(datas)
print(json1)
其中datas
中的headers
可以構造為上面提到的第二種方法,也是可行的。
將執行得到的body使用POST方法進行傳參,即可得到flag