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

 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:
password to leviathan1 

# 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 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 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 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 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 --- 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 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 --- 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 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 --- 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 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 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 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