iT邦幫忙

2023 iThome 鐵人賽

DAY 2
0
Security

一天一個漏洞介紹系列 第 2

CVE-2023-42442 Improper Authentication

  • 分享至 

  • xImage
  •  

前言

今天跑去看CakeResume的Career Fair,決定目標是要進去Dcard了
DCard

介紹

今天的漏洞是跟JumpServer有關的,主要定位為堡壘機,其主要功用為做為公司外部的跳板機,讓使用者可以訪問內部資源(Windows/Linux主機、資料庫等)。類似的產品有CyberarkCrazyEye(不支援Windows)
堡壘機存在的目的為讓外部廠商、人員可以輕鬆存取公司內部資源,又能夠將其操作紀錄下來以供後續稽核用(Session Recording),IT也能控制每個帳號登入堡壘機之後的權限、能夠連線的Host、資源等,可以說是很方便。
另外,堡壘機跟跳板機的不同,在於堡壘機會儲存Host跟資源的登入資訊,所以在設置時需要格外注意。
Cyberark的Session紀錄,這邊每個Session都會被錄影並且可以供後續播放
JumpServer的Session紀錄

原理

這次漏洞主要是被發現在JumpServer的其中一隻獲取Session list的API /api/v1/terminal/sessions 可以被匿名訪問不需要驗證而且可以直接下載Session的錄影檔(如果有額外設定將錄影檔儲存在S3的話則不影響),前面的段落講過堡壘機的功能及其的重要性,在錄影檔裡可能會將機敏資料洩漏出去(例如廠商可能在部屬網站,然後在設定檔裡面放某個帳戶的資訊或者資料庫的資訊)

影響版本

v3.0.0 - v3.6.3

修復版本

v3.6.4, v3.5.5

JumpServer Session API

class SessionViewSet(OrgBulkModelViewSet):
    model = Session
    serializer_classes = {
        'default': serializers.SessionSerializer,
        'display': serializers.SessionDisplaySerializer,
    }
    search_fields = [
        "user", "asset", "account", "remote_addr",
        "protocol", "is_finished", 'login_from',
    ]
    filterset_class = SessionFilterSet
    date_range_filter_fields = [
        ('date_start', ('date_from', 'date_to'))
    ]
    extra_filter_backends = [DatetimeRangeFilter]
    rbac_perms = {
        'download': ['terminal.download_sessionreplay']
    }
    """
    Where it fucked up, either RBACPermission or IsSessionASsignee will be accepted
    """
    permission_classes = [RBACPermission | IsSessionAssignee]

JumpServer IsSessionAssignee

可以看到在IsSessionAssignee裡並沒有處理has_permission,他繼承了Django rest framework的BasePermission,而BasePermission預設是會直接回傳true

class IsSessionAssignee(permissions.BasePermission):

    def has_object_permission(self, request, view, obj):
        try:
            return obj.ticket_relation.first().ticket.has_all_assignee(request.user)
        except:
            return False

Django rest framework base permission

class BasePermission(metaclass=BasePermissionMetaclass):
    """
    A base class from which all permission classes should inherit.
    """

    def has_permission(self, request, view):
        """
        Return `True` if permission is granted, `False` otherwise.
        """
        return True

    def has_object_permission(self, request, view, obj):
        """
        Return `True` if permission is granted, `False` otherwise.
        """
        return True

原因

  • 錯誤設置SessionViewSet權限
  • IsSessionAssignee處理不當

解決方法

在IsSessionAssignee新增has_permission來覆蓋BasePermission (v3.6.4)

class IsSessionAssignee(permissions.BasePermission):
    def has_permission(self, request, view):
        """
        JumpServer changes here to return false to make sure RBACPermission must be valid to get session list
        Ref: https://github.com/jumpserver/jumpserver/blob/v3.6.4/apps/terminal/permissions.py#L11
        """
        return false

    def has_object_permission(self, request, view, obj):
        try:
            return obj.ticket_relation.first().ticket.has_all_assignee(request.user)
        except:
            return False

Reference

GitHub advisor


上一篇
CVE-2023-42471 Arbitrary Code Execution
下一篇
CVE-2023-40580 Information leak
系列文
一天一個漏洞介紹4
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言