{"id":58713,"date":"2024-08-08T19:40:04","date_gmt":"2024-08-08T16:40:04","guid":{"rendered":"https:\/\/packetstormsecurity.com\/files\/180000\/KL-001-2024-007.txt"},"modified":"2024-08-08T19:40:04","modified_gmt":"2024-08-08T16:40:04","slug":"journyx-11-5-4-unauthenticated-password-reset-bruteforce","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/journyx-11-5-4-unauthenticated-password-reset-bruteforce\/","title":{"rendered":"Journyx 11.5.4 Unauthenticated Password Reset Bruteforce"},"content":{"rendered":"<p>KL-001-2024-007: Journyx Unauthenticated Password Reset Bruteforce<\/p>\n<p>Title: Journyx Unauthenticated Password Reset Bruteforce<br \/>Advisory ID: KL-001-2024-007<br \/>Publication Date: 2024.08.07<br \/>Publication URL: https:\/\/korelogic.com\/Resources\/Advisories\/KL-001-2024-007.txt<\/p>\n<p>1. Vulnerability Details<\/p>\n<p>Affected Vendor: Journyx<br \/>Affected Product: Journyx (jtime)<br \/>Affected Version: 11.5.4<br \/>Platform: GNU\/Linux<br \/>CWE Classification: CWE-321: Use of Hard-coded Cryptographic Key,<br \/>CWE-334: Small Space of Random Values,<br \/>CWE-799: Improper Control of Interaction Frequency<br \/>CVE ID: CVE-2024-6890<\/p>\n<p>2. Vulnerability Description<\/p>\n<p>Password reset tokens are generated using an insecure source<br \/>of randomness. Attackers who know the username of the Journyx<br \/>installation user can bruteforce the password reset and change<br \/>the administrator password.<\/p>\n<p>3. Technical Description<\/p>\n<p>From an unauthenticated perspective, a user can initiate the<br \/>password reset flow by clicking the &#8220;Reset your password&#8221; button<br \/>on the Journyx login screen and supplying a valid username. A<br \/>password reset link containing a &#8220;random&#8221; token is sent to the<br \/>email address associated with the username.<\/p>\n<p>The password reset token is generated using the current epoch<br \/>and the user ID associated with the request. The user ID is<br \/>a 128-bit UUID for every user *except* for the user created<br \/>during the initial setup of the Journyx instance, i.e., the<br \/>system administrator account. For this single user, the user<br \/>ID defaults to the username. By targeting this user, the need<br \/>to leak a UUID is removed entirely. If the Journyx instance was<br \/>configured according to the official System Administration guide<br \/>(https:\/\/journyx.com\/Files\/Journyx_Sysadmin_and_Recovery_v11.pdf),<br \/>the username is &#8220;journyx&#8221;. Alternatively, the username can be<br \/>leaked via stacktraces.<\/p>\n<p>When generating the token, a secret key is created by inserting<br \/>the user ID inbetween the strings &#8216;chuck&#8217; and &#8216;palahniuk&#8217;:<\/p>\n<p>mysessiontoken = &#8216;chuck%spalahniuk&#8217; % me<\/p>\n<p>This key is used to XOR the string literal representation of<br \/>the list object &#8220;[userID, time.time()]&#8221;. The output of the XOR<br \/>function is then base64 encoded:<\/p>\n<p>eStr = xor_str(istr, key)<br \/>aStr = binascii.b2a_base64(eStr).strip()<\/p>\n<p>Since the user ID is a known value, only the output of<br \/>&#8220;time.time()&#8221; (the epoch at the time of &#8220;encryption&#8221;) is<br \/>unknown. However, by opening a TCP connection and noting the<br \/>epoch immediately after sending an HTTP request to initiate<br \/>the password reset flow, a pool of tokens can be generated by<br \/>incrementing the epoch. There is a high degree of certainty<br \/>the valid reset token is contained within a pool larger than<br \/>50,000 tokens.<\/p>\n<p>Depending upon network latency and other external factors,<br \/>a successful bruteforce attack using these tokens can take<br \/>anywhere from several minutes to over an hour.<\/p>\n<p>4. Mitigation and Remediation Recommendation<\/p>\n<p>The vendor reports that this issue was remediated in Journyx<br \/>v12.0.0, which is the first wholly cloud-hosted version of<br \/>this product.<\/p>\n<p>For self-hosted versions of Journyx, one incremental<br \/>improvement is to disable user-initiated password reset<br \/>functionality in the application settings.<\/p>\n<p>1) Log into the JournyX web application as an administrator<br \/>2) Navigate to Configuration -&gt; System Settings -&gt; Security Settings<br \/>3) Ensure the checkbox labeled &#8220;Show a password reset button on login<br \/>screen&#8221; is disabled.<br \/>4) Click the &#8220;Save&#8221; button<\/p>\n<p>Another option would be to monkey patch the .pyc file that<br \/>contains these hardcoded strings, .\/wtdoc.pyc, by deploying a .py<br \/>file that uses unique strings and then loads wtdoc_original.pyc<br \/>(see KL-001-2024-008 and KL-001-2024-009 for examples).<\/p>\n<p>5. Credit<\/p>\n<p>This vulnerability was discovered by Jaggar Henry of KoreLogic, Inc.<\/p>\n<p>6. Disclosure Timeline<\/p>\n<p>2024.01.31 &#8211; KoreLogic notifies Journyx support of the intention to<br \/>report vulnerabilities discovered in the licensed,<br \/>on-premises version of the product.<br \/>2024.01.31 &#8211; Journyx acknowledges receipt.<br \/>2024.02.02 &#8211; KoreLogic requests a meeting with Journyx support to share<br \/>vulnerability details.<br \/>2024.02.07 &#8211; KoreLogic reports vulnerability details to Journyx.<br \/>2024.02.09 &#8211; Journyx responds that this vulnerability has been remediated<br \/>in the cloud-hosted version of the product.<br \/>2024.02.21 &#8211; KoreLogic offers to test the cloud version to confirm<br \/>the fix; no response.<br \/>2024.07.01 &#8211; KoreLogic notifies Journyx of impending public disclosure.<br \/>2024.07.09 &#8211; Journyx confirms version number of the remediation.<br \/>2024.08.07 &#8211; KoreLogic public disclosure.<\/p>\n<p>7. Proof of Concept<\/p>\n<p>The following script automatically exploits this issue by initiating<br \/>a password reset flow and bruteforces the value after generating a<br \/>list of 50,000 tokens.<\/p>\n[attacker@box]$ python unauth2rce.py &#8211;url http:\/\/redacted.com:8080\/ &#8211;username foo &#8211;command id<br \/>[*] Beginning Attack. Using the following timestamp: &#8220;1706708084.2051988&#8221;<br \/>[+] New Password Generated: 2DCD5AE1F0F34B84A1E0F1FB5768219B<\/p>\n<p>The contents of this advisory are copyright(c) 2024<br \/>KoreLogic, Inc. and are licensed under a Creative Commons<br \/>Attribution Share-Alike 4.0 (United States) License:<br \/>http:\/\/creativecommons.org\/licenses\/by-sa\/4.0\/<\/p>\n<p>KoreLogic, Inc. is a founder-owned and operated company with a<br \/>proven track record of providing security services to entities<br \/>ranging from Fortune 500 to small and mid-sized companies. We<br \/>are a highly skilled team of senior security consultants doing<br \/>by-hand security assessments for the most important networks in<br \/>the U.S. and around the world. We are also developers of various<br \/>tools and resources aimed at helping the security community.<br \/>https:\/\/www.korelogic.com\/about-korelogic.html<\/p>\n<p>Our public vulnerability disclosure policy is available at:<br \/>https:\/\/korelogic.com\/KoreLogic-Public-Vulnerability-Disclosure-Policy<\/p>\n","protected":false},"excerpt":{"rendered":"<p>KL-001-2024-007: Journyx Unauthenticated Password Reset Bruteforce Title: Journyx Unauthenticated Password Reset BruteforceAdvisory ID: KL-001-2024-007Publication Date: 2024.08.07Publication URL: https:\/\/korelogic.com\/Resources\/Advisories\/KL-001-2024-007.txt 1. Vulnerability Details Affected Vendor: JournyxAffected Product: Journyx (jtime)Affected Version: 11.5.4Platform: GNU\/LinuxCWE Classification: CWE-321: Use of Hard-coded Cryptographic Key,CWE-334: Small Space of Random Values,CWE-799: Improper Control of Interaction FrequencyCVE ID: CVE-2024-6890 2. Vulnerability Description Password reset tokens &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-58713","post","type-post","status-publish","format-standard","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/58713","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/comments?post=58713"}],"version-history":[{"count":0,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/58713\/revisions"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=58713"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=58713"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=58713"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}