Sitemap
Nataliah Alcala-Maharaj

Nataliah Alcala-Maharaj

Cybersecurity MSc Student | GIAC Certified | ISC2 CC | WiCyS Scholar | Lifelong Learner | Committed to Growth & Impact

New to CTFs? Here’s What Solving One Actually Looks Like

15 min readAug 20, 2026

--

A beginner-friendly write-up of the Sisterhood of the Traveling Packets 2026 CTF, covering the solve, the reasoning behind it, and lessons you can take into your next challenge.

Press enter or click to view image in full size
Official Sisterhood of the Traveling Packets CTF merchandise. Image: Flare.

CTF walkthroughs often make the solution look cleaner than the process really was.

They show you what worked, but not always how the solver knew what to try, what they had to research, or when they realized they were heading in the wrong direction.

This write-up takes a different approach.

I’ll walk through how I solved the CTF, including the reasoning behind the decisions, the mistakes that slowed me down, and the lessons I took from the experience.

My goal is not just to show you the solution, but to give you a better sense of how to think through a CTF from start to finish.

Let’s get into it.

The Challenge

This beginner-friendly challenge was part of the Sisterhood of the Traveling Packets CTF, created by Flare, SANS Institute, and Women in CyberSecurity (WiCyS).

“A careless ransomware collective got sloppy. Now it’s your turn to expose their OPSEC failures through forensics, exploitation, and decoding. Turn the hunters into the hunted.”

The challenge brought us to the dark-web leak site of a fictional ransomware group called pantalones, and our job was to investigate the mistakes they had left behind and ultimately find the flag.

Quick Tip: Read the challenge description as part of the evidence, not just as background information. Words like ransomware, OPSEC, forensics, exploitation, and decoding can give you clues about the kinds of things that may matter and help shape where you start looking.

The starting point was a .onion link to the group’s leak site.

A Closer Look: Why Tor Browser and a .onion Site?

Most websites can be opened in a regular browser using familiar addresses such as .com or .org. A .onion address works differently. It is typically accessed through the Tor network, which is why I needed Tor Browser to open the link provided in the challenge.

Tor, short for The Onion Router, is a privacy-focused network designed to make it more difficult to trace where internet traffic is coming from or where a service is being hosted.

Tor itself is not the dark web. The dark web refers to websites and services that are intentionally hidden from the regular web and usually require special software or networks to access. Many .onion sites are part of the dark web and are reached through Tor Browser.

That made the .onion address especially relevant to the ransomware scenario. Real ransomware groups have used Tor-based leak sites to publish stolen data and support extortion operations while making their infrastructure more difficult to trace. So the use of Tor wasn’t just there for effect. It helped recreate the kind of environment associated with a real ransomware operation.

This was my first time using Tor Browser, so that part was new to me. The challenge itself was still straightforward to access and did not require a command line or special exploitation tools. The core solve could be completed in the browser.

Step 1: Exploring The Site

Once I had the leak site open, I started with the simplest thing I could do:

I looked around.

I clicked through the site, checked the About page for more context about the group, and looked at the Crew section, which listed the pantalones members and their roles. The Leaks page listed several victims. Two of them — QuantumCore Systems and AetherFlow Enterprises — already had leaked data available to browse and download, while the files for the other victims were not yet accessible.

pantalones ransomware leak page

I also checked the source code of the pages as I went.

If you’ve never done that before, it’s simple: right-click anywhere on the page and select “View Page Source.” This opens the HTML behind the page in a new tab.

I checked the source of the main Leaks page, the About page and the Crew page, looking for anything that wasn’t immediately visible in the browser.

And eventually, I found something in the Leaks page.

Inside an HTML comment was a long encoded string.

Press enter or click to view image in full size
Page source showing the encoded string

The string looked like Base64, so I copied it into CyberChef and decoded it.

Press enter or click to view image in full size
Base64 string decoded in CyberChef

The result?

not_the_flag_keep_looking

Well.

At least I knew I was looking in the right places. Fun stuff.😂

A Closer Look: Why Check the Page Source?

What you see on a webpage isn’t necessarily everything that’s there. View Page Source lets you look at the HTML the browser received to build the page.

In a CTF, that can be worth checking for things such as comments, unusual paths, encoded strings or other information that isn’t obvious on the visible page.

You don’t need to understand every line of HTML. You’re simply looking for anything that stands out.

Quick Tip: Base64 is an encoding method that converts data into a text-based format. You’ll often recognize Base64 by its combination of letters and numbers, sometimes ending with characters such as =. That doesn’t mean every string that looks like this is Base64, but it’s worth checking. Tools such as CyberChef make this easy. Paste in the string, select “From Base64”, and see what comes out.

The Base64-encoded message told me to keep looking. And so I did.

Step 2: Digging Through The Leaked Files

The leak site contained data belonging to two fictional victim companies: QuantumCore Systems and AetherFlow Enterprises.

Each had files available to browse on the leak site and a ZIP archive that could be downloaded.

Naturally, my next thought was:

There has to be something useful in these files.

So I started exploring.

Press enter or click to view image in full size
QuantumCore Systems leaked files
Press enter or click to view image in full size
AetherFlow Enterprises leaked files

There were SQL files, internal API keys, company data and other files that looked like they could contain useful information. I also downloaded the ZIP archives for both companies and started going through their contents.

This wasn’t a bad approach. In a CTF, investigating the information you’ve been given makes sense.

The problem was that I became convinced the answer had to be somewhere in those files.

So when nothing obvious appeared, I kept digging.

And digging.

And digging.

That was about to send me down my first major rabbit hole.

Step 3: The Shell Script That Sent Me Down A Rabbit Hole

After downloading the aetherflow_leak.zip file, I extracted it on my Windows machine and started going through its contents.

Among the extracted files, one really stood out: .exfil.sh

Press enter or click to view image in full size
Extracted AetherFlow Enterprises files showing .exfil.sh

What Are We Looking At? .exfil.sh file

The .sh extension usually identifies a shell script, which is a text file containing commands that a Unix/Linux shell can execute.

The word exfil is commonly shorthand for exfiltration. In cybersecurity, data exfiltration refers to data being transferred out of a system or environment.

And that dot at the beginning?

On Linux and other Unix-like systems, filenames beginning with . are conventionally treated as hidden. Windows handles hidden files differently, using a hidden file attribute instead. Since I extracted the ZIP on Windows, .exfil.sh was visible to me.

Put all of that together and a file called: .exfil.sh

inside leaked ransomware data was definitely worth opening.

Press enter or click to view image in full size
Contents of .exfil.sh

But the script wasn’t just an interesting technical file.

Its presence in the ZIP was itself interesting.

Remember how the challenge told us that “a careless ransomware collective got sloppy”?

At the very bottom of the script was this comment:

# TODO: delete this before zipping

Someone had apparently intended to remove this file before creating the archive and hadn’t.

That looked very much like the kind of OPSEC mistake the challenge was asking us to find, so naturally, I thought:

This has to be important.

And the contents gave me even more reason to think so.

The script referenced the group’s panel, contained an X-Panel-Key, listed files to be sent, and included this request:

api.php?action=upload

I didn’t understand everything in the script at first, but seeing api.php stood out to me. It told me that there was an API connected to the site, and I had a strong feeling that it was something I needed to investigate.

The upload action made me think this might be the way forward, so I spent a lot of time trying to figure out what I could do with it. When that didn’t get me anywhere, I went back through the downloaded files looking for credentials, passwords, configuration details, or anything else that might connect the pieces.

I spent about two hours here.😫

Eventually, I had to accept that I wasn’t getting any closer to the flag and move on.

But one thing from that script stayed in the back of my mind:

api.php

And that would matter later.

Quick Tip: Finding something interesting doesn’t necessarily mean you’ve found the solution. Make a note of it. Ask what it tells you. Test reasonable ideas. But if you’re repeatedly doing variations of the same thing and learning nothing new, it may be time to investigate another clue.

That would have saved me quite a bit of time here.

Step 4: Checking robots.txt

Eventually, I decided to check whether the site had a robots.txt file.

And honestly, I should have done this much earlier.

But if you’re completely new to web CTFs, “check robots.txt” might not mean much yet. So here's exactly what I did.

I was already on the pantalones .onion website in Tor Browser. I went to the browser's address bar and added/robots.txtto the end of the site’s main address.

So, conceptually, if the site were: http://example.onion

I would navigate to: http://example.onion/robots.txt

No special tool. No command line. I simply requested that path through the browser.

Press enter or click to view image in full size
robots.txt revealing /api.php and /admin.php

And it immediately gave me something useful:

Disallow: /api.php

Disallow: /admin.php

Two paths. Both looked worth investigating.

A Closer Look: What is robots.txt?

robots.txt is a text file that websites can use to give instructions to automated web crawlers — such as search-engine bots — about areas of the site they should or shouldn't crawl.

It’s normally located at the root of a website, which is why I could simply add:

/robots.txtafter the site’s main address.

Here’s the important part for a CTF:

“Don’t crawl this” does not mean “nobody can access this.”

In fact, a robots.txt file can sometimes reveal interesting directories, files or endpoints simply because they've been listed there.

In this case, it pointed me directly toward:

/api.phpand /admin.php

Quick Tip: Checking robots.txt is a good early reconnaissance step in a web-based CTF. It takes seconds and may reveal something worth investigating.

And in my case, doing it earlier would have saved me a lot of time.

I decided to investigate /admin.php first.

Step 5: Finding The Admin Panel

Of the two paths I found in robots.txt, I decided to check /admin.php first.

To do that, I went back to the address bar in Tor Browser and replaced /robots.txt at the end of the URL with: /admin.php

This brought me to a login page.

Press enter or click to view image in full size
pantalones admin login page

The page wanted two things: Username + Password.

The site had already given me a possible answer to the first one.

The Crew page identified four members of the ransomware group and their handles.

Press enter or click to view image in full size
pantalones Crew page showing member handles and roles

So I had possible usernames.

Now I needed a password.

Get Nataliah Alcala-Maharaj’s stories in your inbox

Join Medium for free to get updates from this writer.

This is where I got stuck. Again.

Step 6: Looking For A Password That Wasn’t There

I went back through the leaked files.

I searched for credentials.

I looked for strings that might be passwords.

I went into the browser’s Developer Tools and started inspecting the application there.

Nothing.

I went back through the files again.

Still nothing.

I spent too much time trying to answer one question:

Where did they hide the password?

Eventually, I realized I needed to change the question.

I had discovered two interesting endpoints in robots.txt.

I had spent all this time focusing on:/admin.php

What about:/api.php?

Step 7: Exploring The API

After spending far too long looking for a password, I went back to the other path I’d found in robots.txt: /api.php

Using the same approach as before, I navigated to it in Tor Browser.

The response gave me an error — but it was actually a very useful one.

Press enter or click to view image in full size
/api.php response listing the available actions

It said: missing required parameter: action

and then listed the valid actions:

upload , status , messages , decrypt , wallets , payloads , exfil

An API is a way for software to request or exchange information with an application. Here, /api.php was giving me access to different functions depending on the action I supplied.

So I started trying them.

To specify an action, I added it to the URL like this: api.php?action=status

Then I changed the value to test the others:

api.php?action=messages

api.php?action=decrypt

api.php?action=wallets

…and so on.

I checked all of them, trying to understand what each one returned and whether any of them could move me closer to the flag.

It wasn’t until I saw a hint in the challenge Discord about enumerating conversations that I went back and paid much closer attention to the messages action.

And that’s where things finally started to come together.

💡Pro Tip: If hints are available and you’re stuck, use them. If there’s a Discord or Slack for the challenge, keep an eye on those conversations too. You may find just enough of a nudge to help you see the problem differently.

Step 8: Enumerating The Conversations

The messages action required a conversation_id .

Press enter or click to view image in full size
API response showing the required conversation_id parameter

Okay, now I knew what I needed to do: try different conversation IDs and see what came back.

But I still had to figure out how to add conversation_id to a URL that already contained the action=messages parameter.

A quick bit of research gave me the answer. I could use an ampersand (&) to add another parameter and an equals sign (=) to specify its value:

api.php?action=messages&conversation_id=1

Now I could enumerate the conversations simply by changing the number. I started with 0:

conversation_id=0

conversation_id=1

conversation_id=2

…

Each valid ID returned a different conversation between members of the pantalones crew.

Press enter or click to view image in full size
Internal conversation returned by the API

What Are We Looking At? These weren’t messages displayed on the public leak site. They were internal conversations being returned by the site’s API when a valid conversation_id was supplied.

More importantly, I could access different internal conversations simply by changing that number.

From an OPSEC perspective, that’s a serious mistake. Communications the group presumably intended to keep private were being exposed through their own application.

And one of those exposed conversations contained exactly what I had been looking for.

When I reached conversation_id=2, one crew member was asking another about a forgotten password.

The response contained a Base64-encoded string.

Press enter or click to view image in full size
Excerpt from conversation_id=2 API response

I copied the string into CyberChef, decoded it, and this time I got a password.

Press enter or click to view image in full size
Base64 credential decoded in CyberChef

Even better, the conversation told me whose password it was: mora

After all those hours spent searching through files for credentials, I finally had what I needed: Username + Password.

Remember the /admin.phpadmin panel?

Time to go back.

Step 9: Capturing The Flag

I returned to /admin.phpand entered the credentials.

Press enter or click to view image in full size
Admin dashboard displaying the flag

There it was.

After hours of searching through leaked files, inspecting Developer Tools, experimenting with the shell script and generally looking everywhere except where the password actually was:

flare{pantal0n3s_g0t_pantsed_2026}

🚩 Flag captured.

What Actually Went Wrong?

The group accidentally left .exfil.sh inside a leaked archive, exposing information about its internal panel and API. The API then exposed internal conversations simply by changing a numeric conversation_id. And inside one of those conversations, a crew member shared a password that had only been Base64-encoded.

Individually, each mistake revealed something useful. Together, they exposed enough information to reach the admin panel and capture the flag.

Those were the OPSEC failures the challenge had been pointing to from the beginning.

The Direct Path To The Flag

If we remove all my wrong turns and look only at the steps that ultimately led me to the flag, the solve becomes fairly short:

  1. Check robots.txt.
  2. Discover api.php and admin.php.
  3. Inspect api.php.
  4. Discover the messages action.
  5. Learn that it requires conversation_id.
  6. Enumerate the conversation IDs.
  7. Find the exposed Base64 credential.
  8. Decode it.
  9. Authenticate to the admin panel.
  10. Capture the flag.

Now, I could have simply given you those ten steps and called it a walkthrough.

But I wanted to show you how I actually got there: the clues that made sense, the ones I misunderstood, the rabbit holes, the research, the hints, and eventually, the breakthrough.

Because the clean solution is what the challenge looks like after you know the answer. Figuring out that path in the first place is a very different experience.

That’s not separate from solving a CTF. That’s part of solving a CTF.

Every challenge gives you an opportunity to add something to your toolkit, whether that’s a new technique, a new concept, or simply a better way of approaching a problem.

As a beginner the goal isn’t to know everything before you begin. It’s to know a little more by the time you reach the flag.

What I’d Do Differently Next Time

My biggest mistake was becoming attached to one theory.

Once I found the admin panel and knew the usernames, I decided:

There must be a password hidden in these files.

From that point forward, I interpreted almost everything through that assumption.

But there was an even earlier lesson here:

I should have done the simple reconnaissance first.

Checking robots.txt would have taken seconds. Instead, I spent a significant amount of time digging into more complicated-looking artifacts before checking one of the simplest places available to me.

So next time, before I go too deep, I’ll make sure I’ve covered the basics.

And when a theory isn’t producing anything new, I’ll ask myself whether I’m still investigating or whether I’m simply trying to prove my original assumption.

The better question in this challenge wasn’t: “Where is the password?”

It was: “What else can this application show me?”

Returning to the API changed everything.

That’s something I’ll carry into future CTFs. If I’ve spent a long time testing the same hypothesis without learning anything new, it’s time to pause.

Go back to the evidence.

Question the assumption.

And ask a different question.

For Your Next CTF

Before you head into your next challenge, here are a few things worth carrying with you:

  • Read the challenge description carefully. The wording and theme can give you clues about what kinds of mistakes, artifacts, or techniques might matter.
  • Start with the simple reconnaissance. Before diving into the complicated-looking stuff, make sure you’ve covered the basics.
  • Follow interesting clues, but don’t become attached to them. If you keep testing the same idea and stop learning anything new, it may be time to change direction.
  • Use hints when you need them. Sometimes a small nudge is enough to help you see the problem differently.
  • Research what you don’t know. You don’t need to understand every concept before you begin. Learn what you need for the next step, apply it, and keep going.
  • Know when to step away. If you’ve been staring at the same problem for too long, take a break and come back with fresh eyes. Sometimes a little distance makes the thing you were overlooking much easier to see.

Ready to Try One Yourself?

If you want to put some of those ideas into practice, here are a few beginner-friendly places to start.

CyLab Security Academy (formerly picoCTF)
A great place to experience CTF-style challenges across different areas of cybersecurity. The platform is free, designed to support learners with no prior experience, and lets you practise at your own pace.

OverTheWire: Bandit
A good starting point if you want to become more comfortable with Linux and the command line. Bandit is specifically aimed at absolute beginners and gradually introduces skills that will help with other security challenges.

OverTheWire: Natas
If the web side of this CTF interested you, Natas is worth trying next. It focuses on the basics of server-side web security, with a different website to investigate at each level.

PortSwigger Web Security Academy
Another excellent option if you want to build your web-security skills. It is free and combines learning material with hands-on labs, with structured learning paths available from beginner through more advanced topics.

One Last Thing

My hope is that this write-up gave you more than the solution to one CTF. I hope it gave you a better sense of how to think through a challenge, what to do when an idea isn’t working, and how much of the learning happens while you’re figuring things out.

You don’t have to understand the entire challenge.

You just need to stay curious enough to keep asking questions.

What does this mean? What happens if I try something different? What am I missing?

Curiosity leads to the next question.

And that next question is what ultimately gets you to the flag.🚩

--

Nataliah Alcala-Maharaj
Nataliah Alcala-Maharaj

Written by Nataliah Alcala-Maharaj

Cybersecurity MSc Student | GIAC Certified | ISC2 CC | WiCyS Scholar | Lifelong Learner | Committed to Growth & Impact