Leviathan

Posted by

ShellCon – October 2020

Whaddup fellow agent? Heard you were working on the Rockwell case. We got an update from IT staff that one of their VMs doing log analysis got spiked with malware. Yeah the dumpster fire just keeps getting bigger.. Anyway yeah, so their staff saved the vmdk and passed it to us, HQ figures it's better in your hands. Supposedly the malware was found running as root; IT staff attempted to log in to their IT account but found it was already disabled.
Logs are probably wiped, but HQ doesn't want us to focus on that this roun
d -- they want us to investigate this new malware, if you can manage to fin
d it without frying your box. https://drive.google.com/file/d/1rFCkT0JIMBFpf_HyMm2EZwF3FU2O_7IW/view?usp=sharing
You have a good reputation, but as protocol goes I should probably mention you don't want to run the VM directly if you can avoid it. Cheers and best of skill. Safe handling agent~

So, I’m not sure if the name of this challenge refers to the depth to which one needed to dive to find the flag or the size of the file we need to download, Leviathan.tar.gz weighing in at 2.7GB!

Anyway, that’s not too bad because after unzipping and untaring it I end up with RockwellDataHog.vmdk which is 8.4GB. I google how to deal with vmdk files and find that the full 7-zip package can give me access to it. So this is what I do:

Install the full 7-zip package:

$ apt install p7zip-full

List the files that are in RockwellDataHog.vmdk:

$ 7z l RockwellDataHog.vmdk

This shows me that there are 3 files in there, the 12GB one being the most promising:

Date Time  Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
….. 536870912 536870912 0.fat
….. 12344885248 12344885248 1.img
….. 1048576 1048576 2
------------------- ----- ------------ ------------ ------------------------
12882804736 12882804736 3 files

I go ahead and unzip these files:

$ 7z x RockwellDataHog.vmdk

Then I run a file command on 1.img to get more information on it:

$ file 1.img
1.img: Linux rev 1.0 ext4 filesystem data, UUID=a7942f3f-40d8-48e3-b10a-bb7e2f4fc430 (needs journal recovery) (extents) (64bit) (large files) (huge files)

Ok so it’s a Linux filesystem, let’s mount it and hopefully we’ll be able to access it:

$ mkdir /mnt/leviathan
$ mount 1.img /mnt/leviathan
$ cd /mnt/leviathan
$ ls -la
silence@mayday:/mnt/leviathan$ ls -la
total 557152
drwxr-xr-x  23 root root      4096 Oct  7 04:31 .
drwxr-xr-x   7 root root      4096 Oct 11 02:46 ..
drwxr-xr-x   2 root root      4096 Oct  6 14:00 bin
drwxr-xr-x   4 root root      4096 Oct  6 13:59 boot
drwxr-xr-x   2 root root      4096 Oct  6 13:52 cdrom
drwxr-xr-x   5 root root      4096 Jun 24 16:19 dev
drwxr-xr-x 150 root root     12288 Oct  7 00:38 etc
drwxr-xr-x   3 root root      4096 Oct  6 13:53 home
drwxr-xr-x  23 root root      4096 Oct  6 14:00 lib
drwxr-xr-x   2 root root      4096 Jun 24 15:42 lib64
drwx------   2 root root     16384 Oct  6 13:45 lost+found
drwxr-xr-x   2 root root      4096 Jun 24 15:41 media
drwxr-xr-x   2 root root      4096 Jun 24 15:41 mnt
drwxr-xr-x   2 root root      4096 Jun 24 15:41 opt
drwxr-xr-x   2 root root      4096 Apr 15 07:09 proc
drwxrwxrwx   6 root root      4096 Oct  7 04:27 root
drwxr-xr-x  13 root root      4096 Oct  6 13:53 run
drwxr-xr-x   2 root root     12288 Oct  6 14:00 sbin
drwxr-xr-x   2 root root      4096 Jun 24 15:41 srv
-rw-------   1 root root 570393600 Oct  6 13:45 swapfile
drwxr-xr-x   2 root root      4096 Apr 15 07:09 sys
drwxrwxrwt  14 root root      4096 Oct  7 04:27 tmp
drwxr-xr-x  11 root root      4096 Jun 24 15:41 usr
drwxr-xr-x  11 root root      4096 Jun 24 16:22 var

We have access to the filesystem! I start by looking around in the logs (specifically because in the hint we are told not to review them) and then in /home to see who were the users. There is only 1 user called rit. I check his folders and can’t find anything interesting. Then I check his .bash_history to see what he was up to, and find this:

$ more .bash_history
ls
cd ~/Downloads/
ls
la
cd ..
ls
sudo chown -R root:rit .bash_temps/
ls
la
cd .bash_temps/
ls
cd a
ls
cd a
ls
cd ..
ls -la
sudo chmod -r 710 .bash_temps/
sudo chmod -r .bash_temps/ 710
sudo chmod 710 -r .bash_temps/
sudo chmod -r .bash_temps/
sudo chmod 710 -r .bash_temps
sudo chmod -r .bash_temps 710
sudo chmod 710 -R .bash_temps
man chmod 
ls
ls -la
cd .bash_temps/
ls
cd a
ls
cd ..
cd .
cd .b
cat discoclam
cat discoclama
cd ..
ls
cd ..
ls
vi .bashrc

A few things stand out in this .bash_history file which shows the users’ last keystrokes:

  • Line 8: As root, user rit added the group rit to the .bash_temps directory and subdirectories’ permissions.
  • Line 11: User entered the .bash_temps directory.
  • Line 35: User entered the .b directory.
  • Line 36: User ran the mysterious discoclam.

I head to /root, dive into .bash_temps to see what’s going on in there:

silence@mayday:/mnt/leviathan/root/.bash_temps$ ls -la
total 16
drwxrwxrwx 4 root root 4096 Oct  7 04:15 .
drwxrwxrwx 6 root root 4096 Oct  7 04:27 ..
drwxrwxrwx 2 root root 4096 Oct  7 00:39 a
drwxrwxrwx 2 root root 4096 Oct  7 04:23 .b

There’s that .b directory the user had gone into. But I couldn’t resist entering the a directory first. Had it been called c, would I have gone to .b first? We’ll never know. In a, there are 2 files called a and b. In a there is a obviously base64 encoded string: L3Jvb3QvLmJhc2hfdGVtcHMvLmIvZGlzY29jbGFtCg== which decodes to:

silence@mayday$ cat a | base64 -d
/root/.bash_temps/.b/discoclam

Ok so that confirms that I had nothing to do in the a directory and should have gone directly to the .b directory, but I like to leave no stone unturned. I guess a was there to help out CTFers who only use ls and wouldn’t have seen the .b directory with that command.


Hint

Always use ls -la when exploring filesystems so that you won’t miss hidden files and directories!
Add this to your ~/.bashrc file: alias ll='ls -la'


Back in .b, all I find is a single file called discoclam (reference to ShellCon of course!). The file is executable but let’s be cautious and check it out first with file (turns out it’s just ASCII) and then more:

silence@mayday$ more discoclam
echo "ZXZhbCB1bnBhY2sgdT0+cXtNKFIkTz03LVIrVilJO0JdUDk3KUwiQEhENFRFJz5SPSkzRTBHPzJgXSgiPSkxVFkvNEQ0Ry5QSEQ0VEUnCk0+Uj0
oNTVgRz8yYF0oIj0pMVRZLzRENEcuUEhENFRFJz5S
PTQxNSktKVdUQC8yYEcyND0uM1UpJSlTTCoKTSklLSkxV0xHMFRBLDEiPV0oI1RAKVRFJzNEXTIx
MjxbIkIxMzI0PVspVSEzKVdUQC8yYEcyND0uM1UpJQpNKVNMKiJCLUY7JiVHPlMxTDslXFYsMyFS
PjVcVywlXFc6Iy0/OSMkVThTIUMsMzFNPzBJUz02KEA7JiVVCk05VkE/OzYlTjo2JUM4NlFMPjIh
WyJARVA8RkVOPSJgQjs3NUE6JiVBODZBQShDTCoiMjFJO0YxRT4iYF0KTSgjJFsiQEVXOiZFTDky
YEgsMkRAPlBIKSIyMVI7RjxALzIhUjg2WUQqIyhQKjNMKiJARCkpJlFBPTY9SApNKCNUQChCKFsi
QEQpOjY4QCoiMVI7RjxALyJgVSoyIVsiQEQpIjIxTDg3NUc6ImBdKCIpSDgyKFsiQEQpCk0/MEgp
IjY1TDxWRUYoIkBEPEZZRygjUEAsM2BJKCdMKiIwRCkpJlFBPTY9SCgjVEAoRkFBOiYlQTomJEIK
TS5QSCkiN1QqIjBFRTsnLUk5QmBIKScpTjlSYFwoIyRVKjIhWyJARCkiMjFMODc1RzoiYF0oIilI
ODYlSApNODZBQTomJUg4MihbIkBEKT8wSCkiNjVMPFY0QD5QSCkiMEREOyYlVTlWQEAvMmBCNyZZ
TT02JUg4NkFBCk06JiVIODIoWyJARCk/MEgpIjchUjo2WVQoIjFMODc1RzojTCoiMEREOjZZRDk3
QEsqU0wqIjdUKiI3IVIKTTo2WVQoIik8O0IoWyJHVCooUyRUPTM5SCgnPFEtVkBAOzMsKjsmJVU5
VkE/OzYlTjo2JUM4NlFMPjJASQoiLlBIYH0K" | base64 --decode | perl

Of course the end of this file is what we need to examine. It tells us that the string should first be base64 decoded and then run with perl. So the decoded string will most probably be a perl script. Should we run it and see what it does? Of course not! Ok. Let’s run it.

Ok, I can’t stop the laughter (the one on the screen, at this point I’m not laughing), CTRL-C doesn’t work, I have to close the shell window or kill the process to stop humiliation. I knew I shouldn’t have run this. But this is a CTF, the organizers wouldn’t let us run malware, right? RIGHT? So it felt safe to run it for that reason and also because I’m running it in an expendable vm.

After fighting with my terminal to end this, I shamelessly admitted to having done the undoable.

Alright let’s get to the bottom of this. Now we know that the perl script displays this never ending happiness on our screen, but maybe we can make it do something else, like spit out a flag? Let’s examine the code. I copy discoclam to discosafe and remove | perl from the end of the file to output the decoded string which is supposed to be the perl script. Here is what I end up with:

silence@mayday$ ./discosafe 
eval unpack u=>q{M(R$O=7-R+V)I;B]P97)L"@HD4TE'>R=)3E0G?2`]("=)1TY/4D4G.PHD4TE'
M>R=(55`G?2`]("=)1TY/4D4G.PHD4TE'>R=415)-)WT@/2`G24=.3U)%)SL*
M)%-)1WLG0TA,1"=](#T@)TE'3D]212<["B1324=[)U!3)WT@/2`G24=.3U)%
M)SL*"B-F;&%G>S1L;%\V,3!R>5\W,%\W:#-?9#$U8S!C,31M?0IS=6(@;&%U
M9VA?;6%N:6%C86QL>2!["@EP<FEN="`B;75A:&%A86AA(CL*"21I;F1E>"`]
M(#$["@EW:&EL92`H,2D@>PH)"21R;F<@/2!R86YD*#(P*3L*"@D))&QA=6=H
M(#T@(B(["@D):68@*"1R;F<@/"`U*2!["@D)"21L875G:"`](")H82(["@D)
M?0H)"65L<VEF("@D<FYG(#P@,3`I('L*"0D))&QA=6=H(#T@(FAA:&%A:&$B
M.PH)"7T*"0EE;'-I9B`H)')N9R`\(#$U*2!["@D)"21L875G:"`](")H86%H
M86AA:&%H82(["@D)?0H)"65L<V4@>PH)"0DD;&%U9V@@/2`B7&YM=6%H86AA
M:&%H82(["@D)?0H)"7!R:6YT("1L875G:#L*"0DD:6YD97@K*SL*"7T*"7!R
M:6YT(")<;B(["GT*(S$T=39H('<Q-V@@;3,*;&%U9VA?;6%N:6%C86QL>2@I
".PH`}
Now I’ve created perl scripts in the past but none looked as artistic as this one.

One thing I know though is that perl’s eval function will execute whatever is its parameter. One trick we can use in this case is to replace eval by print and then run the file through perl again. So once again I copy discosafe to discoprint in which I made the aforementioned replacement. It looks like this now:

silence@mayday$ more discoprint 
print unpack u=>q{M(R$O=7-R+V)I;B]P97)L"@HD4TE'>R=)3E0G?2`]("=)1TY/4D4G.PHD4TE'
M>R=(55`G?2`]("=)1TY/4D4G.PHD4TE'>R=415)-)WT@/2`G24=.3U)%)SL*
M)%-)1WLG0TA,1"=](#T@)TE'3D]212<["B1324=[)U!3)WT@/2`G24=.3U)%
M)SL*"B-F;&%G>S1L;%\V,3!R>5\W,%\W:#-?9#$U8S!C,31M?0IS=6(@;&%U
M9VA?;6%N:6%C86QL>2!["@EP<FEN="`B;75A:&%A86AA(CL*"21I;F1E>"`]
M(#$["@EW:&EL92`H,2D@>PH)"21R;F<@/2!R86YD*#(P*3L*"@D))&QA=6=H
M(#T@(B(["@D):68@*"1R;F<@/"`U*2!["@D)"21L875G:"`](")H82(["@D)
M?0H)"65L<VEF("@D<FYG(#P@,3`I('L*"0D))&QA=6=H(#T@(FAA:&%A:&$B
M.PH)"7T*"0EE;'-I9B`H)')N9R`\(#$U*2!["@D)"21L875G:"`](")H86%H
M86AA:&%H82(["@D)?0H)"65L<V4@>PH)"0DD;&%U9V@@/2`B7&YM=6%H86AA
M:&%H82(["@D)?0H)"7!R:6YT("1L875G:#L*"0DD:6YD97@K*SL*"7T*"7!R
M:6YT(")<;B(["GT*(S$T=39H('<Q-V@@;3,*;&%U9VA?;6%N:6%C86QL>2@I
".PH`}

Ok now let’s run perl on this baby:

silence@mayday$ perl discoprint 
#!/usr/bin/perl

$SIG{'INT'} = 'IGNORE';
$SIG{'HUP'} = 'IGNORE';
$SIG{'TERM'} = 'IGNORE';
$SIG{'CHLD'} = 'IGNORE';
$SIG{'PS'} = 'IGNORE';

#flag{4ll_610ry_70_7h3_d15c0c14m}
sub laugh_maniacally {
        print "muahaaaha";
        $index = 1;
        while (1) {
                $rng = rand(20);

                $laugh = "";
                if ($rng < 5) {
                        $laugh = "ha";
                }
                elsif ($rng < 10) {
                        $laugh = "hahaaha";
                }
                elsif ($rng < 15) {
                        $laugh = "haahahahaha";
                }
                else {
                        $laugh = "\nmuahahahaha";
                }
                print $laugh;
                $index++;
        }
        print "\n";
}
#14u6h w17h m3
laugh_maniacally();

A few things here:

  • Line 2: This confirms that this is a perl script
  • Line 4: This is what prevented me from ending the script with CTRL-C, nice move!
  • Line 10: There’s our flag! All Glory to the Discoclam in 1337 in leet speak!
  • Line 14: This is what makes the script author laugh endlessly…
  • Line 35: More leet speak, ok now there’s a grin on my face 🙂

If you’re still reading, thanks! I hope you found this interesting or that part of it at least helped you solve another similar challenge. If you’ve used alternative ways to solve this, please let me know in the comments below, thanks!


Awesome challenge put together by @S1rDr0n3.

Props to the organizers of ShellCon, the event was awesome! The talks, workshops, CTF, See you next year!

Leviathan illustration by the talented Jeff Chang.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s