Ubuntu 0.1.0 Write Up
I will make new posts in the future that cover the changes made to this image from version to version. This post will have three main sections: the scoring system, an explanation of what I’ve done to it and how to fix it, and future plans for this image.
You can download a pre-built version of this virtual machine here: https://files.gingertechnology.net/packersystems/BUILDS/
It is the one called UbuntuWeb.zip. The source code to build this image with Packer, as well as some brief instructions on how to do so, can be found here:
To see the README files for this image, go to http://localhost within the VM, and then open the post that says README.
The scoring system is currently not in a state that I am terribly proud of. It’s a single shell script that is in plaintext and can be read by the player. So I plan to change that as soon as I decide on a better way to handle it. The way that the scoring engine currently functions is that every 15 minutes a cron job runs the script, which then goes through a set of checks. These checks can include seeing if a line is changed in a file, checking if a vulnerability is still present, etc. After finishing that, the engine reports the findings to a text file. If a player wants immediate feedback for something they’ve done, they also have the ability to run the script manually whenever they want. This ability is important in a practice system like this one, where a user needs to be sure that the part they’ve just changed is actually what caused them to get positive feedback. That output is then put into a WordPress post on the web server that the VM is hosting.
As of writing this, I do not have checks running for everything that I plan to check in a final version. For example, I do not have it check that the MySQL password for root and administrator are changed.
Guide for Version 0.1.0 of Ubuntu
The account that a user will be using to solve this image is the “administrator” account with the password “UberPassword”. Upon logging in, I recommend doing a quick check of the system, for example seeing which services are running by using a command such as
ps -e and checking which ports are being used with a command such as
netstat -tulpn | grep LISTEN. After making note of that, I recommend then moving on to checking users, my preferred method for this is
cat /etc/passwd | grep sh, which will list out all accounts on the system that have a login shell containing the characters “sh”, which will include shells such as bash, csh, zsh, and dash. Any user that has one of those shells will be able to log in. One could do a similar check of
/etc/shadow to see which users have passwords, and I recommend doing both, but if I were to have to pick one, I would go with checking passwd, since that will tell me which login shell the user has.
After finishing up inventory of the system, let’s get into making it not terrible. To start with, since it could cause problems later if not fixed, it is best to prioritize patching Shellshock. By now you may have had the system randomly reboot on you. If you haven’t, then every 45 minutes, there is a cronjob that will reboot the system using an old exploit called Shellshock that has been patched for every version of Bash since a bit before Ubuntu 16.04 was released. I purposefully installed an older version of the Bash shell in order to bring it back. Fixing it is a simple matter of doing
sudo apt upgrade bash and then waiting until the update finishes.
With the most breaking issue patched, let’s move on to adjusting user permissions. As stated in the README, the only users that should have sudo privileges are:
If any other user has sudo access, they should be removed from the sudo group. And if one of these users does not have sudo access, then it should be granted. To check who currently has access, we can use the command
cat /etc/group | grep sudo. The usernames that get listed currently have sudo privileges. To fix this, you can use the Ubuntu user manager, modify the file directly, or use the usermod tool. However you prefer, do that and fix the incorrect privileges.
Next up, it is stated in the README that the only ways to access the server should be web, SSH, and FTP. The README also explicitly lists VNC as not being allowed, since the admin won’t need a GUI when connecting. To see if we have any VNC installed via the package manager, let’s try doing
apt list --installed | grep vnc. To check if any others remain, such as a VNC client or server that was installed from source files, one can modify the command used above to be
find / | grep -i vnc, with the “-i” making the search non-case sensitive. The downside to this is that:
- The search will through every file and folder in the system.
- It is possible that there will be cache files with “vnc” in the name
- The match does not have to be perfect. For example, let’s say that you use the exact command above, and in some part of the filesystem there is a folder that ends in “vn” and there’s another folder in that folder that starts with “c”. This will give a positive match, and will show up because it is technically “vn/c”. grep will ignore the “/”.
In the case of this challenge, only the
apt list command is needed, since I only installed a VNC server using apt, but it would be good to note the other method in case it might be needed in the future. With remote connection options limited to only authorized ones, on to securing them.
SSH is a secure way of connecting to a remote Linux or BSD machine and is the primary method of accessing both. As such, it is important to make sure that its settings are set to be as secure as possible. You can open the file with nano, vi, vim, kate, etc. by doing
sudo (editor) /etc/ssh/sshd_config. The first change that should be made is switching from Protocol 1 to Protocol 2. 2 is a more recently made and secure connection protocol and is therefore preferred. Next up, since administrative commands are being given to this system via sudo rather than directly by the root user, we can set PermitRootLogin to “no”. And you should set PermitEmptyPasswords to “no”. While circumstances probably exist that would make it necessary to allow empty passwords, none exist on this system.
Before securing our FTP server, let’s make a quick stop by the hosts file. Before doing that though, if you haven’t already, try visiting a search engine such as Google, duckduckgo, startpage, or Bing. Notice anything odd? Depending on which one of those you picked, you’ll either have been routed to localhost or never made a connection. This is because of what we are about to fix. In the hosts file (
/etc/hosts) you should at the bottom of the file something like this:
The way a hosts file works is that it sets the domain names on the right to be routed to the IP address on the left, with 0.0.0.0 meaning localhost, and 18.104.22.168 being a random Amazon IP address that won’t connect you to anything. To fix these issues and regain the use of search engines, you can just remove these lines and either reboot the virtual machine or restart the networking service.
Finally, let’s do some basic FTP configuration. Open
/etc/vsftpd.conf in your editor of choice, using the command
sudo (editor) /etc/vsftpd.conf. Near the top, disallow anonymous connections by setting
anonymous_enable to “NO”. One should also enable logging by setting
xferlog_enable to “YES”. Since only authorized company employees should be able to upload to and change files in on the webserver, disable anon_upload_enable. And finally, in the future the company will want secure FTP, so set
ssl_enable to “YES”.
Future Plans for This Image
Going forward with this image, I plan to get more in-depth with my checks and have more of them. For example, right now I do not check the MySQL password or whether or not WordFence has been enabled, but I have plans to look for both. At the moment, I am building a better scoring engine in Go. While the current version of it is built specifically for the checks that I need for this image and the two Windows ones, it should be possible to build a more modular system in the future where checks can be changed without a recompile, or still require a rebuild but be simpler edit.
I am also thinking of some possible forensics questions I could use for these. I will probably have several different ones and two will get selected at random each deployment.
Thank you for reading and I hope you make good use of this image! If you have any feedback, feel free to comment and I’ll make sure to reply so that we can discuss any problems or ideas that you have.