penguin.config_patchers module¶
penguin.config_patchers¶
Configuration patch generation utilities for the Penguin emulation environment.
This module provides classes and helpers for generating configuration patches, handling static and dynamic pseudofiles, network devices, library injection, NVRAM defaults, and other config modifications.
- class penguin.config_patchers.BasePatch(arch_info, inits, kernel_versions)[source]¶
Bases:
PatchGeneratorGenerate base config for static_files and default plugins
- Parameters:
arch_info (str)
inits (list)
kernel_versions (dict)
- UNKNOWN_INIT: str = 'UNKNOWN_FIX_ME'¶
- class penguin.config_patchers.DeleteFiles(extract_dir)[source]¶
Bases:
PatchGeneratorDelete some files we don’t want.
- Parameters:
extract_dir (str)
- class penguin.config_patchers.DynamicExploration[source]¶
Bases:
PatchGeneratorWe are dynamically evaluating and refining a configuration. We need to collect data programatically. Disable root shell, enable coverage-tracking and nmap for coverage generation. Enable VPN so nmap has something to talk to.
Ideally this will also be paired with ShimBusybox to get shell-level instrumentation.
- class penguin.config_patchers.FileHelper[source]¶
Bases:
object- static exists(tmp_dir, target)[source]¶
Check if the target exists within the extracted filesystem in tmp_dir, handling symlinks correctly.
- Parameters:
tmp_dir (str) – The root of the extracted filesystem (e.g., /tmp/extracted)
target (str) – The target path to check (e.g., /foo/zoo)
- Returns:
True if the target exists within tmp_dir, False otherwise
- Return type:
bool
- class penguin.config_patchers.ForceWWW(fs_path)[source]¶
Bases:
PatchGeneratorThis is a hacky FirmAE approach to identify webservers and just start them. Unsurprisingly, it increases the rate of web servers starting. We’ll export this into our static files section so we could later decide to try it. We’ll enable this by default here.
- Parameters:
fs_path (str)
- class penguin.config_patchers.GenerateMissingDirs(archive_path, archive_files)[source]¶
Bases:
PatchGeneratorExamine the fs archive to identify missing directories We ignore the extracted filesystem because we want to ensure symlinks are handled correctly
- Parameters:
archive_path (str)
archive_files (list)
- TARGET_DIRECTORIES: list[str] = ['/proc', '/etc_ro', '/tmp', '/var', '/run', '/sys', '/root', '/tmp/var', '/tmp/media', '/tmp/etc', '/tmp/var/run', '/tmp/home', '/tmp/home/root', '/tmp/mnt', '/tmp/opt', '/tmp/www', '/var/run', '/var/lock', '/usr/bin', '/usr/sbin']¶
- class penguin.config_patchers.GenerateMissingFiles(extract_dir)[source]¶
Bases:
PatchGeneratorEnsure we have /bin/sh, /etc/TZ, /var/run/nvramd.pid, and localhost in /etc/hosts.
- Parameters:
extract_dir (str)
- class penguin.config_patchers.GenerateReferencedDirs(extract_dir)[source]¶
Bases:
PatchGeneratorFirmAE “Boot mitigation”: find path strings in binaries, make their directories if they don’t already exist.
- class penguin.config_patchers.GenerateShellMounts(extract_dir, existing)[source]¶
Bases:
PatchGeneratorEnsure we have /mnt/* directories referenced by shell scripts.
- class penguin.config_patchers.KernelModules(extract_dir, kernel_version)[source]¶
Bases:
PatchGeneratorCreate a symlink from the guest kernel module path to our kernel’s module path. (ie.., /lib/modules/1.2.0-custom -> /lib/modules/4.10.0)
- Parameters:
extract_dir (str)
kernel_version (dict)
- class penguin.config_patchers.LibInjectFixedAliases[source]¶
Bases:
PatchGeneratorSet all aliases in libinject from our defaults.
- class penguin.config_patchers.LibInjectStringIntrospection(library_info)[source]¶
Bases:
PatchGeneratorAdd LibInject aliases for string introspection (e.g., for comparison detection). For each method we see in the filesystem that’s in our list of shim targets, add the shim
- Parameters:
library_info (dict)
- class penguin.config_patchers.LibInjectSymlinks(filesystem_root_path)[source]¶
Bases:
PatchGeneratorDetect the ABI of all libc.so files and place a symlink in the same directory to lib_inject of the same ABI.
- Parameters:
filesystem_root_path (str)
- class penguin.config_patchers.LibInjectTailoredAliases(library_info)[source]¶
Bases:
PatchGeneratorSet default aliases in libinject based on library analysis. If one of the defaults is present in a library, we’ll add it to the libinject alias list
- Parameters:
library_info (dict)
- class penguin.config_patchers.LinksysHack(extract_dir)[source]¶
Bases:
PatchGeneratorLinksys specific hack from FirmAE with pseudofile model.
- Parameters:
extract_dir (str)
- class penguin.config_patchers.ManualInteract[source]¶
Bases:
PatchGeneratorInteractive for manual exploration. Enable root shell, enable vpn. Do not terminate on www bind.
- class penguin.config_patchers.NetdevsDefault[source]¶
Bases:
PatchGeneratorAdd list of default network device names.
- class penguin.config_patchers.NetdevsTailored(netdevs)[source]¶
Bases:
PatchGeneratorAdd list of network device names observed in static analysis.
- Parameters:
netdevs (dict)
- class penguin.config_patchers.NvramConfigRecovery(extract_dir)[source]¶
Bases:
PatchGeneratorSearch for files that contain nvram keys and values to populate NVRAM defaults
- Parameters:
extract_dir (str)
- class penguin.config_patchers.NvramConfigRecoveryWild(extract_dir)[source]¶
Bases:
PatchGeneratorSearch for files that contain nvram keys and values to populate NVRAM defaults. This version relaxes the search to allow for basename matches instead of full path matches.
- Parameters:
extract_dir (str)
- class penguin.config_patchers.NvramDefaults[source]¶
Bases:
PatchGeneratorAdd default nvram values from Firmadyne and FirmAE
- class penguin.config_patchers.NvramFirmAEFileSpecific(fs_path)[source]¶
Bases:
PatchGeneratorApply FW-specific nvram patches based on presence of hardcoded strings in files from FirmAE.
- Parameters:
fs_path (str)
- FIRMAE_TARGETS: dict[str, list[tuple[str, str]]] = {'./lib/libacos_shared.so': [('time_zone_x', '0')], './sbin/acos_service': [('rip_enable', '0')], './sbin/rc': [('ipv6_6to4_lan_ip', '2002:7f00:0001::')], './usr/sbin/httpd': [('rip_multicast', '0'), ('bs_trustedip_enable', '0'), ('filter_rule_tbl', '')]}¶
- class penguin.config_patchers.NvramHelper[source]¶
Bases:
object
- class penguin.config_patchers.NvramLibraryRecovery(library_info)[source]¶
Bases:
PatchGeneratorDuring static analysis the LibrarySymbols class collected key->value mappings from libraries exporting some common nvram defaults symbols (“Nvrams”, “router_defaults”) - add these to our nvram config if we have any.
TODO: if we find multiple nvram source files here, we should generate multiple patches. Then we should consider these during search. For now we just take non-conflicting values from largest to smallest source files. More realistic might be to try each file individually.
- class penguin.config_patchers.PseudofilesExpert[source]¶
Bases:
PatchGeneratorFixed set of pseudofile models from FirmAE.
- class penguin.config_patchers.PseudofilesTailored(pseudofiles)[source]¶
Bases:
PatchGeneratorFor all missing pseudofiles we saw referenced during static analysis, try adding them with a default model
- Parameters:
pseudofiles (dict)
- class penguin.config_patchers.RootShell[source]¶
Bases:
PatchGeneratorAdd root shell
- class penguin.config_patchers.ShimBinaries(files)[source]¶
Bases:
objectIdentify binaries in the guest FS that we want to shim and add symlinks to go from guest bin -> igloo bin into our config.
- class penguin.config_patchers.ShimBusybox(files)[source]¶
Bases:
ShimBinaries,PatchGenerator- Parameters:
files (list)
- class penguin.config_patchers.ShimCrypto(files)[source]¶
Bases:
ShimBinaries,PatchGenerator- Parameters:
files (list)
- class penguin.config_patchers.ShimFwEnv(files)[source]¶
Bases:
ShimBinaries,PatchGeneratorReplace fw_printenv/getenv/setenv with hypercall based alternatives Work in progress. Needs testing
- Parameters:
files (list)
- class penguin.config_patchers.ShimNoModules(files)[source]¶
Bases:
ShimBinaries,PatchGenerator- Parameters:
files (list)
- class penguin.config_patchers.ShimStopBins(files)[source]¶
Bases:
ShimBinaries,PatchGenerator- Parameters:
files (list)
- class penguin.config_patchers.SingleShot[source]¶
Bases:
PatchGeneratorWe are doing a single-shot, automated evaluation. Disable root shell, leave coverage/nmap, but keep VPN on and use fetch_web to collect responses
- class penguin.config_patchers.SingleShotFICD[source]¶
Bases:
PatchGeneratorWe are doing a single-shot, automated evaluation. Disable root shell, but keep VPN on and measure FICD