Bearcat CTF 2025
Hey, fellow hackers! 🏴☠️
Today, I’m dropping a writeup for the Bearcat CTF 2025 challenges!️. I teamed up with my squad, P4rad0x. Let’s jump straight into the action! 🚀

Web
Global Redirect - 100

At first glance, it looks like a boring old login page to me. But, there’s always something more beneath the surface. Let’s break it down!
The challenge presents us with a simple login page asking for a username and password. My first instinct? I decided to peek at the page source

and found something very interesting—a JavaScript script handling authentication!
<script>
function loginAuthenticate(){
var password = document.getElementById("password");
var hash = sjcl.hash.sha256.hash(password);
var hexRepresentation = sjcl.codec.hex.fromBits(hash);
if (hexRepresentation == "2a70282a868c0ca9e6fe5bb5cf2ac2ea6b523062102bada26fb87091d511e3f1"){
alert("welcome Home Admin");
window.location = "./0078f62f00305b73de6ccace8f9fc1f68a8f1dcec865d33fcacbaf255ddefaa7";
}else{
alert("Incorrect Password. Please Try Again");
}
alert(hash);
}
</script>
Now, what’s happening here?
The script takes the password entered by the user.
It hashes the password using SHA-256.
It compares the hashed value with a hardcoded hash.
If it matches, it redirects the user to a new page.
Key takeaway: The password isn't checked on the server
The script reveals the secret redirect location:
http://chal.bearcatctf.io:39724/0078f62f00305b73de6ccace8f9fc1f68a8f1dcec865d33fcacbaf255ddefaa7
Visit the URL, the admin page was wide open, and sitting right there was our flag:
BCCTF{T1ck3t_t0_0wn3rsh1p!}
Reversing
Say Cheese - 150

In this challenge, A Python script, it is a simple flag checking program.
In that the ciphertext, key and the encoder function is given, Let’s break it down step by step!
import base64
def encoder(input_str, key):
encoded_chars = []
for i in range(len(input_str)):
key_c = key[i % len(key)]
encoded_c = chr((ord(input_str[i]) + ord(key_c)) % 256)
encoded_chars.append(encoded_c)
encoded_str = ''.join(encoded_chars)
return base64.b64encode(encoded_str.encode()).decode()
def main():
print(""" _--"-.
.-" "-.
|""--.. '-.
| ""--.. '-.
|.-. .-". ""--..".
|'./ -_' .-. |
| .-. '.-' .-'
'--.. '.' .- -.
""--.. '_' :
""--.. |
""-' """)
ciphertext = "wpbCi8KIwpfCh8OPwph5wqnCosK6woTCqcKnwq13wrfCh8KzwqnCpMKKccOJwrh8wqTCl3LDgcKHw4U="
key = "THECAT"
inp = input("Enter your cat: ")
encoded_flag = encoder(inp, key)
if ciphertext == encoded_flag:
print("YAY you found the cat!")
else:
print("Not so easy cheesy huh?")
if __name__ == "__main__":
main()
In this Python script, it does the following:
Takes user input (a string).
Encodes it using a function called
encoder()
.Compares the encoded result to a hardcoded
ciphertext
.If they match, it prints "YAY you found the cat!", otherwise, it denies us.
Here’s the important part—the encoder function:
def encoder(input_str, key):
encoded_chars = []
for i in range(len(input_str)):
key_c = key[i % len(key)]
encoded_c = chr((ord(input_str[i]) + ord(key_c)) % 256)
encoded_chars.append(encoded_c)
encoded_str = ''.join(encoded_chars)
return base64.b64encode(encoded_str.encode()).decode()
It’s basically modifying each character of the input based on the key "THECAT", then encoding it in base64.
Since I don’t know the original input that produced the given ciphertext, I need to reverse the encoding process.
Looking at the logic:
Each character in the input string is shifted using
(ord(input[i]) + ord(key[i % len(key)])) % 256
.To undo it, we just reverse the shift:
import base64
def decoder(ct, key):
d_b64 = base64.b64decode(ct).decode()
d_chars = []
# print(len(d_b64))
for i in range(len(d_b64)):
key_c = key[i % len(key)]
d_c = chr((ord(d_b64[i]) - ord(key_c)) % 256)
d_chars.append(d_c)
return ''.join(d_chars)
ciphertext = "wpbCi8KIwpfCh8OPwph5wqnCosK6woTCqcKnwq13wrfCh8KzwqnCpMKKccOJwrh8wqTCl3LDgcKHw4U="
key = "THECAT"
flag = decoder(ciphertext, key)
print("FLAG:", flag)
BCCTF{D1d_y0U_h4v3_a_G0ud4_T1m3}
Easy - 300

In this challenge, I am going to do a simple reverse engineering.
I am given an ELF executable file. This file prompts for user input and checks if it matches a hidden flag.
To peek inside, I uploaded the binary into Ghidra—a powerful tool for reverse engineering. I navigated to the main function, and guess what❓
There were a bunch of interesting lines dealing with variables and a mysterious XOR function!

XOR is a common trick used to encrypt and decrypt data. The program had a set of encrypted values, and it used a key to XOR them back into the original flag.
Here's how it worked:
The program stored some values in variables.
These values were passed into the XOR function along with a key (0x37333331).
The function returned the decrypted result, which was then compared with user input.

I found these values in the program:
local_168 = 0x7f04487763707073
local_160 = 0x435d4005406c0405
local_158 = 0x734107796803406e
local_150 = 0x4c
Using Python’s struct
module, I wrote a simple script to change the format to little endian.
import struct
local_168 = 0x7f04487763707073
local_160 = 0x435d4005406c0405
local_158 = 0x734107796803406e
def to_little_endian(value):
return struct.pack("<Q", value)
hexa = to_little_endian(local_168).hex() + to_little_endian(local_160).hex() + to_little_endian(local_158).hex() + '4c'
print(f"In little-endian: {hexa}")
This gave me the properly formatted encrypted flag. Using CyberChef’s XOR operation with the key 1337, I decrypted the hidden message.

BCCTF{7H47_w4snt_s0_H4rD}
Miscellaneous
What you see - 200

The challenge, "What You See", gave me just a simple image file.
First things first, I ran the usual checks:
🛠 exiftool
– Nothing suspicious in the metadata.
🛠 file
command – Just a regular JPG file.
r1pp3r 🔱 god2eye ~/Documents/CTF/bearcatctf25
λ file CtfProblem.jpg
CtfProblem.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 1080x1080, components 3
r1pp3r 🔱 god2eye ~/Documents/CTF/bearcatctf25
λ exiftool CtfProblem.jpg
ExifTool Version Number : 12.76
File Name : CtfProblem.jpg
Directory : .
File Size : 261 kB
File Modification Date/Time : 2025:02:02 01:20:13+05:30
File Access Date/Time : 2025:02:03 14:12:20+05:30
File Inode Change Date/Time : 2025:02:02 02:03:53+05:30
File Permissions : -rw-r--r--
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
JFIF Version : 1.01
Resolution Unit : None
X Resolution : 1
Y Resolution : 1
Image Width : 1080
Image Height : 1080
Encoding Process : Baseline DCT, Huffman coding
Bits Per Sample : 8
Color Components : 3
Y Cb Cr Sub Sampling : YCbCr4:4:4 (1 1)
Image Size : 1080x1080
Megapixels : 1.2
Hmm… no easy giveaways. Time to dig deeper!
Since the challenge hints were "Inspect, Extract, Reveal", I tried 🛠 StegSolve, a tool that used to analyze images in different planes by taking off bits of the image.
After sometime, Setting it to "Red Plane 6", I saw a hidden message in the image:

📝'the password is "ctf"'
Now, we had a password—but for what? 🤔
Knowing the file might contain embedded data, I turned to 🛠 StegHide, a steganography program which hides bits of a data file in some of the least significant bits of another file in such a way that the existence of the data file is not visible and cannot be proven.
r1pp3r 🔱 god2eye ~/Documents/CTF/bearcatctf25
λ steghide extract -sf CtfProblem.jpg
Enter passphrase:
wrote extracted data to "secret-text".
It asked for a password. I entered "ctf", and a hidden file popped out! 🎉
Inside the file "secret-text", there it was—the flag! 🏁
BCCTF{w34k_s4uc3_4_u}
Cyptography
Seeing Triple - 400

This one had me seeing triple—literally! The challenge, "Seeing Triple", dropped a text file on us that looked like a wall of 3’s.
33333333333333343333333333333332333333333333333433333333333333333333333333333334333333333333333333333333333333353333333333333334333333333333333433333333333333363333333333333337333333363333333233333333333333343333333333333339333333333333333733333333333333343333333333333337333333333333333333333333333333353333333633333336333333333333333433333336333333313333333333333337333333333333333533333333333333373333333333333333333333333333333233333333333333333333333333333335333333363333333633333333333333343333333333333338333333333333333333333333333333333333333333333337333333333333333833333333333333373333333633333334
At first glance, the file was packed with endless 3’s and a few other numbers sprinkled in. The challenge name hinted at threes everywhere, so my first move was to remove all the 3’s.
❌ Bad idea. That left me with nothing useful.
Hmm… maybe the 3’s weren’t just noise? 🤔
Instead of removing all the 3’s, I looked for a pattern. Turns out, "3333333" (a long chain of 3’s) was acting as a separator!
By removing those big clusters before each different number, I was left with:
3432343334333534343637623439373437333566346137353733323335663438333337383764
This looked a LOT like hex!. I used the xxd command to convert back into Ascii and 🎉 Boom! The flag!
r1pp3r 🔱 god2eye ~/Documents/CTF/bearcatctf25/crypto
λ echo -n 3432343334333534343637623439373437333566346137353733323335663438333337383764 | xxd -r -p | xxd -r -p
BCCTF{Its_Jus#_H3x}
Osint
Been touring the artic - 150

Here I was given a KML file, which is a geographic data file used by applications like Google Earth. Naturally, my first step was to upload it into Google Earth and see where it led me.

Once opened, the file pointed to a specific spot—the University of Cincinnati. But why? Looking closer,
The Title says "Cool Statue" makes me want to see the statue🧐, Then I saw a statue of a Cincinnati Bearcat, a well-known mascot of the university.
The flag was the scientific name of the animal. A quick search revealed that the Cincinnati Bearcat is actually an Arctictis binturong, commonly known as a binturong or “bearcat.”
BCCTF{arctictis_binturong}
Building Breakers - 200

This Challenge, I was given a photo of a building. ❌No coordinates—just an image. My job was to 🔎identify where this building was located.

Now hunting for the landmark, Since I had no immediate clues, I used a combination of:
Google Reverse Image Search
TinEye (another image search tool)
Browsing famous buildings in Zürich
After a long search, 🎉I finally found a match—it was the Swiss National Museum in Zürich, Switzerland!
BCCTF{Swiss_National_Museum}
Last updated