root@akosibrylle.dev:~$

# capture-the-flag is love!


Event: A1SBERG Oblivion Hunt CTF --- **Duration**: October 1– October 31, 2025 **Gamemaster**: Ivan Dizon (kuroshiro) **Type**: ARG-type CTF **Winners**: None This writeup covers the solutions and how to tackle the first ever competition: Oblivion Hunt by A1SBERG. ![Oblivion Hunt](/static/img/oblivion_hunt/oblivion_hunt.png) --- # Part 1: The Poster This poster is scattered throughout **Polytechnic University of the Philippines - Santa Maria Campus**. The ground zero of A1SBERG. Parts of the poster consist of a QR Code, rules and a hint. ![Oblivion Hunt Poster](/static/img/oblivion_hunt/oblivion_poster.png) We can simply read and familiarize the rule, and scan the QR Code. In case that your scanner does not reliably decodes the content of the code, the hint tells you to simply try other tools. **QR Code Content**:
vhhdg://rckbzcor1078.asrwotwfs.qca/e1zmx6idbhbu60Yo8PqoV-GhD0sGSIqM0kqlf1JLz4NSzBUBZ0AXOW20AclVQ8_ofeqMB0T8TGA5vne0b6KZ7xPccRi1FQI--9h131xezylWWBlL8T66vrClo8UWX3tB8-CFOWRFEsC0KDAynBzDP12mHtM5s2eyK18jvzrI1XP5oUO/o1l1vss7nuoc772/wbjwhohwcb.xdu>
This may look garbled but a [simple shift cipher](https://en.wikipedia.org/wiki/Caesar_cipher) on the letters. Doing so yields:
https://download1078.mediafire.com/q1lyj6upntng60Ka8BcaH-StP0eSEUcY0wcxr1VXl4ZElNGNL0MJAI20MoxHC8_arqcYN0F8FSM5hzq0n6WL7jBooDu1RCU--9t131jqlkxIINxX8F66hdOxa8GIJ3fN8-ORAIDRQeO0WPMkzNlPB12yTfY5e2qkW18vhldU1JB5aGA/a1x1hee7zgao772/invitation.jpg
Giving us the next stage of the challenge. # Part 2: Invitation ![invitation.jpg](/static/img/oblivion_hunt/invitation.png) This image, with its minimal aesthetics, look strikingly similar to a challenge from [CICADA 3301](https://en.wikipedia.org/wiki/Cicada_3301). Nonetheless looking with just your plain eyes shows nothing, but using a popular [steganography](https://en.wikipedia.org/wiki/Steganography) tool named **Steghide**, we can extract a file named **starting_point.txt**, with 3 mediafire URLs, the first one being truncated. ![Invitation Content](/static/img/oblivion_hunt/cmd_1.png) With the letter being cryptic messages, we move on to the most important part of the text: the URLs. **WAV File**:
https://download1648.mediafire.com/2ws45qzg5wige4JjCtYGNZaRnAKzsHTOciXVxW1i8SZbJBKmr2smR42Yd2_-S_Lc-9q734yH-2zCRVe1mAlPTZ6NMPQJIySn66NBj_Ig3BqjbDNps_CNaBxyq4mKdYCCqUvRDBBj9zCymTcndTWVPMaC5-OXH04IBrpnkiek6GQedQ/6uyyatf8e06roc6/the_creepiest_sound_you_will_ever_hear.wav
**JPG File**:
https://download1648.mediafire.com/2ws45qzg5wige4JjCtYGNZaRnAKzsHTOciXVxW1i8SZbJBKmr2smR42Yd2_-S_Lc-9q734yH-2zCRVe1mAlPTZ6NMPQJIySn66NBj_Ig3BqjbDNps_CNaBxyq4mKdYCCqUvRDBBj9zCymTcndTWVPMaC5-OXH04IBrpnkiek6GQedQ/6uyyatf8e06roc6/the_creepiest_sound_you_will_ever_hear.wav
Analyzing the JPG File first, you may feel stuck. Basic steganography techniques such as hiding data in LSB or MSB, inside the file as plain text, and using common tools give out nothing. We focus our attention then to the WAV File. # Part 3: WAV File Looking at the WAV file through a DAW Software, like Audacity, using the Spectogram view shows us this pattern. The file is just a series of beeps each lasting exactly 0.5 seconds and plays a frequency exactly divisible 10. The lowest being 400 hertz. These information can be extracted by just analyzing its spectogram. ![WAV file](/static/img/oblivion_hunt/wav_file.png) These parameters, being too specific rather than arbitrary, suggests data encoded within these beeps. With frequency changing over discrete intervals, this may suggest Frequency Shift Keying, where data is encoded by sending varying frequencies over a wave, commonly a radiowave, but this is over a soundwave. FSKs are also commonly in binary format, meaning there are two frequencies that alternate to send data, which is not the case for this one. It also does not seem standard in a way that it follows a specification. But let's *take a few steps back*. Remember three links from **starting_point.txt**? The first one is incomplete. That link may be embedded in here. ![Trial and Error](/static/img/oblivion_hunt/wave_file2.png) We can confirm and decode everything through trial and error. Aligning each 0.5 second beep interval with each letter, the first and second, sixth and seventh, ninth and thirteenth characters should be of the same frequency, because they are the same characters. Respectively: tt, // and oo. And indeed they are. With this, we can deduce that these characters map to these frequencies:
Character Frequency (hertz)
h730
t850
p810
s840
:1060
/1040
d690
o800
w880
n790
l770
a660
We can also write a Python script, or make one with the help of AI, to extract frequencies of each 0.5 second interval note.

import numpy as np
import scipy.io.wavfile as wav

def get_frequencies(filename, chunk_duration=0.5):
    # Read WAV file
    rate, data = wav.read(filename)

    # Handle stereo -> mono
    if data.ndim > 1:
        data = data.mean(axis=1)

    # Samples per chunk
    chunk_size = int(rate * chunk_duration)

    freqs_list = []

    for start in range(0, len(data), chunk_size):
        chunk = data[start:start+chunk_size]
        if len(chunk) < chunk_size:  # skip last incomplete chunk
            break

        # Apply FFT
        fft_spectrum = np.fft.fft(chunk)
        fft_magnitude = np.abs(fft_spectrum)[:len(chunk)//2]  # keep positive freqs
        freqs = np.fft.fftfreq(len(chunk), d=1/rate)[:len(chunk)//2]

        # Find peak frequency
        peak_idx = np.argmax(fft_magnitude)
        peak_freq = freqs[peak_idx]

        freqs_list.append(peak_freq)

    return freqs_list

freqs = get_frequencies("the_creepiest_sound_you_will_ever_hear.wav", chunk_duration=0.5)
for i, f in enumerate(freqs):
    print(f"Chunk {i}: {f:.2f} Hz")
With the current information that we have, we can assume the following deductions - 660Hz (a) - **660+(10*25)** = 950Hz (z) are small letters of the alphabet - Base frequency, 400Hz + **(10*26)** = 660; we'll assume, since this range covers 26 characters, that it is big letters of the alphabet, 400Hz being A, 650Hz being Z. - / is 1040Hz, : is 1060Hz The structure of a mediafire link is as follows:
https://download1078.mediafire.com/
Upon researching, we discover that after the **download** word comes 4 or 5 digits then **.media.fire.com**. Aligning the **.** character, we can deduce that there are four digits and learn that: - **.** has a value of 1030Hz. - digits 0-9 fall in the range of 920Hz - 1010Hz, right next to small letters. At this point we have discovered a partial charset of:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
, starting from 400Hz, increasing by 10Hz every letter up until 1010Hz. We replace each of these frequencies with what we currently know so far and get:
https://download1509.mediafire.com/a6ld8ks6lyggZsWtGv3Zr9TchBKl*4arm719iQm1BfenYiRyiVpPdxLVWLu3uxIX2dWa9Nt5*Q0f*veSeW8IYP0mDlpWNEn2I0yhdY1vOKwvxXtk44VEhH9vTCaaXvoEAjMS3NLXHcbnINJ7EGfbpr9spNurUqgklvLM0xKBmSEEDF0/t4coxe7whcmup0q/th3*mor3*cr33pY*1t*g3ts.zip
with \* being a missing character. This could be - or \_ according to a common mediafire link structure. Either way just a few guesses and we can find the correct link:
https://download1509.mediafire.com/a6ld8ks6lyggZsWtGv3Zr9TchBKl_4arm719iQm1BfenYiRyiVpPdxLVWLu3uxIX2dWa9Nt5_Q0f-veSeW8IYP0mDlpWNEn2I0yhdY1vOKwvxXtk44VEhH9vTCaaXvoEAjMS3NLXHcbnINJ7EGfbpr9spNurUqgklvLM0xKBmSEEDF0/t4coxe7whcmup0q/th3_mor3_cr33pY_1t_g3ts.zip/
# Part 4: The More Creepy It Gets Unzipping the file uncompresses two files, a data file with an .slm extension and a ASCII text file. Let's start with the simplest one first, the ASCII text. It is a bunch of hexadecimal characters. ![tmcig.png](/static/img/oblivion_hunt/tmcig.png) We can decode this hex dump using **xxd** command or using **Cyberchef**. In this case, I'm using the former. We found out that decoding the hexdump gives us a PNG image. ![tmcig_hi.png](/static/img/oblivion_hunt/tmcig_hi.png) The image might potentially trigger some readers, so we omit it for now, it's an image of a face. We use **zsteg**, a common tool for hiding data in either MSB or LSB of a PNG image, to reveal a string of text at b1,rgb,lsb,xy with value: **J4pan3se\_d3nim\_023** ![tmcig_hi.png2](/static/img/oblivion_hunt/tcig_hi2.png) Moving on to the .slm file, this is not a standard file, but rather a file created by Ivan Dizon's [Seclume](https://github.com/kUrOSH1R0oo/Seclume-Linux), an archiving tool. This is available on his Github with complete documentation on how to use. According to the docs, we can extract the contents of an .slm file using the command:
./seclume extract gr34t3st_w1z4rdsz.slm J4pan3se_d3nim_023
![seclume.png](/static/img/oblivion_hunt/seclume.png) # Part 5: Greatest Wizards The extracted **gr34t3st_w1z4rdsz.txt** contains cryptic messages that talk about a certain flower with other details, an ASCII art and some variables. **Cryptic message**: ![greatestwizards.png](/static/img/oblivion_hunt/greatestwizards.png) **Key value pair**:

C = b05df77c1c6a0a20f478e13316c2665db13333d57a87fe04f0fb5fca010597f282aeab4e7bae3b9405a24c2c536de8716925c50301a85525fbf492a89f595fd33f298b7a87d969fa9a071bdea000dcc94751e3fdb36576647ef2606196eaddefbe340c4393892a925eb8f5e306e07c116758c88a5105e8cab8e50b1c1fb13a5e60e884e6227a7219d525cfa08e21f83e1253c50a80fec84a2dcf330ccaf45507611a456dd488111a4fab116906a25750f6691a446a94a434e49f3491459a4e29e4a8409b6bb7861f7517f218d5e30574b266272ab7ae927b46a59a810fd1ffb520cdbb08b052bca3ece5d4155664ef5ac6ca12042c6221f09ba65fdc5fa54a5788704d36d209d1c651013ae705904b3cd6d69fcf7283bf9a90b46ec13e0921ea5500304a50734b6c14893558077feea75cced600575d5533a69dc24837ad962430dbd04e25a94731625b5417a38451ee0a59508488796c5b680cd3ba5a36e3fbc19886f05cc578c50bf449091abe0d4c8871317dae0c083eaebf3422890c321a7b9312e3c5bd9d1306cb2b82b67c037074dfae6f662ac8ad37382f50f73f428cec9b7dd2abc62421edb35e1dffa4252361da9c93cb18151492b5a907702fe1d611b3b4a9aca79acf7111a30f60f8b08689a78bfcbe799d4709c1a3a4d771eab1594ede006b72e3ab38bd4ea209146f42458c71326139c46c008ed256fb46c98d3615199462a4cefc7fcdd30ccec7b79fc6d6b8861f9341b5c202bb95cc8506d10b5cd3c46d7d050f49712345fcc1d371c4075182c2a53f220212e923b976ad24c3922ca336f748991332b063f7bbf2aaa39db62fa6e288bdd8a5f33e4e32e4ca785e92aeb772493c1ff8d98e352c4f15fcb17f605acf6cf257dcb39b2b58f25afea72f84b2b281817483dffc00f93dad37e696fdec849b0226b40489418c60fd85f5e99203d8818e474a2d823c7b779765375a4897e134bdb0b81cc209f51a7726f5a18c91bf5f962069b634dcbe61ccb9aff1395e0e978e77af26312893bf28
K = 01af2bfc483ae9172b366da88db653de
IV = a859709bb5778403829d5217e2363143
The key value pair seems to be from a symmetric cipher like **AES**, where C is ciphertext, K is key and IV is initialization vector. But this is not AES at all. Analyzing the text, here are the important points: - from the quiet corners of the Land of the Rising Sun - There is a flower that blooms only in silence - a spiral that turns inward yet reaches outward at the same time Searching at google for **japanese flowers spiral** reveals a flower named *camellia japonica*. A red, pink-ish flower with spiral patterns. This key, ciphertext and initialization vector may refer to the cipher with the same name as the flower: [Camellia](https://en.wikipedia.org/wiki/Camellia_(cipher). I could not find a reliable decoder for Camellia online, and only a few discussions about it , but fortunately, there is a dedicated Python library for it. For which we just plug the value and call the decrypt function. **Decrypting the contents**: ![camellia.png](/static/img/oblivion_hunt/camellia.png) **Result**:

Within you lies the gravity of distant stars, a force quietly waiting. Turn the flow back through three tens of hidden steps, or let the cycle of half a dozen fives guide you, spiral it backward, again and again, and watch what awakens in the silent folds. The pattern shifts where eyes cannot see, and only those who honor the rhythm of repetition glimpse the pulse beneath. Shadows whisper in threes and tens, folding upon themselves, revealing what is never truly given, only discovered.

https://download947.mediafire.com/43gsfl7wh11gom553oZ0AEei63sdTf4Gj7bjRy3CroS5UecVe_4umHSVM6gGD-Z3X6GRMLWc1Yjhj5Xdo0ejLffBzEO9RIjkSC-FXPmoraQjwxixrAZcVb6ZQ9fgK6udocxQQNbmpdBxbwYHryI2OMGIKLwsM8L19vXEiE5eqsXYVnk/k7j8t6z3tcgidmc/encoded.txt
# Part 6: Layers The file is a whopping 917 kilobytes of Base64 characters. This will definitely make unoptimized decoders lag or even crash. Upon decoding, it is another layer of base64 encoding, simply decode this giant base64 text until it is no longer a base64 and at the end, it yields a base32 text. You can choose to manually decode this one by one, with a total of 31 base64 layers, and a final base32 value:
LBXDKZLIPA2WEXZZM5PTMZ3GL5JTMYJYMZTV6NJXMM3DONRZNY3DOOJWMY4DOOJXHA3DOZRWG43DQNRXNI3DQNRZGUZTSN3CGQ4TMNZZMU3DOOJWG43HCNRXGY4A====
Decoding this base32 text we get:

Xn5ehx5b_9g_6gf_S6a8fg_57c6769n6796f8797867f676867j68695397b49679e679676q6768
This may seem like another garbage text, but when faced with situations like this, try the most common ways to decode text, such as shift cipher or substitution cipher. In this case, this is a shift cipher, but instead of including only letters, we also include the numbers. Decrypting with a **ROT18** cipher, we get:

Ka0ruk0o_4t_1ts_F1n3st_02p1214a1241s3242312s121312w13140842o94124r124121d1213
... What now? # Part 7: The End After long hours of solving, we've reached the end. At this point, you most likely forgot about the details about the previous challenges, and only focusing only on the current challenge. If you remember the very first part of the challenge, the **kuroshiro_crush.jpg** file that seemed like it's a file with no embedded data as no common techniques or results using tools yield anything. The decrypted ROT18 cipher may be a key to **steghide** command, which we can confirm: ![crush.png](/static/img/oblivion_hunt/crush.png) This text below is a series of numbers, which can be either be decimal, octal, or hex. **36 33 39 32 38 32 37 35 34 30 32 38 28 39 20 31 31 29** If you're unsure, [Cyberchef](https://gchq.github.io/CyberChef/) has a feature where it can automatically detect which type of cipher or encoding a text uses. Using Cyberchef, we see that is in hex, and decoding it reveeals the final goal: ``` 639**********(9 11) ``` A phone number, which when called from **9AM - 11PM**, confirms your **win** at Oblivion Hunt. --- # Conclusion While there may be no winners for this year's competition, it was an event worth preparing by the A1SBERG organization as its debut event, featuring how we compete in CTFs and teaching the new generations to not only be aware, but gain hands on experience in cybersecurity. If you did not solve this challenge, do not worry about having lack of knowledge, take it as a motivation. Having difficulties, making mistakes, not realizing something happens to everybody, even to the best of us. And even I, the lone solver, took days, asked for help, got confused, overthought ideas. It is what will shape your mindset as a competitor for A1SBERG, because the other teams will not show you mercy. Once again, congratulations to the participants. See you next year.