Leviathan

Leviathan0

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.


Leviathan1

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.


Leviathan2

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.


Leviathan3

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.


Leviathan4

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.


Leviathan5

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.


Leviathan6

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.


Leviathan7

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.