#!/usr/bin/env python3 # written by sqall # twitter: https://twitter.com/sqall01 # blog: https://h4des.org # github: https://github.com/sqall01 # # Licensed under the MIT License. """ Short summary: Monitor /etc/ld.so.preload for changes to detect malicious attempts to alter the control flow of binaries. Requirements: None """ import os from typing import Set from lib.state import load_state, store_state from lib.util import output_error, output_finding # Read configuration. try: from config.config import ALERTR_FIFO, FROM_ADDR, TO_ADDR, STATE_DIR from config.monitor_ld_preload import ACTIVATED STATE_DIR = os.path.join(os.path.dirname(__file__), STATE_DIR, os.path.basename(__file__)) except: ALERTR_FIFO = None FROM_ADDR = None TO_ADDR = None ACTIVATED = True STATE_DIR = os.path.join("/tmp", os.path.basename(__file__)) def _get_ld_preload() -> Set[str]: path = "/etc/ld.so.preload" ld_data = set() if os.path.isfile(path): with open(path, 'rt') as fp: for line in fp: if line.strip() == "": continue ld_data.add(line.strip()) return ld_data def monitor_ld_preload(): # Decide where to output results. print_output = False if ALERTR_FIFO is None and FROM_ADDR is None and TO_ADDR is None: print_output = True if not ACTIVATED: if print_output: print("Module deactivated.") return stored_ld_data = set() try: state_data = load_state(STATE_DIR) # Convert list to set. if "ld_data" in state_data.keys(): stored_ld_data = set(state_data["ld_data"]) except Exception as e: output_error(__file__, str(e)) return curr_ld_data = set() try: curr_ld_data = _get_ld_preload() except Exception as e: output_error(__file__, str(e)) return # Compare stored data with current one. for stored_entry in stored_ld_data: if stored_entry not in curr_ld_data: message = "LD_PRELOAD entry '%s' was deleted." % stored_entry output_finding(__file__, message) continue # Check new data was added. for curr_entry in curr_ld_data: if curr_entry not in stored_ld_data: message = "LD_PRELOAD entry '%s' was added." % curr_entry output_finding(__file__, message) try: # Convert set to list. state_data = {"ld_data": list(curr_ld_data)} store_state(STATE_DIR, state_data) except Exception as e: output_error(__file__, str(e)) if __name__ == '__main__': monitor_ld_preload()