Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kish2011/1836f88a204e7c9df496269a64373cb6 to your computer and use it in GitHub Desktop.
Save kish2011/1836f88a204e7c9df496269a64373cb6 to your computer and use it in GitHub Desktop.
Static String Decryption For Lockbit 3.0 MacOS Variant
'''
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