【攻防世界】ez_curl

Mr_Soap發表於2024-06-23

ez_curl

題目來源

攻防世界  NO.GFSJ1188

題解

是一個PHP的程式碼審計

img

同時還提供了一個附件app.js,開啟後內容如下

img

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以後的引數將失效,即可讓$urladmin=false被截斷。

繞過headers的判斷

對於php檔案中的繞過,有兩種方法。在做題時可以將兩個檔案放到本地進行除錯,有利於學習NodeJS解析的結果(本文跳過此步驟)

第一種

{"headers": ["xx:xx\nadmin: true"]}

我們可以看到admintrue字串都在第一個冒號後面,因此可以繞過PHP程式碼的檢測,而在NodeJS解析時,會解析得到admin的欄位為true.

第二種

{"headers": ["admin: x", " true: y"]}

由於adminture出現在陣列的兩個元素中,因此可以繞過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

img