PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /opt/imh-scan/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //opt/imh-scan/mkdef |
#!/opt/imh-python/bin/python3 """Module/Script for creating yara based ClamAV definitions""" import re import sys import os import time import shutil import getpass import argparse class MkDef: """Main class for definition maker""" def __init__(self, args): """sets user's database file name based on executing user""" self.args = args if self.args.all: self.condition = 'any of them' else: self.condition = 'PHP and any of them' # writes to tmp which should clear on boot, allowing instant definitions self.def_file = '/opt/imh-scan/sigs/new/new.yara' self.def_dir = os.path.split(self.def_file)[0] self.running_user = getpass.getuser() if self.running_user != 'root': print('mkdef only can be ran as root') sys.exit(1) self.prefix = f'$new_{self.running_user}' self.time = int(time.time()) def check_dir(self): """Makes NDB file if it doesnt exist""" if not os.path.exists(self.def_dir): os.makedirs(self.def_dir) def definition_exists(self, definition): """Checks if the definition already exists in any of the dbs""" if not os.path.exists(self.def_file): print('making new.yara file') return None definition = re.escape(definition) with open(self.def_file, encoding='utf-8') as file: searcher = ( fr'''=\s*("|'){definition}("|')''' fr'.*condition:\s*{self.condition}' ) # searcher = 'strings.*condition' file_data = file.read().replace('\n', '') if re.search(searcher, file_data): print('Definition already in database, skipping') return 1 return None def make_definition(self): """The function that actually writes the definition""" e_sig = self.args.sig.replace('\n', r'\n') if self.definition_exists(e_sig): return sig_line = f' $new_imh_{self.time} = "{e_sig}"\n' default = [ f'rule imh_new_{self.time}\n', '{\n', ' strings:\n', f'{sig_line}\n', ' condition:\n', f' {self.condition}\n', '}', ] def_dir = os.path.split(self.def_file)[0] if not os.path.exists(def_dir): os.makedirs(def_dir) if not os.path.exists(self.def_file): with open(self.def_file, 'w', encoding='utf-8') as file: print(''.join(default), file=file) return insert_index, insert_legit, index = 0, 0, 0 tmp_list = [] with open(self.def_file, encoding='utf-8') as file: lines = file.readlines() for line in lines: if re.search(r'\s* strings:\s*\n', line) and not insert_legit: tmp_list += [line, sig_line] index += 1 insert_index = index continue if ( insert_index and not insert_legit and re.search(r'\s* condition:\s*\n', line) ): cond_index = index + 1 print(lines[cond_index]) if self.condition != lines[cond_index].strip(): print('not the right condition, deleting from tmp_list') del tmp_list[insert_index] else: print('cond is good, writing') insert_legit = 1 tmp_list.append(line) index += 1 if not insert_legit: print(f'adding default block to new.yara:\n{default}') tmp_list += default else: print( f'inserting line to existing cond: ' f'{self.condition}\n{sig_line}' ) tmp_fn = f'/tmp/mkdef_{self.time}' tmp_str = ''.join(tmp_list) with open(tmp_fn, 'w', encoding='utf-8') as file: print(tmp_str, file=file) shutil.move(tmp_fn, self.def_file) def parse_args(): """argparse function""" parser = argparse.ArgumentParser() # fmt: off parser.add_argument( '-a', '--all', action='store_true', default=False, help='allows the definition to match non php', ) parser.add_argument( 'sig', type=str, nargs=1, help='signature to make a definition for' ) # fmt: on args = parser.parse_args() args.sig = ''.join(args.sig) return args def main(): """Main function executions""" args = parse_args() mkdef = MkDef(args) mkdef.check_dir() mkdef.make_definition() if __name__ == '__main__': main()