Log in using the password for the level i.e., UN - leviathan0, PW - leviathan0. Showing the contents of the current directory using ls, we see -
leviathan0@leviathan:~$ ls -la
total 24
drwxr-xr-x 3 root root 4096 Oct 29 21:17 .
drwxr-xr-x 10 root root 4096 Oct 29 21:17 ..
drwxr-x--- 2 leviathan1 leviathan0 4096 Oct 29 21:17 .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
The .backup
folder seems interesting, therefore, changing directory to that and enumerating further, we see -
leviathan0@leviathan:~$ cd .backup/
leviathan0@leviathan:~/.backup$ ls -la
total 140
drwxr-x--- 2 leviathan1 leviathan0 4096 Oct 29 21:17 .
drwxr-xr-x 3 root root 4096 Oct 29 21:17 ..
-rw-r----- 1 leviathan1 leviathan0 133259 Oct 29 21:17 bookmarks.html
The bookmarks html file must contain the password for the next level. Therefore, searching the file for the word password using grep, we get -
leviathan0@leviathan:~/.backup$ cat bookmarks.html | grep password
<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>
This has the next password as rioGegei8m
.
Logging in with the required credentials, and upon enumerating, we see -
leviathan1@leviathan:~$ ls -la
total 28
drwxr-xr-x 2 root root 4096 Oct 29 21:17 .
drwxr-xr-x 10 root root 4096 Oct 29 21:17 ..
-rw-r--r-- 1 root root 220 May 15 2017 .bash_logout
-rw-r--r-- 1 root root 3526 May 15 2017 .bashrc
-r-sr-x--- 1 leviathan2 leviathan1 7452 Oct 29 21:17 check ----------------------> setuid
-rw-r--r-- 1 root root 675 May 15 2017 .profile
We see a setuid binary. Setuid helps the current user i.e., leviathan1 to execute the binary with the elevated permissions of another user i.e., leviathan2. Therefore, executing it directly shows this -
leviathan1@leviathan:~$ ./check
password: hello
Wrong password, Good Bye ...
To see what library calls are being made, we can even use ltrace
. This gives the following output -
leviathan1@leviathan:~$ ltrace ./check
__libc_start_main(0x804853b, 1, 0xffffd794, 0x8048610 <unfinished ...>
printf("password: ") = 10
getchar(1, 0, 0x65766f6c, 0x646f6700password: hello
) = 104
getchar(1, 0, 0x65766f6c, 0x646f6700) = 101
getchar(1, 0, 0x65766f6c, 0x646f6700) = 108
strcmp("hel", "sex") = -1 ---------------> compares with sex
puts("Wrong password, Good Bye ..."Wrong password, Good Bye ...
) = 29
+++ exited (status 0) +++
Therefore, we can use the password sex
to correctly execute the binary.
leviathan1@leviathan:~$ ./check
password: sex
$ whoami
leviathan2
$ cat /etc/leviathan_pass/leviathan2
ougahZi8Ta
Therefore, the password of the next level is ougahZi8Ta
.
Enumerating shows following -
leviathan2@leviathan:~$ ls -l
total 8
-r-sr-x--- 1 leviathan3 leviathan2 7436 Oct 29 21:17 printfile -------------> setuid
We have another setuid. Executing this shows -
leviathan2@leviathan:~$ ./printfile
*** File Printer ***
Usage: ./printfile filename
Thus executing this with a given filename, we get the following -
leviathan2@leviathan:~$ ./printfile /etc/leviathan_pass/leviathan3
You cant have that file...
To check what is going on, we can use the ltrace again -
leviathan2@leviathan:~$ ltrace ./printfile /etc/leviathan_pass/leviathan3
__libc_start_main(0x804852b, 2, 0xffffd754, 0x8048610 <unfinished ...>
access("/etc/leviathan_pass/leviathan3", 4) = -1
puts("You cant have that file..."You cant have that file...
) = 27
+++ exited (status 1) +++
This shows that there is a method called access, which is used to check if the user currently calling the program has access to that file. Therefore, we can make a file which we have permission to read and see what the program does -
leviathan2@leviathan:~$ mkdir /tmp/tangtiphongkul/
leviathan2@leviathan:~$ chmod +777 /tmp/tangtiphongkul/
leviathan2@leviathan:~$ chmod +777 /tmp/tangtiphongkul/ -R
leviathan2@leviathan:~$ ltrace ./printfile /tmp/tangtiphongkul/hi
__libc_start_main(0x804852b, 2, 0xffffd754, 0x8048610 <unfinished ...>
access("/tmp/tangtiphongkul/hi", 4) = 0
snprintf("/bin/cat /tmp/tangtiphongkul/hi", 511, "/bin/cat %s", "/tmp/tangtiphongkul/hi") = 31
geteuid() = 12002
geteuid() = 12002
setreuid(12002, 12002) = 0
system("/bin/cat /tmp/tangtiphongkul/hi" <no return ...>
--- SIGCHLD (Child exited) ---
<... system resumed> ) = 0
+++ exited (status 0) +++
Therefore, we see that the program calls /bin/cat
to read the contents from the file. To fool the program into thinking that we have the permission to read the password of the next level, we can use some properties of cat
. Two filenames given one after the other separated with spaces combines the contents of the two files when given as arguments to /bin/cat
. Thus if we give the filename of two files which are actually a single file with the name separated by spaces, cat will treat it as a combination of 2 different filenames.
Therefore, to work around this, we can try and create a symbolic link to the password file of leviathan3. We can do this in the following way -
leviathan2@leviathan:~$ cd /tmp/tangtiphongkul
leviathan2@leviathan:/tmp/tangtiphongkul$ ls
leviathan2@leviathan:/tmp/tangtiphongkul$ ln -s /etc/leviathan_pass/leviathan3 ./hello
leviathan2@leviathan:/tmp/tangtiphongkul$ ls -l
total 0
lrwxrwxrwx 1 leviathan2 leviathan2 30 Mar 15 14:58 hello -> /etc/leviathan_pass/leviathan3
leviathan2@leviathan:/tmp/tangtiphongkul$ touch "hello bye"
leviathan2@leviathan:/tmp/tangtiphongkul$ ls -l
total 0
lrwxrwxrwx 1 leviathan2 leviathan2 30 Mar 15 15:00 hello -> /etc/leviathan_pass/leviathan3
-rw-r--r-- 1 leviathan2 leviathan2 0 Mar 15 15:05 hello bye
-rw-r--r-- 1 leviathan2 leviathan2 0 Mar 15 15:08 hi
Therefore, we can use this as an input.
leviathan2@leviathan:/tmp/tangtiphongkul$ ~/printfile "hello bye"
Ahdiemoo1j
/bin/cat: bye: No such file or directory
Therefore, the password is Ahdiemoo1j
.
Logging in, we see another setuid -
leviathan3@leviathan:~$ ls -l
total 12
-r-sr-x--- 1 leviathan4 leviathan3 10288 Oct 29 21:17 level3
On running ltrace on the binary, we get the next password quite easily -
leviathan3@leviathan:~$ ./level3
Enter the password> hi
bzzzzzzzzap. WRONG
leviathan3@leviathan:~$ ltrace ./level3
__libc_start_main(0x8048618, 1, 0xffffd794, 0x80486d0 <unfinished ...>
strcmp("h0no33", "kakaka") = -1
printf("Enter the password> ") = 20
fgets(Enter the password> hi
"hi\n", 256, 0xf7fc55a0) = 0xffffd5a0
strcmp("hi\n", "snlprintf\n") = -1
puts("bzzzzzzzzap. WRONG"bzzzzzzzzap. WRONG
) = 19
+++ exited (status 0) +++
leviathan3@leviathan:~$ ./level3
Enter the password> snlprintf
[You've got shell]!
$ whoami
leviathan4
$ cat /etc/leviathan_pass/leviathan4
vuH0coox6m
Therefore, the password for the next level is vuH0coox6m
.
Logging in with the password from the previous level, we see -
leviathan4@leviathan:~$ ls -la
total 24
drwxr-xr-x 3 root root 4096 Oct 29 21:17 .
drwxr-xr-x 10 root root 4096 Oct 29 21:17 ..
-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 21:17 .trash
The .trash
directory is the one out of place. Changing to that for enumeration, we see another setuid -
leviathan4@leviathan:~$ cd .trash/
leviathan4@leviathan:~/.trash$ ls -l
total 8
-r-sr-x--- 1 leviathan5 leviathan4 7352 Oct 29 21:17 bin
Running the executable gives the following output -
leviathan4@leviathan:~/.trash$ ./bin
01010100 01101001 01110100 01101000 00110100 01100011 01101111 01101011 01100101 01101001 00001010
On using python to convert to binary numbers to ascii, we get -
leviathan4@leviathan:~/.trash$ python3 -q
>>> import binascii
>>> n = int('0b0101010001101001011101000110100000110100011000110110111101101011011001010110100100001010', 2)
>>> binascii.unhexlify("%x" % n)
b'Tith4cokei\n'
Thus the password for the next level is Tith4cokei
.
Enumerating with the new login, we get another setuid -
leviathan5@leviathan:~$ ls -l
total 8
-r-sr-x--- 1 leviathan6 leviathan5 7560 Oct 29 21:17 leviathan5
Running the binary gives -
leviathan5@leviathan:~$ ./leviathan5
Cannot find /tmp/file.log
Therefore, we need to create a symbolic link for the given filename i.e, /tmp/file.log
. To do this we can again go to the directory created initially and make a new symbolic link -
leviathan5@leviathan:~$ cd /tmp/tangtiphongkul
leviathan5@leviathan:/tmp/tangtiphongkul$ ls
hello hello bye hi
leviathan5@leviathan:/tmp/tangtiphongkul$ rm *
rm: remove write-protected regular empty file 'hello bye'? yes
rm: remove write-protected regular empty file 'hi'? yes
leviathan5@leviathan:/tmp/tangtiphongkul$ ln -s /etc/leviathan_pass/leviathan6 "/tmp/file.log"
leviathan5@leviathan:/tmp/tangtiphongkul$ ~/leviathan5
UgaoFee4li
This gives the password for the next level as UgaoFee4li
.
Logging in with the new password, we see another setuid -
leviathan6@leviathan:~$ ls -l
total 8
-r-sr-x--- 1 leviathan7 leviathan6 7452 Oct 29 21:17 leviathan6
On executing, we see that it requires a 4 digit passcode. Therefore, we need to figure out the 4 digit passcode. This can be done in gdb as follows -
leviathan6@leviathan:~$ ./leviathan6
usage: ./leviathan6 <4 digit code>
leviathan6@leviathan:~$ ./leviathan6 1234
Wrong
leviathan6@leviathan:~$ gdb -q ./leviathan6
Reading symbols from ./leviathan6...(no debugging symbols found)...done.
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x0804853b <+0>: lea ecx,[esp+0x4]
0x0804853f <+4>: and esp,0xfffffff0
0x08048542 <+7>: push DWORD PTR [ecx-0x4]
0x08048545 <+10>: push ebp
0x08048546 <+11>: mov ebp,esp
0x08048548 <+13>: push ebx
0x08048549 <+14>: push ecx
0x0804854a <+15>: sub esp,0x10
0x0804854d <+18>: mov eax,ecx
0x0804854f <+20>: mov DWORD PTR [ebp-0xc],0x1bd3 --------------> same location from line main+84
0x08048556 <+27>: cmp DWORD PTR [eax],0x2
0x08048559 <+30>: je 0x804857b <main+64>
0x0804855b <+32>: mov eax,DWORD PTR [eax+0x4]
0x0804855e <+35>: mov eax,DWORD PTR [eax]
0x08048560 <+37>: sub esp,0x8
0x08048563 <+40>: push eax
0x08048564 <+41>: push 0x8048660
0x08048569 <+46>: call 0x80483b0 <printf@plt>
0x0804856e <+51>: add esp,0x10
0x08048571 <+54>: sub esp,0xc
0x08048574 <+57>: push 0xffffffff
0x08048576 <+59>: call 0x80483f0 <exit@plt>
0x0804857b <+64>: mov eax,DWORD PTR [eax+0x4]
0x0804857e <+67>: add eax,0x4
0x08048581 <+70>: mov eax,DWORD PTR [eax]
0x08048583 <+72>: sub esp,0xc
0x08048586 <+75>: push eax
0x08048587 <+76>: call 0x8048420 <atoi@plt> --------------> this function converts our string input to integer
0x0804858c <+81>: add esp,0x10
0x0804858f <+84>: cmp eax,DWORD PTR [ebp-0xc] --------------> After that these locations are compared.
0x08048592 <+87>: jne 0x80485bf <main+132>
0x08048594 <+89>: call 0x80483c0 <geteuid@plt>
0x08048599 <+94>: mov ebx,eax
0x0804859b <+96>: call 0x80483c0 <geteuid@plt>
0x080485a0 <+101>: sub esp,0x8
0x080485a3 <+104>: push ebx
0x080485a4 <+105>: push eax
0x080485a5 <+106>: call 0x8048400 <setreuid@plt>
0x080485aa <+111>: add esp,0x10
0x080485ad <+114>: sub esp,0xc
0x080485b0 <+117>: push 0x804867a
0x080485b5 <+122>: call 0x80483e0 <system@plt>
0x080485ba <+127>: add esp,0x10
0x080485bd <+130>: jmp 0x80485cf <main+148>
0x080485bf <+132>: sub esp,0xc
0x080485c2 <+135>: push 0x8048682
0x080485c7 <+140>: call 0x80483d0 <puts@plt>
0x080485cc <+145>: add esp,0x10
0x080485cf <+148>: mov eax,0x0
0x080485d4 <+153>: lea esp,[ebp-0x8]
0x080485d7 <+156>: pop ecx
0x080485d8 <+157>: pop ebx
0x080485d9 <+158>: pop ebp
0x080485da <+159>: lea esp,[ecx-0x4]
0x080485dd <+162>: ret
End of assembler dump.
(gdb)
Seeing as the locations are compared, one of them must contain the location of the 4 digit code we desire. We also find in the beginning of the code that the same location is used in a mov statement, where a value of 0x1bd3 is moved into it. Using python to convert this into integer, we get -
leviathan6@leviathan:~$ python -c "print(0x1bd3)"
7123
Therefore, using this to authenticate the binary as the 4 digit code, we get -
leviathan6@leviathan:~$ ./leviathan6 7123
$ whoami
leviathan7
$ cat /etc/leviathan_pass/leviathan7
ahy7MaeBo9
Therefore, the password for the next level is ahy7MaeBo9
.
Logging in, we see -
leviathan7@leviathan:~$ ls
CONGRATULATIONS
leviathan7@leviathan:~$ cat CONGRATULATIONS
Well Done, you seem to have used a *nix system before, now try something more serious.
(Please don't post writeups, solutions or spoilers about the games on the web. Thank you!)
Hence, all levels are complete.