Stegnography Challenges
Syrio Forel
Challenge: dump
Flag format: aupCTF{***_*****}
Analysis
When we try to read the file we get a huge output (the file is one line), it seems giberish but looks to be Base64 encoding. To check that its Base64 let's try decoding.
└─$ cat dump.txt | base64 -d > unknown
└─$ file unknown
unknown: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, Exif Standard: [TIFF image data, little-endian, direntries=6, orientation=upper-left, xresolution=176, yresolution=184, resolutionunit=2], baseline, precision 8, 500x500, components 3
└─$ mv unknown unknown.jpeg
└─$ display unknown.jpeg

Solution
I was fiddling around a lot trying to find flag in picture (with strings and etc) with no luck, turns out the flag was right in front of me.
Before Arya runs off to take her place in the Godswood, the Red Woman says some familiar words to spur Arya into action: "What do we say to the God of Death?" The answer, as Arya knows all too well, is, "Not today." But she wouldn't know these words if not for her water dancing instructor, Syrio Forel.
Flag:aupCTF{not_today}
Masterpeice
chahat has something for you listen carefully till the end.
Flag format: aupCTF{...}
Solution
First thing I do with mp3 steganography is to look for Spectrogram. I used sonic-visualiser to do this.
sonic-visualiser masterpiece.wav
-> Layer -> Add Spectrogram -> All Channels Mixed -> Scroll To The End (-> Adjust Horizontal Wheel A Bit)

Flag:aupCTF{Sp3ct0gr4m_ri4ght}
LSB
you got this...file
Solution
From the title we can probably guess that we are dealing with hidden data within LSB.
└─$ zsteg naruto.png
imagedata .. text: "$:;`VV(-1"
b1,b,lsb,xy .. file: OpenPGP Secret Key
b1,rgb,lsb,xy .. text: "aupCTF{zst1g-1s-c00l_rig3ht}"
b2,rgb,lsb,xy .. file: big endian ispell 3.0 hash file, and 13698 string characters
Flag:aupCTF{zst1g-1s-c00l_rig3ht}
Deep
Challenge: truefan.wav
Flag format: aupCTF{****_****}
Hint: looking for password ? well thats the iconic dialogue of iron man
Solution
The audio file starts by saying a quote from Iron Man 2 and then quote from Iron Man 3, but it's unclear what it has to do with the puzzle.
Hint mentions password, but there's nothing that requires password unless steghide
or alternative. I tried searching around Audio Steganography combined with Deep and found Deep Sound. Luckily John has a tool deepsound2john.
└─$ deepsound2john truefan.wav > truefan.hash
└─$ john --wordlist=$rockyou truefan.hash
Using default input encoding: UTF-8
Loaded 1 password hash (dynamic_1529 [sha1($p null_padded_to_len_32) (DeepSound) 256/256 AVX2 8x1])
Warning: no OpenMP support for this hash type, consider --fork=4
Press 'q' or Ctrl-C to abort, almost any other key for status
iamironman (truefan.wav)
1g 0:00:00:00 DONE (2023-06-29 18:50) 1.562g/s 551250p/s 551250c/s 551250C/s julian24..hotchick13
Use the "--show --format=dynamic_1529" options to display all of the cracked passwords reliably
Session completed.
Deep Sound only works on windows, so I jumped in and extracted the hidden data using password from file.


Windows was kind enough to identify that executable is a python executable file. Using PyInstaller Extractor we can get the source code.
└─$ python3 pyinstxtractor.py ../marvel.exe
[+] Processing ../marvel.exe
[+] Pyinstaller version: 2.1+
[+] Python version: 3.10
[+] Length of package: 6342224 bytes
[+] Found 61 files in CArchive
[+] Beginning extraction...please standby
[+] Possible entry point: pyiboot01_bootstrap.pyc
[+] Possible entry point: pyi_rth_inspect.pyc
[+] Possible entry point: marvel.pyc
[!] Warning: This script is running in a different Python version than the one used to build the executable.
[!] Please run this script in Python 3.10 to prevent extraction errors during unmarshalling
[!] Skipping pyz extraction
[+] Successfully extracted pyinstaller archive: ../marvel.exe
You can now use a python decompiler on the pyc files within the extracted directory
└─$ strings marvel.exe_extracted/marvel.pyc
Nz2How much does Morgan Starks love her dad? [number]
3000)
question
answerz&What is the full form of J.A.R.V.I.S.?z%Just A Rather Very Intelligent Systemz7What is the full form of AI that replaced J.A.R.V.I.S.?z6Female Replacement Intelligent Digital Assistant Youthc
input
lower)
user_answer
marvel.py
ask_question
Incorrect answer!r
Congratulations! You are a true Marvel Nerd like Me ;/zUFlag format: iron man first appearance year underscore last appearance year in moviesz
Press any key to exit...)
questionsr
print
exitr
main
__main__)
__name__r
<module>
Flag format: iron man first appearance year underscore last appearance year in movies
First appearance: Iron Man, 2008 Last appearance: Avengers: Endgame, 2019
Flag:aupCTF{2008_2019}
Obfuscated
Challenge: download file
Analysis
We have a broken JPG image so let's try to fix it!
First lets find magic bytes

Im going to cut to the chase and directly approach the problem.
Flag Header: FF 8D FF 0E 00 01 A4 64 94 64 00 10
JFIF Header: FF D8 FF E0 00 10 4A 46 49 46 00 01
Do you see what's wrong? Because it's actually f*ing cool D: The hex values are reversed! And the thing is that it's not limited to the header, it's whole file!
Solution
# Open flag to read and new file to write
with open("./flag.jpg", "rb") as f, open("flag_new.jpg", "wb") as new:
# Read each byte from flag till EOF
for byte in iter(lambda: f.read(1), b''):
byte = ord(byte) # byte -> int
# This is where the *magic* happens, it's shifting the values and doing a swap
byte_swap = ((byte & 0xF0) >> 4) | ((byte & 0x0F) << 4)
# Finally write swapped byte (int needs to be converted to byte)
new.write(byte_swap.to_bytes(1, 'little'))

Flag:aupCTF{sw4p3d_w0w453?5422asd!1}
XOR
Solution
We are given two images and title says XOR and solution is pretty straightforward, xor images and get the flag.
import numpy as np
from PIL import Image
# Load the images
image1 = Image.open("img1.png")
image2 = Image.open("img2.png")
# Convert images to NumPy arrays
array1 = np.array(image1)
array2 = np.array(image2)
# Perform XOR operation
xor_result = np.bitwise_xor(array1, array2)
# Create a new Image object from the XOR result array
xor_image = Image.fromarray(xor_result)
# Save the XOR image
xor_image.save("xor_image.png")

ShortsID: LYkCU8Kn3a8
As someone who (sadly) watches ton of youtube shorts... it was obvious where to look. almost there
Description: some kind of cipher i guess I found hexahue cipher and tried decoding. First we need to split video into images
└─$ mkdir output && ffmpeg -i "almost there.mp4" -vf fps=1 output/frame%d.png
Using the tool above I entered images by frames to get the message > WW00WGGRAARAAPSS
If you notice output has duplicates and that's due not perfect split using ffmpeg
Flag:aupCTF{W0WGRARAPS}
Arcane
In the city of Piltover, chaos reigns supreme as Jinx, the mischievous troublemaker, roams the streets. Armed with her deadly arsenal and a wicked grin, she sets the city ablaze with her explosive antics. navigate Jinx's twisted mind, decipher her puzzles, and outsmart her at every turn to uncover the hidden flag. Will you be able to tame the chaos and triumph over Jinx's mischief?
Analysis
First let's take a look at file.
└─$ file arcane.exe
arcane.exe: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=8e560e56d7a2f51f749b1eae13f127bb5805cfc2, for GNU/Linux 3.2.0, stripped
So exe
is just a deception... let's trying running the file. When ran the program generates directory called arcane
with 1000 jpg
images, img
png (broken) and 786_dba.jpg
.
└─$ exiftool arcane/786_dba.jpg
...
File Name : 786_dba.jpg
Directory : arcane
File Size : 78 kB
Comment : don't be the database enginner that enter data manually
...
don't be the database enginner that enter data manually ? What does it mean...?
Let's try to fix img
which is PNG, and the best way to fix PNG is to compare it to another valid PNG. (I used random png -> dice).
After changing only PNG chunk image didnt open, so I tried copying first line from dice.png
to img
and it worked! Dont forget to change extension to png!

The image is white? Let's open it in stegsolve

Hmmm... I wasn't looking for password, but now I am. Is there steghide tool involved?
We have too many similar images, what if they are just duplicates? I decided to filter out files by hash.
import os
from hashlib import md5
arcane_dir = "arcane"
known_hashes = {}
files = sorted(
os.listdir(arcane_dir), # Get all the files from arcane and sort them by numerical order
key=lambda f: int(f.split('.')[0]) if f.split('.')[0].isnumeric() else -1
)
for file in files:
with open(f"{arcane_dir}/{file}", "rb") as f:
# Compute hashes
hash_ = md5(f.read()).hexdigest()
# Record unknown hashes (eliminate duplicates)
if hash_ not in known_hashes:
known_hashes[hash_] = file
for k,v in known_hashes.items():
print(k, v) # Print hash:file
897782c73bdc5a7c7a2e78641a4097eb
img
Expected
d2c255e28d329713ca8eba5679e71921
786_dba.jpg
Expected
375fa576de8f9cafa59baba700a4e722
1.jpg
Expected
2a43c34ddf5dc950792b94d282083815
2.jpg
Expected
90477a828f52384b3b69b80417ac8f33
869.jpg
Unexpected
Solution
└─$ steghide extract -sf arcane/869.jpg -p jinx
wrote extracted data to "flag.txt".
└─$ cat flag.txt
aupCTF{JinxTheArcaneTrickster}
Flag:aupCTF{JinxTheArcaneTrickster}
Last updated