War Games at OverTheWire: Leviathan

Leviathan Description

Leviathan is a beginner-friendly wargame hosted on OverTheWire.org. It focuses on teaching basic Linux commands and common sense rather than programming knowledge, although it was very handy to know how to use Python and being able to analyse disassembly.

There are 8 levels, each requiring solving a challenge to progress. It’s all about finding the clues and exploiting vulnerabilities within a simulated Linux environment.

OverTheWire describes Leviathan as having a difficulty of 1/10, making it a great starting point for those new to cybersecurity and wargaming.

Instead of detailed walkthroughs for each level, I’ll focus on my thought process as I encounter each challenge. Expect more of a stream-of-consciousness as I navigate through the levels, hopefully providing insights into how I approach problem-solving in this capture-the-flag environment.

https://overthewire.org/wargames/leviathan

Level 0

The command-line tool that actually understands regular expressions.

File identified, long shot using ‘grep’, however, it worked.

leviathan0@gibson:~$ id
uid=12000(leviathan0) gid=12000(leviathan0) groups=12000(leviathan0)
leviathan0@gibson:~$ ls -la
total 24
drwxr-xr-x  3 root       root       4096 Sep 19 07:07 .
drwxr-xr-x 83 root       root       4096 Sep 19 07:09 ..
drwxr-x---  2 leviathan1 leviathan0 4096 Sep 19 07:07 .backup
-rw-r--r--  1 root       root        220 Mar 31  2024 .bash_logout
-rw-r--r--  1 root       root       3771 Mar 31  2024 .bashrc
-rw-r--r--  1 root       root        807 Mar 31  2024 .profile
leviathan0@gibson:~$ cd .backup/
leviathan0@gibson:~/.backup$ ls -la
total 140
drwxr-x--- 2 leviathan1 leviathan0   4096 Sep 19 07:07 .
drwxr-xr-x 3 root       root         4096 Sep 19 07:07 ..
-rw-r----- 1 leviathan1 leviathan0 133259 Sep 19 07:07 bookmarks.html
leviathan0@gibson:~/.backup$ grep "password" bookmarks.html 
<DT><A HREF="http://leviathan.labs.overthewire.org/passwordus.html | This will be fixed later, the password for leviathan1 is 3QJ3TgzHDq" ADD_DATE="1155384634" LAST_CHARSET="ISO-8859-1" ID="rdf:#$2wIU71">password to leviathan1</A>

Level 1

Exposing your code’s dirty little secrets.

I have used ‘ltrace’ in the past without a luck, but today, it was the jackpot.

leviathan1@gibson:~$ id
uid=12001(leviathan1) gid=12001(leviathan1) groups=12001(leviathan1)
leviathan1@gibson:~$ ls -la
total 36
drwxr-xr-x  2 root       root        4096 Sep 19 07:07 .
drwxr-xr-x 83 root       root        4096 Sep 19 07:09 ..
-rw-r--r--  1 root       root         220 Mar 31  2024 .bash_logout
-rw-r--r--  1 root       root        3771 Mar 31  2024 .bashrc
-r-sr-x---  1 leviathan2 leviathan1 15080 Sep 19 07:07 check
-rw-r--r--  1 root       root         807 Mar 31  2024 .profile
leviathan1@gibson:~$ ./check
password: password
Wrong password, Good Bye ...
leviathan1@gibson:~$ ltrace ./check
__libc_start_main(0x80490ed, 1, 0xffffd474, 0 <unfinished ...>
printf("password: ")                                                       = 10
getchar(0, 0, 0x786573, 0x646f67password: password
)                                          = 112
getchar(0, 112, 0x786573, 0x646f67)                                        = 97
getchar(0, 0x6170, 0x786573, 0x646f67)                                     = 115
strcmp("pas", "sex")                                                       = -1
puts("Wrong password, Good Bye ..."Wrong password, Good Bye ...
)                                       = 29
+++ exited (status 0) +++
leviathan1@gibson:~$ ./check
password: sex
$ id
uid=12002(leviathan2) gid=12001(leviathan1) groups=12001(leviathan1)
$ ls -la
total 36
drwxr-xr-x  2 root       root        4096 Sep 19 07:07 .
drwxr-xr-x 83 root       root        4096 Sep 19 07:09 ..
-rw-r--r--  1 root       root         220 Mar 31  2024 .bash_logout
-rw-r--r--  1 root       root        3771 Mar 31  2024 .bashrc
-r-sr-x---  1 leviathan2 leviathan1 15080 Sep 19 07:07 check
-rw-r--r--  1 root       root         807 Mar 31  2024 .profile
$ cd /etc/leviathan_pass
$ cat leviathan2
NsN1HwFoyN
$ exit

Level 2

Ah, the sweet smell of mediocrity with a hint of improvement.

Few hours later…

Today, I have learned about cat and access(). It was a good day!

leviathan2@gibson:~$ id
uid=12002(leviathan2) gid=12002(leviathan2) groups=12002(leviathan2)
leviathan2@gibson:~$ ls -la
total 36
drwxr-xr-x  2 root       root        4096 Sep 19 07:07 .
drwxr-xr-x 83 root       root        4096 Sep 19 07:09 ..
-rw-r--r--  1 root       root         220 Mar 31  2024 .bash_logout
-rw-r--r--  1 root       root        3771 Mar 31  2024 .bashrc
-r-sr-x---  1 leviathan3 leviathan2 15068 Sep 19 07:07 printfile
-rw-r--r--  1 root       root         807 Mar 31  2024 .profile
leviathan2@gibson:~$ ./printfile
*** File Printer ***
Usage: ./printfile filename
leviathan2@gibson:~$ ./printfile /etc/leviathan_pass/leviathan3
You cant have that file...
leviathan2@gibson:~$ ltrace ./printfile
__libc_start_main(0x80490ed, 1, 0xffffd484, 0 <unfinished ...>
puts("*** File Printer ***"*** File Printer ***
)                                               = 21
printf("Usage: %s filename\n", "./printfile"Usage: ./printfile filename
)                              = 28
+++ exited (status 255) +++
leviathan2@gibson:~$ mkdir /tmp/spawn
leviathan2@gibson:~$ echo "amiga roolez" > /tmp/spawn/amiga.txt
leviathan2@gibson:~$ ltrace ./printfile /tmp/spawn/amiga.txt
__libc_start_main(0x80490ed, 2, 0xffffd464, 0 <unfinished ...>
access("/tmp/spawn/amiga.txt", 4)                                          = 0
snprintf("/bin/cat /tmp/spawn/amiga.txt", 511, "/bin/cat %s", "/tmp/spawn/amiga.txt") = 29
geteuid()                                                                  = 12002
geteuid()                                                                  = 12002
setreuid(12002, 12002)                                                     = 0
system("/bin/cat /tmp/spawn/amiga.txt"amiga roolez
 <no return ...>
--- SIGCHLD (Child exited) ---
<... system resumed> )                                                     = 0
+++ exited (status 0) +++
leviathan2@gibson:~$ ltrace ./printfile /etc/leviathan_pass/leviathan3
__libc_start_main(0x80490ed, 2, 0xffffd454, 0 <unfinished ...>
access("/etc/leviathan_pass/leviathan3", 4)                                = -1
puts("You cant have that file..."You cant have that file...
)                                         = 27
+++ exited (status 1) +++
leviathan2@gibson:/tmp/spawn$ echo "amiga roolez" > "amiga.txt pass.txt"
leviathan2@gibson:/tmp/spawn$ ln -s /etc/leviathan_pass/leviathan3 /tmp/spawn/pass.txt
leviathan2@gibson:/tmp/spawn$ ls -la
total 816
drwxrwxr-x    2 leviathan2 leviathan2   4096 Sep 30 16:42 .
drwxrwx-wt 2889 root       root       819200 Sep 30 16:43 ..
-rw-rw-r--    1 leviathan2 leviathan2     13 Sep 30 16:32 amiga.txt
-rw-rw-r--    1 leviathan2 leviathan2     13 Sep 30 16:41 amiga.txt pass.txt
lrwxrwxrwx    1 leviathan2 leviathan2     30 Sep 30 16:42 pass.txt -> /etc/leviathan_pass/leviathan3
leviathan2@gibson:/tmp/spawn$ /home/leviathan2/printfile "amiga.txt pass.txt"
amiga roolez
f0n8h2iWLP
leviathan2@gibson:/tmp/spawn$ rm -rf /tmp/spawn

Findings

After being stuck for a few hours, here is what I have learned.

  • cat‘s behavior: The cat command is designed to concatenate files. When you give it multiple filenames separated by spaces, it treats them as a single stream. It essentially reads the first file, then the second, and so on, outputting the content as one continuous flow.
  • access‘s behavior: The access command is much stricter. It expects a single filename as an argument to check its permissions. When it encounters spaces, it assumes they are part of that single filename.

The Exploit

Let’s say you have these files:

  • file1.txt (contains the flag)
  • file2.txt (some other data)

If you try:

cat file1.txt file2.txt

cat will happily display the contents of both files.

However, if you try:

access file1.txt file2.txt

access will look for a file literally named “file1.txt file2.txt”, which doesn’t exist, and likely return an error.

This difference in behavior can be exploited. The game might have a script that uses access to check if you’re allowed to read a specific file (like flag.txt). But, if you can manipulate the input to the script and inject another filename along with flag.txt, you can trick cat into displaying the flag’s content while bypassing the access check.

This exploit highlights the importance of understanding how commands interpret arguments and how seemingly harmless characters like spaces can be used to manipulate their behavior. It’s a common vulnerability in poorly written scripts and a valuable lesson for anyone learning about cybersecurity.

Level 3

LTRACE – The one-stop shop

Well, it is awkward. It worked again.

leviathan3@gibson:~$ id
uid=12003(leviathan3) gid=12003(leviathan3) groups=12003(leviathan3)
leviathan3@gibson:~$ ls -la
total 40
drwxr-xr-x  2 root       root        4096 Sep 19 07:07 .
drwxr-xr-x 83 root       root        4096 Sep 19 07:09 ..
-rw-r--r--  1 root       root         220 Mar 31  2024 .bash_logout
-rw-r--r--  1 root       root        3771 Mar 31  2024 .bashrc
-r-sr-x---  1 leviathan4 leviathan3 18096 Sep 19 07:07 level3
-rw-r--r--  1 root       root         807 Mar 31  2024 .profile
leviathan3@gibson:~$ ./level3
Enter the password> amiga
bzzzzzzzzap. WRONG
leviathan3@gibson:~$ ./level3
Enter the password> level4
bzzzzzzzzap. WRONG
leviathan3@gibson:~$ ltrace ./level3 
__libc_start_main(0x80490ed, 1, 0xffffd494, 0 <unfinished ...>
strcmp("h0no33", "kakaka")                                                 = -1
printf("Enter the password> ")                                             = 20
fgets(Enter the password> kakaka 
"kakaka\n", 256, 0xf7fae5c0)                                         = 0xffffd26c
strcmp("kakaka\n", "snlprintf\n")                                          = -1
puts("bzzzzzzzzap. WRONG"bzzzzzzzzap. WRONG
)                                                 = 19
+++ exited (status 0) +++
leviathan3@gibson:~$ ./level3
Enter the password> snlprintf
[You've got shell]!
$ ls -la
total 40
drwxr-xr-x  2 root       root        4096 Sep 19 07:07 .
drwxr-xr-x 83 root       root        4096 Sep 19 07:09 ..
-rw-r--r--  1 root       root         220 Mar 31  2024 .bash_logout
-rw-r--r--  1 root       root        3771 Mar 31  2024 .bashrc
-r-sr-x---  1 leviathan4 leviathan3 18096 Sep 19 07:07 level3
-rw-r--r--  1 root       root         807 Mar 31  2024 .profile
$ cat /etc/leviathan_pass/leviathan4
WG1egElCvO
$ exit

Level 4

Because life is too short for semicolons.

Easy. Python comes in handy to save the day. It throws an error, but it works.

leviathan4@gibson:~$ id
uid=12004(leviathan4) gid=12004(leviathan4) groups=12004(leviathan4)
leviathan4@gibson:~$ ls -la
total 24
drwxr-xr-x  3 root root       4096 Sep 19 07:07 .
drwxr-xr-x 83 root root       4096 Sep 19 07:09 ..
-rw-r--r--  1 root root        220 Mar 31  2024 .bash_logout
-rw-r--r--  1 root root       3771 Mar 31  2024 .bashrc
-rw-r--r--  1 root root        807 Mar 31  2024 .profile
dr-xr-x---  2 root leviathan4 4096 Sep 19 07:07 .trash
leviathan4@gibson:~$ cd .trash/
leviathan4@gibson:~/.trash$ ls -la
total 24
dr-xr-x--- 2 root       leviathan4  4096 Sep 19 07:07 .
drwxr-xr-x 3 root       root        4096 Sep 19 07:07 ..
-r-sr-x--- 1 leviathan5 leviathan4 14936 Sep 19 07:07 bin
leviathan4@gibson:~/.trash$ ./bin
00110000 01100100 01111001 01111000 01010100 00110111 01000110 00110100 01010001 01000100 00001010
leviathan4@gibson:~/.trash$ ls -ls /usr/bin/python*
   0 lrwxrwxrwx 1 root root      10 Aug  7 17:44 /usr/bin/python3 -> python3.12
7832 -rwxr-xr-x 1 root root 8019136 Sep 11 14:17 /usr/bin/python3.12
   0 lrwxrwxrwx 1 root root      34 Sep 11 14:17 /usr/bin/python3.12-config -> x86_64-linux-gnu-python3.12-config
   0 lrwxrwxrwx 1 root root      17 Aug  7 17:44 /usr/bin/python3-config -> python3.12-config
leviathan4@gibson:~/.trash$ mkdir /tmp/spawn
leviathan4@gibson:~/.trash$ nano /tmp/spawn/bin.py
#!/usr/bin/env python3

import binascii

text_string = "00110000 01100100 01111001 01111000 01010100 00110111 01000110 00110100 01010001 01000100 00001010"

def decode_binary_string(text_string):
  decoded_text = ""
  binary_numbers = text_string.split()
  for binary_number in binary_numbers:
    try:
      decimal_value = int(binary_number, 2)
      hex_value = hex(decimal_value)[2:]  # Remove "0x" prefix
      decoded_char = binascii.unhexlify(hex_value).decode('ascii')
      decoded_text += decoded_char
    except ValueError:
      print(f"Invalid binary number: {binary_number}")
    except binascii.Error:
      print(f"Error decoding binary number: {binary_number}")
  return decoded_text
  
decoded_text = decode_binary_string(text_string)
print(f"Decoded text: {decoded_text}")
eviathan4@gibson:~/.trash$ python3 /tmp/spawn/bin.py 
Decoded text: 0dyxT7F4QD

Level 5

Organization? Who needs it when you have symbolic links?

I swear, that was my first idea. There was 100% chance it was going to work and I still doubted.

leviathan5@gibson:~$ id
uid=12005(leviathan5) gid=12005(leviathan5) groups=12005(leviathan5)
leviathan5@gibson:~$ ls -la
total 36
drwxr-xr-x  2 root       root        4096 Sep 19 07:07 .
drwxr-xr-x 83 root       root        4096 Sep 19 07:09 ..
-rw-r--r--  1 root       root         220 Mar 31  2024 .bash_logout
-rw-r--r--  1 root       root        3771 Mar 31  2024 .bashrc
-r-sr-x---  1 leviathan6 leviathan5 15140 Sep 19 07:07 leviathan5
-rw-r--r--  1 root       root         807 Mar 31  2024 .profile
leviathan5@gibson:~$ ./leviathan5 
Cannot find /tmp/file.log
leviathan5@gibson:~$ ltrace ./leviathan5 
__libc_start_main(0x804910d, 1, 0xffffd484, 0 <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) +++
leviathan5@gibson:~$ ln -s /etc/leviathan_pass/leviathan6 /tmp/file.log
leviathan5@gibson:~$ ./leviathan5 
szo7HDB88w

Level 6

Making sense of the gibberish that is machine code.

Finally, a level that was a pure joy to wrap my head around it. These two lines hold the secret, which is the PIN as hex, mind blown.

80491da:	c7 45 f4 d3 1b 00 00 	mov    DWORD PTR [ebp-0xc],0x1bd3
 80491e1:	83 38 02             	cmp    DWORD PTR [eax],0x2
leviathan6@gibson:~$ id
uid=12006(leviathan6) gid=12006(leviathan6) groups=12006(leviathan6)
leviathan6@gibson:~$ ls -la
total 36
drwxr-xr-x  2 root       root        4096 Sep 19 07:07 .
drwxr-xr-x 83 root       root        4096 Sep 19 07:09 ..
-rw-r--r--  1 root       root         220 Mar 31  2024 .bash_logout
-rw-r--r--  1 root       root        3771 Mar 31  2024 .bashrc
-r-sr-x---  1 leviathan7 leviathan6 15032 Sep 19 07:07 leviathan6
-rw-r--r--  1 root       root         807 Mar 31  2024 .profile
leviathan6@gibson:~$ ./leviathan6
usage: ./leviathan6 <4 digit code>
leviathan6@gibson:~$ ltrace ./leviathan6
__libc_start_main(0x80490dd, 1, 0xffffd484, 0 <unfinished ...>
printf("usage: %s <4 digit code>\n", "./leviathan6"usage: ./leviathan6 <4 digit code>
)                       = 35
exit(-1 <no return ...>
+++ exited (status 255) +++
leviathan6@gibson:~$ ltrace ./leviathan6 1234
__libc_start_main(0x80490dd, 2, 0xffffd474, 0 <unfinished ...>
atoi(0xffffd5e0, 0, 0, 0)                                                  = 1234
puts("Wrong"Wrong
)                                                              = 6
+++ exited (status 0) +++
leviathan6@gibson:~$ file leviathan6 
leviathan6: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=8d21eae4ea4ee29abbdfd21171064af6840bb32b, for GNU/Linux 3.2.0, not stripped
leviathan6@gibson:~$ objdump -M intel-d leviathan6
leviathan6:     file format elf32-i386


Disassembly of section .init:

08049000 <_init>:
 8049000:	53                   	push   ebx
 8049001:	83 ec 08             	sub    esp,0x8
 8049004:	e8 f7 00 00 00       	call   8049100 <__x86.get_pc_thunk.bx>
 8049009:	81 c3 eb 2f 00 00    	add    ebx,0x2feb
 804900f:	8b 83 fc ff ff ff    	mov    eax,DWORD PTR [ebx-0x4]
 8049015:	85 c0                	test   eax,eax
 8049017:	74 02                	je     804901b <_init+0x1b>
 8049019:	ff d0                	call   eax
 804901b:	83 c4 08             	add    esp,0x8
 804901e:	5b                   	pop    ebx
 804901f:	c3                   	ret

Disassembly of section .plt:

08049020 <__libc_start_main@plt-0x10>:
 8049020:	ff 35 f8 bf 04 08    	push   DWORD PTR ds:0x804bff8
 8049026:	ff 25 fc bf 04 08    	jmp    DWORD PTR ds:0x804bffc
 804902c:	00 00                	add    BYTE PTR [eax],al
	...

08049030 <__libc_start_main@plt>:
 8049030:	ff 25 00 c0 04 08    	jmp    DWORD PTR ds:0x804c000
 8049036:	68 00 00 00 00       	push   0x0
 804903b:	e9 e0 ff ff ff       	jmp    8049020 <_init+0x20>

08049040 <printf@plt>:
 8049040:	ff 25 04 c0 04 08    	jmp    DWORD PTR ds:0x804c004
 8049046:	68 08 00 00 00       	push   0x8
 804904b:	e9 d0 ff ff ff       	jmp    8049020 <_init+0x20>

08049050 <geteuid@plt>:
 8049050:	ff 25 08 c0 04 08    	jmp    DWORD PTR ds:0x804c008
 8049056:	68 10 00 00 00       	push   0x10
 804905b:	e9 c0 ff ff ff       	jmp    8049020 <_init+0x20>

08049060 <puts@plt>:
 8049060:	ff 25 0c c0 04 08    	jmp    DWORD PTR ds:0x804c00c
 8049066:	68 18 00 00 00       	push   0x18
 804906b:	e9 b0 ff ff ff       	jmp    8049020 <_init+0x20>

08049070 <system@plt>:
 8049070:	ff 25 10 c0 04 08    	jmp    DWORD PTR ds:0x804c010
 8049076:	68 20 00 00 00       	push   0x20
 804907b:	e9 a0 ff ff ff       	jmp    8049020 <_init+0x20>

08049080 <exit@plt>:
 8049080:	ff 25 14 c0 04 08    	jmp    DWORD PTR ds:0x804c014
 8049086:	68 28 00 00 00       	push   0x28
 804908b:	e9 90 ff ff ff       	jmp    8049020 <_init+0x20>

08049090 <setreuid@plt>:
 8049090:	ff 25 18 c0 04 08    	jmp    DWORD PTR ds:0x804c018
 8049096:	68 30 00 00 00       	push   0x30
 804909b:	e9 80 ff ff ff       	jmp    8049020 <_init+0x20>

080490a0 <atoi@plt>:
 80490a0:	ff 25 1c c0 04 08    	jmp    DWORD PTR ds:0x804c01c
 80490a6:	68 38 00 00 00       	push   0x38
 80490ab:	e9 70 ff ff ff       	jmp    8049020 <_init+0x20>

Disassembly of section .text:

080490b0 <_start>:
 80490b0:	31 ed                	xor    ebp,ebp
 80490b2:	5e                   	pop    esi
 80490b3:	89 e1                	mov    ecx,esp
 80490b5:	83 e4 f0             	and    esp,0xfffffff0
 80490b8:	50                   	push   eax
 80490b9:	54                   	push   esp
 80490ba:	52                   	push   edx
 80490bb:	e8 19 00 00 00       	call   80490d9 <_start+0x29>
 80490c0:	81 c3 34 2f 00 00    	add    ebx,0x2f34
 80490c6:	6a 00                	push   0x0
 80490c8:	6a 00                	push   0x0
 80490ca:	51                   	push   ecx
 80490cb:	56                   	push   esi
 80490cc:	8d 83 e9 d0 ff ff    	lea    eax,[ebx-0x2f17]
 80490d2:	50                   	push   eax
 80490d3:	e8 58 ff ff ff       	call   8049030 <__libc_start_main@plt>
 80490d8:	f4                   	hlt
 80490d9:	8b 1c 24             	mov    ebx,DWORD PTR [esp]
 80490dc:	c3                   	ret

080490dd <__wrap_main>:
 80490dd:	e9 e4 00 00 00       	jmp    80491c6 <main>
 80490e2:	66 90                	xchg   ax,ax
 80490e4:	66 90                	xchg   ax,ax
 80490e6:	66 90                	xchg   ax,ax
 80490e8:	66 90                	xchg   ax,ax
 80490ea:	66 90                	xchg   ax,ax
 80490ec:	66 90                	xchg   ax,ax
 80490ee:	66 90                	xchg   ax,ax

080490f0 <_dl_relocate_static_pie>:
 80490f0:	c3                   	ret
 80490f1:	66 90                	xchg   ax,ax
 80490f3:	66 90                	xchg   ax,ax
 80490f5:	66 90                	xchg   ax,ax
 80490f7:	66 90                	xchg   ax,ax
 80490f9:	66 90                	xchg   ax,ax
 80490fb:	66 90                	xchg   ax,ax
 80490fd:	66 90                	xchg   ax,ax
 80490ff:	90                   	nop

08049100 <__x86.get_pc_thunk.bx>:
 8049100:	8b 1c 24             	mov    ebx,DWORD PTR [esp]
 8049103:	c3                   	ret
 8049104:	66 90                	xchg   ax,ax
 8049106:	66 90                	xchg   ax,ax
 8049108:	66 90                	xchg   ax,ax
 804910a:	66 90                	xchg   ax,ax
 804910c:	66 90                	xchg   ax,ax
 804910e:	66 90                	xchg   ax,ax

08049110 <deregister_tm_clones>:
 8049110:	b8 28 c0 04 08       	mov    eax,0x804c028
 8049115:	3d 28 c0 04 08       	cmp    eax,0x804c028
 804911a:	74 24                	je     8049140 <deregister_tm_clones+0x30>
 804911c:	b8 00 00 00 00       	mov    eax,0x0
 8049121:	85 c0                	test   eax,eax
 8049123:	74 1b                	je     8049140 <deregister_tm_clones+0x30>
 8049125:	55                   	push   ebp
 8049126:	89 e5                	mov    ebp,esp
 8049128:	83 ec 14             	sub    esp,0x14
 804912b:	68 28 c0 04 08       	push   0x804c028
 8049130:	ff d0                	call   eax
 8049132:	83 c4 10             	add    esp,0x10
 8049135:	c9                   	leave
 8049136:	c3                   	ret
 8049137:	2e 8d b4 26 00 00 00 	lea    esi,cs:[esi+eiz*1+0x0]
 804913e:	00 
 804913f:	90                   	nop
 8049140:	c3                   	ret
 8049141:	2e 8d b4 26 00 00 00 	lea    esi,cs:[esi+eiz*1+0x0]
 8049148:	00 
 8049149:	8d b4 26 00 00 00 00 	lea    esi,[esi+eiz*1+0x0]

08049150 <register_tm_clones>:
 8049150:	b8 28 c0 04 08       	mov    eax,0x804c028
 8049155:	2d 28 c0 04 08       	sub    eax,0x804c028
 804915a:	89 c2                	mov    edx,eax
 804915c:	c1 e8 1f             	shr    eax,0x1f
 804915f:	c1 fa 02             	sar    edx,0x2
 8049162:	01 d0                	add    eax,edx
 8049164:	d1 f8                	sar    eax,1
 8049166:	74 20                	je     8049188 <register_tm_clones+0x38>
 8049168:	ba 00 00 00 00       	mov    edx,0x0
 804916d:	85 d2                	test   edx,edx
 804916f:	74 17                	je     8049188 <register_tm_clones+0x38>
 8049171:	55                   	push   ebp
 8049172:	89 e5                	mov    ebp,esp
 8049174:	83 ec 10             	sub    esp,0x10
 8049177:	50                   	push   eax
 8049178:	68 28 c0 04 08       	push   0x804c028
 804917d:	ff d2                	call   edx
 804917f:	83 c4 10             	add    esp,0x10
 8049182:	c9                   	leave
 8049183:	c3                   	ret
 8049184:	8d 74 26 00          	lea    esi,[esi+eiz*1+0x0]
 8049188:	c3                   	ret
 8049189:	8d b4 26 00 00 00 00 	lea    esi,[esi+eiz*1+0x0]

08049190 <__do_global_dtors_aux>:
 8049190:	f3 0f 1e fb          	endbr32
 8049194:	80 3d 28 c0 04 08 00 	cmp    BYTE PTR ds:0x804c028,0x0
 804919b:	75 1b                	jne    80491b8 <__do_global_dtors_aux+0x28>
 804919d:	55                   	push   ebp
 804919e:	89 e5                	mov    ebp,esp
 80491a0:	83 ec 08             	sub    esp,0x8
 80491a3:	e8 68 ff ff ff       	call   8049110 <deregister_tm_clones>
 80491a8:	c6 05 28 c0 04 08 01 	mov    BYTE PTR ds:0x804c028,0x1
 80491af:	c9                   	leave
 80491b0:	c3                   	ret
 80491b1:	8d b4 26 00 00 00 00 	lea    esi,[esi+eiz*1+0x0]
 80491b8:	c3                   	ret
 80491b9:	8d b4 26 00 00 00 00 	lea    esi,[esi+eiz*1+0x0]

080491c0 <frame_dummy>:
 80491c0:	f3 0f 1e fb          	endbr32
 80491c4:	eb 8a                	jmp    8049150 <register_tm_clones>

080491c6 <main>:
 80491c6:	8d 4c 24 04          	lea    ecx,[esp+0x4]
 80491ca:	83 e4 f0             	and    esp,0xfffffff0
 80491cd:	ff 71 fc             	push   DWORD PTR [ecx-0x4]
 80491d0:	55                   	push   ebp
 80491d1:	89 e5                	mov    ebp,esp
 80491d3:	53                   	push   ebx
 80491d4:	51                   	push   ecx
 80491d5:	83 ec 10             	sub    esp,0x10
 80491d8:	89 c8                	mov    eax,ecx
 80491da:	c7 45 f4 d3 1b 00 00 	mov    DWORD PTR [ebp-0xc],0x1bd3
 80491e1:	83 38 02             	cmp    DWORD PTR [eax],0x2
 80491e4:	74 20                	je     8049206 <main+0x40>
 80491e6:	8b 40 04             	mov    eax,DWORD PTR [eax+0x4]
 80491e9:	8b 00                	mov    eax,DWORD PTR [eax]
 80491eb:	83 ec 08             	sub    esp,0x8
 80491ee:	50                   	push   eax
 80491ef:	68 08 a0 04 08       	push   0x804a008
 80491f4:	e8 47 fe ff ff       	call   8049040 <printf@plt>
 80491f9:	83 c4 10             	add    esp,0x10
 80491fc:	83 ec 0c             	sub    esp,0xc
 80491ff:	6a ff                	push   0xffffffff
 8049201:	e8 7a fe ff ff       	call   8049080 <exit@plt>
 8049206:	8b 40 04             	mov    eax,DWORD PTR [eax+0x4]
 8049209:	83 c0 04             	add    eax,0x4
 804920c:	8b 00                	mov    eax,DWORD PTR [eax]
 804920e:	83 ec 0c             	sub    esp,0xc
 8049211:	50                   	push   eax
 8049212:	e8 89 fe ff ff       	call   80490a0 <atoi@plt>
 8049217:	83 c4 10             	add    esp,0x10
 804921a:	39 45 f4             	cmp    DWORD PTR [ebp-0xc],eax
 804921d:	75 2b                	jne    804924a <main+0x84>
 804921f:	e8 2c fe ff ff       	call   8049050 <geteuid@plt>
 8049224:	89 c3                	mov    ebx,eax
 8049226:	e8 25 fe ff ff       	call   8049050 <geteuid@plt>
 804922b:	83 ec 08             	sub    esp,0x8
 804922e:	53                   	push   ebx
 804922f:	50                   	push   eax
 8049230:	e8 5b fe ff ff       	call   8049090 <setreuid@plt>
 8049235:	83 c4 10             	add    esp,0x10
 8049238:	83 ec 0c             	sub    esp,0xc
 804923b:	68 22 a0 04 08       	push   0x804a022
 8049240:	e8 2b fe ff ff       	call   8049070 <system@plt>
 8049245:	83 c4 10             	add    esp,0x10
 8049248:	eb 10                	jmp    804925a <main+0x94>
 804924a:	83 ec 0c             	sub    esp,0xc
 804924d:	68 2a a0 04 08       	push   0x804a02a
 8049252:	e8 09 fe ff ff       	call   8049060 <puts@plt>
 8049257:	83 c4 10             	add    esp,0x10
 804925a:	b8 00 00 00 00       	mov    eax,0x0
 804925f:	8d 65 f8             	lea    esp,[ebp-0x8]
 8049262:	59                   	pop    ecx
 8049263:	5b                   	pop    ebx
 8049264:	5d                   	pop    ebp
 8049265:	8d 61 fc             	lea    esp,[ecx-0x4]
 8049268:	c3                   	ret

Disassembly of section .fini:

0804926c <_fini>:
 804926c:	53                   	push   ebx
 804926d:	83 ec 08             	sub    esp,0x8
 8049270:	e8 8b fe ff ff       	call   8049100 <__x86.get_pc_thunk.bx>
 8049275:	81 c3 7f 2d 00 00    	add    ebx,0x2d7f
 804927b:	83 c4 08             	add    esp,0x8
 804927e:	5b                   	pop    ebx
 804927f:	c3 
leviathan6@gibson:~$ python3
Python 3.12.3 (main, Sep 11 2024, 14:17:37) [GCC 13.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> int(0x1bd3)
7123
>>> quit()
leviathan6@gibson:~$ ./leviathan6 7123
$ id
uid=12007(leviathan7) gid=12006(leviathan6) groups=12006(leviathan6)
$ cat /etc/leviathan_pass/leviathan7
qEs5Io5yM8
$ exit

Level 7

That’s it!

It was fun.

leviathan7@gibson:~$ id
uid=12007(leviathan7) gid=12007(leviathan7) groups=12007(leviathan7)
leviathan7@gibson:~$ ls -la
total 24
drwxr-xr-x  2 root       root       4096 Sep 19 07:07 .
drwxr-xr-x 83 root       root       4096 Sep 19 07:09 ..
-rw-r--r--  1 root       root        220 Mar 31  2024 .bash_logout
-rw-r--r--  1 root       root       3771 Mar 31  2024 .bashrc
-r--r-----  1 leviathan7 leviathan7  178 Sep 19 07:07 CONGRATULATIONS
-rw-r--r--  1 root       root        807 Mar 31  2024 .profile
leviathan7@gibson:~$ 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!)

Outro

I know enough to know I’ll never know enough.

My personal favorites were level 2, for teaching me about that neat trick with ‘cat’ and ‘access’, and level 6, where I dusted off my rusty assembler skills and surprised myself with how valuable they were. These challenges highlighted the importance of having a diverse toolkit. I firmly believe that being a ‘Jack of all trades’ is far from a negative thing. In fact, it’s essential in this ever-changing landscape of threats and technologies, not only in cyber-security.