Created
April 17, 2023 03:05
-
-
Save X-Junior/2c49f52b5361bf28c3eba8a825a72ebe to your computer and use it in GitHub Desktop.
Static String Decryption For Lockbit 3.0 MacOS Variant
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
Author: Mohamed Ashraf (@X__Junior) | |
tested samples: | |
0be6f1e927f973df35dad6fc661048236d46879ad59f824233d757ec6e722bde | |
3e4bbd21756ae30c24ff7d6942656be024139f8180b7bddd4e5c62a9dfbd8c79 | |
usage: | |
python3 lockbit_macos_string_decryption.py sample.bin | |
''' | |
import sys | |
import macholib.MachO | |
def is_ascii(bytes): | |
''' | |
basic check to get the ascii characters only. | |
''' | |
return all(char < 128 or char == 0 for char in bytes) | |
def decrypt_xor(enc_bytes, xor_key): | |
''' | |
Implementation of the XOR decryption as seen in the samples. | |
:param enc_bytes: the extracted encrypted bytes. | |
:param xor_key: the extracted xor key. | |
:return dec_strings: list of decrypted strings. | |
''' | |
dec_strings = [] | |
dec_string = "" | |
for index in range(len(enc_bytes)): | |
if enc_bytes[index] == xor_key: | |
dec_strings.append(dec_string) | |
dec_string = "" | |
dec_string += chr(enc_bytes[index] ^ xor_key) | |
return dec_strings | |
def extract_encrypted_data(data_section): | |
''' | |
Extract the encrypted_data and xor_key given the data_section. | |
:param data_section: the extracted data section from lockbit binary. | |
:return enc_data, xor_key: the encrypted data and xor key. | |
''' | |
if data_section: | |
data_offset = data_section.offset | |
data_size = data_section.size | |
with open(binary_path, "rb") as file: | |
file.seek(data_offset) | |
section_data = file.read(data_size) | |
section_data = section_data.replace(b'\x00',b'') | |
xor_key = section_data[0] | |
enc_data = section_data[1:] | |
return enc_data, xor_key | |
def parse_macos_binary(binary_path): | |
''' | |
load the macos_binary using macholib library and get the .data section. | |
:param binary_path: the given lockbit binary. | |
:return data_section: extracted data section. | |
''' | |
binary = macholib.MachO.MachO(binary_path) | |
data_section = None | |
cmds = binary.headers[0].commands | |
for cmd in cmds: | |
count = 0 | |
if int(cmd[count].cmd) == macholib.MachO.LC_SEGMENT_64: | |
count += 1 | |
if cmd[count].segname.strip(b'\x00') == b'__DATA': | |
count += 1 | |
for section in cmd[count]: | |
if section.sectname.strip(b'\x00') == b'__data': | |
data_section = section | |
return data_section | |
if __name__ == "__main__": | |
binary_path = sys.argv[1] | |
data_section = parse_macos_binary(binary_path) | |
if data_section: | |
enc_data , xor_key = extract_encrypted_data(data_section) | |
dec_strings = decrypt_xor(enc_data , xor_key) | |
# sanity check to make sure we don't print garbage chars | |
for dec_string in dec_strings: | |
if is_ascii(bytes(dec_string,"utf-8")): | |
print(dec_string) | |
else: | |
print("Could not find the .data section") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment