May 16, 2026
Forensics CTF writeups — Securinets isetZaghouan x isetRades
sh1tty cr0n: Hiding Messages in Cron Jobs
Slender-man
3 min read
sh1tty cr0n: Hiding Messages in Cron Jobs
In this challenge, we're given a syslog file (syslog_challenge.log). At first glance, it's full of normal CRON noise — until you notice something unusual: a backup_agent command with a --job-id in hex.
Step 1: Open the log and get a feel
less syslog_challenge.logless syslog_challenge.logYou see thousands of lines — normal syslog noise: CRON entries. You notice lots of CRON lines running typical commands (run-parts --report /etc/cron.hourly, php /var/www/html/cron.php).Then your eyes catch something different: a command with --job-id 0x33. That doesn't look like standard system cron. You scroll further and see --job-id 0x53, then 0x59, etc. The values are changing.
Step 2: Isolate all occurrences of that weird command
You want to see only those lines. A simple grep for the program name:
grep "backup_agent" syslog_challenge.loggrep "backup_agent" syslog_challenge.log
=> You notice the timestamps: exactly one minute apart (10:00, 10:01, 10:02, ... 10:22). This is a deliberate sequence, not random logging.
Hypothesis: The attacker scheduled a job that prints a different hex value every minute — probably encoding a message.
Step 3: Extract Hex and transform it to characters
You know hex 0x43 is C in ASCII (because 0x43 = 67 = 'C'). You could manually decode each one, but that's slow. Instead, you can use Python :
grep "backup_agent" syslog_challenge.log | grep -oP '0x[0-9A-Fa-f]+' | while read h; do python3 -c "print(chr($h), end='')"; done && echogrep "backup_agent" syslog_challenge.log | grep -oP '0x[0-9A-Fa-f]+' | while read h; do python3 -c "print(chr($h), end='')"; done && echo
Result: 3@SY_M0Neyy_SH1TTY_CR0N
Flag format is Securinets{..} => flag = Securinets{3@SY_M0Neyy_SH1TTY_CR0N}
Log4Shell: Uncovering a Hidden Message Without Network Exfiltration
In this challenge, we're given an archive ( Log4shell.tar.gz). You unarchive the challenge file, you now have three files: access.log, error.log, app.log. The description says "A server fell to Log4Shell", but no data exfiltration was caught by the network sensors. The goal is uncover the hidden message the attacker left inside the logs.
Step 1: Hunt for Log4Shell Traces
Log4Shell injections always contain a characteristic string: ${jndi:...}. Search recursively for that pattern:
grep -rn '\${jndi:' *.loggrep -rn '\${jndi:' *.logYou will see lines like:
You note three injections, all targeting the same IP but with different encoded strings after the slash.
Step 2: Extract All Suspicious Payloads, Ordered by Time
The log lines already contain precise timestamps. Extract everything after the last slash and before the closing brace:
These are base64 strings (detectable by the == padding and character set).
Step 3: Decode and Reassemble
Decode each in order:
Result: L0G_4_Y0U_&_Y0U'R3_TH3_SH3LL
Wrap in the flag format:Securinets{L0G_4_Y0U_&_Y0U'R3_TH3_SH3LL}
Glyphzz: When Fonts lie.
In the world of digital forensics, PDF files are a goldmine for hiding malicious content. This CTF challenge presents a PDF that gives a garbage flag, and even copy-paste and OCR tools fail to extract anything meaningful. But hidden inside the embedded font lies the real flag. This writeup walks through the forensic methodology of extracting and analyzing custom fonts to recover the truth.
Upon opening the PDF (chall.pdf), we're greeted with unreadable, distorted flag.
This is clearly not a simple text encoding issue. We need to dig deeper.
Even normal analysis reveal nothing, 'pdffonts' only show the TruType fonts, so we should use a better option, which is 'mutool':
Finally something meaningful, that last extracted font tells us something, now to analysize .ttf files we have a lot of options one of the best is 'fontforge', it will show us the glyph table. so let's discover what's going on:
fontforge file-0032.ttffontforge file-0032.ttf
When navigating through the glyph table. We notice something odd, the glyph names don't always match their visual shapes. For example:
- Character code for '@' maps to a glyph named "a"
- Character code for '' maps to a glyph named "p"
- Character code for 'g' maps to a glyph named "p"
- Character code for 'P' maps to a glyph named ""
- etc…
first correction will give us this flag: Securinets{plyph5_p0N3_cr@zyy}
But it still incorrect, why? coz 'p' is played with twice:
- '' gives 'p'
- then 'p' gives ''
the font system doesn't work like that, actually it will do the following:
- The character code for '' maps to the glyph named 'p'
- then the font system will read the 'p' as the glyph and map to the first character code that correspond to it, which is 'g'
So the final flag will be: Securinets{glyph5_g0N3_cr@zyy}
Hope that was helpful — see ya in the next one! 👋