BSidesCT 2025 CTF Writeup - Web, OSINT, Forensics & Stego

 9 min read

Cover for BSidesCT 2025 CTF Writeup - Web, OSINT, Forensics & Stego

On September 20, 2025, Bsides Connecticut hosted a CTF. My team, Kern(a)l came in 3rd during this CTF, and in this blog, we will dive into some of the challenges that were solved. If you are a visual learner and want a visual representation of this CTF walkthrough, consider watching the video version on the MRE Security YouTube Channel.

Web

Question MFA

Author: skeyellama

MFA is for chumps. You know what you need to do.

https://webapp-4.challenge.ctf.bsidesct.org/

Looking at the application, we see that there is a login page with demo credentials.

Supplying the admin:password123 credentials onto the login page, we see that the user gets prompted with an MFA page. However, we don’t know the code to access the application.

Looking at the Page Source, there is some JavaScript.

function verifyMFA() {
        const code = document.getElementById('mfa-code').value;
        const errorDiv = document.getElementById('error-msg');
        
        if (!code || code.length !== 6) {
            showError('Please enter a 6-digit code');
            return;
        }
        
        fetch('/verify-mfa', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify({code: code})
        })
        .then(response => response.json())
        .then(data => {
            if (data.status === 'success') {
                // Set MFA verified flag before redirect
                fetch('/set-mfa-verified', {method: 'POST'})
                .then(() => {
                    window.location.href = '/dashboard';
                });
            } else {
                showError(data.message || 'Invalid authentication code');
            }
        })
        .catch(error => {
            showError('Verification failed. Please try again.');
        });
    }

This code is sending a POST request to the /verify-mfa endpoint. It retrieves the response, and checks to see if the body of the JSON has a status set to success. If that’s the case, it will proceed to send a POST request to the /set-mfa/verified endpoint and redirect the user to /dashboard.

Make sure to set up Burp Suite Intercept, supply a 6-digit code, and submit it. Right-click on the request and select Do Intercept -> Response to this request. Proceed to forward the request.

Once the request comes back with the response, modify the status parameter to have the value as success, then proceed to forward the request.

Turn off Burp Suite Intercept and observe the browser redirects to the /dashboard endpoint, revealing the flag.

Flag: BSidesCT{mf4_byp4ss_1s_n0t_1mp0ss1bl3}

CONSUME

Author: skeyellama

I’m sure you obey price tags. Unless…?

https://webapp-5.challenge.ctf.bsidesct.org/

Looking at the application, we see it’s a standard e-commerce shop.

Looking at a few of the items, we see that one of the items has an Exclusive tag.

After adding the item to the cart, we can go to the /cart endpoint and observe our items and coupons that are available.

Using the CORPORATE200 coupon, we can see the coupon was applied, but we need the item to get to 0 so we can purchase it.

Since Burp Suite is running in the background, it is capturing every request that’s being sent to the server. Looking at the requests, we see that there’s an /apply-coupon endpoint being used. Sending the request to repeater, we can continuously send the request until the balance hits 0.

Going back to the browser, we can see that the coupon was applied numerous times, and we can complete the purchase.

We see that the flag is in the success page.

Flag: BSidesCT{bu51n3ss_l0g1c_fl4ws_c0st_m0n3y}

OSINT

Chat Logs

Author(s): watafk & boom

You recently joined Disorganized Arachnid, one of the most notorious hacking groups in the game. You log on for the day and see they’re hunting for their next target. Read through the chat logs and see what you all are going to hit next.

What is the street address of the target company and what year did the VP of Information Systems start their role at the company?

Flag Format: BSIDESCT{#_StreetName_StreetType_Year}

SHA1: fe92ee670c7560a7be3cc9f120f25233e584853f

challenge.html

Looking a the challenge, we have to identify the company’s address and the VP of Information Systems. Looking at the chat log, we can see at the bottom that there are two interesting clues. The first is that there’s a company called Mindware Media. Additionally, there is a person by the username: s1gnaltap. Since this challenge is tailored towards us finding additional information about the company, let’s start with Mindware Media.

Looking at Google, typing Mindware Media doesn’t reveal too much. When dealing with a company name, I try different variations such as MindwareMedia or Mindware-Media. After a few variation attempts, I got a hit with MindwareMedia, where there’s a LinkedIn titled: David Chen - VP at Mindware-Media Corp.

Looking at David Chen’s job history on LinkedIn, we find the address of the company and when David started at Mindware Media.

Flag: BSIDESCT{6_Subliminal_Drive_2015}

Put On The Glasses

Author(s): watafk & boom

Looks like this one is all on you. Put on the glasses and start to build out the employee’s foot print and look for a good target to find our in.

What department does Maya Rodriguez work in and what is her social media handle?

Flag Format: BSIDESCT{handle_department}

With this David Chen user, we can see that he posted something on his page about a new SOC Analyst who is posting some great content.

Clicking on the link in the post, we get redirected to pr0ph3cy39871’s SOC Analyst Insights Page. Looking around GitHub and going to the user’s page, we see that the user has an Instagram page attached to their GitHub.

Navigating to the Instagram page, we see an interesting photo attached; it looks like an Employee ID.

Since the challenge wants a handle and department, it is safe to say that we have the information needed to proceed to the next challenge.

Flag: BSIDESCT{pr0ph3cy39871_SOC}

Behind The Message

Author(s): watafk & boom

Looks like one of the employees writes security blogs somewhere. We need you to find their email address, it should be on there.

Flag Format: BSIDESCT{[email protected]}

Since we have the user’s GitHub, we can perform a reverse lookup of their username to retrieve their email by visiting a website like Elliott’s DIY GitHub Finder Page. Supply the pr0ph3cy39871 username to the website, and observe the email address that comes back.

Flag: BSIDESCT{[email protected]}

Infostealer

Author(s): watafk & boom

Huh, looks like there is already an insider at Mindware that dumped some infostealer logs.. I heard they might have gotten popped and it’s not actually them. We need you to figure out who it is. They post on a site that used to be known as something else and they also like decentralized platforms. Find which employee it is and the numbers in their handle.

Flag Format: BSIDESCT{First_Last_####}

Looking back at the chat log, we saw a username, s1gnaltap appear. This user is our person of interest during this challenge, and we need to figure out where their username is being used. To do this, a site called Whats My Name can be used to retrieve information about a specific username. This website will scrape and try to identify where the user is registered on different social media.

Looking at the user’s X account (which requires you to be signed in), we can see that the user has a Pastebin, which is notoriously known for having malware and leaked data stored on it.

[NergalC2 v3.4.1 - Information Harvest Log]
[Campaign ID: BSIDESCT_CTF_2025]
[C2 Server: 192.168.56.13:8443]
========================================

[2024-09-19 14:23:41] [INFO] Connection established from 10.0.2.15
[2024-09-19 14:23:42] [HARVEST] Beginning credential extraction...

---[ SYSTEM INFO ]---
Hostname: DESKTOP-OBY-2742
OS: Windows 10 Pro 21H2 Build 19044
User: S1gnalTap_8264
Domain: MINDWARE-MEDIA
IP: 10.0.2.15
MAC: 00:1B:44:11:3A:B7

---[ BROWSER CREDENTIALS ]---
[Chrome v117.0.5938.132]
URL: https://internal.mindware-media.corp/admin
Username: S1gnalTap_8264
Password: 0B3Y_C0N5UM3_5L33P!
Cookies: session_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

<...>

Using the Instant Username Search tool, we can check to see if that username is taken on different social media platforms. Looking at the results, there are a few.

Since the challenge mentions decentralized platforms, we could look at Bluesky since they have communities. Searching for the username S1gnalTap_8264 in Bluesky doesn’t retrieve anything, but looking up s1gnaltap does.

We can see the s1gnaltap user’s first and last name.

Flag: BSIDESCT{priya_patel_8264}

The Call

Author(s): watafk & boom

Now it’s your time to shine and hit Mindware. You should have everything you need to get a password reset on one of Mindware’s employees so we can get in and do what we do best.

Look through their accounts and build a profile on them to see who is the best victim. This should help you out a bit. Afterwards, call their password reset line at their IT helpdesk and social engineer a password reset from the helpdesk employee.

Flag Format: You’ll know it when you see it. Don’t mess this up.

Looking at the previous challenges, we have details that profile individuals, which the IT helpdesk may request. This is the importance of documentation when performing OSINT. In Maya Rodriguez’s email address, we saw a domain mindware-media.com. Navigating to this page, we find the phone number for the call center on the Contact page.

When you call this number, another person will answer and ask you the following questions.

After answering each question correctly, the IT would send you a Password Reset Link, which looked like this.

Opening the link that was provided in the email, it redirects you to the /secure/2f71c7d1f999304fd8d9239411701d55/ endpoint, which reveals the flag.

Flag: BSIDESCT{S1GN4L_T3RM1NAT3D_TH3Y_S33_US_N0W}

Miscellaneous

Trust, But Verify

Author(s): fortyseven & boom

You know what you must do.

https://www.bsidesct.org/truth

Looking at the web page, we see green terminal text.

There’s not a whole lot on this page, but taking a look at the source, we see something interesting.

There is a truth.js file on the server. In this JavaScript file, we see that there is an asynchronous function.

async function flagUser() {
    /*
    Frank talk: rev'enging this is not the challenge. Don't be boring.
    I just did this mostly as a speedbump so I'm not explicitly dumping
    the flag in plaintext of the repo.
    */

    if (typeof window.denton !== "function") {
        await new Promise((resolve, reject) => {
            const script = document.createElement("script")
            script.src = "/truth/js/denton.js"
            script.onload = () => resolve()
            script.onerror = () => reject(new Error("Failed to load denton.js"))
            document.head.appendChild(script)
        })
    }
    const response = await fetch("/truth/a11y.dat")
    if (!response.ok) throw new Error("Failed to fetch a11y.dat")
    const data = await response.text()
    const decoded = window.denton(data)

    await humanType(`\n${decoded}`, 400, "#fff")
    await sleep(500)
    await humanType(`\n`, 40)
}

It will decode something for us. Going back to the application and right-clicking, we can go to Inspect -> Console and supply flagUser().

Flag: BSIDESCT{y0u_p4ss3d_th3_ex4m!}

BSidesOS

Author: boom

Now comes with even more telemetry!

SHA1: e0bcc1765ce2958c8d684050e28e22c7b5daebf7

bsidesOS.iso

Looking at the file we can see it is a ISO 9660 CD-ROM.

We can perform a strings onto this file, which reveals there’s a FLAG.TXT and in it is an ASCII representation of the flag.

Flag: BSIDESCT{Mount_or_Burn_M3}

Mr. Robot

Author: boom

Such a good show, but I don’t ever recall Elliot making robot noises..

With most web applications, there is a robots.txt file that tells crawlers, such as Google, what not to index in search results. Going to this file on the web server, we retrieve the flag.

Flag: BSIDESCT{ins3rt_r0b0t_n01s35}

Slow Down

Author: boom

Woah there.. slow your roll this ain’t a freebie!

SHA1: 003af54eb5e2aa565a5e747d8e789385b0a78531

flag.zip

Looking at the ZIP file, when attempting to unzip it, it shows a rock.png file is inside but requires a password.

One of the easiest ways to crack a ZIP file’s password is by using zip2john.

zip2john flag.zip > hash

Then, we can pass the hash file to JohnTheRipper and retrieve the password.

john hash /usr/share/wordlists/rockyou.txt --format=PKZIP

JTR came back with smilebig! was the password. Unzipping the file and extracting the rock.png, we can retrieve the flag.

Flag: BSIDESCT{r0ck_4nd_r0ll_4ll_n1ght}

Warez

Author: boom

We just crafted up this new strain of ransomware and we’d like you to be our first victim :)

SHA1: b72dee8acc6d426d5e67b5e62cc32d8b52ca8c6b

sleepware

Looking at the file, we see that it’s just some ASCII art and a little message at the bottom saying the flag isn’t in the file.

The description of this challenge clearly states that this was a new strain of ransomware. When dealing with malware samples, people usually don’t download and execute them without placing them in a sandboxed and controlled environment. In this case, we can take the SHA1 hash that was provided in the description of the challenge and paste it into a tool called VirusTotal.

Looking at VirusTotal, we can see that there are 0 detections that this was actually malware, but when we navigate to the Details section, we can retrieve the flag.

Flag: BSIDESCT{not_4_m4lw4r3_s4mpl3}

Forensics

PUT ON THE GLASSES, FRANK!

Author: boom

Are you either going to put on the glasses or start eating the trash can?

SHA1: cdd0afb72687288e9dd5659393573cf84acde930

glasses.jpg

Looking at the JPEG, we can do a file command on it and retrieve the flag. The data that was found extracts information from the metadata of the image, which can also be retrieved using exiftool.

Flag: BSIDESCT{you_aint_the_first_to_wake_up}

Steganography

Author: boom

Is anyone else feeling tired today?

SHA1: b5156ecd3f5cdd024952ac183239207f702d71a8

we_sleep.jpg

Doing a file command on this JPG, we see it appears to be a standard JPG.

There are two ways to see if there are hidden files. One is by using binwalk, which will carve out data that could be embedded into the file.

It looks like there is a ZIP file embedded in the JPG. Something that is also interesting that you can do is try to strings a JPG file. If you see a PK or ZIP, most of the time, that indicates that the file has a ZIP file embedded into it.

Moving the file from a we_sleep.jpg to we_sleep.zip, we can unzip the file and retrieve the flag.

Flag: BSIDESCT{h0nk_sh00_h0nk_m1m1m1}