For a few years now I’ve had a small project in mind. I wanted to make a game where you’re on a host computer and need to work out the story by navigating around the filesystem and using Linux applications. Finally this year I started experimenting with a story and came up with the first tiny and short demo for Outpost 73. You can play it in it’s current form via a web browser.
Setting
You’re a new digital forensics intern at ScorpInc in 1991 and you’ve been tasked with working out why remote outpost #73 has stopped reporting in. Thankfully you have access to one user’s account due to their lax password use (seriously, “password”? they’ll be sanctioned for that in this life or the next) and you need to read emails and files and jump between users as you discover passwords and hints. It’s a pretty short demo and if you’re reading Hiro’s emails then you’re probably done. ;) For those not familiar with Linux (or any *nix terminal) or wanting a bit of an experience of the game and fictional(?) world it exists in, I’d recommend following the tutorial.
Challenge #1: Tutorial
How do you teach people how to use the Linux (or the Scorpion Systems 6000 Series Operating System) terminal while they’re already in the terminal? I thought the easiest and lowest tech way around this was to modify the motd
or Message Of The Day, a customisable message that shows when you log in to a Linux terminal. There I informed users to simply type a particular command and then press Enter.
That command was cat
followed by the path of a text file I’d already pre-placed on the system. That text file describes what the user did and the command they used and then leads them to run more commands. These commands tell them to look in a directory (ls
) and then try and cat
out the next tutorial text file to the standard output. Using this system, we also get them to explore cd
and provide optional tutorials about using the system’s mail client (alpine
). In this way I didn’t need to actually write any code, just throw a bunch of files into the user’s home directory and let them discover that magic themselves.
With the exception of the email client, I wanted to avoid using any custom applications such as choosing particular editors. This way users can learn some pure command-line-fu.
Challenge #2: Story Content
This one was pretty easy really. I just set up all the users I wanted on a Linux virtual machine and then got them to send a bunch of emails to each other. This way it’d populate the /var/mail/USER
files and include all the necessary email headers to be recognised by the mail client on the system if I just dropped them in there on a fresh install. Of course, I had to manually edit all the dates to match the right time period and also remove a lot of extraneous emails (all the in-between replies). My biggest regret is accidentally wiping the sent items, maybe I’ll redo them in a future version.
For IRC logs I set up an IRC server on my virtual machine and used irssi
to join from multiple users and save logs. These were then kept as well to be dropped in home directories on a fresh install.
Challenge #3: A Fresh Install For Each Player
The very first play test by someone else was done on a DigitalOcean droplet I set up for that purpose. They were pretty happy with the experience and seemed interested that it was a fully fledged operating system they were playing around with that they could modify (such as send new emails or edit files). While it meant the game wasn’t an on rails experience or a subset of functionality provided by an OS, it did present a challenge: people could mess with the files/emails/system and ruin the experience for others!
I wanted a way to solve this and so I Dockerised my application into a single container containing everything needed to play the game, including an SSH agent. Of course, this limited the game to only people who had experience in installing and running Docker and the willingness to run everything just to play my demo.
So I overcame this with the hackiest hack hack that ever hacked. I created a host virtual machine on Digital Ocean and then created the user to which people would connect. I then modified /etc/ssh/sshd_config
to match against that user and added ForceCommand /home/user/hijack-ssh.sh
.
What does hijack-ssh.sh
do?
TIMESTAMP=$(date +%s)
sudo docker run -d -P --name lm$TIMESTAMP lostmachine:dev
PORT=$(sudo docker port lm$TIMESTAMP 22 | sed -n 's/^0.0.0.0\:\(.*\)/\1/p')
ssh rob@localhost -p $PORT
We store the users current Unix timestamp and then spin up a new Docker container named after that timestamp. We then get the SSH port of that Docker container and start an SSH connection to it!
Now the user is required to type in Rob’s password (thankfully it’s just “password”) and they’ll be automatically dropped into the game. Since hijack-ssh.sh
doesn’t end by dropping the user to a prompt, when they exit out of the inner SSH session they’ll be automatically booted off the host server.
Challenge #4: Web users
For the last challenge, I wanted to be open up my game to anyone on a web browser, not just people who knew SSH. So I used SSHy to create a web SSH session that connects to a web socket and forwards the connection to the SSH server. I also put a little explanatory page to give some game background and after some feedback.
What’s Next?
I want to work more on this, I want to develop the story and add more content. I want to make it more complex as well, forcing users to learn about hidden files, maybe network shares, have interactive IRC bots and so on. From the infrastructure side I’d like to have users sessions remembered, which means I need both an accounts system and a way of saving and storing the containers between plays. We’ll see though, watch this space.