National Cyber League - Web Application
November 17th, 2025
Γ-Intro
Winter of 2025 marked my first participation in the National Cyber League (NCL), a cybersecurity organization that challenges students with real-world cyber security scenarios of most fields. My team consisted of five memembers, including myself, where we team up to tackle each challenge that is presented to us. Myself and a team member named Andrew, who also has experience in the web field, decided to work together on the web application section of NCL. As Andrew and I flyed past the first two challenges we encounterd the final third challenge. At this point Andrew was appointed to another section of NCL and I was left to solve the final challenge on my own. The challenge was named: 'The Cucumber's Secret' with five sub-questions. Due to NCL/CyberSkylines policy, I am unable to provide both questions and answers to this challenege. This is a simple write-up of my findings for this challenge.
Γ-Overview
The title, 'The Cucumber's Secret' is a play on words. A cucumbers secret is simply a pickle, which is also the name of a serialization method for creating an object for data transfer. Think of it like a JSON object, but for other languages. In this instance, the web-server was only accepting Python related Pickles. The website had two fields to work with. The field on the left was an input field. This field had text where I believe it said something along the lines of 'Archive ID.' The field of the right was the output field. This field had no description but was outputting whatever was inputted on the left-hand field. The code below is a good representation of how the website looked. Quick note: The value on the left-hand field is generated by a Python Pickle object script, it tries to be identifical as much to the original. The right-hand field simply decodes the inputted Python Pickle Object.
Archive ID:
gASVngAAAAAAAACMCGFwcC5tYWlulIwLQXJjaGl2ZU1ldGGUk5QpgZR
9lCiMA3VybJSMDmh0dHA6Ly9hcmNoaXZllIwFdGl0bGWUjBVUaGUgQ3
VjdW1iZXIncyBTZWNyZXSUjAl0aW1lc3RhbXCUjBQyMDI2LTAzLTIzV
DE3OjM1OjQzWpSMC3N0YXR1c19jb2RllEvIjApjaGFyX2NvdW50lE1n
AnViLg
OUTPUT:
{
'url': 'http://archive',
'title': 'The Cucumber's Secret',
'timestamp': '2025-11-17T17:30:10Z',
'status_code': 200,
'char_count': 615
}
Γ-Challenge
With the overview out of the way, it's time to get into the actual challenege. I designated my first task to be understanding how Pickles work and how the website interacts with them. After some quick OSINT research, I found a whole article detailing how Pickles work, how they can be malfored and created, and how they can be exploited. To do so, I had to create a Python program that creates a malformed Pickle object with the same format that the website follows. Below is the code that I created to generate a basic Python Pickle Object.
import pickle
import base64
from datetime import datetime, timezone
class ArchiveMeta:
def __init__(self):
self.url = 'http://archive'
self.title = 'The Cucumber's Secret
self.timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
self.status_code = 200
self.char_count = 615
The imported modules helped me craft the malformed Pickle object. The class 'ArchiveMeta' is the format the website follows, with the class name 'ArchiveMeta' with the variables: url, title, timestamp, status_code, and char_count. But Jackson, how did you know what the class name and the variables were? This is a very good observation that I faced when first writing the script. If you were to take the original Pickle object the website generates on refresh, decode it using a base64 decoder, you would get a rather interesting output. As the Pickle object is sanitized and 'encrypted', using a base64 decoder wouldn't decode the entire payload, just tiny informative parts. The few parts that were decoded were at the beginning of the object, and they revealed the class name and module. With this information, I was able to craft an object with the same class-name and later, same module name. With the script crafted, it was time for the challenege. The challenege for this CTF was to get a working Remote Code Execution (RCE) through this Python Pickle Object. I was able to figure out that the objective of this challenge was to get a working RCE through the assitance of my team as well as my further research into Python Pickles. Python Pickles aren't as common as they used to be because of major vulnerabilities that were uncovered years after its creation. A simple internet search of Python Pickles would reveal that these objects are extremely prone to RCE vulnerabilities. With the script created and infomration gathered, it was time to completely solve this lab and finish off the Web Application section of the Winter 2025 NCL.
Γ-Solution
After an hour or two of reserach and collaboration with my team, I was able to craft a working RCE Python Pickle Object creator. Following the script formed above, I added a couple of areas to satisfify the websites requirements. The first thing I added was a '__reduce__' method. The reduce double underscore (dunder) method is a special method in Python that is used to define object serializations. In this instance, I used it to craft a malfored reqeust and execute code on demand.
import pickle
import base64
from datetime import datetime, timezone
class MaintenanceMode:
def __reduce__(self):
self.execute_task = 'cd ../.env'
class ArchiveMeta:
def __init__(self):
self.url = 'http://archive'
self.title = 'The Cucumber's Secret'
self.timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
self.status_code = 200
self.char_count = 615
obj = ArchiveMeta()
pickle_obj = pickle.dumps(obj)
pickle_obj = pickle_obj.replace(b'__main__', b'app.main')
malformed_payload = base64.b64encode(pickle_obj).decode()
print(malformed_payload)
Now that we are here it is important to go over an annoying aspect in this CTF. The CTF was very picky on which commands could be executed through the RCE vulnerability. I had to do a lot of trial and error to find a command that would work.
After a while, I was able to determine that change directory (cd) command was the only command to seem to run. I'm sure the CTF was crafted to only accept very few commands so that people don't accidentally go too far and cause potential damage.
After further trial and error with their directory structure, I was able to find the '.env' file. This file is a rather common file in web applications and I have done a CTF in the past that involved reading the contents of an '.env' file using RCE.
The malfored Python Pickle script successfully answered all five questions that were asked at the beginning of the CTF. Unfortunately, NCL or CyberSkyline, has a strict policy where I can not give out any specific details about the answers.
Since this is a simple write up of a previous challenege, this falls into their policy about sharing experiences in their labs.
Γ-Findings
Though I am unable to share the answers, I can provide insight of my discoverings throughout this challenge. For one, this is the first time I've heard and used a Pickle Object before. This lab made me research and truely dig deep into how Pickle objects work and their vulnerabilities. This also includes finding my own exploits for this challenge that aren't related to any of the questions/objective. Throughout this challenge, trying to make a working RCE, I managed to find a working XSS exploit within the Pickle Object reader.
class ArchiveMeta:
def __init__(self):
self.url = 'http://archive'
self.title = '<h1>XSS</h1>'
self.status_code = 200
self.char_count = 615
OUTPUT:
{
'url': 'http://archive',
'title': 'XSS
',
'timestamp': '2025-11-17T17:30:10Z',
'status_code': 200,
'char_count': 615
}
Γ-Lessons Learned
Concluding this challenge, I had a great time and I learned so much. At first I was hesitant to begin this lab without a team and tackle it solo but I was amazed on how well I performed.
I was able to solve the challenege and answer all of the questions and it would awarded us about 65 points in total. Additioanlly, I was very euphoric when I managed to figure out an unintentional and it made me realize that everything that I have learned is being appilied.
This was my first time doing the NCL/CyberSkyline events and I had a blast. Stay tuned for next semester because Andrew and I will be tackling the web application section for the Spring of 2026 NCL.