From 9f14814b2cf940ecc0ba0eb383c70bc8b90a8dd7 Mon Sep 17 00:00:00 2001 From: k4amos Date: Mon, 30 Dec 2024 14:33:47 +0100 Subject: [PATCH] Add oracle2john.py --- run/oracle2john.py | 133 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 run/oracle2john.py diff --git a/run/oracle2john.py b/run/oracle2john.py new file mode 100644 index 0000000000..e59364b664 --- /dev/null +++ b/run/oracle2john.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 + +# This software is Copyright (c) 2024, k4amos +# and it is hereby released to the general public under the following terms: +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted. + +# --- + +# Utility to obtain a hash of ORACLE authentication (o5logon) that can be cracked with John +# Usage: ./oracle2john.py -f +# +# This script depends on Scapy (https://scapy.net) +# To install: pip install --user scapy + +import sys +import argparse +import re + +try: + import scapy.all as scapy +except ImportError: + print( + "\033[91m[Error] Scapy seems to be missing, run 'pip install --user scapy' to install it\033[0m" + ) + sys.exit(1) + + +def read_file(args, filename): + """ + Reads a PCAP file and extracts relevant Oracle authentication data (o5logon). + """ + auth_data = { + "server_auth_sesskey": None, + "auth_vfr_data": None, + "auth_password": None, + "client_auth_sesskey": None, + } + + packets = scapy.rdpcap(filename) + for packet in packets: + auth_data = process_packet(args, packet, auth_data) + + if auth_data["server_auth_sesskey"] is None or auth_data["auth_vfr_data"] is None: + print( + f"\033[91m[Error] The PCAP file {filename} does not contain the required fields of o5logon authentification\033[0m" + ) + elif None not in list(auth_data.values()): + # Format of the hash : $o5logon$ * * * + print( + f'$o5logon${auth_data["server_auth_sesskey"]}*{auth_data["auth_vfr_data"]}*{auth_data["auth_password"]}*{auth_data["client_auth_sesskey"]}' + ) + + else: + # Format of the hash : $o5logon$ * + print( + f'$o5logon${auth_data["server_auth_sesskey"]}*{auth_data["auth_vfr_data"]}' + ) + + +def select_hexa(raw_string): + """ + Extracts the first valid hexadecimal string from the raw data. + """ + match_hexa = re.search( + "([A-Fa-f0-9]+)", raw_string.decode("ascii", errors="ignore").replace(" ", "") + ) + if match_hexa: + return match_hexa.group(1) + + +def process_packet(args, packet, auth_data): + """ + Processes a packet and updates the auth_data dictionary with the extracted values. + """ + raw_data = bytes(packet) + + pbkdf2_match = re.search(rb"PBKDF2", raw_data) + if pbkdf2_match: + print( + "\033[91m[Error] Sorry, PBKDF2 is not (yet) supported by this utility (only o5logon is)\033[0m" + ) + sys.exit(1) + + server_auth_sesskey_match = re.search( + rb"AUTH_SESSKEY([\s\S]+?)AUTH_VFR_DATA", raw_data + ) + if server_auth_sesskey_match: + auth_data["server_auth_sesskey"] = select_hexa( + server_auth_sesskey_match.group(1) + ) + + auth_vfr_data_match = re.search( + rb"AUTH_VFR_DATA([\s\S]+?)(AUTH_GLOBALLY_UNIQUE_DBID|$)", raw_data + ) + if auth_vfr_data_match: + auth_data["auth_vfr_data"] = select_hexa(auth_vfr_data_match.group(1)) + + auth_password_match = re.search(rb"AUTH_PASSWORD([\s\S]+?)AUTH_RTT", raw_data) + if auth_password_match: + auth_data["auth_password"] = select_hexa(auth_password_match.group(1)) + + client_auth_sesskey_match = re.search( + rb"AUTH_SESSKEY([\s\S]+?)AUTH_PASSWORD", raw_data + ) + if client_auth_sesskey_match: + auth_data["client_auth_sesskey"] = select_hexa( + client_auth_sesskey_match.group(1) + ) + + return auth_data + + +if __name__ == "__main__": + + parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" + ### Utility to obtain a hash of ORACLE authentication (o5logon) that can be cracked with John + Written by k4amos + + Usage: ./oracle2john.py -f + """, + ) + + parser.add_argument("-f", "--file", type=str, required=True, nargs="+") + + parsed_args = parser.parse_args() + args = vars(parsed_args) + + for filename in args["file"]: + auth_data = read_file(args, filename)