Skip to content

Instantly share code, notes, and snippets.

@c3rb3ru5d3d53c
Last active July 15, 2022 14:34
Show Gist options
  • Save c3rb3ru5d3d53c/4f2c984d81ef64e5f133e37726619c64 to your computer and use it in GitHub Desktop.
Save c3rb3ru5d3d53c/4f2c984d81ef64e5f133e37726619c64 to your computer and use it in GitHub Desktop.
Lockbit MultiTool
#!/usr/bin/env python
import sys
import struct
try:
import pefile
except ImportError or ModuleNotFoundError:
print('missing pefile module', file=sys.stderr)
sys.exit(1)
import pickle
import argparse
from glob import glob
from pprint import pprint
from os.path import basename
from os import name as os_name
logo = """ .:^
^ / :
'`. /;/ / /
\ \ /;/ / /
\\ \ /;/ / ///
\\ \ /;/ / ///
\ \/_/____________________/ /
`/ \ /
{ o o }'
\_________________________/"""
__version__ = '1.0.0'
__author__ = '@c3rb3ru5d3d53c'
def ror(n,rotations=1,width=32):
return (2**width-1)&(n>>rotations|n<<(width-rotations))
def rol(n,rotations=1,width=32):
return (2**width-1)&(n<<rotations|n>>(width-rotations))
def encrypt_ptr(data, key):
return ror((~data & 0xffffffff), rotations=key, width=32)
def decrypt_ptr(data, key):
return rol((~data & 0xffffffff), rotations=key, width=32)
def hash_mod(string, xmod):
# 004010ec
string = bytes(string, 'ascii') + b'\x00'
result = 0xc8b32494 ^ xmod
for c in string:
if c > 0x41 and c < 0x5a: c = c | 0x20
result = ror(result, rotations=0x0d, width=32)
result += c
if c == 0x00: break
return result
def hash_fnc(string, mod_hash):
# 004010b8
string = bytes(string, 'ascii') + b'\x00'
result = 0xc8b32494 ^ mod_hash
for c in string:
result = ror(result, rotations=0x0d, width=32)
result += c
if c == 0x00: break
return result
def hash_fin(fnc_hash):
# Finalize Hash
return (~fnc_hash & 0xffffffff) ^ 0x29009fe6
def hash_all(module, function, xmod):
# Hash Module and Function
return hash_fin(hash_fnc(function, hash_mod(module, xmod)))
def get_exports(dll):
pe = pefile.PE(dll)
d = [pefile.DIRECTORY_ENTRY["IMAGE_DIRECTORY_ENTRY_EXPORT"]]
pe.parse_data_directories(directories=d)
exports = []
for export in pe.DIRECTORY_ENTRY_EXPORT.symbols:
if export.name is not None: exports.append(export.name.decode())
return list(set(exports))
def create_hash_table(file_path):
hashmap = {}
dlls = glob('C:\Windows\System32\*.dll')
for dll in dlls:
try:
print('[-] ' + dll)
exports = get_exports(dll)
for export in exports:
fnc_hash = hash_all(basename(dll), export, 0x00000000)
fnc_name = basename(dll)[:-4] + '.' + export
hashmap[fnc_hash] = fnc_name
hashmap[hash_fin(hash_mod(basename(dll), 0x00000000))] = basename(dll)
print('[+] ' + dll)
except KeyboardInterrupt:
pickle.dump(hashmap, open(file_path, 'wb'), protocol=pickle.HIGHEST_PROTOCOL)
sys.exit(0)
except:
pass
pickle.dump(hashmap, open(file_path, 'wb'), protocol=pickle.HIGHEST_PROTOCOL)
def decrypt_str(data):
# 00401010
data = bytes.fromhex(data)
result = b''
if (len(data) % 4)!= 0: return None
for i in range(0, len(data), 4):
dword = struct.unpack('<I', data[i:i+4])[0]
dword = (~(dword ^ 0x29009fe6) & 0xffffffff)
result += dword.to_bytes(4, byteorder='little')
return result.decode('utf-16')
def check_windows():
if os_name != 'nt': return False
return True
def main():
parser = argparse.ArgumentParser(
prog=f'lbmt v{__version__}',
description='A Lockbit Multi-Tool',
epilog=f'Author: {__author__}'
)
parser.add_argument(
'--version',
action='version',
version=f'v{__version__}'
)
parser.add_argument(
'--create-hashmap',
type=str,
default=None,
help='Create Hash Table (Windows Only)',
required=False
)
parser.add_argument(
'--decrypt-string',
type=str,
default=None,
help='Decrypt Hex String',
required=False
)
parser.add_argument(
'--encrypt-ptr',
type=str,
default=None,
help='Encrypt Pointer',
required=False
)
parser.add_argument(
'--decrypt-ptr',
type=str,
default=None,
help='Decrypt Pointer',
required=False
)
parser.add_argument(
'--ptr-key',
type=str,
default=None,
required=False
)
for arg in sys.argv:
if arg in ['-h', '--help']:
print(logo)
if len(sys.argv) == 1:
print(logo)
parser.print_help(sys.stdout)
sys.exit(0)
args = parser.parse_args()
if args.create_hashmap is not None:
if check_windows() is False:
print('Windows OS is required for this feature', file=sys.stderr)
sys.exit(1)
create_hash_table(args.create_hashmap)
elif args.decrypt_string is not None:
print(decrypt_str(args.decrypt_string))
elif args.encrypt_ptr is not None and args.ptr_key is not None:
print(hex(encrypt_ptr(int(args.encrypt_ptr, base=16), int(args.ptr_key, base=16))))
elif args.decrypt_ptr is not None and args.ptr_key is not None:
print(hex(decrypt_ptr(int(args.decrypt_ptr, base=16), int(args.ptr_key, base=16))))
if __name__ in '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment