Source code for pyplugins.hyper.bash_command

"""
Bash Command Plugin
===================

This module provides a plugin for capturing and logging Bash command executions within the Penguin hypervisor environment.
It listens for Bash command events and writes details to a CSV file for coverage or auditing purposes.

Usage
-----

The plugin is typically loaded by the Penguin framework and does not require direct invocation.

Example CSV Output
------------------

.. code-block:: csv

    filename,lineno,pid,command
    /home/user/script.sh,12,1234,ls -l

Arguments
---------

- ``outdir``: Output directory for the CSV file.
- ``verbose``: If set, enables debug logging.

Classes
-------

- BashCommand: Main plugin class for handling Bash command events.

"""

import csv
import os
from penguin import plugins, Plugin


[docs] class BashCommand(Plugin): """ BashCommand is a plugin that logs Bash command executions to a CSV file. It subscribes to the "bash_command" hypercall and writes each command's filename, line number, process ID, and command string to a CSV file. **Arguments:** - `outdir` (str): Output directory for the CSV file. - `verbose` (bool): Enables debug logging if True. """ def __init__(self) -> None: """ Initialize the BashCommand plugin. - Sets up the output CSV file in the specified directory. - Configures logging level if verbose is enabled. - Subscribes to the "bash_command" hypercall. **Returns:** None """ self.outdir = self.get_arg("outdir") if self.get_arg_bool("verbose"): self.logger.setLevel("DEBUG") # Bash outdir = self.get_arg("outdir") path = os.path.join(outdir, "bash_cov.csv") self.bash_cov_csv = open(path, "w") csv.writer(self.bash_cov_csv).writerow( ["filename", "lineno", "pid", "command"]) self.bash_cov_csv.flush()
[docs] @plugins.SendHypercall.subscribe("bash_command") def cmd_bash_command(self, cmd: str, path: str, lineno: int, pid: int) -> tuple[int, str]: """ Handle a Bash command event and log it to the CSV file. **Parameters:** - `cmd` (str): The Bash command executed. - `path` (str): The file path where the command was executed. - `lineno` (int): The line number in the file. - `pid` (int): The process ID of the Bash process. **Returns:** - `(int, str)`: Tuple containing status code (0 for success) and an empty string. """ csv.writer(self.bash_cov_csv).writerow([path, lineno, pid, cmd]) self.bash_cov_csv.flush() self.logger.debug(f"bash_command {path}:{lineno} {pid}: {cmd}") return 0, ""