<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>0xkakashi</title><description>Home</description><link>https://0xkakashi.com/</link><language>en</language><item><title>🐛 Bug Hunting Methodology</title><link>https://0xkakashi.com/posts/bug-hunting/methodology/</link><guid isPermaLink="true">https://0xkakashi.com/posts/bug-hunting/methodology/</guid><description>How I approach vulnerability research and bug hunting, recon, common bug classes, and disclosure flow.</description><pubDate>Wed, 13 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;First post in the Bug Hunting section. This is my repeatable methodology, refined over time. I&apos;ll edit and expand as I learn.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;1. Target intake&lt;/h2&gt;
&lt;p&gt;Before any tool runs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Confirm you have &lt;strong&gt;explicit permission&lt;/strong&gt; to test the target (self-owned, authorized engagement, or a public VDP). No permission, no testing.&lt;/li&gt;
&lt;li&gt;Understand what the target actually does. A bug that&apos;s noise in one threat model can be P1 in another.&lt;/li&gt;
&lt;li&gt;Map out what&apos;s in scope and what&apos;s off-limits. Stay inside that boundary the entire time.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2. Recon&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Subdomain enumeration&lt;/strong&gt;: &lt;code&gt;amass&lt;/code&gt;, &lt;code&gt;subfinder&lt;/code&gt;, &lt;code&gt;crt.sh&lt;/code&gt; for cert transparency&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tech fingerprinting&lt;/strong&gt;: &lt;code&gt;wappalyzer&lt;/code&gt;, &lt;code&gt;whatweb&lt;/code&gt;, &lt;code&gt;httpx&lt;/code&gt; for response headers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Content discovery&lt;/strong&gt;: &lt;code&gt;feroxbuster&lt;/code&gt; / &lt;code&gt;ffuf&lt;/code&gt; with curated wordlists by tech stack&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JS analysis&lt;/strong&gt;: pull all JS, search for endpoints, secrets, internal API paths&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I lean heavily on my own &lt;a href=&quot;/projects/&quot;&gt;RECOG.py&lt;/a&gt; pipeline to chain these.&lt;/p&gt;
&lt;h2&gt;3. Bug classes I prioritize (web)&lt;/h2&gt;
&lt;p&gt;In rough order of impact on most targets:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;IDOR / broken access control&lt;/strong&gt;: still the highest-impact class on most web apps&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auth bypass / session handling&lt;/strong&gt;: race conditions, token reuse, OAuth misconfig&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSRF&lt;/strong&gt;: especially via image fetchers, webhooks, URL parameter parsing&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Server-side template injection&lt;/strong&gt;: when frameworks expose user-rendered templates&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Business logic&lt;/strong&gt;: race conditions, state machine abuse, price/quantity manipulation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stored XSS in admin / privileged surfaces&lt;/strong&gt;: high impact, often overlooked&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;XSS in user-facing surfaces is fine but lower impact, so go for higher-leverage classes first.&lt;/p&gt;
&lt;h2&gt;4. Triage and write-up&lt;/h2&gt;
&lt;p&gt;Before reporting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reproduce on a &lt;strong&gt;clean account / browser&lt;/strong&gt; (no extensions, no logged-in cookies)&lt;/li&gt;
&lt;li&gt;Capture &lt;strong&gt;minimal repro steps&lt;/strong&gt; in 3 to 5 lines&lt;/li&gt;
&lt;li&gt;Describe &lt;strong&gt;impact in business terms&lt;/strong&gt;, not just &quot;I can call X endpoint&quot;&lt;/li&gt;
&lt;li&gt;Provide &lt;strong&gt;remediation guidance&lt;/strong&gt;. Make it easy for the team to fix it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5. Ethics&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Never test outside what you&apos;re authorized to test. Period.&lt;/li&gt;
&lt;li&gt;No data exfiltration beyond proof of impact. One record beats a full dump.&lt;/li&gt;
&lt;li&gt;Disclose responsibly. Coordinate with the team, don&apos;t publish until they&apos;ve had time to fix and are okay with it.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;This is a living document. I&apos;ll update it as my methodology evolves.&lt;/em&gt;&lt;/p&gt;
</content:encoded></item><item><title>🌐 Security Platforms I Use</title><link>https://0xkakashi.com/posts/platforms-i-use/</link><guid isPermaLink="true">https://0xkakashi.com/posts/platforms-i-use/</guid><description>A rundown of the labs, CTF practice sites, and blue team training platforms I actively use, with what each is good for.</description><pubDate>Wed, 13 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The full grid with logos and direct links lives at &lt;a href=&quot;/platforms/&quot;&gt;/platforms&lt;/a&gt;. This post is the narrative version: what each platform is for, when to use it, and what I&apos;ve personally got out of them.&lt;/p&gt;
&lt;h2&gt;Labs (interactive environments)&lt;/h2&gt;
&lt;p&gt;These are the boot-to-root and hands-on-curriculum platforms. Real machines or guided environments to exploit.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TryHackMe&lt;/strong&gt; is where I started. Best on-ramp for someone new to offensive security. Guided rooms, learning paths, beginner-friendly. Once you finish the SOC Analyst or PenTester path you&apos;re ready for the harder stuff.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HackTheBox&lt;/strong&gt; is the next step. No hand-holding, real machines, active community. Use the main platform for boxes, HTB Academy for structured paths (paid, so I lean on the free tier).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HackMyVM&lt;/strong&gt; is like Vulnhub but with online flag submission and a leaderboard. Good if you want to root machines but don&apos;t want to download VMs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hackviser&lt;/strong&gt; is a newer entry, focused on practical pentesting upskilling with certifications (CAPT, CWSE, CSOA). Free tier is generous.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PortSwigger Web Security Academy&lt;/strong&gt; is the gold standard for web. 100% free, deep, well-maintained. If you&apos;re doing any web work, you have to do these labs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hacker101&lt;/strong&gt; by HackerOne. Free CTF labs covering common web bug classes. No bounty involvement needed to use it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;CTF Practice (challenge-based)&lt;/h2&gt;
&lt;p&gt;Standing challenges across categories. Solve at your own pace.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CyLab Security Academy&lt;/strong&gt; (formerly picoCTF / PicoGym) is the easiest on-ramp. Carnegie Mellon CyLab&apos;s beginner-friendly platform. Annual competition + an always-on challenge gym.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CryptoHack&lt;/strong&gt; is the best crypto-specific platform out there. I&apos;ve done 33 challenges and counting. Math-heavy in the upper tiers, which is the fun part.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Root-Me&lt;/strong&gt; is huge. 300+ challenges across web, crypto, network, forensics, RE. Older but still active.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CTFlearn&lt;/strong&gt; is simpler challenges, good for filling skill gaps.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pwn.college&lt;/strong&gt; is binary exploitation taught dojo-style. The belt progression makes it feel like a real curriculum.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RingZer0 CTF&lt;/strong&gt; has a huge catalog (300+) across multiple categories. Long-running and underrated.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pwnable.tw&lt;/strong&gt; is for serious binary exploitation. Authored by top DEFCON CTF players. Don&apos;t start here.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Webhacking.kr&lt;/strong&gt; is a veteran Korean platform focused on web exploitation. Classic SQLi / XSS / auth bypass focus.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FlagYard&lt;/strong&gt; is a relatively new platform with realistic-feeling challenges.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;247CTF&lt;/strong&gt; is always-on with a modern UI and a balanced category mix.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ImaginaryCTF&lt;/strong&gt; runs monthly events plus a permanent catalog.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MetaCTF&lt;/strong&gt; is team-style practice with an emphasis on realistic scenarios.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CTFGuide&lt;/strong&gt; is more of a learning platform but with challenge progression.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Crackmes.one&lt;/strong&gt; is the spot for reverse engineering challenges specifically.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PyDefis&lt;/strong&gt; is French Python-focused challenges with crypto and security flavor.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hack.arrrg.de&lt;/strong&gt; is a smaller German CTF platform.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Blue Team / SOC&lt;/h2&gt;
&lt;p&gt;Defensive-focused training. SIEM, IR, threat hunting, malware analysis.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LetsDefend&lt;/strong&gt; is where I&apos;ve earned the most badges. SOC Analyst learning path, hands-on alert triage, real-feeling tickets. Highly recommend for anyone going into SOC work.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CyberDefenders&lt;/strong&gt; runs blue team CTFs and labs on real incident data (memory dumps, packet captures, log archives).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Blue Team Labs Online&lt;/strong&gt; is similar to CyberDefenders, with more focus on threat hunting scenarios.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;CTF Tracker&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CTFtime&lt;/strong&gt; isn&apos;t a challenge platform. It&apos;s where every live CTF event gets listed, and where individual and team rankings live across the whole CTF universe. If you compete, you should have a profile here.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Where to start&lt;/h2&gt;
&lt;p&gt;If you&apos;re new and reading this, my unfair-but-useful advice:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Do all of &lt;strong&gt;TryHackMe&lt;/strong&gt;&apos;s SOC Analyst (or PenTester) path&lt;/li&gt;
&lt;li&gt;Pick a specialty and dig in: &lt;strong&gt;HackTheBox&lt;/strong&gt; for offensive, &lt;strong&gt;LetsDefend&lt;/strong&gt; for blue team&lt;/li&gt;
&lt;li&gt;Compete in one CTFtime-listed event with a team&lt;/li&gt;
&lt;li&gt;Pick a vertical you actually enjoy (web / pwn / crypto / RE) and go deep on the platform that specializes in it&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Don&apos;t try to do everything on every platform. Breadth here is a trap.&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - C3</title><link>https://0xkakashi.com/posts/picogym/cryptography/c3/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/c3/</guid><description>This is the Custom Cyclical Cipher! Enclose the flag in our wrapper for submission. If the flag was &quot;example&quot; you would submit &quot;picoCTF{example}&quot;.</description><pubDate>Wed, 31 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/C3/convert.py&quot; download&amp;gt;📂 Download encoder.&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;a href=&quot;/files/PicoGym/Cryptography/C3/ciphertext&quot; download&amp;gt;📂 Download ciphertext.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; This is the Custom Cyclical Cipher! Enclose the flag in our wrapper for submission. If the flag was &quot;example&quot; you would submit &quot;picoCTF{example}&quot;.&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Matt Superdock&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge involves &lt;strong&gt;C3 (Custom Cyclical Cipher)&lt;/strong&gt;, a custom encryption algorithm that uses differential encoding with lookup tables. We&apos;re given the encoder program and ciphertext, but need to reverse-engineer the decryption process. By understanding how the cipher works, we can write a simple reversal script to recover the original flag.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;h3&gt;Challenge Files&lt;/h3&gt;
&lt;p&gt;We have two components:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;convert.py&lt;/strong&gt; - The encoder/encryption program that shows us the algorithm&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ciphertext&lt;/strong&gt; - The encrypted message we need to decrypt&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;How the Encryption Works&lt;/h3&gt;
&lt;p&gt;Here&apos;s the complete encoder program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import sys
chars = &quot;&quot;
from fileinput import input
for line in input():
  chars += line

lookup1 = &quot;\n \&quot;#()*+/1:=[]abcdefghijklmnopqrstuvwxyz&quot;
lookup2 = &quot;ABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrst&quot;

out = &quot;&quot;

prev = 0
for char in chars:
  cur = lookup1.index(char)
  out += lookup2[(cur - prev) % 40]
  prev = cur

sys.stdout.write(out)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Breaking down the algorithm:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reading Input:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from fileinput import input
for line in input():
  chars += line
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;fileinput.input()&lt;/code&gt; reads from files passed as command-line arguments (or stdin)&lt;/li&gt;
&lt;li&gt;This loops through each line in the input file&lt;/li&gt;
&lt;li&gt;All lines are concatenated into the &lt;code&gt;chars&lt;/code&gt; variable&lt;/li&gt;
&lt;li&gt;So if the plaintext file has multiple lines, they&apos;re all combined into one string&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The Lookup Tables:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;lookup1&lt;/code&gt; = &lt;code&gt;\n &quot;#()*+/1:=[]abcdefghijklmnopqrstuvwxyz&lt;/code&gt; (41 characters - valid plaintext alphabet)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lookup2&lt;/code&gt; = &lt;code&gt;ABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrst&lt;/code&gt; (40 characters - valid ciphertext alphabet)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Differential Encoding Process:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For each character in the input plaintext:
&lt;ul&gt;
&lt;li&gt;Find its &lt;strong&gt;position&lt;/strong&gt; in &lt;code&gt;lookup1&lt;/code&gt; (call this &lt;code&gt;cur&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Calculate the &lt;strong&gt;difference&lt;/strong&gt; from the previous position: &lt;code&gt;(cur - prev) % 40&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Use this difference as an &lt;strong&gt;index into &lt;code&gt;lookup2&lt;/code&gt;&lt;/strong&gt; to get the encrypted character&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Save&lt;/strong&gt; the current position as &lt;code&gt;prev&lt;/code&gt; for the next iteration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The &quot;Cyclical&quot; Part:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The modulo 40 operation wraps differences around, creating a cyclic pattern&lt;/li&gt;
&lt;li&gt;This is why it&apos;s called the &quot;Custom &lt;strong&gt;Cyclical&lt;/strong&gt; Cipher&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Example Walkthrough&lt;/h3&gt;
&lt;p&gt;Let&apos;s say we&apos;re encrypting &quot;ab&quot;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;First character &apos;a&apos;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Index in lookup1: 33&lt;/li&gt;
&lt;li&gt;prev = 0&lt;/li&gt;
&lt;li&gt;difference = (33 - 0) % 40 = 33&lt;/li&gt;
&lt;li&gt;lookup2[33] = &apos;h&apos;&lt;/li&gt;
&lt;li&gt;Output: &apos;h&apos;, prev = 33&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Second character &apos;b&apos;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Index in lookup1: 34&lt;/li&gt;
&lt;li&gt;prev = 33&lt;/li&gt;
&lt;li&gt;difference = (34 - 33) % 40 = 1&lt;/li&gt;
&lt;li&gt;lookup2[1] = &apos;B&apos;&lt;/li&gt;
&lt;li&gt;Output: &apos;B&apos;, prev = 34&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Final ciphertext: &quot;hB&quot;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;The Encrypted Message&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;DLSeGAGDgBNJDQJDCFSFnRBIDjgHoDFCFtHDgJpiHtGDmMAQFnRBJKkBAsTMrsPSDDnEFCFtIbEDtDCIbFCFtHTJDKerFldbFObFCFtLBFkBAAAPFnRBJGEkerFlcPgKkImHnIlATJDKbTbFOkdNnsgbnJRMFnRBNAFkBAAAbrcbTKAkOgFpOgFpOpkBAAAAAAAiClFGIPFnRBaKliCgClFGtIBAAAAAAAOgGEkImHnIl
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is what we need to decrypt.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;h3&gt;Reversing the Encryption&lt;/h3&gt;
&lt;p&gt;Since encryption uses only &lt;strong&gt;addition and modulo&lt;/strong&gt;, it&apos;s easily reversible:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Encryption:&lt;/strong&gt; difference = (cur - prev) % 40 â†’ lookup2[difference]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Decryption:&lt;/strong&gt; We reverse this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Find the encrypted character in &lt;code&gt;lookup2&lt;/code&gt; to get the difference&lt;/li&gt;
&lt;li&gt;Add the difference to prev: cur = (difference + prev) % 40&lt;/li&gt;
&lt;li&gt;Look up the character in &lt;code&gt;lookup1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Update prev for the next character&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Decryption Script&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;lookup1 = &quot;\n \&quot;#()*+/1:=[]abcdefghijklmnopqrstuvwxyz&quot;
lookup2 = &quot;ABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrst&quot;

ciphertext = &quot;DLSeGAGDgBNJDQJDCFSFnRBIDjgHoDFCFtHDgJpiHtGDmMAQFnRBJKkBAsTMrsPSDDnEFCFtIbEDtDCIbFCFtHTJDKerFldbFObFCFtLBFkBAAAPFnRBJGEkerFlcPgKkImHnIlATJDKbTbFOkdNnsgbnJRMFnRBNAFkBAAAbrcbTKAkOgFpOgFpOpkBAAAAAAAiClFGIPFnRBaKliCgClFGtIBAAAAAAAOgGEkImHnIl&quot;

plaintext = &quot;&quot;
prev = 0

for char in ciphertext:
    # Step 1: Find the difference from lookup2
    diff = lookup2.index(char)
    
    # Step 2: Calculate the original index
    cur = (diff + prev) % 40
    
    # Step 3: Get the plaintext character
    plaintext += lookup1[cur]
    
    # Step 4: Update prev for next iteration
    prev = cur

print(plaintext)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Running the Script&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ python decrypt.py ciphertext
#asciiorder
#fortychars
#selfinput
#pythontwo

chars = &quot;&quot;
from fileinput import input
for line in input():
    chars += line

for i in range(len(chars)):
    if i == b * b * b:
        print chars[i] #prints
        b += 1 / 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Understanding the Decrypted Output&lt;/h3&gt;
&lt;p&gt;The decrypted text is actually a Python script! Looking at it carefully:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Comments: &lt;code&gt;#asciiorder&lt;/code&gt;, &lt;code&gt;#fortychars&lt;/code&gt;, &lt;code&gt;#selfinput&lt;/code&gt;, &lt;code&gt;#pythontwo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;A loop that prints characters at specific positions: where &lt;code&gt;i == b * b * b&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This means it prints at positions: 1Â³=1, 2Â³=8, 3Â³=27, 4Â³=64, 5Â³=125, 6Â³=216... (perfect cubes!)&lt;/p&gt;
&lt;h3&gt;Fixing the Script&lt;/h3&gt;
&lt;p&gt;The decrypted script had some issues (using &lt;code&gt;/&lt;/code&gt; instead of proper integer, old Python 2 syntax):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#asciiorder
#fortychars
#selfinput
#pythontwo

chars = &quot;&quot;
from fileinput import input
for line in input():
    chars += line

b = 1

for i in range(len(chars)):
    if i == b * b * b:
        print(chars[i], end=&apos;&apos;)  # Fixed: Python 3 syntax
        b += 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Changes made:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Changed &lt;code&gt;b = 1 / 1&lt;/code&gt; to &lt;code&gt;b = 1&lt;/code&gt; (proper integer)&lt;/li&gt;
&lt;li&gt;Changed &lt;code&gt;print chars[i]&lt;/code&gt; to &lt;code&gt;print(chars[i], end=&apos;&apos;)&lt;/code&gt; (Python 3 syntax)&lt;/li&gt;
&lt;li&gt;Changed &lt;code&gt;b += 1 / 1&lt;/code&gt; to &lt;code&gt;b += 1&lt;/code&gt; (proper increment)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Extracting the Flag&lt;/h3&gt;
&lt;p&gt;Running the fixed script extracts characters at cube positions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Position 1 (1Â³): &apos;a&apos;&lt;/li&gt;
&lt;li&gt;Position 8 (2Â³): &apos;d&apos;&lt;/li&gt;
&lt;li&gt;Position 27 (3Â³): &apos;l&apos;&lt;/li&gt;
&lt;li&gt;Position 64 (4Â³): &apos;i&apos;&lt;/li&gt;
&lt;li&gt;Position 125 (5Â³): &apos;b&apos;&lt;/li&gt;
&lt;li&gt;Position 216 (6Â³): &apos;s&apos;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;The hidden flag:&lt;/strong&gt; &lt;code&gt;adlibs&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat decrypted.txt | python solve.py
adlibs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[âš¡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Final answer:&lt;/strong&gt; &lt;code&gt;picoCTF{adlibs}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
âœ… &lt;strong&gt;Differential Encoding&lt;/strong&gt; - Encrypting based on differences between consecutive positions&lt;br /&gt;
âœ… &lt;strong&gt;Lookup Tables&lt;/strong&gt; - Using predefined character mappings for substitution&lt;br /&gt;
âœ… &lt;strong&gt;Modular Arithmetic&lt;/strong&gt; - The &lt;code&gt;% 40&lt;/code&gt; creates the cyclic behavior&lt;br /&gt;
âœ… &lt;strong&gt;Stateful Cipher&lt;/strong&gt; - The cipher maintains state (&lt;code&gt;prev&lt;/code&gt;) affecting each character&lt;br /&gt;
âœ… &lt;strong&gt;Reversible Operations&lt;/strong&gt; - Addition and modulo are easily reversed for decryption&lt;br /&gt;
âœ… &lt;strong&gt;Layered Puzzles&lt;/strong&gt; - The plaintext itself contains another puzzle (cube position extraction)
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - New Caesar</title><link>https://0xkakashi.com/posts/picogym/cryptography/new-caesar/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/new-caesar/</guid><description>We found a brand new type of encryption, can you break the secret code (Wrap with picoCTF{}) fegdeogdgecoeocgcgchcfcffccfca</description><pubDate>Tue, 16 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/New Caesar/new_caesar.py&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; We found a brand new type of encryption, can you break the secret code (Wrap with picoCTF{}) fegdeogdgecoeocgcgchcfcffccfca&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; madStacks&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge involves breaking a &quot;New Caesar&quot; cipher that combines two encryption techniques:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Base-16 encoding&lt;/strong&gt;: The flag is converted to binary and encoded using only 16 alphabet characters&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shift cipher&lt;/strong&gt;: Each encoded character is shifted by a secret key (which is only 1 character long)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Since the key is single character, we can brute-force all 16 possible keys to find the original flag.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;We are provided with a Python file called &lt;code&gt;new_caesar.py&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file new_caesar.py 
new_caesar.py: Python script, ASCII text executable
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&apos;s the complete code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import string

LOWERCASE_OFFSET = ord(&quot;a&quot;)
ALPHABET = string.ascii_lowercase[:16]

def b16_encode(plain):
	enc = &quot;&quot;
	for c in plain:
		binary = &quot;{0:08b}&quot;.format(ord(c))
		enc += ALPHABET[int(binary[:4], 2)]
		enc += ALPHABET[int(binary[4:], 2)]
	return enc

def shift(c, k):
	t1 = ord(c) - LOWERCASE_OFFSET
	t2 = ord(k) - LOWERCASE_OFFSET
	return ALPHABET[(t1 + t2) % len(ALPHABET)]

flag = &quot;redacted&quot;
key = &quot;redacted&quot;
assert all([k in ALPHABET for k in key])
assert len(key) == 1

b16 = b16_encode(flag)
enc = &quot;&quot;
for i, c in enumerate(b16):
	enc += shift(c, key[i % len(key)])
print(enc)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Understanding the Encryption&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Step 1: Setting up the variables&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;LOWERCASE_OFFSET = ord(&quot;a&quot;)&lt;/code&gt; â†’ This is 97, used to convert letters to numbers&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ALPHABET = string.ascii_lowercase[:16]&lt;/code&gt; â†’ This creates a reduced alphabet: &lt;strong&gt;a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p&lt;/strong&gt; (only 16 characters)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Step 2: The &lt;code&gt;b16_encode&lt;/code&gt; function&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This function converts plaintext to a special base-16 format. Here&apos;s what it does step-by-step:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Takes each character from the flag&lt;/li&gt;
&lt;li&gt;Converts it to 8 binary digits (its ASCII value in binary)&lt;/li&gt;
&lt;li&gt;Splits those 8 digits into two groups of 4 digits each&lt;/li&gt;
&lt;li&gt;Treats each group as a number (0-15)&lt;/li&gt;
&lt;li&gt;Maps each number to a letter (a=0, b=1, c=2... p=15)&lt;/li&gt;
&lt;li&gt;Combines these two letters to encode one character&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; Encoding the letter &apos;a&apos;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ASCII value: 97&lt;/li&gt;
&lt;li&gt;Binary form: &lt;code&gt;01100001&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;First 4 bits: &lt;code&gt;0110&lt;/code&gt; = 6 in decimal â†’ maps to letter &lt;code&gt;g&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Last 4 bits: &lt;code&gt;0001&lt;/code&gt; = 1 in decimal â†’ maps to letter &lt;code&gt;b&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Final encoded result: &lt;code&gt;gb&lt;/code&gt; (represents the original &apos;a&apos;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Step 3: The &lt;code&gt;shift&lt;/code&gt; function&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This function applies a simple shift cipher (like the traditional Caesar cipher):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Takes an encoded character and a key character&lt;/li&gt;
&lt;li&gt;Converts each to a number (a=0, b=1, c=2... p=15)&lt;/li&gt;
&lt;li&gt;Adds the two numbers together&lt;/li&gt;
&lt;li&gt;Uses modulo 16 to wrap around if needed (so it stays in the a-p range)&lt;/li&gt;
&lt;li&gt;Converts the result back to a letter&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; Shifting &apos;g&apos; with key &apos;c&apos;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&apos;g&apos; = 6, &apos;c&apos; = 2&lt;/li&gt;
&lt;li&gt;6 + 2 = 8&lt;/li&gt;
&lt;li&gt;8 maps to letter &apos;i&apos;&lt;/li&gt;
&lt;li&gt;Result: &apos;i&apos;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Step 4: Encryption process&lt;/strong&gt;
The algorithm:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Encodes the flag using &lt;code&gt;b16_encode&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;For each character in the encoded message, shifts it by the key&lt;/li&gt;
&lt;li&gt;Since &lt;code&gt;len(key) == 1&lt;/code&gt;, the same single key character is used for all positions&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Key Weakness&lt;/h3&gt;
&lt;p&gt;The assertion &lt;code&gt;assert len(key) == 1&lt;/code&gt; tells us the key is only &lt;strong&gt;1 character long&lt;/strong&gt;. This means there are only &lt;strong&gt;16 possible keys&lt;/strong&gt; (a through p). We can brute-force all of them!&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;Since we know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The encrypted message: &lt;code&gt;fegdeogdgecoeocgcgchcfcffccfca&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The key is single character from alphabet {a-p}&lt;/li&gt;
&lt;li&gt;We need to reverse the process&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We&apos;ll:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Try all 16 possible keys&lt;/li&gt;
&lt;li&gt;For each key, decrypt the message&lt;/li&gt;
&lt;li&gt;Decode the base-16 result back to plaintext&lt;/li&gt;
&lt;li&gt;Find which result looks like a readable flag&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Creating the Decryption Script&lt;/h3&gt;
&lt;p&gt;My solution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import string

LOWERCASE_OFFSET = ord(&quot;a&quot;)
ALPHABET = string.ascii_lowercase[:16]

def b16_decode(enc):
    &quot;&quot;&quot;Converts base-16 encoded text back to plaintext&quot;&quot;&quot;
    dec = &quot;&quot;
    for i in range(0, len(enc), 2):
        # Get two characters from the encoded message
        c1 = ALPHABET.index(enc[i])
        c2 = ALPHABET.index(enc[i + 1])
        
        # Combine the two 4-bit values back into 8 bits
        byte_value = (c1 &amp;lt;&amp;lt; 4) + c2
        
        # Convert back to ASCII character
        dec += chr(byte_value)
    return dec

def unshift(c, k):
    &quot;&quot;&quot;Reverses the shift operation&quot;&quot;&quot;
    t1 = ord(c) - LOWERCASE_OFFSET
    t2 = ord(k) - LOWERCASE_OFFSET
    # Subtract instead of add, and use modulo to handle negative numbers
    return ALPHABET[(t1 - t2) % len(ALPHABET)]

def decrypt(ciphertext, key):
    dec = &quot;&quot;
    for i, c in enumerate(ciphertext):
        # Reverse the shift
        dec += unshift(c, key[i % len(key)])
    return b16_decode(dec)

# The encrypted message from the challenge
encrypted = &quot;fegdeogdgecoeocgcgchcfcffccfca&quot;

# Try all 16 possible keys (a through p)
for key_char in ALPHABET:
    try:
        result = decrypt(encrypted, key_char)
        print(f&quot;Key: {key_char} â†’  picoCTF{{{result}}}&quot;)
    except:
        print(f&quot;Key: {key_char} â†’ Invalid result&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Output&lt;/h3&gt;
&lt;p&gt;Most will produce unreadable gibberish, but one will show &lt;strong&gt;readable text that makes sense&lt;/strong&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python solve.py
Key: a â†’ picoCTF{TcNcd.N&amp;amp;&amp;amp;&apos;%%R% }
Key: b â†’ picoCTF{CR=RS=A}
Key: c â†’ picoCTF{2A,AB,0}
Key: d â†’ picoCTF{!01Ã»Ã³Ã´Ã²Ã²/Ã²Ã½}
Key: e â†’ picoCTF{/Ãª Ã¢Ã¢Ã£Ã¡Ã¡Ã¡Ã¬}
Key: f â†’ picoCTF{Ã¹Ã™Ã¹Ã‘Ã‘Ã’ÃÃ ÃˆÃ¨Ã€Ã€ÃÃÃÃ¼ÃÃŠ}
Key: g â†’ picoCTF{Ã¾Ã½ÃÃ½Ã¾Â¿ÃÃ§Ã§Â¿Â¾Â¾ÃªÂ¾Â¹}
Key: h â†’ picoCTF{Ã­Ã¼Ã, Ã¼Ã½Â·Ã, Â¿Â¿Â°Â¾Â¾Ã«Â¾Â¹}
Key: i â†’ picoCTF{ÃœÃ«Ã†Ã«Ã¬Â¦Ã†Â®Â®Â¯Â­Â­ÃšÂ­Â¨}
Key: j â†’ picoCTF{Ã‹ÃšÂµÃšÃ›ÂµÃ‰}
Key: k â†’ picoCTF{ÂºÃ‰Â¤Ã‰ÃŠÂ¤Â¸}
Key: l â†’ picoCTF{Â©Â¸Â¸Â¹s{{|zzÂ§zu}
Key: m â†’ picoCTF{Â§Â§Â¨bjjkiiid}
Key: n â†’ picoCTF{qQqYYZXXXS}
Key: o â†’ picoCTF{v`@`HHIGGtGB}
Key: p â†’ picoCTF{et_tu_77866c61}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Finding the Correct Flag&lt;/h3&gt;
&lt;p&gt;Looking at all 16 results, only &lt;strong&gt;one&lt;/strong&gt; contains readable words and valid characters:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;s&gt;&lt;code&gt;picoCTF{et_tu_77866c61}&lt;/code&gt;&lt;/s&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;:::note[âš¡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
âœ… &lt;strong&gt;Base-16 encoding&lt;/strong&gt; converts data using only 16 symbols (0-15, represented as a-p)&lt;br /&gt;
âœ… &lt;strong&gt;Single-character keys are extremely weak&lt;/strong&gt; - only 16 possibilities to brute-force&lt;br /&gt;
âœ… &lt;strong&gt;Combining two weak ciphers doesn&apos;t create strong encryption&lt;/strong&gt; - both layers must be broken&lt;br /&gt;
âœ… &lt;strong&gt;Always read the code for clues&lt;/strong&gt; - the &lt;code&gt;assert&lt;/code&gt; statements revealed the key length was just 1&lt;br /&gt;
âœ… &lt;strong&gt;Brute-force is valid when key space is small&lt;/strong&gt; - with 16 possibilities, trying them all is practical&lt;br /&gt;
âœ… &lt;strong&gt;Look for readable output&lt;/strong&gt; - the correct flag stands out from gibberish immediately
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - spelling-quiz</title><link>https://0xkakashi.com/posts/picogym/cryptography/spelling-quiz/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/spelling-quiz/</guid><description>I found the flag, but my brother wrote a program to encrypt all his text files. He has a spelling quiz study guide too, but I don&apos;t know if that helps.</description><pubDate>Tue, 16 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/spelling-quiz/public.zip&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; I found the flag, but my brother wrote a program to encrypt all his text files. He has a spelling quiz study guide too, but I don&apos;t know if that helps.&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; BrownieInMotion&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;It&apos;s an encryption of all text files using a &lt;strong&gt;substitution cipher&lt;/strong&gt;. We have three things to work with: the encryption program, an encrypted flag, and an encrypted spelling quiz study guide. The key advantage is that the study guide and flag were encrypted using the same cipher key. By analyzing the encrypted study guide with frequency analysis, we can discover the substitution mapping and decrypt the hidden flag.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;h3&gt;Challenge Files&lt;/h3&gt;
&lt;p&gt;The challenge provides a &lt;code&gt;public.zip&lt;/code&gt; file containing three items:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;encrypt.py         → The encryption program
flag.txt           → The encrypted flag
study-guide.txt    → Encrypted spelling quiz words
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;The Encrypted Flag&lt;/h3&gt;
&lt;p&gt;Looking at the encrypted flag:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat flag.txt
brcfxba_vfr_mid_hosbrm_iprc_exa_hoav_vwcrm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This looks like random letters - but it&apos;s actually a substitution cipher.&lt;/p&gt;
&lt;h3&gt;Understanding the Encryption&lt;/h3&gt;
&lt;p&gt;Here&apos;s the encryption program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import random
import os

files = [
    os.path.join(path, file)
    for path, dirs, files in os.walk(&apos;.&apos;)
    for file in files
    if file.split(&apos;.&apos;)[-1] == &apos;txt&apos;
]

alphabet = list(&apos;abcdefghijklmnopqrstuvwxyz&apos;)
random.shuffle(shuffled := alphabet[:])
dictionary = dict(zip(alphabet, shuffled))

for filename in files:
    text = open(filename, &apos;r&apos;).read()
    encrypted = &apos;&apos;.join([
        dictionary[c]
        if c in dictionary else c
        for c in text
    ])
    open(filename, &apos;w&apos;).write(encrypted)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;What this does:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Finds all &lt;code&gt;.txt&lt;/code&gt; files in the directory&lt;/li&gt;
&lt;li&gt;Creates a shuffled alphabet (randomized order)&lt;/li&gt;
&lt;li&gt;Creates a dictionary mapping original letters to shuffled letters&lt;/li&gt;
&lt;li&gt;For each file, replaces every letter using the dictionary&lt;/li&gt;
&lt;li&gt;Saves the encrypted text back to the file&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Key insight:&lt;/strong&gt; The same shuffled alphabet is used to encrypt ALL files, including the study guide and flag!&lt;/p&gt;
&lt;h3&gt;The Study Guide&lt;/h3&gt;
&lt;p&gt;The encrypted study guide contains words from a spelling quiz:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ head study-guide.txt
gocnfwnwtr
sxlyrxaic
dcrrtfrxcv
uxbvwavcq
lwvicwtiwm
pwtmwnxvicq
avingciisa
ylwtmrcawx
mwaxdcrrxuwlwvq
yciflwnf
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Identifying the Cipher Type&lt;/h3&gt;
&lt;p&gt;Using cipher identification tools like &lt;a href=&quot;https://www.dcode.fr/cipher-identifier&quot;&gt;dcode.fr&lt;/a&gt;, these encrypted words are strongly identified as &lt;strong&gt;Monoalphabetic Substitution&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-2.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;h3&gt;How Frequency Analysis Works&lt;/h3&gt;
&lt;p&gt;In English, certain letters appear more frequently than others:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&apos;e&apos; appears most often (~12.7%)&lt;/li&gt;
&lt;li&gt;&apos;t&apos;, &apos;a&apos;, &apos;o&apos;, &apos;i&apos; are also very common&lt;/li&gt;
&lt;li&gt;&apos;z&apos;, &apos;q&apos;, &apos;x&apos; are rare&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If we encrypt English text, the most common encrypted letter should correspond to &apos;e&apos;, the second most common to &apos;t&apos;, etc.&lt;/p&gt;
&lt;h3&gt;Cracking the Cipher&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Use frequency analysis tools&lt;/strong&gt; on the encrypted texts&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Upload to &lt;a href=&quot;https://www.dcode.fr/monoalphabetic-substitution&quot;&gt;dcode.fr Monoalphabetic Substitution&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Feed it the encrypted study guide&lt;/strong&gt; - the tool analyzes letter frequencies&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The tool outputs the original alphabet mapping&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use the mapping to decrypt the flag&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Results&lt;/h3&gt;
&lt;p&gt;After running frequency analysis on the encrypted study guide and flag:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The decrypted flag:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PERHAPS_THE_DOG_JUMPED_OVER_WAS_JUST_TIRED
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;p&gt;Wrap it as: &lt;code&gt;picoCTF{PERHAPS_THE_DOG_JUMPED_OVER_WAS_JUST_TIRED}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
✅ &lt;strong&gt;Substitution Cipher&lt;/strong&gt; - Each letter maps to exactly one other letter&lt;br /&gt;
✅ &lt;strong&gt;Monoalphabetic&lt;/strong&gt; - The mapping never changes (unlike polyalphabetic ciphers)&lt;br /&gt;
✅ &lt;strong&gt;Frequency Analysis&lt;/strong&gt; - Using letter frequency patterns to break encryption&lt;br /&gt;
✅ &lt;strong&gt;Ciphertext-only attack&lt;/strong&gt; - We don&apos;t need the key, just encrypted text and patterns&lt;br /&gt;
✅ &lt;strong&gt;Using known plaintext&lt;/strong&gt; - The spelling quiz study guide is likely real English words!&lt;br /&gt;
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - Pixelated</title><link>https://0xkakashi.com/posts/picogym/cryptography/pixelated/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/pixelated/</guid><description>I have these 2 images, can you make a flag out of them?</description><pubDate>Mon, 15 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/Pixelated/scrambled1.png&quot; download&amp;gt;📂 Download challenge file 1.&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;a href=&quot;/files/PicoGym/Cryptography/Pixelated/scrambled2.png&quot; download&amp;gt;📂 Download challenge file 2.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; I have these 2 images, can you make a flag out of them?&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Sara&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;In this challenge, we&apos;re given two scrambled PNG images and need to combine them to reveal a hidden flag. This is an example of &lt;strong&gt;visual cryptography&lt;/strong&gt;, where secret information is hidden across multiple images. Each image alone shows only random noise, but when you overlay them together correctly, the hidden message appears!&lt;/p&gt;
&lt;p&gt;Think of it like two transparent sheets with random dots - when you stack them on top of each other, the dots align to form letters.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;We are given 2 scrambled PNG files:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file scrambled1.png
scrambled1.png: PNG image data, 256 x 256, 8-bit/color RGB, non-interlaced
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$ file scrambled2.png
scrambled2.png: PNG image data, 256 x 256, 8-bit/color RGB, non-interlaced
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both are 256×256 pixel PNG images in RGB color format and individually, they contain no readable information.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;alt text&quot; /&gt;
&lt;img src=&quot;image-1.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Visual Cryptography Explained&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Visual cryptography&lt;/strong&gt; is a special encryption method where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A secret message is split across multiple images&lt;/li&gt;
&lt;li&gt;Each image alone looks like random noise or garbage&lt;/li&gt;
&lt;li&gt;When you overlay (stack) the images together, the secret message becomes visible to the human eye&lt;/li&gt;
&lt;li&gt;No complex math or computer decryption is needed!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Imagine you have a secret message. Instead of encrypting it with math, you break it down into pixel patterns across multiple transparent sheets. When someone places all sheets on top of each other and holds them up to the light, the message appears!&lt;/p&gt;
&lt;h3&gt;The images&lt;/h3&gt;
&lt;p&gt;When we look at the two images, they appear to be completely random:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;scrambled1.png&lt;/code&gt; - looks like random noise/static&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scrambled2.png&lt;/code&gt; - looks like random noise/static&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But when combined correctly, they reveal the hidden message!&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;h3&gt;Step 1: Understanding how to combine the images&lt;/h3&gt;
&lt;p&gt;When combining two noisy images that contain a hidden message:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;random noise&lt;/strong&gt; in each image is different and unpredictable&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;hidden message&lt;/strong&gt; is encoded in BOTH images at the same locations&lt;/li&gt;
&lt;li&gt;When we add the pixel values together, the message pixels become much brighter (because they&apos;re bright in both images)&lt;/li&gt;
&lt;li&gt;The random noise stays relatively dark (because it&apos;s different in each image)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Think of it this way: if both images have a white pixel in the same spot, adding them together gives an even brighter white. But if only one image has noise at a location, adding them gives a medium gray.&lt;/p&gt;
&lt;h3&gt;Step 2: Solution&lt;/h3&gt;
&lt;p&gt;We load both images, convert them into arrays, and add their pixel values together.&lt;/p&gt;
&lt;p&gt;Here&apos;s the Python solution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from PIL import Image
import numpy as np

# Load both images
img1 = Image.open(&apos;scrambled1.png&apos;)
img2 = Image.open(&apos;scrambled2.png&apos;)

# Convert to numpy arrays (keeps RGB format)
array1 = np.asarray(img1)
array2 = np.asarray(img2)

# Add the two images together
# Where both have bright pixels (the message), result is very bright
# Where they differ (noise), result is medium brightness
result = np.add(array1, array2)

# Convert back to PIL Image
result_img = Image.fromarray(result, mode=&quot;RGB&quot;)

# Display and save the result
result_img.show()
result_img.save(&apos;flag.png&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Step 3: Read the flag&lt;/h3&gt;
&lt;p&gt;After running the script, the hidden text appears in the generated &lt;code&gt;flag.png&lt;/code&gt; file:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;strong&gt;&lt;s&gt;&lt;code&gt;picoCTF{8cdf93c3}&lt;/code&gt;&lt;/s&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-2.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Each image alone is useless, the secret only appears when both are combined&lt;/li&gt;
&lt;li&gt;Pixel addition is enough; no complex math or encryption is needed&lt;/li&gt;
&lt;li&gt;Bright pixels in both images reinforce each other&lt;/li&gt;
&lt;li&gt;Visual cryptography relies on human vision, not cryptographic algorithms&lt;/li&gt;
&lt;li&gt;This challenge is about observation and image processing, not math
:::&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>🔐 PicoGym - basic-mod2</title><link>https://0xkakashi.com/posts/picogym/cryptography/basic-mod2/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/basic-mod2/</guid><description>A new modular challenge! Take each number mod 41 and find the modular inverse for the result. Then map to the following character set: 1-26 are the alphabet, 27-36 are the decimal digits, and 37 is an underscore. Wrap your decrypted message in the picoCTF flag format (i.e. picoCTF{decrypted_message})</description><pubDate>Mon, 15 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/basic-mod2/message.txt&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; A new modular challenge! Take each number mod 41 and find the modular inverse for the result. Then map to the following character set: 1-26 are the alphabet, 27-36 are the decimal digits, and 37 is an underscore. Wrap your decrypted message in the picoCTF flag format (i.e. picoCTF{decrypted_message})&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Will Hong&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;In this challenge, we decrypt a message by performing modular arithmetic operations. Each number must be reduced modulo 41, then we find its modular multiplicative inverse. The resulting values are mapped to a custom character set where 1-26 represent letters A-Z, 27-36 represent digits 0-9, and 37 represents an underscore.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;We are provided with a file named &lt;code&gt;message.txt&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file message.txt 
message.txt: ASCII text, with no line terminators
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its content:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat message.txt 
104 372 110 436 262 173 354 393 351 297 241 86 262 359 256 441 124 154 165 165 219 288 42
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So according to the challenge description, we need to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Take each number mod 41&lt;/li&gt;
&lt;li&gt;Find the modular inverse for the result&lt;/li&gt;
&lt;li&gt;Then map to the following character set: 1-26 are the alphabet, 27-36 are the decimal digits, and 37 is an underscore.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;What Does “mod 41” Mean?&lt;/h3&gt;
&lt;p&gt;Taking a number mod 41 means:&lt;/p&gt;
&lt;p&gt;Divide the number by 41 and keep the remainder&lt;/p&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;104 mod 41 = 22&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;372 mod 41 = 3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;110 mod 41 = 28&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This reduces all large numbers into a small range between 0 and 40.&lt;/p&gt;
&lt;h3&gt;What is Modular Inverse?&lt;/h3&gt;
&lt;p&gt;The modular inverse of a number answers this question:&lt;/p&gt;
&lt;p&gt;:::note[]
&lt;code&gt;“What number do I multiply by this value to get 1 (mod 41)?&quot;&lt;/code&gt;
:::&lt;/p&gt;
&lt;p&gt;Mathematically, it is written as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;a⋅x≡1(mod41)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Multiply &lt;code&gt;a&lt;/code&gt; by &lt;code&gt;x&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Take the result mod 41&lt;/li&gt;
&lt;li&gt;If the answer is 1, then &lt;code&gt;x&lt;/code&gt; is the modular inverse of &lt;code&gt;a&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::note[]
You can think of a modular inverse as the undo button for multiplication (when working modulo 41).
:::&lt;/p&gt;
&lt;h3&gt;Example&lt;/h3&gt;
&lt;p&gt;The modular inverse of 3 mod 11 is 4, because:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;3×4=12≡1(mod11)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Why inverses always exist here&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;41 is a prime number&lt;/li&gt;
&lt;li&gt;This means every number from 1 to 40 has a modular inverse modulo 41&lt;/li&gt;
&lt;li&gt;So we are guaranteed that an inverse exists (except when the value is 0)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Character Mapping&lt;/h3&gt;
&lt;p&gt;After finding the modular inverse, we convert it into a character using this mapping:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1-26: A-Z (alphabet)&lt;/li&gt;
&lt;li&gt;27-36: 0-9 (digits)&lt;/li&gt;
&lt;li&gt;37: _ (underscore)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;h3&gt;Implementing the decryption&lt;/h3&gt;
&lt;p&gt;Here&apos;s the Python solution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def decrypt_basic_mod2(ciphertext):
    # Character mapping
    # 1-26: a-z, 27-36: 0-9, 37: _
    char_map = {
        1: &apos;a&apos;, 2: &apos;b&apos;, 3: &apos;c&apos;, 4: &apos;d&apos;, 5: &apos;e&apos;, 6: &apos;f&apos;, 7: &apos;g&apos;, 8: &apos;h&apos;, 9: &apos;i&apos;, 10: &apos;j&apos;,
        11: &apos;k&apos;, 12: &apos;l&apos;, 13: &apos;m&apos;, 14: &apos;n&apos;, 15: &apos;o&apos;, 16: &apos;p&apos;, 17: &apos;q&apos;, 18: &apos;r&apos;, 19: &apos;s&apos;, 20: &apos;t&apos;,
        21: &apos;u&apos;, 22: &apos;v&apos;, 23: &apos;w&apos;, 24: &apos;x&apos;, 25: &apos;y&apos;, 26: &apos;z&apos;,
        27: &apos;0&apos;, 28: &apos;1&apos;, 29: &apos;2&apos;, 30: &apos;3&apos;, 31: &apos;4&apos;, 32: &apos;5&apos;, 33: &apos;6&apos;, 34: &apos;7&apos;, 35: &apos;8&apos;, 36: &apos;9&apos;,
        37: &apos;_&apos;
    }
    
    plaintext = []
    
    for num in ciphertext:
        # Step 1: Take mod 41
        mod_result = num % 41
        
        # we use Python 3.8+ built-in: pow(a, -1, 41)
        if mod_result == 0:
            # Edge case: if mod_result is 0, there&apos;s no inverse
            continue
        
        inverse = pow(mod_result, -1, 41)
        
        # Step 3: Map to character
        if inverse in char_map:
            plaintext.append(char_map[inverse])
    
    return &apos;&apos;.join(plaintext)

# Parse the ciphertext
ciphertext = [104, 372, 110, 436, 262, 173, 354, 393, 351, 297, 241, 86, 262, 359, 256, 441, 124, 154, 165, 165, 219, 288, 42]

# Decrypt
message = decrypt_basic_mod2(ciphertext)
print(f&quot;Decrypted message: {message}&quot;)
print(f&quot;Flag: picoCTF{{{message}}}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Running the solution&lt;/h3&gt;
&lt;p&gt;The decrypted message is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1nv3r53ly_h4rd_dadaacaa
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python solve.py
Decrypted message: 1nv3r53ly_h4rd_dadaacaa
Flag: picoCTF{1nv3r53ly_h4rd_dadaacaa}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;s&gt;&lt;code&gt;picoCTF{br1nv3r53ly_h4rd_dadaacaa}&lt;/code&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Modular inverse&lt;/strong&gt;: Understanding that the modular multiplicative inverse is the key operation for decryption. Since 41 is prime, every non-zero number has an inverse.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Character mapping&lt;/strong&gt;: The custom alphabet (1-26 = a-z, 27-36 = 0-9, 37 = _) is crucial for converting the numeric result back to characters.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Modular arithmetic&lt;/strong&gt;: Taking mod 41 first reduces large numbers to a manageable range (0-40), making the inverse operation efficient.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Python&apos;s pow() function&lt;/strong&gt;: The three-argument &lt;code&gt;pow(a, -1, m)&lt;/code&gt; efficiently computes modular inverses (available in Python 3.8+), making the solution elegant and fast.
:::&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>🔐 PicoGym - transposition-trial</title><link>https://0xkakashi.com/posts/picogym/cryptography/transposition-trial/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/transposition-trial/</guid><description>Our data got corrupted on the way here. Luckily, nothing got replaced, but every block of 3 got scrambled around! The first word seems to be three letters long, maybe you can use that to recover the rest of the message.</description><pubDate>Sun, 14 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/transposition-trial/message.txt&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; Our data got corrupted on the way here. Luckily, nothing got replaced, but every block of 3 got scrambled around! The first word seems to be three letters long, maybe you can use that to recover the rest of the message.&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Will Hong&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;In this challenge, we are given a corrupted message where every group of three characters has been scrambled, but no characters were lost or replaced. By leveraging the hint that the first word is three letters long, we can identify the scrambling pattern and apply it consistently across the entire ciphertext to recover the flag.&lt;/p&gt;
&lt;p&gt;This is a classic &lt;code&gt;block transposition cipher&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;We are provided with a file named &lt;code&gt;message.txt&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file message.txt 
message.txt: ASCII text, with no line terminators
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its content:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat message.txt 
heTfl g as iicpCTo{7F4NRP051N5_16_35P3X51N3_V091B0AE}2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The challenge name (&lt;code&gt;transposition-trial&lt;/code&gt;) and the description strongly suggest a &lt;strong&gt;transposition cipher&lt;/strong&gt;, where characters are rearranged but not modified.&lt;/p&gt;
&lt;p&gt;To confirm, we can use &lt;a href=&quot;https://www.dcode.fr/cipher-identifier&quot;&gt;dCode’s Cipher Identifier&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Yep, I was right, it&apos;s &lt;code&gt;Transposition Cipher&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;What is Transposition Cipher?&lt;/h3&gt;
&lt;p&gt;A transposition cipher encrypts a message by rearranging the order of characters according to a fixed pattern or key, without changing the characters themselves.&lt;br /&gt;
Key properties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No substitution occurs&lt;/li&gt;
&lt;li&gt;Character frequency remains the same&lt;/li&gt;
&lt;li&gt;Decryption requires discovering the correct permutation&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Encryption&lt;/h3&gt;
&lt;p&gt;In this challenge, the permutation is applied per block of 3 characters. The plaintext is divided into blocks of 3 characters, and each block is scrambled according to a fixed pattern.&lt;/p&gt;
&lt;p&gt;For example, if we have a block &lt;code&gt;abc&lt;/code&gt; and the pattern is a specific permutation, the encrypted block might be &lt;code&gt;cab&lt;/code&gt; or &lt;code&gt;bac&lt;/code&gt; depending on the pattern used.&lt;/p&gt;
&lt;h3&gt;Decryption&lt;/h3&gt;
&lt;p&gt;To decrypt, we need to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Identify the correct permutation pattern used for scrambling&lt;/li&gt;
&lt;li&gt;Reverse that pattern (apply the inverse permutation) to each block of 3 characters&lt;/li&gt;
&lt;li&gt;Concatenate the decrypted blocks to recover the plaintext&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The hint tells us the first word is three letters long, which is likely &quot;The&quot;. This gives us a known plaintext-ciphertext pair:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ciphertext: &lt;code&gt;heT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Plaintext: &lt;code&gt;The&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From this, we can determine the permutation pattern.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;h3&gt;Step 1: Determine the permutation pattern&lt;/h3&gt;
&lt;p&gt;The first block &lt;code&gt;heT&lt;/code&gt; should decrypt to &lt;code&gt;The&lt;/code&gt;. Let&apos;s map the positions:&lt;/p&gt;
&lt;p&gt;The plaintext is &lt;code&gt;The&lt;/code&gt;, encrypted as &lt;code&gt;heT&lt;/code&gt;. To encrypt:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;T&lt;/code&gt; (index 0) → position 2 (becomes &lt;code&gt;T&lt;/code&gt; at the end)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;h&lt;/code&gt; (index 1) → position 0 (becomes &lt;code&gt;h&lt;/code&gt; at the start)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;e&lt;/code&gt; (index 2) → position 1 (becomes &lt;code&gt;e&lt;/code&gt; in middle)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So the encryption pattern is: &lt;code&gt;[1, 2, 0]&lt;/code&gt; (take char at 1, then 2, then 0 of original)&lt;/p&gt;
&lt;p&gt;To decrypt, we need the inverse permutation. If encryption uses pattern &lt;code&gt;[1, 2, 0]&lt;/code&gt;, decryption uses &lt;code&gt;[2, 0, 1]&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Encrypted position 0 → goes to plaintext position 2&lt;/li&gt;
&lt;li&gt;Encrypted position 1 → goes to plaintext position 0&lt;/li&gt;
&lt;li&gt;Encrypted position 2 → goes to plaintext position 1&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Step 2: Implement the decryption&lt;/h3&gt;
&lt;p&gt;Let&apos;s verify with the first block &lt;code&gt;heT&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Apply pattern &lt;code&gt;[2, 0, 1]&lt;/code&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[2]&lt;/code&gt;: &lt;code&gt;heT&lt;/code&gt;[2] = &lt;code&gt;T&lt;/code&gt; → position 0&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[0]&lt;/code&gt;: &lt;code&gt;heT&lt;/code&gt;[0] = &lt;code&gt;h&lt;/code&gt; → position 1&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[1]&lt;/code&gt;: &lt;code&gt;heT&lt;/code&gt;[1] = &lt;code&gt;e&lt;/code&gt; → position 2&lt;/li&gt;
&lt;li&gt;Result: &lt;code&gt;The&lt;/code&gt; ✓&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&apos;s a Python solution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ciphertext = &quot;heTfl g as iicpCTo{7F4NRP051N5_16_35P3X51N3_V091B0AE}2&quot;

# inverse permutation of [1, 2, 0]
perm = [2, 0, 1]

plaintext = &quot;&quot;

for i in range(0, len(ciphertext), 3):
    block = ciphertext[i:i+3]
    if len(block) == 3:
        plaintext += &apos;&apos;.join(block[p] for p in perm)
    else:
        plaintext += block  # handle leftover chars if any

print(plaintext)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Step 3: Decrypt the entire message&lt;/h3&gt;
&lt;p&gt;Running the decryption function on the ciphertext :&lt;/p&gt;
&lt;p&gt;&lt;s&gt;&lt;code&gt;picoCTF{7R4N5P051N6_15_3XP3N51V3_109AB02E}&lt;/code&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python solve.py
The flag is picoCTF{7R4N5P051N6_15_3XP3N51V3_109AB02E}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Known plaintext attack&lt;/strong&gt;: The hint that the first word is three letters (likely &quot;The&quot;) was crucial for determining the permutation pattern.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Block transposition with fixed pattern&lt;/strong&gt;: Once we identified the pattern from one block, we could apply it consistently to all other blocks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No character substitution&lt;/strong&gt;: This confirms it&apos;s purely a transposition, not a substitution cipher - all characters remain unchanged, just reordered within each 3-character block.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inverse permutation&lt;/strong&gt;: To decrypt, we need to apply the mathematical inverse of the encryption permutation to reverse the scrambling.
:::&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>🔐 PicoGym - substitution1</title><link>https://0xkakashi.com/posts/picogym/cryptography/substitution1/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/substitution1/</guid><description>A second message has come in the mail, and it seems almost identical to the first one. Maybe the same thing will work again.</description><pubDate>Tue, 09 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/substitution1/message.txt&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; A second message has come in the mail, and it seems almost identical to the first one. Maybe the same thing will work again.
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Will Hong&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge presents another ciphertext that appears very similar to substitution2, suggesting that the same underlying technique, monoalphabetic substitution, is once again the solution. Even though the message is compact and lacks punctuation, classical substitution analysis still works perfectly.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;We are given the file &lt;code&gt;message.txt&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file message.txt 
message.txt: ASCII text, with very long lines (638), with no line terminators
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And its content :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ZWDg (gejfw djf zacwpfx wex dqar) afx a wscx jd zjicpwxf gxzpfbws zjicxwbwbjv. Zjvwxgwavwg afx cfxgxvwxm hbwe a gxw jd zeaqqxvrxg hebze wxgw wexbf zfxawbybws, wxzevbzaq (avm rjjrqbvr) gnbqqg, avm cfjtqxi-gjqybvr atbqbws. Zeaqqxvrxg pgpaqqs zjyxf a vpitxf jd zawxrjfbxg, avm hexv gjqyxm, xaze sbxqmg a gwfbvr (zaqqxm a dqar) hebze bg gptibwwxm wj av jvqbvx gzjfbvr gxfybzx. ZWDg afx a rfxaw has wj qxafv a hbmx affas jd zjicpwxf gxzpfbws gnbqqg bv a gadx, qxraq xvybfjvixvw, avm afx ejgwxm avm cqasxm ts iavs gxzpfbws rfjpcg afjpvm wex hjfqm djf dpv avm cfazwbzx. 
Djf webg cfjtqxi, wex dqar bg: cbzjZWD{DF3LP3VZS_4774ZN5_4F3_Z001_4871X6DT}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The ciphertext is continuous text with no spacing, making it visually harder to read, but still vulnerable to frequency analysis.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;To decode this efficiently, we load the ciphertext into: &lt;a href=&quot;https://www.dcode.fr/monoalphabetic-substitution&quot;&gt;Mono-alphabetic Substitution&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The tool performs frequency analysis and heuristic reconstruction to rebuild natural English from the continuous letter stream.&lt;/p&gt;
&lt;p&gt;After processing, we obtain the fully decrypted plaintext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CTFS (SHORT FOR CAPTURE THE FLAG) ARE A TYPE OF COMPUTER SECURITY COMPETITION. CONTESTANTS ARE PRESENTED WITH A SET OF CHALLENGES WHICH TEST THEIR CREATIVITY, TECHNICAL (AND GOOGLING) SKILLS, AND PROBLEM-SOLVING ABILITY. CHALLENGES USUALLY COVER A NUMBER OF CATEGORIES, AND WHEN SOLVED, EACH YIELDS A STRING (CALLED A FLAG) WHICH IS SUBMITTED TO AN ONLINE SCORING SERVICE. CTFS ARE A GREAT WAY TO LEARN A WIDE ARRAY OF COMPUTER SECURITY SKILLS IN A SAFE, LEGAL ENVIRONMENT, AND ARE HOSTED AND PLAYED BY MANY SECURITY GROUPS AROUND THE WORLD FOR FUN AND PRACTICE. 
FOR THIS PROBLEM, THE FLAG IS: PICOCTF{FR3QU3NCY_4774CK5_4R3_C001_4871E6FB}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;From here, at the very end, we can see the flag already.&lt;/p&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;p&gt;Some substitution solvers occasionally mix up mappings when two letters have nearly identical frequency patterns.
In this ciphertext, J and Q were swapped in the raw solver output, producing: &lt;strong&gt;&lt;s&gt;&lt;code&gt;PICOCTF{FR3JU3NCY_4774CK5_4R3_C001_4871E6FB}&lt;/code&gt;&lt;/s&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;But logically, the correct flag is: &lt;strong&gt;&lt;s&gt;&lt;code&gt;PICOCTF{FR3QU3NCY_4774CK5_4R3_C001_4871E6FB}&lt;/code&gt;&lt;/s&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
Challenge uses a monoalphabetic substitution cipher.&lt;br /&gt;
Feed ciphertext into DCODE’s solver → plaintext recovers almost instantly.&lt;br /&gt;
Solver swapped J and Q, but context makes the correction obvious.&lt;br /&gt;
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - Waves Over Lambda</title><link>https://0xkakashi.com/posts/picogym/cryptography/waves-over-lambda/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/waves-over-lambda/</guid><description>We made a lot of substitutions to encrypt this. Can you decrypt it</description><pubDate>Mon, 08 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; We made a lot of &lt;code&gt;substitutions&lt;/code&gt; to encrypt this. Can you decrypt it
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; invisibility/Danny&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge provides a remote service that outputs a long ciphertext. The prompt hints that â€œa lot of substitutionsâ€ were used, strongly suggesting a monoalphabetic substitution cipher. The goal is to identify the substitution mapping and decrypt the full text to recover the flag.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;A netcat service is given : &lt;code&gt;nc fickle-tempest.picoctf.net 56322&lt;/code&gt;
Connecting to it returns the following ciphertext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ nc fickle-tempest.picoctf.net 56322
-------------------------------------------------------------------------------
qnaixvsd rhxh od enux fcvi - fxhguhaqe_od_q_nphx_cvtmjv_f3ff3v4j
-------------------------------------------------------------------------------
mhswhha ud srhxh wvd, vd o rvph vcxhvje dvoj dnthwrhxh, srh mnaj nf srh dhv. mhdojhd rncjoai nux rhvxsd snihsrhx srxnuir cnai yhxonjd nf dhyvxvsona, os rvj srh hffhqs nf tvkoai ud snchxvas nf hvqr nsrhx&apos;d evxadvaj hpha qnapoqsonad. srh cvwehxsrh mhds nf ncj fhccnwdrvj, mhqvudh nf rod tvae ehvxd vaj tvae poxsuhd, srh nace qudrona na jhqk, vaj wvd ceoai na srh nace xui. srh vqqnuasvas rvj mxnuirs nus vcxhvje v mnb nf jntoanhd, vaj wvd sneoai vxqroshqsuxvcce wosr srh mnahd. tvxcnw dvs qxndd-chiihj xoirs vfs, chvaoai vivoads srh tozzha-tvds. rh rvj duakha qrhhkd, v ehccnw qntychbona, v dsxvoirs mvqk, va vdqhsoq vdyhqs, vaj, wosr rod vxtd jxnyyhj, 
srh yvctd nf rvajd nuswvxjd, xhdhtmchj va ojnc. srh joxhqsnx, dvsodfohj srh vaqrnx rvj innj rncj, tvjh rod wve vfs vaj dvs jnwa vtnaids ud. wh hbqrvaihj v fhw wnxjd cvzoce. vfshxwvxjd srhxh wvd dochaqh na mnvxj srh evqrs. fnx dnth xhvdna nx nsrhx wh joj ans mhioa srvs ivth nf jntoanhd. wh fhcs thjosvsoph, vaj fos fnx ansroai mus ycvqoj dsvxoai. srh jve wvd hajoai oa v dhxhaose nf dsocc vaj hbguodosh mxoccovaqh. srh wvshx drnah yvqofoqvcce; srh dke, wosrnus v dyhqk, wvd v mhaoia otthadose nf uadsvoahj coirs; srh phxe tods na srh hddhb tvxdr wvd cokh v ivuze vaj xvjovas fvmxoq, ruai fxnt srh wnnjhj xodhd oacvaj, vaj jxvyoai srh cnw drnxhd oa jovyrvanud fncjd. nace srh icnnt sn srh whds, mxnnjoai nphx srh uyyhx xhvqrhd, mhqvth tnxh dntmxh hphxe toaush, vd of vaihxhj me srh vyyxnvqr nf srh dua.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Based on the challenge description, it seems that they made a lot of substutions and this points to susitution cipher.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;To assist in solving, we can load the ciphertext into a tool such as: &lt;a href=&quot;https://www.dcode.fr/monoalphabetic-substitution&quot;&gt;Mono-alphabetic Substitution&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This tool uses frequency analysis and heuristics to predict the English plaintext.&lt;/p&gt;
&lt;p&gt;From this, we got :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;------------------------------------------------------------------------------- 
CONGRATS HERE IS YOUR FLAG - FREQUENCY_IS_C_OVER_LAMBDA_F3FF3A4D 
------------------------------------------------------------------------------- 
BETWEEN US THERE WAS, AS I HAVE ALREADY SAID SOMEWHERE, THE BOND OF THE SEA. BESIDES HOLDING OUR HEARTS TOGETHER THROUGH LONG PERIODS OF SEPARATION, IT HAD THE EFFECT OF MAKING US TOLERANT OF EACH OTHER&apos;S YARNSAND EVEN CONVICTIONS. THE LAWYERTHE BEST OF OLD FELLOWSHAD, BECAUSE OF HIS MANY YEARS AND MANY VIRTUES, THE ONLY CUSHION ON DECK, AND WAS LYING ON THE ONLY RUG. THE ACCOUNTANT HAD BROUGHT OUT ALREADY A BOX OF DOMINOES, AND WAS TOYING ARCHITECTURALLY WITH THE BONES. MARLOW SAT CROSS-LEGGED RIGHT AFT, LEANING AGAINST THE MIZZEN-MAST. HE HAD SUNKEN CHEEKS, A YELLOW COMPLEXION, A STRAIGHT BACK, AN ASCETIC ASPECT, AND, WITH HIS ARMS DROPPED, THE PALMS OF HANDS OUTWARDS, RESEMBLED AN IDOL. THE DIRECTOR, SATISFIED THE ANCHOR HAD GOOD HOLD, MADE HIS WAY AFT AND SAT DOWN AMONGST US. WE EXCHANGED A FEW WORDS LAZILY. AFTERWARDS THERE WAS SILENCE ON BOARD THE YACHT. FOR SOME REASON OR OTHER WE DID NOT BEGIN THAT GAME OF DOMINOES. WE FELT MEDITATIVE, AND FIT FOR NOTHING BUT PLACID STARING. THE DAY WAS ENDING IN A SERENITY OF STILL AND EXQUISITE BRILLIANCE. THE WATER SHONE PACIFICALLY; THE SKY, WITHOUT A SPECK, WAS A BENIGN IMMENSITY OF UNSTAINED LIGHT; THE VERY MIST ON THE ESSEX MARSH WAS LIKE A GAUZY AND RADIANT FABRIC, HUNG FROM THE WOODED RISES INLAND, AND DRAPING THE LOW SHORES IN DIAPHANOUS FOLDS. ONLY THE GLOOM TO THE WEST, BROODING OVER THE UPPER REACHES, BECAME MORE SOMBRE EVERY MINUTE, AS IF ANGERED BY THE APPROACH OF THE SUN.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;From this decryption, we can also extract the &lt;code&gt;substitution mapping&lt;/code&gt; used in the challenge:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;â‡’ VMQJHFIROLKCTANYGXDSUPWBEZ (Original Encryption Alphabet)
â‡’ NXLSYFQEGDKJBOIVCHTMUAWRPZ (Reciprocal â‡… Decryption Alphabet)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This mapping illustrates how each ciphertext letter was substituted to produce the readable plaintext.&lt;/p&gt;
&lt;p&gt;:::note[âš¡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FREQUENCY_IS_C_OVER_LAMBDA_F3FF3A4D 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
Challenge gives a long ciphertext via netcat.&lt;br /&gt;
Hint suggests &lt;code&gt;substitution cipher&lt;/code&gt; â†’ use monoalphabetic solver.&lt;br /&gt;
Paste ciphertext into DCODE â†’ instantly recovers readable English and flag.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - substitution2</title><link>https://0xkakashi.com/posts/picogym/cryptography/substitution2/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/substitution2/</guid><description>It seems that another encrypted message has been intercepted. The encryptor seems to have learned their lesson though and now there isn&apos;t any punctuation! Can you still crack the cipher?</description><pubDate>Mon, 08 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/substitution2/message.txt&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; It seems that another encrypted message has been intercepted. The encryptor seems to have learned their lesson though and now there isn&apos;t any punctuation! Can you still crack the cipher?&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Will Hong&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge provides a long ciphertext with no spacing or punctuation, making frequency analysis slightly harder than usual. Since the title is &lt;strong&gt;substitution2&lt;/strong&gt;, this strongly suggests another monoalphabetic substitution cipher, just without word boundaries. By leveraging automated tools and frequency patterns, we can still recover the plaintext and extract the flag hidden at the end.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;We are given the file &lt;code&gt;message.txt&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file message.txt 
message.txt: ASCII text, with very long lines (1288), with no line terminators
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And its content is a &lt;code&gt;massive block of text&lt;/code&gt; with no spaces and no punctuation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fnjdjjzqsfsjpjdxwmfnjdcjwwjsfxhwqsnjynqensknmmwkmuvafjdsjkadqftkmuvjfqfqmgsqgkwayqgekthjdvxfdqmfxgyaskthjdknxwwjgejfnjsjkmuvjfqfqmgslmkasvdquxdqwtmgstsfjusxyuqgqsfdxfqmglagyxujgfxwscnqknxdjpjdtasjlawxgyuxdojfxhwjsoqwwsnmcjpjdcjhjwqjpjfnjvdmvjdvadvmsjmlxnqensknmmwkmuvafjdsjkadqftkmuvjfqfqmgqsgmfmgwtfmfjxknpxwaxhwjsoqwwshafxwsmfmejfsfayjgfsqgfjdjsfjyqgxgyjzkqfjyxhmafkmuvafjdskqjgkjyjljgsqpjkmuvjfqfqmgsxdjmlfjgwxhmdqmasxllxqdsxgykmujymcgfmdaggqgeknjkowqsfsxgyjzjkafqgekmglqeskdqvfsmlljgsjmgfnjmfnjdnxgyqsnjxpqwtlmkasjymgjzvwmdxfqmgxgyquvdmpqsxfqmgxgymlfjgnxsjwjujgfsmlvwxtcjhjwqjpjxkmuvjfqfqmgfmaknqgemgfnjmlljgsqpjjwjujgfsmlkmuvafjdsjkadqftqsfnjdjlmdjxhjffjdpjnqkwjlmdfjknjpxgejwqsufmsfayjgfsqgxujdqkxgnqensknmmwsladfnjdcjhjwqjpjfnxfxgagyjdsfxgyqgemlmlljgsqpjfjkngqiajsqsjssjgfqxwlmdumagfqgexgjlljkfqpjyjljgsjxgyfnxffnjfmmwsxgykmglqeadxfqmglmkasjgkmagfjdjyqgyjljgsqpjkmuvjfqfqmgsymjsgmfwjxysfayjgfsfmogmcfnjqdjgjutxsjlljkfqpjwtxsfjxknqgefnjufmxkfqpjwtfnqgowqojxgxffxkojdvqkmkflqsxgmlljgsqpjwtmdqjgfjynqensknmmwkmuvafjdsjkadqftkmuvjfqfqmgfnxfsjjosfmejgjdxfjqgfjdjsfqgkmuvafjdskqjgkjxumgenqensknmmwjdsfjxknqgefnjujgmaenxhmafkmuvafjdsjkadqftfmvqiajfnjqdkadqmsqftumfqpxfqgefnjufmjzvwmdjmgfnjqdmcgxgyjgxhwqgefnjufmhjffjdyjljgyfnjqduxknqgjsfnjlwxeqsvqkmKFL{G6D4U_4G41T515_15_73Y10A5_42JX1770}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The absence of whitespace is deliberate: it makes pattern spotting harder, but it’s still just a substitution cipher, as implied by the challenge title.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;To decode this efficiently, we load the ciphertext into: &lt;a href=&quot;https://www.dcode.fr/monoalphabetic-substitution&quot;&gt;Mono-alphabetic Substitution&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The tool performs frequency analysis and heuristic reconstruction to rebuild natural English from the continuous letter stream.&lt;/p&gt;
&lt;p&gt;After processing, we obtain the fully decrypted plaintext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;THEREEXISTSEVERALOTHERWELLESTABLISHEDHIGHSCHOOLCOMPUTERSECURITYCOMPETITIONSINCLUDINGCYBERPATRIOTANDUSCYBERCHALLENGETHESECOMPETITIONSFOCUSPRIMARILYONSYSTEMSADMINISTRATIONFUNDAMENTALSWHICHAREVERYUSEFULANDMARKETABLESKILLSHOWEVERWEBELIEVETHEPROPERPURPOSEOFAHIGHSCHOOLCOMPUTERSECURITYCOMPETITIONISNOTONLYTOTEACHVALUABLESKILLSBUTALSOTOGETSTUDENTSINTERESTEDINANDEXCITEDABOUTCOMPUTERSCIENCEDEFENSIVECOMPETITIONSAREOFTENLABORIOUSAFFAIRSANDCOMEDOWNTORUNNINGCHECKLISTSANDEXECUTINGCONFIGSCRIPTSOFFENSEONTHEOTHERHANDISHEAVILYFOCUSEDONEXPLORATIONANDIMPROVISATIONANDOFTENHASELEMENTSOFPLAYWEBELIEVEACOMPETITIONTOUCHINGONTHEOFFENSIVEELEMENTSOFCOMPUTERSECURITYISTHEREFOREABETTERVEHICLEFORTECHEVANGELISMTOSTUDENTSINAMERICANHIGHSCHOOLSFURTHERWEBELIEVETHATANUNDERSTANDINGOFOFFENSIVETECHNIQUESISESSENTIALFORMOUNTINGANEFFECTIVEDEFENSEANDTHATTHETOOLSANDCONFIGURATIONFOCUSENCOUNTEREDINDEFENSIVECOMPETITIONSDOESNOTLEADSTUDENTSTOKNOWTHEIRENEMYASEFFECTIVELYASTEACHINGTHEMTOACTIVELYTHINKLIKEANATTACKERPICOCTFISANOFFENSIVELYORIENTEDHIGHSCHOOLCOMPUTERSECURITYCOMPETITIONTHATSEEKSTOGENERATEINTERESTINCOMPUTERSCIENCEAMONGHIGHSCHOOLERSTEACHINGTHEMENOUGHABOUTCOMPUTERSECURITYTOPIQUETHEIRCURIOSITYMOTIVATINGTHEMTOEXPLOREONTHEIROWNANDENABLINGTHEMTOBETTERDEFENDTHEIRMACHINES
THEFLAGISPICOCTF{N6R4M_4N41Y515_15_73D10U5_42EA1770}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;From here, at the very end, we can see the flag already.&lt;/p&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;p&gt;THE FLAG IS &lt;strong&gt;&lt;s&gt;&lt;code&gt;PICOCTF{N6R4M_4N41Y515_15_73D10U5_42EA1770}&lt;/code&gt;&lt;/s&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
The file contains a giant block of text encrypted via monoalphabetic substitution.&lt;br /&gt;
Removing punctuation and spaces increases difficulty slightly but doesn’t change the cipher.&lt;br /&gt;
Feeding the ciphertext into DCODE&apos;s substitution solver reconstructs readable English.&lt;br /&gt;
Even when obfuscated with no word boundaries, substitution ciphers crumble under frequency analysis.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - credstuff</title><link>https://0xkakashi.com/posts/picogym/cryptography/credstuff/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/credstuff/</guid><description>We found a leak of a blackmarket website&apos;s login credentials. Can you find the password of the user cultiris and successfully decrypt it? The first user in usernames.txt corresponds to the first password in passwords.txt. The second user corresponds to the second password, and so on.</description><pubDate>Tue, 25 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/credstuff/leak.tar&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; We found a leak of a blackmarket website&apos;s login credentials. Can you find the password of the user cultiris and successfully decrypt it? The first user in usernames.txt corresponds to the first password in passwords.txt. The second user corresponds to the second password, and so on.&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Will Hong / LT &apos;syreal&apos; Jones&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge provides a leaked archive containing two files: a list of usernames and a list of passwords. Each username corresponds directly to the password on the same line number. The goal is to locate the user &lt;code&gt;cultiris&lt;/code&gt;, find their associated password, and then decrypt it to obtain the flag.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;We are given a tar archive named leak.tar:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file leak.tar 
leak.tar: POSIX tar archive (GNU)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A quick reminder:
&lt;code&gt;tar&lt;/code&gt; (Tape ARchive) is a Linux utility used for packaging multiple files into a single archive. It’s commonly used for backups, data transfer, and compressing directory structures. Extracting it will reveal the files inside.&lt;/p&gt;
&lt;p&gt;Let&apos;s untar it&lt;/p&gt;
&lt;p&gt;Let&apos;s extract the archive:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tar -xvf leak.tar
leak/
leak/passwords.txt
leak/usernames.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Step 1, View the leaked usernames&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ cat usernames.txt
engineerrissoles
icebunt
fruitfultry
celebritypentathlon
galoshesopinion
favorboeing
bindingcouch
entersalad
ruthlessconfidence
coupleelevator
remotesword
researchfall
alertborn
excitedcool
actressbogus
volcanicram
glassesspring
fixoutrigger
boozerfirework
therapistvigorous
withoutbelgian
treedon’t
healobligation
volunteerprofessor
tweedboilersuit
underwingpale
whirlmolar
crawlrake
sandpiperband
turbulentbrisk
strippedimminent
croakmuffler
netherrackdelay
harrascroak
leeryspiffy
mineshaftlevel
paragraphswarm
horizongrimacing
aheadmeek
grimacingstain
analysttooth
majoritygillette
droopyoatmeal
councilmonster
fencegreek
treaclerebel
kentishpartial
habitualregardless
overallglistening
cootnoise
victimscalloped
patienceyawl
depictnine
widoweveryone
survivalunlikely
clovestair
lardfacecrash
mewguitar
dellminer
croquetdroopy
drabparcel
platformcancel
sutehummus
fearlessherring
shypresident
deliverunsightly
swooshdelicious
resistancedistorted
...
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Step 2, Count the usernames&lt;/h3&gt;
&lt;p&gt;There are many usernames, so let’s count them:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ wc -l usernames.txt
505 usernames.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Step 3, View the leaked passwords&lt;/h3&gt;
&lt;p&gt;And I think it will be the same on the password.txt since line N of usernames.txt corresponds to line N of passwords.txt.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat passwords.txt
CMPTmLrgfYCexGzJu6TbdGwZa
GK73YKE2XD2TEnvJeHRBdfpt2
UukmEk5NCPGUSfs5tGWPK26gG
kaL36YJtvZMdbTdLuQRx84t85
K9gzHFpwF2azPayAUSrcL8fJ9
rYrtRbkHvJzPmDwzD6gSDbAE3
kfcVXjcFkvNQQPpATErx6eVDd
kDrPVvMakUsNd7BvmJtK3ACY4
dvDvWjzXNk8WwqEzJ5P2FP5YH
86L5w4sH9ZXTCPAa5ExMSPFNh
qXFEg8ZasLxQhUYWnhTemgqxh
gd7panTqNpUvBXBxpGpcqP9X7
Y3KcHyg7kSf6RgX5THyjrw3g1
WkHQ78HaKgkcf8bHat9GbTJmj
LhY5mfRsaKjaueVhdeHqUrMKp
fcdy7jz9VmfPQcuHRnULJvwUf
fVsT4tJ5ahRUbBp4YEdVAvLtF
cLr6pyDpuvQyAda35CdcCsSgk
mkY39jWhLQAABWNg7GQQCqhr9
JPTeqgHpbTYra2jXn7KLvNXt1
BskbdvkHv8Dv9NAgRHJ3uwDG0
hD795qgYzpbhXGSYadJRJpRGB
WLVn9cV4NL7kZ2WCagP8jV2Gc
XccQXznLtdWbs6ga24tMEXNfe
kw6zFzfZvEGk6fxrMNQYUXeXh
XgqXaMhG65X4aP6GqadBAYKfs
fHfNeGsefznBCnpPvKxVk6au1
nb6ErH5LkVNyAD4mggFtdyVqn
J4jyAn9apZSERG52NHsAZPkTJ
MxFFeMG8GYpqTuFjBgeEZYyMx
HrrWkXXrTmmnyTWbSkMp9Ex5R
TW9wgrcfu6Ts5g7B52h35rLv9
96HpneHwr2NkwQTGapdGJ2zHH
Kbm4VSy5AwC5GJqdB7LyBQjmB
nUVsKGwX3aQfQbaVCFJhEEevs
wtcfmPjPWFtKr2dsJ3xHJTsEf
fNadeE2VUsZhvrp9jtSwAHLEV
Bu2RE6MNb6m3fEAB7ybzKYubN
FWT6WftJ4DjZaQkTF8g7cfPHJ
eLb8JZbmgVkkg8Um3M3cgBSJm
rXYhx9zD7sDEwrvJDq24hBw6D
Q4zpdfMkAccQUFhGtWxtysKFk
cBZJ76hxZFrSfUdubQXvRbnKx
t8jgSfmGcSdk6xcP5mq5NAXBG
NSAx3BZ4spPGgsSddB6tcq974
ZrqGJCkPKMTgNJsnjM7ZsDewP
JzrVE3xzLHJwbug7YU4cAdRLz
xMUtE5ZXeddJmmQVp5te8eMwX
93tVFsU4FnhATXdk4TFgscyE4
wKhzpAM9bTYDLUpnvWwD3kJG9
mRuTNPuN3xNvyPb4XQqqXcteN
WSxghvfrLaUyJuuds9VPPC9Tr
MNmUBhP89UyF5Y35mG6vWbF98
QKMa8FVXBapTfdGukHHjbyBGX
UZhEA4bBB4Ygeqc22G69eSH5B
qLdf6j7XCbq5VVSkwjKdfj8gX
HhFzWEGRNeHPLwaGxFDedkznR
UnYbztbH2HxJHugn8cXCvsJ9H
9AaAGz4Q5seQBQquBJFgVUBWQ
z2NWxfQedMaaCp4ud4QePyyFe
....
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Step 4, Count the passwords&lt;/h3&gt;
&lt;p&gt;As expected, the passwords file contains the same number of entries; I was right xD.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ wc -l passwords.txt
505 passwords.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;Now let&apos;s see if the username &lt;code&gt;cultiris&lt;/code&gt; exist on usernames.txt using &lt;strong&gt;grep&lt;/strong&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat usernames.txt | grep &quot;cultiris&quot;
cultiris
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nice we have it here!&lt;/p&gt;
&lt;p&gt;Now let&apos;s locate the target username &lt;code&gt;cultiris&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ grep -n &quot;cultiris&quot; usernames.txt
378:cultiris
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Perfect, &lt;code&gt;cultiris&lt;/code&gt; is on line 378.&lt;/p&gt;
&lt;p&gt;I can search manually or by using this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sed -n &apos;378p&apos; passwords.txt
cvpbPGS{P7e1S_54I35_71Z3}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This looks like a flag, but it’s clearly not decrypted yet. The structure strongly resembles ROT13.&lt;/p&gt;
&lt;p&gt;To confirm, we check DCODE’s Cipher Identifier:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It detects ROT13, just as suspected.&lt;/p&gt;
&lt;p&gt;We can use this &lt;a href=&quot;https://www.dcode.fr/rot-13-cipher&quot;&gt;ROT13 Decoder&lt;/a&gt; and this gives us the flag :&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-2.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;p&gt;Flag : &lt;strong&gt;&lt;s&gt;&lt;code&gt;picoCTF{C7r1F_54V35_71M3}&lt;/code&gt;&lt;/s&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
Extract the tar archive → two files: usernames &amp;amp; passwords.&lt;br /&gt;
Line numbers correspond exactly between both files.&lt;br /&gt;
Locate &lt;code&gt;cultiris&lt;/code&gt; → line 378.&lt;br /&gt;
Retrieve password from &lt;code&gt;passwords.txt&lt;/code&gt; line 378.&lt;br /&gt;
Decrypt the ROT13-encoded string → flag appears
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - morse-code</title><link>https://0xkakashi.com/posts/picogym/cryptography/morse-code/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/morse-code/</guid><description>Morse code is well known. Can you decrypt this? Download the file here. Wrap your answer with picoCTF{}, put underscores in place of pauses, and use all lowercase.</description><pubDate>Mon, 24 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/morse-code/morse_chal.wav&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; Morse code is well known. Can you decrypt this? Download the file here. Wrap your answer with picoCTF{}, put underscores in place of pauses, and use all lowercase.&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Will Hong&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge provides an audio recording containing Morse code beeps. The goal is to decode the audio into text.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;We are given an audio file named &lt;code&gt;morse_chal.wav&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file morse_chal.wav 
morse_chal.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, mono 44100 Hz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since it&apos;s a WAV file, the next logical step is to listen to it, and immediately, it becomes clear that the audio consists of classic Morse code beeps.&lt;/p&gt;
&lt;p&gt;To decode the Morse from audio, we can use any online audio Morse decoder. One reliable option is: https://morsecode.world/international/decoder/audio-decoder-adaptive.html&lt;/p&gt;
&lt;p&gt;Upload the file and wait for the decoder to process the signal.
&lt;img src=&quot;image.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The decoder output gives us: &lt;code&gt;WH47 H47H 90D W20U9H7&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now we need to replace the spaces with underscores and wrap it with the flag format:
&lt;s&gt;&lt;code&gt;picoCTF{WH47_H47H_90D_W20U9H7}&lt;/code&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 Flag &lt;strong&gt;pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
Audio Morse can be decoded easily using online adaptive decoders.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - Tapping</title><link>https://0xkakashi.com/posts/picogym/cryptography/tapping/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/tapping/</guid><description>There&apos;s tapping coming in from the wires. Additional details will be available after launching your challenge instance.</description><pubDate>Sun, 23 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; There&apos;s tapping coming in from the wires. Additional details will be available after launching your challenge instance.&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Danny&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge provides a message from a remote service. The message consists entirely of dots, dashes, and spacing, a strong indicator that it is encoded using &lt;strong&gt;Morse Code&lt;/strong&gt;. The goal is to decode it and extract the flag.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;Since this is an instance-based challenge, we first connect to the service using &lt;code&gt;nc&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ nc fickle-tempest.picoctf.net 60330.
.--. .. -.-. --- -.-. - ..-. { -- ----- .-. ... ...-- -.-. ----- -.. ...-- .---- ... ..-. ..- -. ----- ....- ...-- .- ...-- ....- ..... ----- }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is clearly Morse Code.&lt;/p&gt;
&lt;h2&gt;What is morse code?&lt;/h2&gt;
&lt;p&gt;Morse code is a method of encoding characters using sequences of short and long signals:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Short signal = dot (&lt;code&gt;.&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Long signal = dash (&lt;code&gt;-&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each letter or number is represented by a specific sequence of dots and dashes.
Example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A = &lt;code&gt;.-&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Kakashi = &lt;code&gt;-.- .- -.- .- ... .... ..&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Spacing rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each letter is separated by a space&lt;/li&gt;
&lt;li&gt;Each word is separated by a slash &lt;code&gt;/&lt;/code&gt; (or newline)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;How to encrypt using Morse Code cipher?&lt;/h3&gt;
&lt;p&gt;To encrypt text:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Convert each letter into its dot/dash representation using the Morse table.&lt;/li&gt;
&lt;li&gt;Separate characters with spaces.&lt;/li&gt;
&lt;li&gt;Separate words using / or additional spacing.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example:
HELLO → &lt;code&gt;.... . .-.. .-.. ---&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The complete table of Morse Code is :&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;How to decrypt Morse Code cipher?&lt;/h3&gt;
&lt;p&gt;To decrypt:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Split the input by spaces.&lt;/li&gt;
&lt;li&gt;Convert each dot/dash sequence back to its letter using the Morse table.&lt;/li&gt;
&lt;li&gt;Join the letters to form words.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tools such as CyberChef, DCode, or any Morse decoder can automate this process.&lt;/p&gt;
&lt;p&gt;`&lt;/p&gt;
&lt;h3&gt;How to recognize Morse Code ciphertext?&lt;/h3&gt;
&lt;p&gt;Morse ciphertext is easy to spot:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Contains only dots, dashes, spaces, and sometimes slashes.&lt;/li&gt;
&lt;li&gt;Often delivered as tapping, beeps, or light flashes.&lt;/li&gt;
&lt;li&gt;In text-based CTFs → sequences like:
&lt;code&gt;.---- ..--- ...--&lt;/code&gt;
&lt;code&gt;-.-. --- -.. .&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Decrypting the Challenge Ciphertext&lt;/h2&gt;
&lt;p&gt;We paste the cipher into CyberChef using From Morse Code, which decodes it automatically:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-1.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Alternatively, here’s the manual breakdown:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;--       0     .-.     ...--    -.-.     -----     -..     ...--     .----     ...     ..-.     ..-     -.     -----     ....-     ...--     .-     ...--     ....-     .....     -----
M        0      R        3        C        0         D        3         1        S        F        U       N       0        4         3        A        3        4         5         0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the decoded message is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;M0R3C0D31SFUN043A3450
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 Flag &lt;strong&gt;pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;h2&gt;Final Flag&lt;/h2&gt;
&lt;p&gt;The flag is &lt;s&gt;&lt;code&gt;picoCTF{M0R3C0D31SFUN043A3450}&lt;/code&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
Morse Code uses dots and dashes to represent characters.
Spacing matters: space = new letter, slash = new word.
Easy to decode using CyberChef or any online Morse decoder.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - La Cifra De</title><link>https://0xkakashi.com/posts/picogym/cryptography/la-cifra-de/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/la-cifra-de/</guid><description>I found this cipher in an old book. Additional details will be available after launching your challenge instance.</description><pubDate>Sun, 23 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; I found this cipher in an old book. Additional details will be available after launching your challenge instance.&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Alex Fulton/Daniel Tunitis&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge provides an encrypted text from a remote instance. The goal is to identify the cipher and decrypt the message to extract the flag.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;Since this is an instance-based challenge, we first connect to the service using &lt;code&gt;nc&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ nc fickle-tempest.picoctf.net 51614
Encrypted message:
âˆ©â•, â”Ne iy nytkwpsznyg nth it mtsztcy vjzprj zfzjy rkhpibj nrkitt ltc tnnygy ysee itd tte cxjltk

Ifrosr tnj noawde uk siyyzre, yse Bnretâ”œÂ¿wp Cousex mls hjpn xjtnbjytki xatd eisjd

Iz bls lfwskqj azycihzeej yz Brftsk ip Volpnâ”œÂ¿xj ls oy hay tcimnyarqj dkxnrogpd os 1553 my Mnzvgs Mazytszf Merqlsu ny hox moup Wa inqrg ipl. Ynr. Gotgat Gltzndtg Gplrfdo

Ltc tnj tmvqpmkseaznzn uk ehox nivmpr g ylbrj ts ltcmki my yqtdosr tnj wocjc hgqq ol fy oxitngwj arusahje fuw ln guaaxjytrd catizm tzxbkw zf vqlckx hizm ceyupcz yz tnj fpvjc hgqqpohzCZK{m311a50_0x_a1rn3x3_h1ah3xim3eKhQa}

Zmp fowdt cjwl-jtnusjytki oeyhcivytot tq a vtwygqahggptoh nivmpr nthebjc, wgx xajj lruzyd 1467 hd Weus Mazytszf Llhjcto.

Yse Bnretâ”œÂ¿wp Cousex nd tnjceltce ytxeznxey hllrjo tnj Llhjcto Itsi tc Argprzn Nivmpr.

Os 1508, Uonfynkx Eroysesnfs osgetypd zmp su-hllrjo tggflg wpczf (l mgycid tq snnqtki llvmlbkyd) tnfe wuzwd rfeex gp a iwttohll itxpuspnz tq tnj Gimjyâ”œÂ¿rk Htpnjc.

BkqwaytÎ“Ã‡Ã–d skhznj gzoqqpt guaegwpd os 1555 ls g hznznyugytot tq tnj qixxe. Tnj wocjc hgqgey tq tnj llvmlbkyd axj yoc xsilypd xjrurfcle, gft zmp arusahjes gso tnj tnjji lkyeexx lrk rtxki my sjlny tq a sspmustc qjj pnwlsk, bsiim nat gp dokqexjyt cneh kfnh itcrkxaotipnz.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The instance responds with a long encrypted message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;âˆ©â•, â”Ne iy nytkwpsznyg nth it mtsztcy vjzprj zfzjy rkhpibj nrkitt ltc tnnygy ysee itd tte cxjltk

Ifrosr tnj noawde uk siyyzre, yse Bnretâ”œÂ¿wp Cousex mls hjpn xjtnbjytki xatd eisjd

Iz bls lfwskqj azycihzeej yz Brftsk ip Volpnâ”œÂ¿xj ls oy hay tcimnyarqj dkxnrogpd os 1553 my Mnzvgs Mazytszf Merqlsu ny hox moup Wa inqrg ipl. Ynr. Gotgat Gltzndtg Gplrfdo

Ltc tnj tmvqpmkseaznzn uk ehox nivmpr g ylbrj ts ltcmki my yqtdosr tnj wocjc hgqq ol fy oxitngwj arusahje fuw ln guaaxjytrd catizm tzxbkw zf vqlckx hizm ceyupcz yz tnj fpvjc hgqqpohzCZK{m311a50_0x_a1rn3x3_h1ah3xim3eKhQa}

Zmp fowdt cjwl-jtnusjytki oeyhcivytot tq a vtwygqahggptoh nivmpr nthebjc, wgx xajj lruzyd 1467 hd Weus Mazytszf Llhjcto.

Yse Bnretâ”œÂ¿wp Cousex nd tnjceltce ytxeznxey hllrjo tnj Llhjcto Itsi tc Argprzn Nivmpr.

Os 1508, Uonfynkx Eroysesnfs osgetypd zmp su-hllrjo tggflg wpczf (l mgycid tq snnqtki llvmlbkyd) tnfe wuzwd rfeex gp a iwttohll itxpuspnz tq tnj Gimjyâ”œÂ¿rk Htpnjc.

BkqwaytÎ“Ã‡Ã–d skhznj gzoqqpt guaegwpd os 1555 ls g hznznyugytot tq tnj qixxe. Tnj wocjc hgqgey tq tnj llvmlbkyd axj yoc xsilypd xjrurfcle, gft zmp arusahjes gso tnj tnjji lkyeexx lrk rtxki my sjlny tq a sspmustc qjj pnwlsk, bsiim nat gp dokqexjyt cneh kfnh itcrkxaotipnz.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is clearly not substitution, since the structure of the text is too varied.
It also doesnâ€™t look like transposition â€” the letter distribution resembles normal English frequency patterns, meaning:&lt;/p&gt;
&lt;p&gt;This is likely a polyalphabetic substitution cipher.&lt;/p&gt;
&lt;p&gt;To confirm, I run the ciphertext through a cipher identification tool: &lt;a href=&quot;https://www.dcode.fr/cipher-identifier&quot;&gt;cipher identifier&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And dcode.fr strongly suggests its &lt;code&gt;Vigenère Cipher&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Decrypting (Using a Vigenère Solver)&lt;/h2&gt;
&lt;p&gt;Instead of doing key-length analysis manually, we simply use an &lt;a href=&quot;https://www.guballa.de/vigenere-solver&quot;&gt;automated solver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Paste the entire ciphertext into the solver and it automatically:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Detects the key length&lt;/li&gt;
&lt;li&gt;Recovers the Vigenère key&lt;/li&gt;
&lt;li&gt;Outputs the full decrypted English plaintext&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;image-1.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It discovers the key: &lt;strong&gt;flag&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Decrypted message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;âˆ©â•, â”It is interesting how in history people often receive credit for things they did not create

During the course of history, the Vigenère Cipher has been reinvented many times

It was falsely attributed to Blaise de Vigenère as it was originally described in 1553 by Giovan Battista Bellaso in his book La cifra del. Sig. Giovan Battista Bellaso

For the implementation of this cipher a table is formed by sliding the lower half of an ordinary alphabet for an apparently random number of places with respect to the upper halfpicoCTF{b311a50_0r_v1gn3r3_c1ph3rdb3eEcFa}

The first well-documented description of a polyalphabetic cipher however, was made around 1467 by Leon Battista Alberti.

The Vigenère Cipher is therefore sometimes called the Alberti Disc or Alberti Cipher.

In 1508, Johannes Trithemius invented the so-called tabula recta (a matrix of shifted alphabets) that would later be a critical component of the Vigenère Cipher.

BellasoÎ“Ã‡Ã–s second booklet appeared in 1555 as a continuation of the first. The lower halves of the alphabets are now shifted regularly, but the alphabets and the index letters are mixed by means of a mnemonic key phrase, which can be different with each correspondent.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[âš¡ Raikiri]
🎉 Flag &lt;strong&gt;pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;p&gt;The flag appears to be &lt;s&gt;&lt;code&gt;picoCTF{b311a50_0r_v1gn3r3_c1ph3rdb3eEcFa}&lt;/code&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
Long, natural-looking ciphertext with proper spacing strongly hints at Vigenère or another polyalphabetic cipher.
Classical ciphers like Vigenère are trivially broken using modern automated solvers.
Always try cipher-identification tools first â€” they save time.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐🕵️ PicoGym - Mr-Worldwide</title><link>https://0xkakashi.com/posts/picogym/cryptography/mr-worldwide/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/mr-worldwide/</guid><description>A musician left us a message. What&apos;s it mean?</description><pubDate>Sat, 22 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/Mr-Worldwide/message.txt&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; A musician left us a message. What&apos;s it mean?&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; speeeday/Danny&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge hides a message inside a series of &lt;strong&gt;GPS coordinates&lt;/strong&gt; formatted inside &lt;code&gt;picoCTF{...}&lt;/code&gt;.&lt;br /&gt;
By identifying the locations and taking the first letter of each city, we can reconstruct the final flag.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;We are provided with the file &lt;code&gt;message.txt&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file message.txt 
message.txt: ASCII text, with no line terminators
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its contents are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;picoCTF{(35.028309, 135.753082)(46.469391, 30.740883)(39.758949, -84.191605)(41.015137, 28.979530)(24.466667, 54.366669)(3.140853, 101.693207)_(9.005401, 38.763611)(-3.989038, -79.203560)(52.377956, 4.897070)(41.085651, -73.858467)(57.790001, -152.407227)(31.205753, 29.924526)}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At first glance, this clearly resembles a list of latitude/longitude GPS coordinates wrapped inside &lt;code&gt;picoCTF{}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I&apos;ll extract only the coordinates to make the data easier to read and analyze:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(35.028309, 135.753082)
(46.469391, 30.740883)
(39.758949, -84.191605)
(41.015137, 28.979530)
(24.466667, 54.366669)
(3.140853, 101.693207)
_
(9.005401, 38.763611)
(-3.989038, -79.203560)
(52.377956, 4.897070)
(41.085651, -73.858467)
(57.790001, -152.407227)
(31.205753, 29.924526)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;What places do these GPS coordinates point to?&lt;/h3&gt;
&lt;p&gt;The underscore &lt;code&gt;_&lt;/code&gt; appears to separate two words, meaning:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first group of coordinates → first word&lt;/li&gt;
&lt;li&gt;The second group → second word&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The next step is to reverse-lookup each coordinate using tools like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://maps.google.com/&quot;&gt;Google Maps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.openstreetmap.org/&quot;&gt;OpenStreetMap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.latlong.net/&quot;&gt;latlong.net&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Identifying the locations&lt;/h3&gt;
&lt;p&gt;Now I&apos;ll plug each coordinate into Google Maps and note the city.&lt;/p&gt;
&lt;p&gt;Example lookup :&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;first&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;35.028309, 135.753082&lt;/code&gt; → &lt;strong&gt;Kyoto, Japan&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Proceeding similarly, the coordinates resolve to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;(35.028309, 135.753082)&lt;/code&gt; → &lt;strong&gt;Kyoto&lt;/strong&gt;, Japan&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(46.469391, 30.740883)&lt;/code&gt; → &lt;strong&gt;Odesa&lt;/strong&gt;, Ukraine&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(39.758949, -84.191605)&lt;/code&gt; → &lt;strong&gt;Dayton&lt;/strong&gt;, USA&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(41.015137, 28.979530)&lt;/code&gt; → &lt;strong&gt;Istanbul&lt;/strong&gt;, Turkey&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(24.466667, 54.366669)&lt;/code&gt; → &lt;strong&gt;Abu Dhabi&lt;/strong&gt;, UAE&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(3.140853, 101.693207)&lt;/code&gt; → &lt;strong&gt;Kuala Lumpu&lt;/strong&gt;r, Malaysia&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then after the underscore:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;(9.005401, 38.763611)&lt;/code&gt; → &lt;strong&gt;Addis Ababa&lt;/strong&gt;, Ethiopia&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(-3.989038, -79.203560)&lt;/code&gt; → &lt;strong&gt;Loja&lt;/strong&gt;, Ecuador&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(52.377956, 4.897070)&lt;/code&gt; → &lt;strong&gt;Amsterdam&lt;/strong&gt;, Netherlands&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(41.085651, -73.858467)&lt;/code&gt; → &lt;strong&gt;Sleepy Hollow&lt;/strong&gt;, USA&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(57.790001, -152.407227)&lt;/code&gt; → &lt;strong&gt;Kodiak&lt;/strong&gt;, USA&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(31.205753, 29.924526)&lt;/code&gt; → &lt;strong&gt;Alexandria&lt;/strong&gt;, Egypt&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now we look for a pattern. A common trick in these kinds of challenges is to take the first letter of each city:&lt;/p&gt;
&lt;p&gt;First group:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;K&lt;/code&gt;yoto&lt;/li&gt;
&lt;li&gt;&lt;code&gt;O&lt;/code&gt;desa&lt;/li&gt;
&lt;li&gt;&lt;code&gt;D&lt;/code&gt;ayton&lt;/li&gt;
&lt;li&gt;&lt;code&gt;I&lt;/code&gt;stanbul&lt;/li&gt;
&lt;li&gt;&lt;code&gt;A&lt;/code&gt;bu Dhabi&lt;/li&gt;
&lt;li&gt;&lt;code&gt;K&lt;/code&gt;uala Lumpur&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;→ &lt;code&gt;KODIAK&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Second group:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;A&lt;/code&gt;ddis Ababa&lt;/li&gt;
&lt;li&gt;&lt;code&gt;L&lt;/code&gt;oja&lt;/li&gt;
&lt;li&gt;&lt;code&gt;A&lt;/code&gt;msterdam&lt;/li&gt;
&lt;li&gt;&lt;code&gt;S&lt;/code&gt;leepy Hollow&lt;/li&gt;
&lt;li&gt;&lt;code&gt;K&lt;/code&gt;odiak&lt;/li&gt;
&lt;li&gt;&lt;code&gt;A&lt;/code&gt;lexandria&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;→ &lt;code&gt;ALASKA&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;So the hidden message is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;KODIAK_ALASKA
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 Flag &lt;strong&gt;pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;h2&gt;Final flag&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;picoCTF{KODIAK_ALASKA}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
Location-based puzzles usually hide words in the initials of cities.&lt;br /&gt;
Map the coordinates, take the first letters, and the message appears.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - rail-fence</title><link>https://0xkakashi.com/posts/picogym/cryptography/rail-fence/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/rail-fence/</guid><description>A type of transposition cipher is the rail fence cipher, which is described here. Here is one such cipher encrypted using the rail fence with 4 rails. Can you decrypt it? Download the message here. Put the decoded message in the picoCTF flag format, picoCTF{decoded_message}.</description><pubDate>Thu, 20 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/rail-fence/message.txt&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; A type of transposition cipher is the rail fence cipher, which is described &lt;a href=&quot;https://en.wikipedia.org/wiki/Rail_fence_cipher&quot;&gt;here&lt;/a&gt;. Here is one such cipher encrypted using the rail fence with 4 rails. Can you decrypt it? Download the message here. Put the decoded message in the picoCTF flag format, picoCTF{decoded_message}.&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Will Hong&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge introduces the Rail Fence Cipher, a classic transposition cipher.
The goal is to decrypt the ciphertext stored in &lt;code&gt;message.txt&lt;/code&gt; using a Rail Fence with 4 rails, then wrap the result in the flag format: &lt;code&gt;picoCTF{decoded_message}&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;We are provided with a file named &lt;code&gt;message.txt&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file message.txt 
message.txt: ASCII text, with no line terminators
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$ cat message.txt 
Ta _7N6D49hlg:W3D_H3C31N__A97ef sHR053F38N43D7B i33___N6
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the ciphertext is : &lt;code&gt;Ta _7N6D49hlg:W3D_H3C31N__A97ef sHR053F38N43D7B i33___N6&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Since the challenge description specifies &lt;code&gt;Rail Fence Cipher with 4 rails&lt;/code&gt;, we know this is a transposition cipher, not substitution. Before decrypting it, let&apos;s first understand how the Rail Fence Cipher works.&lt;/p&gt;
&lt;h3&gt;What is Rail Fence Cipher?&lt;/h3&gt;
&lt;p&gt;The Rail Fence Cipher is a transposition cipher that encrypts a message by writing it in a zig-zag pattern across several “rails” (rows), then reading the characters row by row.&lt;/p&gt;
&lt;p&gt;It is often described as writing text in a wave-like pattern:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Write characters diagonally downwards.&lt;/li&gt;
&lt;li&gt;When the bottom rail is reached, move diagonally upwards.&lt;/li&gt;
&lt;li&gt;Repeat the pattern until the entire message is written.&lt;/li&gt;
&lt;li&gt;Finally, read off each rail from top to bottom to form the ciphertext.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;How Rail Fence Encryption &amp;amp; Decryption Work&lt;/h2&gt;
&lt;h3&gt;Encryption Steps&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Choose a number of rails (rows).&lt;/li&gt;
&lt;li&gt;Place characters in an up–down zig-zag pattern across the rails.&lt;/li&gt;
&lt;li&gt;Read each rail straight across.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Decryption Steps&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Recreate the zig-zag structure.&lt;/li&gt;
&lt;li&gt;Fill the rails row-by-row using the ciphertext.&lt;/li&gt;
&lt;li&gt;Reconstruct the plaintext by following the original zig-zag path.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Encrytion Example (with 4 rails)&lt;/h2&gt;
&lt;p&gt;Plaintext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;WEAREDISCOVEREDFLEEATONCE
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Written in zig-zag:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Rail 1: W . . . R . . . E . . . E . . . A . . .
Rail 2: . E . R . D . S . O . E . E . F . E . T .
Rail 3: . . A . . C . . . V . . . R . . . L . . .
Rail 4: . . . E . . . . . . . . . . . . . . . . .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Periods represent empty positions.)&lt;/p&gt;
&lt;p&gt;Now read each rail from top to bottom:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Rail 1 → W R E E A C  
Rail 2 → E R D S O E E F E T N  
Rail 3 → A C V R L E  
Rail 4 → E
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ciphertext :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;WREEACERDSOEEFE TNA CVRLE
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Decryption Example (with 4 rails)&lt;/h2&gt;
&lt;p&gt;To decrypt, we reverse the process.&lt;/p&gt;
&lt;h3&gt;Step 1, Mark the zig-zag path&lt;/h3&gt;
&lt;p&gt;For a 4-rail fence, the pattern repeats every:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2×(rails−1)=2×3=6
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We first draw the empty rails for the length of the ciphertext (25 chars):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Rail 1: * . . . * . . . * . . . * . . . * . . . * 
Rail 2: . * . * . * . * . * . * . * . * . * . * . *
Rail 3: . . * . . * . . * . . * . . * . . * . . * .
Rail 4: . . . * . . . * . . . * . . . * . . . * . .
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Step 2, Fill in rails row by row&lt;/h3&gt;
&lt;p&gt;Fill row by row using characters from the ciphertext.&lt;/p&gt;
&lt;h3&gt;Step 3, Read the plaintext in zig-zag&lt;/h3&gt;
&lt;p&gt;Plaintext obtained:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;WEAREDISCOVEREDFLEEATONCE
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Decrypting the ciphertext (4 Rails)&lt;/h2&gt;
&lt;p&gt;Using the same decryption process or an online tool such as &lt;a href=&quot;https://cryptii.com/pipes/rail-fence-cipher&quot;&gt;Rail Fence decoder&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We obtain the plaintext: &lt;code&gt;The flag is: WH3R3_D035_7H3_F3NC3_8361N_4ND_3ND_4A76B997&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;PicoCTF flag Format&lt;/h3&gt;
&lt;p&gt;Now for the flag, we need to just wrap it in the format : &lt;s&gt;&lt;code&gt;picoCTF{WH3R3_D035_7H3_F3NC3_8361N_4ND_3ND_4A76B997}&lt;/code&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
The Rail Fence cipher is a simple transposition method, it only rearranges characters without altering them.
Decryption is straightforward once you know the number of rails and reconstruct the zig-zag pattern used during encryption.
Like most classical ciphers, Rail Fence is &lt;strong&gt;not secure&lt;/strong&gt; today; it is vulnerable to pattern analysis and can be solved quickly with modern tools.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐🫙 PicoGym - HideToSee</title><link>https://0xkakashi.com/posts/picogym/cryptography/hidetosee/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/hidetosee/</guid><description>How about some hide and seek heh? Look at this image here.</description><pubDate>Sun, 16 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/HideToSee/atbash.jpg&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; How about some hide and seek heh? Look at this image here.&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Sunday Jacob Nwanyim&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge combines two concepts: &lt;strong&gt;image steganography&lt;/strong&gt; (using &lt;code&gt;steghide&lt;/code&gt;) and the &lt;strong&gt;Atbash cipher&lt;/strong&gt;. The goal is to extract hidden data from a JPEG image and decode it using Atbash.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;We are provided with a file named &lt;code&gt;atbash.jpg&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file atbash.jpg
atbash.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 465x455, components 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the file is a normal JPEG image:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;atbash&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Step 1: Extracting Hidden Data&lt;/h2&gt;
&lt;p&gt;The most common steganography tool for JPEGs is &lt;code&gt;steghide&lt;/code&gt;, which can hide text or files inside images.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ steghide atbash.jpg
wrote extracted data to &quot;encrypted.txt&quot;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gives us a new file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat encrypted.txt
krxlXGU{zgyzhs_xizxp_8z0uvwwx}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the hidden message inside the JPEG is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;krxlXGU{zgyzhs_xizxp_8z0uvwwx}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It clearly looks like a flag, but encoded.&lt;/p&gt;
&lt;h2&gt;Step 2: Understanding Atbash&lt;/h2&gt;
&lt;h3&gt;What is atbash cipher ?&lt;/h3&gt;
&lt;p&gt;Atbash is a monoalphabetic substitution cipher where every letter is mapped to its “reverse”:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A ↔ Z&lt;/li&gt;
&lt;li&gt;B ↔ Y&lt;/li&gt;
&lt;li&gt;C ↔ X&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;li&gt;M ↔ N&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It applies only to alphabetic characters, numbers, braces, underscores, etc., remain unchanged.
So to decode, we simply reverse each letter using the Atbash mapping.&lt;/p&gt;
&lt;h2&gt;Step 3: Manually Decoding the String&lt;/h2&gt;
&lt;p&gt;Let’s decode it character by character.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;k → &lt;code&gt;p&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;r → &lt;code&gt;i&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;x → &lt;code&gt;c&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;l → &lt;code&gt;o&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;X → &lt;code&gt;C&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;G → &lt;code&gt;T&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;U → &lt;code&gt;F&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;krxlXGU  → picoCTF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Continuing the Atbash mapping over the rest of the string gives : &lt;s&gt;&lt;code&gt;picoCTF{atbash_crack_8a0feddc}&lt;/code&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;Manual decoding works, but to speed things up we can also use an online tool such as the &lt;a href=&quot;https://www.dcode.fr/atbash-cipher&quot;&gt;Atbash Decoder&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 Flag &lt;strong&gt;pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-1.png&quot; alt=&quot;decoded&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Final flag : &lt;s&gt;&lt;code&gt;picoCTF{atbash_crack_8a0feddc}&lt;/code&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
This challenge shows how to extract hidden data from a JPEG using &lt;strong&gt;steghide&lt;/strong&gt; and decode it using the &lt;strong&gt;Atbash cipher&lt;/strong&gt;, revealing the final flag.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - ReadMyCert</title><link>https://0xkakashi.com/posts/picogym/cryptography/readmycert/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/readmycert/</guid><description>How about we take you on an adventure on exploring certificate signing requests. Take a look at this CSR file here.</description><pubDate>Sat, 15 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/ReadMyCert/readmycert.csr&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; How about we take you on an adventure on exploring certificate signing requests. Take a look at this CSR file here.
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Sunday Jacob Nwanyim&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge introduces the concepts of &lt;code&gt;PEM certificates&lt;/code&gt;, certificate signing requests (CSR), and &lt;code&gt;Base64&lt;/code&gt; encoding. The goal is to explore how certificate data is stored and how to inspect what’s inside a CSR file.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;We are provided with a file named &lt;code&gt;readmycert.csr&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file readmycert.csr 
readmycert.csr: PEM certificate request
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From this, we can see that it is a &lt;code&gt;PEM certificate request&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;What is PEM certificate?&lt;/h2&gt;
&lt;p&gt;A &lt;a href=&quot;https://comodosslstore.com/resources/what-is-a-pem-certificate/#:~:text=A%20PEM%20Certificate%20File%20is%E2%80%A6,Here&apos;s%20what%20it%20looks%20like:&quot;&gt;PEM&lt;/a&gt; (Privacy Enhanced Mail) certificate is a text-based file format that stores cryptographic data such as digital certificates, certificate signing requests, or private keys. It is commonly used by web servers like Apache and is easy to identify because it contains Base64-encoded text wrapped between headers like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Key characteristics of a PEM certificate file:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Text-based format: PEM files are human-readable text files, though the content itself is encoded in Base64.&lt;/li&gt;
&lt;li&gt;Content: They can contain various security data, including public keys, private keys, and certificate requests.&lt;/li&gt;
&lt;li&gt;Headers and footers: The start and end of the data within a PEM file are marked by clear text labels, such as &lt;code&gt;-----BEGIN CERTIFICATE-----&lt;/code&gt; and &lt;code&gt;-----END CERTIFICATE-----&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;File extensions: While the .pem extension is common, PEM-formatted data can also be found in other file extensions like .crt, .cer, .csr, or .key.&lt;/li&gt;
&lt;li&gt;Container format: A single PEM file can sometimes contain multiple certificates and/or keys bundled together.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since PEM stores Base64-encoded data, let’s briefly look at &lt;code&gt;Base64 encoding&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;What is Base64 encoding?&lt;/h2&gt;
&lt;p&gt;Base64 is a binary-to-text encoding scheme used to represent arbitrary binary data (like certificates, keys, or files) using only readable ASCII characters. This makes it safe for transmission through systems that may not handle raw binary properly.&lt;/p&gt;
&lt;h3&gt;How it works&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The binary data is split into 6-bit groups.&lt;/li&gt;
&lt;li&gt;Each 6-bit value (0–63) maps to a character in the Base64 index table:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;A–Z&lt;/code&gt; → 0–25&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a–z&lt;/code&gt; → 26–51&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0–9&lt;/code&gt; → 52–61&lt;/li&gt;
&lt;li&gt;&lt;code&gt;+&lt;/code&gt; → 62&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/&lt;/code&gt; → 63&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If the final chunk is incomplete, padding &lt;code&gt;(=)&lt;/code&gt; is added so the output length is always a multiple of 4.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Manual Encoding (The Concept)&lt;/h3&gt;
&lt;p&gt;Let&apos;s manually encode the word &lt;code&gt;Hi&lt;/code&gt; into Base64 to see the algorithm in action.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Convert to ASCII Decimal&lt;/strong&gt;: First, find the ASCII values for each character.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;H&lt;/code&gt; = 72&lt;/li&gt;
&lt;li&gt;&lt;code&gt;i&lt;/code&gt; = 105&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Convert to Binary&lt;/strong&gt;: Convert the decimal values to 8-bit binary.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;72&lt;/code&gt; = &lt;code&gt;01001000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;105&lt;/code&gt; = &lt;code&gt;01101001&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Combined binary stream: &lt;code&gt;01001000 01101001&lt;/code&gt; (16 bits)&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Split into 6-bit chunks&lt;/strong&gt;: Split the 16-bit stream into 6-bit groups.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;010010&lt;/code&gt; -&amp;gt; Decimal 18&lt;/li&gt;
&lt;li&gt;&lt;code&gt;000110&lt;/code&gt; -&amp;gt; Decimal 6&lt;/li&gt;
&lt;li&gt;&lt;code&gt;1001&lt;/code&gt; -&amp;gt; We only have 4 bits. We need to pad with two zeros to make a 6-bit chunk.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;100100&lt;/code&gt; -&amp;gt; Decimal 36&lt;/li&gt;
&lt;li&gt;We had 16 bits, which is not divisible by 6. We will need to handle padding later.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Map to Base64 Table&lt;/strong&gt;: Convert each 6-bit number using the Base64 index table.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;18 -&amp;gt; &lt;code&gt;S&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;6 -&amp;gt; &lt;code&gt;G&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;36 -&amp;gt; &lt;code&gt;k&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Apply Padding&lt;/strong&gt;: The original data was 2 bytes (16 bits). We ended up with three 6-bit chunks (18 bits), but the last one was padded. Since we had 2 bytes, which is &lt;code&gt;2 mod 3&lt;/code&gt;, we add one &lt;code&gt;=&lt;/code&gt; padding character.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;So, &lt;code&gt;Hi&lt;/code&gt; in Base64 is &lt;code&gt;SGk=&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Command-Line&lt;/h3&gt;
&lt;p&gt;In practice, we use CLI tools instead of manual conversion. On Linux, macOS, or WSL, you can decode Base64 like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ echo &quot;SGk=&quot; | base64 --decode
Hi
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Challenge&lt;/h2&gt;
&lt;p&gt;The content of the file is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-----BEGIN CERTIFICATE REQUEST-----
MIICpzCCAY8CAQAwPDEmMCQGA1UEAwwdcGljb0NURntyZWFkX215Y2VydF8zYWE4
MDA5MH0xEjAQBgNVBCkMCWN0ZlBsYXllcjCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAN1PdpW4sKum7AhFubDl86sflki20dWKkZ/iZBYYX/RYqZIWm9ve
pdfwkeiDdz7KriPzM9tTDuJm1kWv8/3AxHrYwliFHK0lsmUYdOcPfrvlh6SIuZwH
vxhrR0DJ0+W5vU+4j9G/hk2+JLMURh8WZadwBhRcfIxk97OXujjvHS9KplMAs5ul
cSSQcv77QkIcxVg1OSDVZoEjTr131g+/Jox3T+uFPEvzF9iq03JMU39oqfGaFL02
EQTaTl8efLIDkGxrKCc+Jhn4e1mD+9UlUmIn9nsOBCYNrnfq4usAL10ZPMDty2Sx
yVTl0171trvCA9DF5PRG6eMYirJOmF18oSUCAwEAAaAmMCQGCSqGSIb3DQEJDjEX
MBUwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAMa7s/l3
mAwJi7LsosPS6/VlZwfTdiJAv+WOKN9T1q2JRHsAGRrW9Gz5p7nSBKJxevRaOMwn
XWK0HqmN3y2/lor50jWzqLhM4TnbKsakXnEIo90XgHoy+n0DL0296Lg/xoXrRgrh
2o3rtZTc+irqUzTRM7Q1F76LNmgtEXqvbOm6Gx2dASPhVAAfylRBCTyz2dYwg2vM
kwt4e5bTvpze/xyTyI8Pydq09YYJe0+a2cHSgcoyGoWXjIK4CUxjBNXAFxSPCcS3
5JRkBnyGo+KL+XtuK9yCX7xBFkwLybK7Mj4TeGiwDsR/0SwqyWGb7Q2m58ay8RVm
pmAIEs21M3236Z4=
-----END CERTIFICATE REQUEST-----
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can immediately notice the &lt;code&gt;=&lt;/code&gt; padding at the end, which confirms that the content is &lt;code&gt;Base64-encoded&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To decode or inspect the certificate request, we can either use the command line or an online tool like CyberChef.&lt;/p&gt;
&lt;h3&gt;Using the command line:&lt;/h3&gt;
&lt;p&gt;OpenSSL can parse and display CSR details:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ openssl req -in readmycert.csr -noout -text
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will show fields such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Subject (CN, OU, etc.)&lt;/li&gt;
&lt;li&gt;Public key information&lt;/li&gt;
&lt;li&gt;Signature algorithm&lt;/li&gt;
&lt;li&gt;CSR attributes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The output includes the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: CN=picoCTF{read_mycert_3aa80090}, name=ctfPlayer
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:dd:4f:76:95:b8:b0:ab:a6:ec:08:45:b9:b0:e5:
                    f3:ab:1f:96:48:b6:d1:d5:8a:91:9f:e2:64:16:18:
                    5f:f4:58:a9:92:16:9b:db:de:a5:d7:f0:91:e8:83:
                    77:3e:ca:ae:23:f3:33:db:53:0e:e2:66:d6:45:af:
                    f3:fd:c0:c4:7a:d8:c2:58:85:1c:ad:25:b2:65:18:
                    74:e7:0f:7e:bb:e5:87:a4:88:b9:9c:07:bf:18:6b:
                    47:40:c9:d3:e5:b9:bd:4f:b8:8f:d1:bf:86:4d:be:
                    24:b3:14:46:1f:16:65:a7:70:06:14:5c:7c:8c:64:
                    f7:b3:97:ba:38:ef:1d:2f:4a:a6:53:00:b3:9b:a5:
                    71:24:90:72:fe:fb:42:42:1c:c5:58:35:39:20:d5:
                    66:81:23:4e:bd:77:d6:0f:bf:26:8c:77:4f:eb:85:
                    3c:4b:f3:17:d8:aa:d3:72:4c:53:7f:68:a9:f1:9a:
                    14:bd:36:11:04:da:4e:5f:1e:7c:b2:03:90:6c:6b:
                    28:27:3e:26:19:f8:7b:59:83:fb:d5:25:52:62:27:
                    f6:7b:0e:04:26:0d:ae:77:ea:e2:eb:00:2f:5d:19:
                    3c:c0:ed:cb:64:b1:c9:54:e5:d3:5e:f5:b6:bb:c2:
                    03:d0:c5:e4:f4:46:e9:e3:18:8a:b2:4e:98:5d:7c:
                    a1:25
                Exponent: 65537 (0x10001)
        Attributes:
            Requested Extensions:
                X509v3 Extended Key Usage:
                    TLS Web Client Authentication
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        c6:bb:b3:f9:77:98:0c:09:8b:b2:ec:a2:c3:d2:eb:f5:65:67:
        07:d3:76:22:40:bf:e5:8e:28:df:53:d6:ad:89:44:7b:00:19:
        1a:d6:f4:6c:f9:a7:b9:d2:04:a2:71:7a:f4:5a:38:cc:27:5d:
        62:b4:1e:a9:8d:df:2d:bf:96:8a:f9:d2:35:b3:a8:b8:4c:e1:
        39:db:2a:c6:a4:5e:71:08:a3:dd:17:80:7a:32:fa:7d:03:2f:
        4d:bd:e8:b8:3f:c6:85:eb:46:0a:e1:da:8d:eb:b5:94:dc:fa:
        2a:ea:53:34:d1:33:b4:35:17:be:8b:36:68:2d:11:7a:af:6c:
        e9:ba:1b:1d:9d:01:23:e1:54:00:1f:ca:54:41:09:3c:b3:d9:
        d6:30:83:6b:cc:93:0b:78:7b:96:d3:be:9c:de:ff:1c:93:c8:
        8f:0f:c9:da:b4:f5:86:09:7b:4f:9a:d9:c1:d2:81:ca:32:1a:
        85:97:8c:82:b8:09:4c:63:04:d5:c0:17:14:8f:09:c4:b7:e4:
        94:64:06:7c:86:a3:e2:8b:f9:7b:6e:2b:dc:82:5f:bc:41:16:
        4c:0b:c9:b2:bb:32:3e:13:78:68:b0:0e:c4:7f:d1:2c:2a:c9:
        61:9b:ed:0d:a6:e7:c6:b2:f1:15:66:a6:60:08:12:cd:b5:33:
        7d:b7:e9:9e
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As we can see, the flag is embedded directly inside the Subject CN field:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CN=picoCTF{read_mycert_3aa80090}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Using CyberChef&lt;/h3&gt;
&lt;p&gt;If using CyberChef, the PEM headers must first be removed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-----BEGIN CERTIFICATE REQUEST-----
-----END CERTIFICATE REQUEST-----
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once removed, apply the “From Base64” operation to decode the CSR data and inspect the ASN.1 structure. CyberChef will then display the embedded fields, including the flag.&lt;/p&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 Flag &lt;strong&gt;pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;flag&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
This challenge demonstrates:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How &lt;strong&gt;PEM files&lt;/strong&gt; store cryptographic information in Base64 format.&lt;/li&gt;
&lt;li&gt;How to decode and inspect CSR files using OpenSSL or CyberChef.&lt;/li&gt;
&lt;li&gt;How flags can be hidden in metadata fields like the Subject CN
:::&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>🔐 PicoGym - Vigenere</title><link>https://0xkakashi.com/posts/picogym/cryptography/vigenere/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/vigenere/</guid><description>Can you decrypt this message? Decrypt this message using this key &quot;CYLAB&quot;.</description><pubDate>Fri, 14 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/Vigenere/cipher.txt&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; Can you decrypt this message? Decrypt this message using this key &quot;&lt;code&gt;CYLAB&lt;/code&gt;&quot;..&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Mubarak Mikail&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge is about &lt;code&gt;Vigenère cipher&lt;/code&gt;, a classic polyalphabetic substitution cipher.&lt;/p&gt;
&lt;p&gt;It can be solved either manually (tabula recta) or automatically using an online tool like &lt;a href=&quot;https://cryptii.com/pipes/vigenere-cipher&quot;&gt;Vignere cipher&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The approach is quite similar to the one used in &lt;a href=&quot;https://0xkakashiofficial.netlify.app/posts/picogym/cryptography/easy1/&quot;&gt;Easy1&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Analysis&lt;/h3&gt;
&lt;p&gt;We are given a file &lt;code&gt;cipher.txt&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file cipher.txt
cipher.txt: ASCII text
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its contents are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rgnoDVD{O0NU_WQ3_G1G3O3T3_A1AH3S_2951c89f}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At first glance, the text inside the braces looks like a flag, but the prefix &lt;code&gt;rgnoDVD&lt;/code&gt; doesn’t match the standard &lt;code&gt;picoCTF{}&lt;/code&gt; format.
This suggests that the flag string has been encrypted using the Vigenère cipher with the provided key &quot;&lt;code&gt;CYLAB&lt;/code&gt;&quot;.&lt;/p&gt;
&lt;p&gt;It’s important to note that only alphabetic characters are affected by the cipher, symbols, digits, and underscores remain unchanged.&lt;/p&gt;
&lt;h2&gt;Decryption Steps&lt;/h2&gt;
&lt;p&gt;Since the key and ciphertext lengths differ, the key must be repeated to align with the entire text.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Key:      CYLABCYLABCYLABCYLABCYLABCYLABCYLABCYLABCY
Cipher:   rgnoDVD{O0NU_WQ3_G1G3O3T3_A1AH3S_2951c89f}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We then decrypt only the alphabetic characters using the Vigenère decryption formula, leaving all non-letter characters as they are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;plaintext_letter = (ciphertext_index - key_index) mod 26
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Steps to Solve&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Align ciphertext and key.&lt;/li&gt;
&lt;li&gt;Convert each letter to its alphabet index (A=0 to Z=25).&lt;/li&gt;
&lt;li&gt;Subtract the key index from the ciphertext index (mod 26).&lt;/li&gt;
&lt;li&gt;Convert the result back to letters.&lt;/li&gt;
&lt;li&gt;Combine all results to get the plaintext message.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Alternatively, we can simplify the process by using an online &lt;a href=&quot;https://cryptii.com/pipes/vigenere-cipher&quot;&gt;Vigenère Cipher Decoder&lt;/a&gt;, which follows the same &lt;code&gt;tabula recta&lt;/code&gt; decryption method.&lt;/p&gt;
&lt;p&gt;The decrypted flag is &lt;s&gt;&lt;code&gt;picoCTF{D0NT_US3_V1G3N3R3_C1PH3R_2951a89h}&lt;/code&gt;&lt;/s&gt;.&lt;/p&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-1.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
The &lt;strong&gt;Vigenère cipher&lt;/strong&gt; encrypts letters by shifting them according to a repeating keyword.&lt;/p&gt;
&lt;p&gt;Non-alphabetic characters (like {}, _, and digits) remain untouched.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - basic-mod1</title><link>https://0xkakashi.com/posts/picogym/cryptography/basic-mod1/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/basic-mod1/</guid><description>We found this weird message being passed around on the servers, we think we have a working decryption scheme. Download the message here. Take each number mod 37 and map it to the following character set: 0-25 is the alphabet (uppercase), 26-35 are the decimal digits, and 36 is an underscore. Wrap your decrypted message in the picoCTF flag format (i.e. picoCTF{decrypted_message})</description><pubDate>Fri, 14 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/basic-mod1/message.txt&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; We found this weird message being passed around on the servers, we think we have a working decryption scheme. Download the message here. Take each number &lt;code&gt;mod 37&lt;/code&gt; and map it to the following character set: &lt;code&gt;0-25 is the alphabet (uppercase)&lt;/code&gt;, &lt;code&gt;26-35 are the decimal digits&lt;/code&gt;, and &lt;code&gt;36 is an underscore&lt;/code&gt;. Wrap your decrypted message in the picoCTF flag format (i.e. &lt;code&gt;picoCTF{decrypted_message}&lt;/code&gt;)&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Will Hong&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge introduces the concept of &lt;code&gt;modulo (mod)&lt;/code&gt; arithmetic, a fundamental concept in cryptography.&lt;/p&gt;
&lt;p&gt;It can be solved either manually or using a simple Python script.&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;So we got a file &lt;code&gt;messgae.txt&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file message.txt 
message.txt: ASCII text, with no line terminators
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its content is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;350 63 353 198 114 369 346 184 202 322 94 235 114 110 185 188 225 212 366 374 261 213 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;What is modulo?&lt;/h2&gt;
&lt;p&gt;Modulo is a mathematical operation that finds the remainder when one number is divided by another. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10 mod 3 = 1  (because 10 ÷ 3 = 3 remainder 1)
350 mod 37 = 17
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In cryptography, modulo is often used to wrap numbers into a fixed range, such as mapping numbers to letters or digits.&lt;/p&gt;
&lt;h2&gt;Challenge&lt;/h2&gt;
&lt;p&gt;According to the challenge instructions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Take each number mod 37&lt;/li&gt;
&lt;li&gt;Map the result to a character using this mapping:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0–25 → A–Z&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;26–35 → 0–9&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;36 → _&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;Combine the decoded characters.&lt;/li&gt;
&lt;li&gt;Wrap the result in the format: &lt;code&gt;picoCTF{decrypted_message}&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Decryption&lt;/h2&gt;
&lt;p&gt;We calculate each number modulo 37 and map it to the corresponding character:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Number&lt;/th&gt;
&lt;th&gt;Calculation&lt;/th&gt;
&lt;th&gt;mod 37&lt;/th&gt;
&lt;th&gt;Character&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;350&lt;/td&gt;
&lt;td&gt;350 − (37×9 = 333)&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;R&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;63&lt;/td&gt;
&lt;td&gt;63 − (37×1 = 37)&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;353&lt;/td&gt;
&lt;td&gt;353 − (37×9 = 333)&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;U&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;198&lt;/td&gt;
&lt;td&gt;198 − (37×5 = 185)&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;114&lt;/td&gt;
&lt;td&gt;114 − (37×3 = 111)&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;369&lt;/td&gt;
&lt;td&gt;369 − (37×9 = 333)&lt;/td&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;_&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;346&lt;/td&gt;
&lt;td&gt;346 − (37×9 = 333)&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;184&lt;/td&gt;
&lt;td&gt;184 − (37×4 = 148)&lt;/td&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;_&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;202&lt;/td&gt;
&lt;td&gt;202 − (37×5 = 185)&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;R&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;322&lt;/td&gt;
&lt;td&gt;322 − (37×8 = 296)&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;94&lt;/td&gt;
&lt;td&gt;94 − (37×2 = 74)&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;U&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;235&lt;/td&gt;
&lt;td&gt;235 − (37×6 = 222)&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;114&lt;/td&gt;
&lt;td&gt;114 − (37×3 = 111)&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;110&lt;/td&gt;
&lt;td&gt;110 − (37×2 = 74)&lt;/td&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;_&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;185&lt;/td&gt;
&lt;td&gt;185 − (37×5 = 185)&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;188&lt;/td&gt;
&lt;td&gt;188 − (37×5 = 185)&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;225&lt;/td&gt;
&lt;td&gt;225 − (37×6 = 222)&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;212&lt;/td&gt;
&lt;td&gt;212 − (37×5 = 185)&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;366&lt;/td&gt;
&lt;td&gt;366 − (37×9 = 333)&lt;/td&gt;
&lt;td&gt;33&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;374&lt;/td&gt;
&lt;td&gt;374 − (37×10 = 370)&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;261&lt;/td&gt;
&lt;td&gt;261 − (37×7 = 259)&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;213&lt;/td&gt;
&lt;td&gt;213 − (37×5 = 185)&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Decrypted Message&lt;/h2&gt;
&lt;p&gt;Putting it together:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;R0UND_N_R0UND_ADD17EC2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar can be done with Python:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;numbers = [350, 63, 353, 198, 114, 369, 346, 184, 202, 322, 94, 235, 114, 110, 185, 188, 225, 212, 366, 374, 261, 213]

def decode(n):
    r = n % 37
    if 0 &amp;lt;= r &amp;lt;= 25:
        return chr(ord(&apos;A&apos;) + r)
    elif 26 &amp;lt;= r &amp;lt;= 35:
        return chr(ord(&apos;0&apos;) + (r - 26))
    else:
        return &quot;_&quot;

flag = &quot;&quot;.join(decode(n) for n in numbers)
print(&quot;picoCTF{&quot; + flag + &quot;}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;p&gt;Wrapped in picoCTF flag format:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;picoCTF{R0UND_N_R0UND_ADD17EC2}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
This challenge demonstrates how the &lt;code&gt;modulo&lt;/code&gt; operation can be used in cryptography to map numbers to a fixed set of symbols, such as letters, digits, or special characters.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - Flags</title><link>https://0xkakashi.com/posts/picogym/cryptography/flags/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/flags/</guid><description>What do the flags mean?</description><pubDate>Thu, 13 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/Flags/flag.png&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; What do the flags mean?&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Danny&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge focuses on decoding a message hidden using &lt;strong&gt;Maritime Signal Flags&lt;/strong&gt;, a visual communication method used by ships.&lt;br /&gt;
The challenge provides an image file named &lt;code&gt;flag.png&lt;/code&gt;, which displays a sequence of maritime flags.&lt;/p&gt;
&lt;p&gt;Decoding can be done manually using the reference chart or automatically through online tools like &lt;a href=&quot;https://www.dcode.fr/maritime-signals-code&quot;&gt;Maritime Signals decoder&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;We are given a PNG file, and upon opening it, we can see a series of flags resembling country or signal flags:&lt;br /&gt;
&lt;img src=&quot;image-6.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;However, I noticed that the flag format &lt;strong&gt;PICOCTF{...}&lt;/strong&gt; is preserved, the curly braces remain intact.&lt;/p&gt;
&lt;p&gt;This suggests that the encoding technique only affects &lt;strong&gt;letters and numbers&lt;/strong&gt;, leaving symbols like &lt;code&gt;{&lt;/code&gt; and &lt;code&gt;}&lt;/code&gt; unchanged.&lt;/p&gt;
&lt;p&gt;A quick search suggests that this is likely using the &lt;a href=&quot;https://en.wikipedia.org/wiki/International_maritime_signal_flags&quot;&gt;Navy Signals Cipher&lt;/a&gt;, a system that maps letters and digits to specific maritime flags.&lt;/p&gt;
&lt;h3&gt;What Are Nautical Signal Flags?&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;International Code of Maritime Signals (ICS)&lt;/strong&gt; is a &lt;strong&gt;visual communication system&lt;/strong&gt; used in maritime navigation to transmit messages between ships or between a ship and the shore.&lt;br /&gt;
It uses a set of distinct flags (also called &lt;em&gt;pennants&lt;/em&gt; or &lt;em&gt;semaphores&lt;/em&gt;), and each flag represents a &lt;strong&gt;specific letter or number&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;How Does the Navy Signals Cipher Work?&lt;/h3&gt;
&lt;p&gt;The International Maritime Signal Code can also be used as a &lt;strong&gt;monoalphabetic substitution cipher&lt;/strong&gt;,&lt;br /&gt;
each nautical flag stands for a letter (A–Z) or a number (0–9).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-1.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br /&gt;
&lt;img src=&quot;image.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Number Flags&lt;/h3&gt;
&lt;p&gt;Digits have distinct flag designs and correspond to lowercase ASCII characters:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-2.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;How to Decrypt Maritime Signal Flags&lt;/h3&gt;
&lt;p&gt;Decryption is straightforward, substitute each flag with its corresponding letter or digit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br /&gt;
&lt;img src=&quot;image-4.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Recognizing Maritime Flag Ciphertext&lt;/h3&gt;
&lt;p&gt;Ciphertext made with this method typically contains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Square flags in &lt;strong&gt;blue&lt;/strong&gt;, &lt;strong&gt;white&lt;/strong&gt;, &lt;strong&gt;yellow&lt;/strong&gt;, &lt;strong&gt;red&lt;/strong&gt;, or &lt;strong&gt;black&lt;/strong&gt; (no green or mixed colors).&lt;/li&gt;
&lt;li&gt;Patterns or themes related to &lt;strong&gt;ships&lt;/strong&gt;, &lt;strong&gt;navy&lt;/strong&gt;, or &lt;strong&gt;seafaring&lt;/strong&gt; clues (like lighthouses or distress signals).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These visual hints indicate that the challenge likely involves &lt;strong&gt;Nautical Signal Flags&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Why Use Maritime Signal Flags?&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;International Maritime Signal Flags&lt;/strong&gt; system allows ships to communicate when &lt;strong&gt;radio or electronic communication is unavailable&lt;/strong&gt;.&lt;br /&gt;
It’s used for transmitting &lt;strong&gt;navigation instructions&lt;/strong&gt;, &lt;strong&gt;warnings&lt;/strong&gt;, and &lt;strong&gt;emergency messages&lt;/strong&gt;, forming a critical part of naval operations.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;To decode the message, I substituted each maritime flag in the PNG file with its corresponding letter or digit.&lt;br /&gt;
I used the &lt;a href=&quot;https://www.dcode.fr/maritime-signals-code&quot;&gt;Maritime Signals decoder&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-7.png&quot; alt=&quot;Decoded flag sequence&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The decoded flag is &lt;code&gt;PICOCTFF1AG5AND5TUFF&lt;/code&gt;.&lt;br /&gt;
Since the curly braces &lt;code&gt;{}&lt;/code&gt; were not part of the encryption, I added them back to match the flag format:&lt;/p&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt; The Navy Signals Cipher has been successfully decoded.
:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PICOCTF{F1AG5AND5TUFF}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
The International Maritime Signal Flags system was primarily a visual communication tool for ships, not a cryptographic system. Its main purpose was safe, reliable signaling over distances when radio or other means weren’t available.&lt;/p&gt;
&lt;p&gt;This system was originally used by ships to communicate visually over distances. However, this type of communication is no longer used for security purposes, as it is easily breakable.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - Easy1</title><link>https://0xkakashi.com/posts/picogym/cryptography/easy1/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/easy1/</guid><description>The one time pad can be cryptographically secure, but not when you know the key. Can you solve this? We&apos;ve given you the encrypted flag, key, and a table to help UFJKXQZQUNB with the key of SOLVECRYPTO. Can you use this table to solve it?.</description><pubDate>Thu, 13 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/Easy1/table.txt&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; The one time pad can be cryptographically secure, but not when you know the key. Can you solve this? We&apos;ve given you the encrypted flag, key, and a table to help &lt;code&gt;UFJKXQZQUNB&lt;/code&gt; with the key of &lt;code&gt;SOLVECRYPTO&lt;/code&gt;. Can you use this table to solve it?.&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Alex Fulton/Danny&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge introduces the concept of the &lt;code&gt;Vigenère cipher&lt;/code&gt;, a classic polyalphabetic substitution cipher.&lt;/p&gt;
&lt;p&gt;It can be solved either manually using the provided &lt;code&gt;table.txt&lt;/code&gt; (tabula recta) or automatically using an online tool like &lt;a href=&quot;https://cryptii.com/pipes/vigenere-cipher&quot;&gt;Vignere cipher&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Analysis&lt;/h3&gt;
&lt;p&gt;We are given a file &lt;code&gt;table.txt&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file table.txt
table.txt: ASCII text
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its contents are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 
   +----------------------------------------------------
A | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
B | B C D E F G H I J K L M N O P Q R S T U V W X Y Z A
C | C D E F G H I J K L M N O P Q R S T U V W X Y Z A B
D | D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
E | E F G H I J K L M N O P Q R S T U V W X Y Z A B C D
F | F G H I J K L M N O P Q R S T U V W X Y Z A B C D E
G | G H I J K L M N O P Q R S T U V W X Y Z A B C D E F
H | H I J K L M N O P Q R S T U V W X Y Z A B C D E F G
I | I J K L M N O P Q R S T U V W X Y Z A B C D E F G H
J | J K L M N O P Q R S T U V W X Y Z A B C D E F G H I
K | K L M N O P Q R S T U V W X Y Z A B C D E F G H I J
L | L M N O P Q R S T U V W X Y Z A B C D E F G H I J K
M | M N O P Q R S T U V W X Y Z A B C D E F G H I J K L
N | N O P Q R S T U V W X Y Z A B C D E F G H I J K L M
O | O P Q R S T U V W X Y Z A B C D E F G H I J K L M N
P | P Q R S T U V W X Y Z A B C D E F G H I J K L M N O
Q | Q R S T U V W X Y Z A B C D E F G H I J K L M N O P
R | R S T U V W X Y Z A B C D E F G H I J K L M N O P Q
S | S T U V W X Y Z A B C D E F G H I J K L M N O P Q R
T | T U V W X Y Z A B C D E F G H I J K L M N O P Q R S
U | U V W X Y Z A B C D E F G H I J K L M N O P Q R S T
V | V W X Y Z A B C D E F G H I J K L M N O P Q R S T U
W | W X Y Z A B C D E F G H I J K L M N O P Q R S T U V
X | X Y Z A B C D E F G H I J K L M N O P Q R S T U V W
Y | Y Z A B C D E F G H I J K L M N O P Q R S T U V W X
Z | Z A B C D E F G H I J K L M N O P Q R S T U V W X Y

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This table is known as the &lt;code&gt;tabula recta&lt;/code&gt;, which is the foundation of the &lt;strong&gt;Vigenère cipher&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;What is the Vigenère Cipher?&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher&quot;&gt;Vigenère cipher&lt;/a&gt; is a method of encrypting text using a series of Caesar ciphers with different shift values determined by a repeating keyword.&lt;/p&gt;
&lt;p&gt;It’s considered a polyalphabetic substitution cipher because it uses multiple substitution alphabets, making it stronger than a simple Caesar cipher.&lt;/p&gt;
&lt;h2&gt;Decryption&lt;/h2&gt;
&lt;p&gt;The provided ciphertext and key are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ciphertext: &lt;code&gt;UFJKXQZQUNB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Key:        &lt;code&gt;SOLVECRYPTO&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since the key length (11) matches the ciphertext length, each ciphertext letter corresponds directly to one key letter.
The decryption formula is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;plaintext_letter = (ciphertext_letter_index - key_letter_index) mod 26
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Example (first character):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cipher &lt;code&gt;U&lt;/code&gt; = 20 (A=0)&lt;/li&gt;
&lt;li&gt;Key &lt;code&gt;S&lt;/code&gt; = 18&lt;/li&gt;
&lt;li&gt;Plain = (20 - 18) mod 26 = 2 → &lt;code&gt;C&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Steps to Solve&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Align ciphertext and key.&lt;/li&gt;
&lt;li&gt;Convert each letter to its alphabet index (A=0 to Z=25).&lt;/li&gt;
&lt;li&gt;Subtract the key index from the ciphertext index (mod 26).&lt;/li&gt;
&lt;li&gt;Convert the result back to letters.&lt;/li&gt;
&lt;li&gt;Combine all results to get the plaintext message.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Alternatively, we can simplify the process by using an online &lt;a href=&quot;https://cryptii.com/pipes/vigenere-cipher&quot;&gt;Vigenère Cipher Decoder&lt;/a&gt;, which follows the same tabula recta decryption method.&lt;/p&gt;
&lt;p&gt;The decrypted message is &lt;code&gt;CRYPTOISFUN&lt;/code&gt;. Flag:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;picoCTF{CRYPTOISFUN}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt;
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
The &lt;code&gt;Vigenère cipher&lt;/code&gt; is a form of polyalphabetic substitution cipher that uses a repeating keyword to shift letters in the plaintext.&lt;/p&gt;
&lt;p&gt;Unlike a simple Caesar cipher that uses one shift value, Vigenère applies multiple shifts based on the keyword, making it more secure, but still vulnerable to frequency and key-reuse analysis.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - rotation</title><link>https://0xkakashi.com/posts/picogym/cryptography/rotation/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/rotation/</guid><description>You will find the flag after decrypting this file. Download the encrypted flag here.</description><pubDate>Thu, 13 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/rotation/encrypted.txt&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; You will find the flag after decrypting this file. Download the encrypted flag here.&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Loic Shema&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge uses the concept of a &lt;strong&gt;Caesar Cipher&lt;/strong&gt;.&lt;br /&gt;
You are provided with an encoded message file named &lt;code&gt;encrypted.txt&lt;/code&gt; and must decrypt it to recover the flag.&lt;/p&gt;
&lt;p&gt;Decoding can be done manually by trying different shift keys or automatically using tools like &lt;a href=&quot;https://cryptii.com/pipes/caesar-cipher&quot;&gt;Caesar Cipher&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;The file &lt;code&gt;encrypted.txt&lt;/code&gt; contains ASCII text:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file encrypted.txt
encrypted.txt: ASCII text
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So its contents look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;xqkwKBN{z0bib1wv_l3kzgxb3l_555957n3}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Based on the format, this appears to be a rotation/shift cipher (like a &lt;code&gt;Caesar cipher&lt;/code&gt;), because the beginning of the string &lt;code&gt;xqkwKBN{&lt;/code&gt; matches the flag format &lt;code&gt;picoCTF{&lt;/code&gt; after applying a shift.&lt;/p&gt;
&lt;p&gt;I brute-forced the shift keys to find the correct one using the tool &lt;a href=&quot;https://cryptii.com/pipes/caesar-cipher&quot;&gt;Caesar Cipher&lt;/a&gt;. The correct key is &lt;strong&gt;+8&lt;/strong&gt;, which gvies the decrypted flag:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;picoCTF{r0tat1on_d3crypt3d_555957f3}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 &lt;strong&gt;Flag pwned!&lt;/strong&gt; The Caesar Cipher has been successfully decrypted.
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
The Caesar Cipher works by shifting letters by a fixed number of positions in the alphabet.&lt;br /&gt;
By identifying the correct shift key, we can reverse the encryption and recover the hidden flag.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - Substitution0</title><link>https://0xkakashi.com/posts/picogym/cryptography/substitution0/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/substitution0/</guid><description>A message has come in but it seems to be all scrambled. Luckily it seems to have the key at the beginning. Can you crack this substitution cipher?</description><pubDate>Thu, 13 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/substitution0/message.txt&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; A message has come in but it seems to be all scrambled. Luckily it seems to have the key at the beginning. Can you crack this substitution cipher?&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Will Hongandu&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge introduces the concept of a &lt;strong&gt;Substitution Cipher&lt;/strong&gt;.&lt;br /&gt;
You’re given an encoded message file named &lt;code&gt;message.txt&lt;/code&gt; and need to decrypt it to reveal the flag.&lt;/p&gt;
&lt;p&gt;You can solve it using online tools like &lt;a href=&quot;https://cryptii.com/pipes/alphabetical-substitution&quot;&gt;Cryptii Substitution Decoder&lt;/a&gt; or by manually analyzing letter frequencies and patterns.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Analysis&lt;/h3&gt;
&lt;h2&gt;What is a (Monoalphabetic) Substitution Cipher?&lt;/h2&gt;
&lt;p&gt;A &lt;strong&gt;monoalphabetic substitution cipher&lt;/strong&gt; replaces each letter of the alphabet with another letter according to a &lt;strong&gt;one-to-one correspondence&lt;/strong&gt;, meaning a specific plaintext letter always maps to the same ciphertext letter.&lt;/p&gt;
&lt;p&gt;It’s called &lt;em&gt;monoalphabetic&lt;/em&gt; because only &lt;strong&gt;one alphabet mapping&lt;/strong&gt; is used throughout the message. The substitution alphabet is a scrambled or reordered version of the normal alphabet.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;How Encryption Works&lt;/h3&gt;
&lt;p&gt;To encrypt, a mixed (shuffled) alphabet replaces the standard one.&lt;br /&gt;
For example:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plain Alphabet&lt;/th&gt;
&lt;th&gt;A&lt;/th&gt;
&lt;th&gt;B&lt;/th&gt;
&lt;th&gt;C&lt;/th&gt;
&lt;th&gt;D&lt;/th&gt;
&lt;th&gt;E&lt;/th&gt;
&lt;th&gt;F&lt;/th&gt;
&lt;th&gt;G&lt;/th&gt;
&lt;th&gt;H&lt;/th&gt;
&lt;th&gt;I&lt;/th&gt;
&lt;th&gt;J&lt;/th&gt;
&lt;th&gt;K&lt;/th&gt;
&lt;th&gt;L&lt;/th&gt;
&lt;th&gt;M&lt;/th&gt;
&lt;th&gt;N&lt;/th&gt;
&lt;th&gt;O&lt;/th&gt;
&lt;th&gt;P&lt;/th&gt;
&lt;th&gt;Q&lt;/th&gt;
&lt;th&gt;R&lt;/th&gt;
&lt;th&gt;S&lt;/th&gt;
&lt;th&gt;T&lt;/th&gt;
&lt;th&gt;U&lt;/th&gt;
&lt;th&gt;V&lt;/th&gt;
&lt;th&gt;W&lt;/th&gt;
&lt;th&gt;X&lt;/th&gt;
&lt;th&gt;Y&lt;/th&gt;
&lt;th&gt;Z&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Substitution Alphabet&lt;/td&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;K&lt;/td&gt;
&lt;td&gt;W&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;S&lt;/td&gt;
&lt;td&gt;L&lt;/td&gt;
&lt;td&gt;F&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;O&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Z&lt;/td&gt;
&lt;td&gt;T&lt;/td&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;H&lt;/td&gt;
&lt;td&gt;J&lt;/td&gt;
&lt;td&gt;U&lt;/td&gt;
&lt;td&gt;M&lt;/td&gt;
&lt;td&gt;I&lt;/td&gt;
&lt;td&gt;G&lt;/td&gt;
&lt;td&gt;P&lt;/td&gt;
&lt;td&gt;V&lt;/td&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;Q&lt;/td&gt;
&lt;td&gt;R&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Using this table, the plaintext &quot;TEST&quot; would encrypt to &lt;strong&gt;GAIG&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Any permutation of the alphabet can serve as a valid key, as long as no letter is repeated.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;ACA Classification (K1–K4 Systems)&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;American Cryptogram Association (ACA)&lt;/strong&gt; defines four common key-based variants of the monoalphabetic substitution cipher:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;K1&lt;/strong&gt; – The key is placed at the start of the substitution alphabet, followed by the remaining unused letters in alphabetical order.&lt;br /&gt;
Example: Key “CODE” → &lt;code&gt;CODEABFGHIJKLMNPQRSTUVWXYZ&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;K2&lt;/strong&gt; – The key is placed in the &lt;strong&gt;cipher alphabet&lt;/strong&gt; (reciprocal of K1).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;K3&lt;/strong&gt; – The same key is used for both the &lt;strong&gt;plaintext&lt;/strong&gt; and &lt;strong&gt;cipher&lt;/strong&gt; alphabets.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;K4&lt;/strong&gt; – Two different keys are used: one for the plaintext alphabet and one for the cipher alphabet.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;How Decryption Works&lt;/h3&gt;
&lt;p&gt;To decrypt, the process is simply reversed, replace each cipher letter with its corresponding plaintext letter using the inverse substitution table.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Substitution Alphabet&lt;/th&gt;
&lt;th&gt;N&lt;/th&gt;
&lt;th&gt;B&lt;/th&gt;
&lt;th&gt;A&lt;/th&gt;
&lt;th&gt;J&lt;/th&gt;
&lt;th&gt;Y&lt;/th&gt;
&lt;th&gt;F&lt;/th&gt;
&lt;th&gt;O&lt;/th&gt;
&lt;th&gt;W&lt;/th&gt;
&lt;th&gt;L&lt;/th&gt;
&lt;th&gt;Z&lt;/th&gt;
&lt;th&gt;M&lt;/th&gt;
&lt;th&gt;P&lt;/th&gt;
&lt;th&gt;X&lt;/th&gt;
&lt;th&gt;I&lt;/th&gt;
&lt;th&gt;K&lt;/th&gt;
&lt;th&gt;U&lt;/th&gt;
&lt;th&gt;V&lt;/th&gt;
&lt;th&gt;C&lt;/th&gt;
&lt;th&gt;D&lt;/th&gt;
&lt;th&gt;E&lt;/th&gt;
&lt;th&gt;G&lt;/th&gt;
&lt;th&gt;R&lt;/th&gt;
&lt;th&gt;Q&lt;/th&gt;
&lt;th&gt;S&lt;/th&gt;
&lt;th&gt;T&lt;/th&gt;
&lt;th&gt;H&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Plain Alphabet&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;F&lt;/td&gt;
&lt;td&gt;G&lt;/td&gt;
&lt;td&gt;H&lt;/td&gt;
&lt;td&gt;I&lt;/td&gt;
&lt;td&gt;J&lt;/td&gt;
&lt;td&gt;K&lt;/td&gt;
&lt;td&gt;L&lt;/td&gt;
&lt;td&gt;M&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;O&lt;/td&gt;
&lt;td&gt;P&lt;/td&gt;
&lt;td&gt;Q&lt;/td&gt;
&lt;td&gt;R&lt;/td&gt;
&lt;td&gt;S&lt;/td&gt;
&lt;td&gt;T&lt;/td&gt;
&lt;td&gt;U&lt;/td&gt;
&lt;td&gt;V&lt;/td&gt;
&lt;td&gt;W&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Z&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Example: The ciphertext &lt;strong&gt;EYDE&lt;/strong&gt; decrypts to &lt;strong&gt;TEST&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;How to Identify a Substitution Cipher&lt;/h3&gt;
&lt;p&gt;Monoalphabetic substitutions can often be recognized by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Letter frequency&lt;/strong&gt; similar to natural language (like English).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Spaces preserved&lt;/strong&gt;, called an &lt;em&gt;Aristocrat&lt;/em&gt; cipher.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No spaces&lt;/strong&gt;, called a &lt;em&gt;Patristocrat&lt;/em&gt; cipher.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These characteristics make substitution ciphers ideal for practicing classical cryptanalysis techniques such as frequency analysis and pattern recognition.&lt;/p&gt;
&lt;h2&gt;Decryption&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;message.txt&lt;/code&gt; file contains the following ciphertext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;OHNFUMWSVZLXEGCPTAJDYIRKQB 

Suauypcg Xuwaogf oacju, rvds o waoiu ogf jdoduxq ova, ogf hacywsd eu dsu huudxu
mace o wxojj noju vg rsvns vd roj ugnxcjuf. Vd roj o huoydvmyx jnoaohouyj, ogf, od
dsod dveu, yglgcrg dc godyaoxvjdj, cm ncyaju o wauod pavbu vg o jnvugdvmvn pcvgd
cm ivur. Dsuau ruau drc acygf hxonl jpcdj guoa cgu ukdauevdq cm dsu honl, ogf o
xcgw cgu guoa dsu cdsua. Dsu jnoxuj ruau uknuufvgwxq soaf ogf wxcjjq, rvds oxx dsu
oppuoaognu cm hyagvjsuf wcxf. Dsu ruvwsd cm dsu vgjund roj iuaq aueoalohxu, ogf,
dolvgw oxx dsvgwj vgdc ncgjvfuaodvcg, V ncyxf soafxq hxoeu Zypvdua mca svj cpvgvcg
aujpundvgw vd.

Dsu mxow vj: pvncNDM{5YH5717Y710G_3I0XY710G_03055505}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From the start of the file, I noticed a key hint: the first few letters indicate the substitution alphabet order. Using this &lt;code&gt;OHNFUMWSVZLXEGCPTAJDYIRKQB&lt;/code&gt;, we can reconstruct the mapping table.&lt;/p&gt;
&lt;p&gt;By applying the monoalphabetic substitution decryption (either manually or using &lt;a href=&quot;https://cryptii.com/pipes/alphabetical-substitution&quot;&gt;Cryptii Substitution Decoder&lt;/a&gt;), we get the plaintext:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;picoCTF{5UB5717U710N_3V0LU710N_03055505}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 Flag &lt;strong&gt;pwned!&lt;/strong&gt; The ciphertext has been decoded successfully.
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;pt&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
Monoalphabetic substitution ciphers replace each letter with a fixed substitute from a defined alphabet.
While simple to break with frequency analysis or known hints, they illustrate the basics of classical cryptography and the evolution toward modern, more secure encryption methods.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - 13</title><link>https://0xkakashi.com/posts/picogym/cryptography/13/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/13/</guid><description>Cryptography can be easy, do you know what ROT13 is? cvpbPGS{abg_gbb_onq_bs_n_ceboyrz}</description><pubDate>Wed, 12 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; Cryptography can be easy, do you know what ROT13 is? cvpbPGS{abg_gbb_onq_bs_n_ceboyrz}&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Alex Fulton/Daniel Tunitis&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge focuses on the &lt;strong&gt;ROT13&lt;/strong&gt; cipher, a simple substitution cipher that shifts each letter by 13 places in the alphabet.&lt;br /&gt;
The goal is to decode the ciphertext &lt;code&gt;cvpbPGS{abg_gbb_onq_bs_n_ceboyrz}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can solve it using any online ROT13 tool, such as &lt;a href=&quot;https://rot13.com/&quot;&gt;rot13.com&lt;/a&gt;, or by applying the shift manually.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;This challenge is quite similar to &lt;a href=&quot;https://0xkakashiofficial.netlify.app/posts/picogym/cryptography/mod-26/&quot;&gt;Mod 26&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;UIisng the &lt;a href=&quot;https://rot13.com/&quot;&gt;ROT13&lt;/a&gt;, we get the flag : &lt;code&gt;picoCTF{not_too_bad_of_a_problem}&lt;/code&gt;
:::note[⚡ Raikiri]
🎉 Flag &lt;strong&gt;pwned!&lt;/strong&gt; The ROT13 cipher has been successfully decoded.
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;ROT13&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
ROT13 is a Caesar cipher with a fixed shift of 13.&lt;br /&gt;
Applying it twice returns the original text, a simple yet elegant example of modular arithmetic in action.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - The Numbers</title><link>https://0xkakashi.com/posts/picogym/cryptography/the_numbers/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/the_numbers/</guid><description>The numbers... what do they mean?</description><pubDate>Wed, 12 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/The_Numbers/the_numbers.png&quot; download&amp;gt;📂 Download the challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; The numbers... what do they mean?&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Danny&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge provides an image containing a sequence of numbers.&lt;/p&gt;
&lt;p&gt;The goal is to decode the numbers inside the braces using the &lt;strong&gt;Letter-to-Number Cipher&lt;/strong&gt; to recover the flag.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;We are provided with the image &lt;code&gt;the_numbers.png&lt;/code&gt;. On this it contains this &lt;code&gt;16 9 3 15 3 20 6 {20 8 5 14 21 13 2 5 18 19 13 1 19 15 14}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;To identify the cipher method, we can use &lt;a href=&quot;https://www.dcode.fr/cipher-identifier&quot;&gt;dcode.fr&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;dcode.fr&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It suggests that the sequence uses a &lt;strong&gt;Letter-to-Number Cipher&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is Letter-to-Number Cipher?&lt;/strong&gt;
Also known as the &lt;strong&gt;Number-to-Letter Cipher&lt;/strong&gt; or &lt;strong&gt;A1Z26&lt;/strong&gt;, this cipher replaces each letter with its &lt;strong&gt;position in the alphabet&lt;/strong&gt;:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Letter&lt;/th&gt;
&lt;th&gt;A&lt;/th&gt;
&lt;th&gt;B&lt;/th&gt;
&lt;th&gt;C&lt;/th&gt;
&lt;th&gt;D&lt;/th&gt;
&lt;th&gt;E&lt;/th&gt;
&lt;th&gt;F&lt;/th&gt;
&lt;th&gt;G&lt;/th&gt;
&lt;th&gt;H&lt;/th&gt;
&lt;th&gt;I&lt;/th&gt;
&lt;th&gt;J&lt;/th&gt;
&lt;th&gt;K&lt;/th&gt;
&lt;th&gt;L&lt;/th&gt;
&lt;th&gt;M&lt;/th&gt;
&lt;th&gt;N&lt;/th&gt;
&lt;th&gt;O&lt;/th&gt;
&lt;th&gt;P&lt;/th&gt;
&lt;th&gt;Q&lt;/th&gt;
&lt;th&gt;R&lt;/th&gt;
&lt;th&gt;S&lt;/th&gt;
&lt;th&gt;T&lt;/th&gt;
&lt;th&gt;U&lt;/th&gt;
&lt;th&gt;V&lt;/th&gt;
&lt;th&gt;W&lt;/th&gt;
&lt;th&gt;X&lt;/th&gt;
&lt;th&gt;Y&lt;/th&gt;
&lt;th&gt;Z&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Number&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3&gt;How to Encrypt Using A1Z26&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Take the plaintext letter.&lt;/li&gt;
&lt;li&gt;Find its position in the alphabet.&lt;/li&gt;
&lt;li&gt;Replace the letter with its corresponding number.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For example, &quot;A&quot; becomes 1, &quot;B&quot; becomes 2, and so on up to &quot;Z&quot; = 26.&lt;br /&gt;
&lt;code&gt;Decoding&lt;/code&gt; is simply the reverse process: convert numbers back into letters to recover the original text.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Now let&apos;s decrypt our flag:&lt;/p&gt;
&lt;p&gt;Split into the part before the braces and the part inside:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Before braces: &lt;code&gt;16 9 3 15 3 20 6&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Inside braces: &lt;code&gt;20 8 5 14 21 13 2 5 18 19 13 1 19 15 14&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Convert each number using A1Z26 (A=1, B=2, …, Z=26):&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Before braces&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;16 → P&lt;/li&gt;
&lt;li&gt;9  → I&lt;/li&gt;
&lt;li&gt;3  → C&lt;/li&gt;
&lt;li&gt;15 → O&lt;/li&gt;
&lt;li&gt;3  → C&lt;/li&gt;
&lt;li&gt;20 → T&lt;/li&gt;
&lt;li&gt;6  → F&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Assembled: &lt;code&gt;P I C O C T F&lt;/code&gt; → &lt;strong&gt;PICOCTF&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Inside braces&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;20 → T&lt;/li&gt;
&lt;li&gt;8  → H&lt;/li&gt;
&lt;li&gt;5  → E&lt;/li&gt;
&lt;li&gt;14 → N&lt;/li&gt;
&lt;li&gt;21 → U&lt;/li&gt;
&lt;li&gt;13 → M&lt;/li&gt;
&lt;li&gt;2  → B&lt;/li&gt;
&lt;li&gt;5  → E&lt;/li&gt;
&lt;li&gt;18 → R&lt;/li&gt;
&lt;li&gt;19 → S&lt;/li&gt;
&lt;li&gt;13 → M&lt;/li&gt;
&lt;li&gt;1  → A&lt;/li&gt;
&lt;li&gt;19 → S&lt;/li&gt;
&lt;li&gt;15 → O&lt;/li&gt;
&lt;li&gt;14 → N&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Assembled: &lt;code&gt;T H E N U M B E R S M A S O N&lt;/code&gt; → &lt;strong&gt;THENUMBERSMASON&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Using the standard flag format, the final flag is: &lt;code&gt;PICOCTF{THENUMBERSMASON}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 Flag &lt;strong&gt;pwned!&lt;/strong&gt; The numeric ciphertext has been decoded successfully.
:::&lt;/p&gt;
&lt;p&gt;This can also be solved using online tools like &lt;a href=&quot;https://www.dcode.fr/letter-number-cipher&quot;&gt;dcode.fr&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
Number-to-Letter (A1Z26) ciphers are simple yet effective for learning about encoding.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - interencdec</title><link>https://0xkakashi.com/posts/picogym/cryptography/interencdec/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/interencdec/</guid><description>Can you get the real meaning from this file. Download the file here.</description><pubDate>Wed, 12 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/interencdec/enc_flag&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; Can you get the real meaning from this file.&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Easy&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; NGIRIMANA Schadrack&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge introduces the concept of basic text encoding and substitution ciphers.
You’re given an encoded flag file named enc_flag and need to uncover its hidden message.&lt;/p&gt;
&lt;p&gt;You can solve it using online tools like &lt;a href=&quot;https://gchq.github.io/&quot;&gt;cyberchef&lt;/a&gt; and &lt;a href=&quot;https://www.dcode.fr/cipher-identifier&quot;&gt;dcode.fr&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;First we identify the file type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file enc_flag
enc_flag: ASCII text
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s plain ASCII text, so let’s open it. The file contains:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;YidkM0JxZGtwQlRYdHFhR3g2YUhsZmF6TnFlVGwzWVROclh6ZzJhMnd6TW1zeWZRPT0nCg==
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Base64&lt;/strong&gt; is a binary-to-text encoding scheme that converts binary data into ASCII characters. It’s commonly used to encode data for safe transmission over text-based protocols. Base64 strings often end with &lt;code&gt;=&lt;/code&gt; or &lt;code&gt;==&lt;/code&gt; as padding. &lt;a href=&quot;https://en.wikipedia.org/wiki/Base64&quot;&gt;Read more about base64&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Stage 1&lt;/h2&gt;
&lt;p&gt;The trailing == suggests Base64 encoding. Let&apos;s verify this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;b64&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So we decode it. You can use base64 locally or an online tool like CyberChef. Decoding the first layer gives:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-1.png&quot; alt=&quot;b64 deocde&quot; /&gt;&lt;/p&gt;
&lt;p&gt;which is &lt;code&gt;b&apos;d3BqdkpBTXtqaGx6aHlfazNqeTl3YTNrXzg2a2wzMmsyfQ==&apos;&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Stage 2&lt;/h2&gt;
&lt;p&gt;This looks like a Python bytes literal &lt;code&gt;(b&apos;...&apos;)&lt;/code&gt;, the actual Base64 payload is the inner string:
&lt;code&gt;d3BqdkpBTXtqaGx6aHlfazNqeTl3YTNrXzg2a2wzMmsyfQ==&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Decode that second Base64 layer and we get: &lt;code&gt;wpjvJAM{jhlzhy_k3jy9wa3k_86kl32k2}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-2.png&quot; alt=&quot;second b64&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Stage 3&lt;/h2&gt;
&lt;p&gt;Now this looks familier the challenge &lt;a href=&quot;https://0xkakashiofficial.netlify.app/posts/picogym/cryptography/mod-26/&quot;&gt;mod 26&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To recover the flag, I performed a simple Caesar shift (mod 26) brute force over all 26 shifts. The correct shift was &lt;code&gt;19&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 Flag &lt;strong&gt;pwned!&lt;/strong&gt; The ciphertext has been decoded successfully.
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-3.png&quot; alt=&quot;pwned&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
Double Base64 → ROT cipher → Flag recovered.&lt;br /&gt;
Always check for multiple layers of encoding, even in simple CTF files.&lt;br /&gt;
Don’t rely on simple encodings for real-world security!
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - Caesar</title><link>https://0xkakashi.com/posts/picogym/cryptography/caesar/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/caesar/</guid><description>Decrypt this message.</description><pubDate>Wed, 12 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;a href=&quot;/files/PicoGym/Cryptography/Caesar/data.enc&quot; download&amp;gt;📂 Download challenge file.&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; Decrypt this message.&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Medium&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; NSanjay C/Daniel Tunitis&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge introduces the concept of &lt;code&gt;Caesar cipher&lt;/code&gt;.
You’re given an encoded flag file named &lt;code&gt;data.enc&lt;/code&gt; and need to decrypt it to reveal the hidden flag.&lt;/p&gt;
&lt;p&gt;You can solve it using online tools like &lt;a href=&quot;https://cryptii.com/pipes/caesar-cipher&quot;&gt;Caesar cipher decoder&lt;/a&gt; or by manually testing shifts.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;First we identify the file type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file data.enc
data.enc: ASCII text
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s plain ASCII text, so let’s open it. The file contains:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;picoCTF{hwtxxnslymjwzgnhtswlvhsgdv}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The flag clearly starts with the known prefix picoCTF{}, but the inner text &lt;code&gt;hwtxxnslymjwzgnhtswlvhsgdv&lt;/code&gt; is encrypted.&lt;/p&gt;
&lt;p&gt;This strongly suggests the &lt;strong&gt;Caesar cipher&lt;/strong&gt;, a classic encryption method where each letter in the plaintext is shifted by a fixed number of positions in the alphabet.&lt;/p&gt;
&lt;h2&gt;What Is the Caesar Cipher?&lt;/h2&gt;
&lt;p&gt;The Caesar cipher is one of the oldest and simplest encryption techniques.
It works by shifting each letter of the alphabet by a fixed number (called the key or offset).&lt;/p&gt;
&lt;p&gt;For example, with a shift of 3:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A → D&lt;/li&gt;
&lt;li&gt;B → E&lt;/li&gt;
&lt;li&gt;C → F&lt;/li&gt;
&lt;li&gt;... and so on.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Decryption simply reverses this process by shifting in the opposite direction.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Now, let’s decode the ciphertext.
Using a &lt;a href=&quot;https://cryptii.com/pipes/caesar-cipher&quot;&gt;Caesar cipher decoder&lt;/a&gt;, I tried different shifts (0–25) until I found the one that gives readable text.&lt;/p&gt;
&lt;p&gt;After testing a few offsets, we find that a shift of &lt;code&gt;5&lt;/code&gt; correctly decrypts the message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;picoCTF{crossingtherubiconrgqcnbyq}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 Flag &lt;strong&gt;pwned!&lt;/strong&gt; The ciphertext has been decoded successfully.
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;caesar&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
The Caesar cipher works by shifting letters by a fixed offset, a foundational concept in classical cryptography.&lt;br /&gt;
It’s &lt;strong&gt;no longer used in modern security&lt;/strong&gt; because it can be easily decoded, though it was once used in early military communications.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - Mod 26</title><link>https://0xkakashi.com/posts/picogym/cryptography/mod-26/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/mod-26/</guid><description>Cryptography can be easy, do you know what ROT13 is cvpbPGS{arkg_gvzr_V&apos;yy_gel_2_ebhaqf_bs_ebg13_nSkgmDJE}</description><pubDate>Tue, 11 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; &quot;Cryptography can be easy, do you know what ROT13 is &lt;code&gt;cvpbPGS{arkg_gvzr_V&apos;yy_gel_2_ebhaqf_bs_ebg13_nSkgmDJE}&lt;/code&gt;&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Easy&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Pandu&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge teaches ROT13 by asking you to decode the ciphertext &lt;code&gt;cvpbPGS{arkg_gvzr_V&apos;yy_gel_2_ebhaqf_bs_ebg13_nSkgmDJE}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can solve it using online ROT13 tools or by applying the ROT13 substitution manually.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;ROT13 is a simple substitution cipher that replaces each letter in a text with the letter 13 places after it in the alphabet. Because there are 26 letters in the Latin alphabet, applying ROT13 twice returns the original text, making it both an encryption and decryption method. For example, &quot;A&quot; becomes &quot;N&quot; and &quot;N&quot; becomes &quot;A&quot;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now how Modulo 26 is related to ROT13&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In cryptography, Mod 26 represents arithmetic done within the bounds of the 26-letter alphabet. ROT13 can be expressed mathematically as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;E(x) = (x + 13) \bmod 26
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each letter is first converted to a number (A = 0, B = 1, ..., Z = 25).&lt;/li&gt;
&lt;li&gt;Then, 13 is added to that number.&lt;/li&gt;
&lt;li&gt;The result is taken &lt;strong&gt;modulo 26&lt;/strong&gt; to ensure it wraps back around the alphabet once it passes â€œZ.â€&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This modular operation guarantees the cyclic behavior of the cipher â€” after â€œZ,â€ it starts again at â€œA.â€&lt;br /&gt;
In other words, &lt;strong&gt;ROT13 is simply a Caesar cipher with a fixed shift of 13, powered by Mod 26 arithmetic.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;Decoding ROT13&lt;/h2&gt;
&lt;p&gt;Applying ROT13 transforms each letter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;c â†’ p&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;v â†’ i&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;p â†’ c&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;b â†’ o&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;P â†’ C&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;G â†’ T&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;S â†’ F&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;â€¦and so on, until the full flag is revealed.&lt;/p&gt;
&lt;h2&gt;Tools for ROT13&lt;/h2&gt;
&lt;p&gt;You can decode ROT13 either &lt;strong&gt;manually&lt;/strong&gt; or with online tools:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Online decoders:&lt;/strong&gt; &lt;a href=&quot;https://www.rot13.com&quot;&gt;https://www.rot13.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Command-line:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;cvpbPGS{arkg_gvzr_V&apos;yy_gel_2_ebhaqf_bs_ebg13_nSkgmDJE}&quot; | tr &apos;A-Za-z&apos; &apos;N-ZA-Mn-za-m&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;cipher = &quot;cvpbPGS{arkg_gvzr_V&apos;yy_gel_2_ebhaqf_bs_ebg13_nSkgmDJE}&quot;
plaintext = cipher.encode(&apos;rot_13&apos;)
print(plaintext)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[âš¡ Raikiri]
?? Flag &lt;strong&gt;pwned!&lt;/strong&gt; The ciphertext has been decoded successfully.
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;ROT13&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
ROT13 is a simple substitution cipher that demonstrates modular arithmetic in cryptography.&lt;br /&gt;
Applying &lt;code&gt;+13 mod 26&lt;/code&gt; twice restores the original message.&lt;br /&gt;
Remember: ROT13 is &lt;strong&gt;not secure&lt;/strong&gt; and should never be used for real-world encryption.
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 PicoGym - Hashcrack</title><link>https://0xkakashi.com/posts/picogym/cryptography/hashcrack/</link><guid isPermaLink="true">https://0xkakashi.com/posts/picogym/cryptography/hashcrack/</guid><description>A company stored a secret message on a server which got breached due to the admin using weakly hashed passwords. Can you gain access to the secret stored within the server? Additional details will be available after launching your challenge instance.</description><pubDate>Mon, 10 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; A company stored a secret message on a server which got breached due to the admin using weakly hashed passwords. Can you gain access to the secret stored within the server? Additional details will be available after launching your challenge instance.&lt;br /&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Easy&lt;br /&gt;
&lt;strong&gt;Author:&lt;/strong&gt; Nana Ama Atombo-Sackey&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This challenge presents a remote service that gives you three hashes sequentially and asks you to provide their plaintexts. The server hints that weak passwords were used, so common password lookup or a dictionary attack is the right approach.&lt;/p&gt;
&lt;p&gt;During the solve I interacted with the service and tested common passwords; all three hashes were weak and cracked quickly. The final step revealed the flag.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Tools&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nc&lt;/code&gt; (netcat), to talk to the remote service&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hashid&lt;/code&gt; / &lt;code&gt;hash-identifier&lt;/code&gt;, to identify hash types&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hashcat&lt;/code&gt; or &lt;code&gt;john&lt;/code&gt;, for offline cracking using wordlists&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rockyou.txt&lt;/code&gt;, common password list&lt;/li&gt;
&lt;li&gt;Online hash lookup services like &lt;code&gt;CrackStation&lt;/code&gt;, useful for common passwords and precomputed hash databases.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;I connected to the remote service:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nc domain port
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we get the following message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Welcome!! Looking For the Secret?

We have identified a hash: 482c811da5d5b4bc6d497ffa98491e38
Enter the password for identified hash: 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The hash provided is: &lt;code&gt;482c811da5d5b4bc6d497ffa98491e38&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;A hash is a fixed-length string of characters produced by a hash function, representing input data uniquely. Common hashing algorithms include MD5, SHA-1, and SHA-256.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MD5 produces a 32-character hexadecimal digest.&lt;/li&gt;
&lt;li&gt;SHA-1 produces a 40-character hexadecimal digest.&lt;/li&gt;
&lt;li&gt;SHA-256 produces a 64-character hexadecimal digest.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since our hash is 32 characters long, it is very likely an MD5 hash.
&lt;a href=&quot;https://www.techtarget.com/searchdatamanagement/definition/hashing&quot;&gt;Hash&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Using online tools like :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https://hashes.com/en/tools/hash_identifier&lt;/li&gt;
&lt;li&gt;https://www.tunnelsup.com/hash-analyzer/&lt;/li&gt;
&lt;li&gt;https://www.dcode.fr/hash-identifier&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We also have offline tool like &lt;a href=&quot;https://www.kali.org/tools/hash-identifier/&quot;&gt;hash-identifier&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Because the provided hash is 32 hexadecimal characters long (128 bits), this strongly indicates an MD5 digest. To confirm the hash type I used several online identifier tools, &lt;code&gt;Hashes.com&lt;/code&gt;, &lt;code&gt;TunnelsUp&lt;/code&gt;, and &lt;code&gt;dCode&lt;/code&gt;, and the offline &lt;code&gt;hash-identifier&lt;/code&gt; utility included with Kali Linux.&lt;/p&gt;
&lt;p&gt;Hashing is a one-way process, once data is hashed, it cannot be reversed. While older algorithms like MD5 and SHA-1 have been broken, newer ones remain strong for now. Still, with the rapid growth of quantum computing and AI, even current standards may eventually be at risk.&lt;/p&gt;
&lt;p&gt;Because hashing is one-way, you can’t directly “reverse” a digest. In practice, recovery relies on searching for a matching input: either by computing hashes for candidate plaintexts (dictionary or brute-force attacks) or by using precomputed lookup tables/rainbow tables. When a candidate’s computed hash equals the target digest, that candidate is the likely original plaintext.&lt;/p&gt;
&lt;h2&gt;Stage 1: MD5&lt;/h2&gt;
&lt;p&gt;The target digest is an MD5 hash. I used an online lookup service (&lt;a href=&quot;https://crackstation.net/&quot;&gt;CrackStation&lt;/a&gt;) to search their database of known plaintext–hash pairs.
CrackStation matched the hash and returned the original password: &lt;code&gt;password123&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can crack this kind of hash with tools like &lt;code&gt;hashcat&lt;/code&gt; or &lt;code&gt;john&lt;/code&gt; using a large wordlist (e.g., &lt;code&gt;rockyou.txt&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;After submitting &lt;code&gt;password123&lt;/code&gt; to the service, the server responded:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Welcome!! Looking For the Secret?

We have identified a hash: 482c811da5d5b4bc6d497ffa98491e38
Enter the password for identified hash: password123
Correct! You&apos;ve cracked the MD5 hash with no secret found!

Flag is yet to be revealed!! Crack this hash: b7a875fc1ea228b9061041b7cec4bd3c52ab3ce3
Enter the password for the identified hash:
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Stage 2: SHA-1&lt;/h2&gt;
&lt;p&gt;I fed the new hash (&lt;code&gt;b7a875fc1ea228b9061041b7cec4bd3c52ab3ce3&lt;/code&gt;) to the same identification tools. Hashes.com and other identifiers indicated this is likely &lt;code&gt;SHA-1&lt;/code&gt; (40 hex characters).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image1.png&quot; alt=&quot;SHA1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Using CrackStation, the hash resolved to &lt;code&gt;letmein&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image2.png&quot; alt=&quot;SHA1_Crack&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Stage 3: SHA-256&lt;/h2&gt;
&lt;p&gt;Submitting &lt;code&gt;letmein&lt;/code&gt; to the service produced:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;We have identified a hash: 482c811da5d5b4bc6d497ffa98491e38
Enter the password for identified hash: password123
Correct! You&apos;ve cracked the MD5 hash with no secret found!

Flag is yet to be revealed!! Crack this hash: b7a875fc1ea228b9061041b7cec4bd3c52ab3ce3
Enter the password for the identified hash: letmein
Correct! You&apos;ve cracked the SHA-1 hash with no secret found!

Almost there!! Crack this hash: 916e8c4f79b25028c9e467f1eb8eee6d6bbdff965f9928310ad30a8d88697745
Enter the password for the identified hash:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The next hash (&lt;code&gt;916e8c4f79b25028c9e467f1eb8eee6d6bbdff965f9928310ad30a8d88697745&lt;/code&gt;) is 64 hex characters long, so I treated it as &lt;code&gt;SHA-256&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image3.png&quot; alt=&quot;SHA256&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Again using CrackStation (and wordlist-based cracking tools if needed), it resolved to &lt;code&gt;qwerty098&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image4.png&quot; alt=&quot;SHA256&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note[⚡ Raikiri]
🎉 Flag pwned! The final hash was cracked, and the flag is now obtained. All stages successfully cleared.
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;flag.png&quot; alt=&quot;FLAG&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note[💡 TL;DR / Lesson Learned]
Weak passwords = easy cracks. All hashes in this challenge were broken using public databases. Always use strong, unique passwords, don’t give attackers a free pass!
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 CryptoHack - Modular Arithmetic</title><link>https://0xkakashi.com/posts/cryptohack/modular-arithmetic/</link><guid isPermaLink="true">https://0xkakashi.com/posts/cryptohack/modular-arithmetic/</guid><description>Build a strong foundation in modular arithmetic for cryptography challenges.</description><pubDate>Tue, 04 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Greatest Common Divisor&lt;/h2&gt;
&lt;p&gt;The Greatest Common Divisor (GCD), sometimes known as the highest common factor, is the largest number which divides two positive integers &lt;code&gt;(a,b)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For &lt;code&gt;a=12,b=8&lt;/code&gt; we can calculate the divisors of &lt;code&gt;{1,2,3,4,6,12}&lt;/code&gt; and the divisors of &lt;code&gt;{1,2,4,8}&lt;/code&gt;. Comparing these two, we see that &lt;code&gt;gcd(a,b)=4&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now imagine we take &lt;code&gt;a=11,b=17&lt;/code&gt;. Both &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; are prime numbers. As a prime number has only itself and &lt;code&gt;1&lt;/code&gt; as divisors, &lt;code&gt;gcd(a,b)=1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We say that for any two integers &lt;code&gt;a,b&lt;/code&gt;, if &lt;code&gt;gcd(a,b)=1&lt;/code&gt; then &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; are coprime integers.&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; are prime, they are also coprime. If &lt;code&gt;a&lt;/code&gt; is prime and &lt;code&gt;b&amp;lt;a&lt;/code&gt; then &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; are coprime.&lt;/p&gt;
&lt;p&gt;:::note
Think about the case for &lt;code&gt;a&lt;/code&gt; prime and &lt;code&gt;b&amp;gt;a&lt;/code&gt;, why are these not necessarily coprime
:::&lt;/p&gt;
&lt;p&gt;There are many tools to calculate the GCD of two integers, but for this task we recommend looking up &lt;a href=&quot;https://en.wikipedia.org/wiki/Euclidean_algorithm&quot;&gt;Euclid&apos;s Algorithm&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Try coding it up; it&apos;s only a couple of lines. Use &lt;code&gt;a=12,b=8&lt;/code&gt; to test it.&lt;/p&gt;
&lt;p&gt;Now calculate &lt;code&gt;gcd(a,b)&lt;/code&gt; for &lt;code&gt;a=66528,b=52920&lt;/code&gt; and enter it below.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;GCD.png&quot; alt=&quot;GCD&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Function to return gcd of a and b 
def gcd(a, b): 
  if a == 0 : 
      return b 
   
  return gcd(b%a, a) # This will loop until a == 0

a = 66528
b = 52920
print(&quot;gcd(&quot;, a , &quot;,&quot; , b, &quot;) = &quot;, gcd(a, b)) 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
By running this script, we get the flag. 🎯
:::&lt;/p&gt;
&lt;h2&gt;Extended GCD&lt;/h2&gt;
&lt;p&gt;Let &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; be positive integers.
The extended Euclidean algorithm is an efficient way to find integers &lt;code&gt;u,v&lt;/code&gt; such that&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;a⋅u+b⋅v=gcd(a,b)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note
Later, when we learn to decrypt RSA ciphertexts, we will need this algorithm to calculate the modular inverse of the public exponent.
:::
Using the two primes &lt;code&gt;p=26513,q=32321&lt;/code&gt;, find the integers &lt;code&gt;u,v&lt;/code&gt; such that&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;p⋅u+q⋅v=gcd(p,q)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enter whichever of &lt;code&gt;u&lt;/code&gt; and &lt;code&gt;v&lt;/code&gt; is the lower number as the flag.&lt;/p&gt;
&lt;p&gt;:::note
Knowing that &lt;code&gt;p,q&lt;/code&gt; are prime, what would you expect &lt;code&gt;gcd(p,q)&lt;/code&gt; to be For more details on the extended Euclidean algorithm, check out &lt;a href=&quot;https://web.archive.org/web/20230511143526/http://www-math.ucdenver.edu/~wcherowi/courses/m5410/exeucalg.html&quot;&gt;this page&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;EGCD.png&quot; alt=&quot;EGCD&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Extended Euclidean Algorithm to find gcd and coefficients (u, v) such that:
# a*u + b*v = gcd(a, b)
def extended_gcd(a, b):
  # Base case: if a is 0, gcd is b, and the coefficients are (0, 1)
  if a == 0:
      return (b, 0, 1)
  else:
       # Recursively apply the extended Euclidean algorithm
      g, x, y = extended_gcd(b % a, a)
      return (g, y - (b // a) * x, x)

p = 26513
q = 32321

gcd, u, v = extended_gcd(p, q)
print(&quot;gcd:&quot;, gcd)
print(&quot;u:&quot;, u)
print(&quot;v:&quot;, v)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
By running this script, we get the flag. 🎯
:::&lt;/p&gt;
&lt;h2&gt;Modular Arithmetic 1&lt;/h2&gt;
&lt;p&gt;Imagine you lean over and look at a cryptographer&apos;s notebook. You see some notes in the margin:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;4 + 9 = 1
5 - 7 = 10
2 + 3 = 5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At first you might think they&apos;ve gone mad. Maybe this is why there are so many data leaks nowadays you&apos;d think, but this is nothing more than modular arithmetic modulo 12 (albeit with some sloppy notation).&lt;/p&gt;
&lt;p&gt;You may not have been calling it modular arithmetic, but you&apos;ve been doing these kinds of calculations since you learnt to tell the time (look again at those equations and think about adding hours).&lt;/p&gt;
&lt;p&gt;Formally, &quot;calculating time&quot; is described by the theory of congruences. We say that two integers are congruent modulo m if &lt;code&gt;a ≡ b mod m&lt;/code&gt;.
Another way of saying this, is that when we divide the integer &lt;code&gt;a&lt;/code&gt; by &lt;code&gt;m&lt;/code&gt;, the remainder is &lt;code&gt;b&lt;/code&gt;. This tells you that if &lt;code&gt;m&lt;/code&gt; divides &lt;code&gt;a&lt;/code&gt; (this can be written as &lt;code&gt;m∣a&lt;/code&gt;) then &lt;code&gt;a ≡ 0 mod m&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Calculate the following integers:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;11 ≡ x mod 6
8146798528947 ≡ y mod 17
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The solution is the smaller of the two integers, &lt;code&gt;(x,y)&lt;/code&gt;, you obtained after reducing by the modulus.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;MA1.png&quot; alt=&quot;MA1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# First congruence
x = 11 % 6

# Second congruence
y = 8146798528947 % 17

# Output results
print(&quot;x =&quot;, x)
print(&quot;y =&quot;, y)
print(&quot;Smaller of the two =&quot;, min(x, y))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
By running this script, we get the flag. 🎯
:::&lt;/p&gt;
&lt;h2&gt;Modular Arithmetic 2&lt;/h2&gt;
&lt;p&gt;We&apos;ll pick up from the last challenge and imagine we&apos;ve picked a modulus &lt;code&gt;p&lt;/code&gt;, and we will restrict ourselves to the case when &lt;code&gt;p&lt;/code&gt; is prime.&lt;/p&gt;
&lt;p&gt;:::NOTE
If the modulus is not prime, the set of integers modulo &lt;code&gt;n&lt;/code&gt; define a ring.
:::&lt;/p&gt;
&lt;p&gt;A finite field &lt;code&gt;Fₚ&lt;/code&gt; is the set of integers &lt;code&gt;0, 1, ..., p − 1&lt;/code&gt;, and under both addition and multiplication, there are inverse elements &lt;code&gt;b₊&lt;/code&gt; and &lt;code&gt;bₓ&lt;/code&gt;for every element &lt;code&gt;a&lt;/code&gt; in the set, such that: &lt;code&gt;a + b₊ = 0&lt;/code&gt; and &lt;code&gt;a · bₓ = 1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;:::note
Note that the identity element for addition and multiplication is different! This is because the identity when acted with the operator should do nothing: &lt;code&gt;a + 0 = a&lt;/code&gt; and &lt;code&gt;a ⋅ 1 = a&lt;/code&gt;.
:::&lt;/p&gt;
&lt;p&gt;Let&apos;s say we pick &lt;code&gt;p = 17&lt;/code&gt;.
Calculate &lt;code&gt;3¹⁷ mod 17&lt;/code&gt;.
Now do the same but with &lt;code&gt;5¹⁷ mod 17&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;What would you expect to get for &lt;code&gt;7¹⁶ mod 17&lt;/code&gt;
Try calculating that.&lt;/p&gt;
&lt;p&gt;This interesting fact is known as &lt;code&gt;Fermat&apos;s Little Theorem&lt;/code&gt;.
We&apos;ll be needing this (and its generalizations) when we look at RSA cryptography.&lt;/p&gt;
&lt;p&gt;Now take the prime &lt;code&gt;p = 65537&lt;/code&gt;.
Calculate &lt;code&gt;27324678765⁴⁶⁵⁵³⁶ mod 65537&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Did you need a calculator&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;MA2.png&quot; alt=&quot;MA2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Fermat&apos;s Little Theorem demonstrations
p1 = 17

# 3^17 mod 17
res1 = pow(3, 17, p1)
print(&quot;3^17 mod 17 =&quot;, res1)

# 5^17 mod 17
res2 = pow(5, 17, p1)
print(&quot;5^17 mod 17 =&quot;, res2)

# 7^16 mod 17
res3 = pow(7, 16, p1)
print(&quot;7^16 mod 17 =&quot;, res3)

# Now using the large prime p = 65537
p2 = 65537
base = pow(27324678765, 4, p2)
res4 = pow(base, 65536, p2)
print(&quot;27324678765^4^65536 mod 65537 =&quot;, res4) 

# This script shows that for a prime p and integer a not divisible by p:
# a^(p-1) ≡ 1 (mod p)
# Hence answer is 1

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
By running this script, we get the flag. 🎯
:::&lt;/p&gt;
&lt;h2&gt;Modular Inverting&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;MI.png&quot; alt=&quot;MI&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Find d such that (3 * d) % 13 == 1

g = 3
p = 13

# Try each number from 1 to 12 to see which one gives (3 * d) % 13 = 1
for d in range(1, p):
  if (g * d) % p == 1:
      print(f&quot;The modular inverse of {g} mod {p} is: {d}&quot;)
      break
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
By running this script, we get the flag. 🎯
:::&lt;/p&gt;
&lt;h2&gt;Quadratic Residues&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;QR.png&quot; alt=&quot;QR&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Find the quadratic residue and then calculate its square root. Of the two possible roots, submit the smaller one as the flag.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;p = 29 ints=[14, 6, 11]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;p = 29
numbers = [14, 6, 11]

# Loop through each number in the list
for x in numbers:
   # Try every number a from 1 to p-1
  for a in range(1, p):
      if (a * a) % p == x:
          # If found, x is a quadratic residue
          print(f&quot;{x} is a square (quadratic residue) mod {p}&quot;)
          print(f&quot;Square roots: {a} and {p - a}&quot;)
          print(f&quot;Smaller root to submit as flag: {min(a, p - a)}&quot;)
          break
  else:
      print(f&quot;{x} is NOT a square mod {p}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
By running this script, we get the flag. 🎯
:::&lt;/p&gt;
&lt;h2&gt;Legendre Symbol&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;LS.png&quot; alt=&quot;LS&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Before looking at Legendre&apos;s symbol, let&apos;s take a brief detour to see an interesting property of quadratic (non-)residues:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Quadratic Residue * Quadratic Residue = Quadratic Residue
Quadratic Residue * Quadratic Non-residue = Quadratic Non-residue
Quadratic Non-residue * Quadratic Non-residue = Quadratic Residue

Want an easy way to remember this Replace &quot;Quadratic Residue&quot; with +1 and &quot;Quadratic Non-residue&quot; with −1, all three results are the same!
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Given an integer a and an odd prime p, the Legendre symbol (a/p) tells you:

(a/p) = 1 if a is a quadratic residue modulo p (i.e., there exists some x such that x² ≡ a mod p)

(a/p) = -1 if a is not a quadratic residue modulo p

(a/p) = 0 if a ≡ 0 mod p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Challenge file: &lt;a href=&quot;https://cryptohack.org/static/challenges/output_479698cde19aaa05d9e9dfca460f5443.txt&quot;&gt;Output.txt&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;p = 101524035174539890485408575671085261788758965189060164484385690801466167356667036677932998889725476582421738788500738738503134356158197247473850273565349249573867251280253564698939768700489401960767007716413932851838937641880157263936985954881657889497583485535527613578457628399173971810541670838543309159139

ints = [25081841204695904475894082974192007718642931811040324543182130088804239047149283334700530600468528298920930150221871666297194395061462592781551275161695411167049544771049769000895119729307495913024360169904315078028798025169985966732789207320203861858234048872508633514498384390497048416012928086480326832803, 45471765180330439060504647480621449634904192839383897212809808339619841633826534856109999027962620381874878086991125854247108359699799913776917227058286090426484548349388138935504299609200377899052716663351188664096302672712078508601311725863678223874157861163196340391008634419348573975841578359355931590555, 17364140182001694956465593533200623738590196990236340894554145562517924989208719245429557645254953527658049246737589538280332010533027062477684237933221198639948938784244510469138826808187365678322547992099715229218615475923754896960363138890331502811292427146595752813297603265829581292183917027983351121325, 14388109104985808487337749876058284426747816961971581447380608277949200244660381570568531129775053684256071819837294436069133592772543582735985855506250660938574234958754211349215293281645205354069970790155237033436065434572020652955666855773232074749487007626050323967496732359278657193580493324467258802863, 4379499308310772821004090447650785095356643590411706358119239166662089428685562719233435615196994728767593223519226235062647670077854687031681041462632566890129595506430188602238753450337691441293042716909901692570971955078924699306873191983953501093343423248482960643055943413031768521782634679536276233318, 85256449776780591202928235662805033201684571648990042997557084658000067050672130152734911919581661523957075992761662315262685030115255938352540032297113615687815976039390537716707854569980516690246592112936796917504034711418465442893323439490171095447109457355598873230115172636184525449905022174536414781771, 50576597458517451578431293746926099486388286246142012476814190030935689430726042810458344828563913001012415702876199708216875020997112089693759638454900092580746638631062117961876611545851157613835724635005253792316142379239047654392970415343694657580353333217547079551304961116837545648785312490665576832987, 96868738830341112368094632337476840272563704408573054404213766500407517251810212494515862176356916912627172280446141202661640191237336568731069327906100896178776245311689857997012187599140875912026589672629935267844696976980890380730867520071059572350667913710344648377601017758188404474812654737363275994871, 4881261656846638800623549662943393234361061827128610120046315649707078244180313661063004390750821317096754282796876479695558644108492317407662131441224257537276274962372021273583478509416358764706098471849536036184924640593888902859441388472856822541452041181244337124767666161645827145408781917658423571721, 18237936726367556664171427575475596460727369368246286138804284742124256700367133250078608537129877968287885457417957868580553371999414227484737603688992620953200143688061024092623556471053006464123205133894607923801371986027458274343737860395496260538663183193877539815179246700525865152165600985105257601565]

for a in ints:
    # Compute Legendre symbol
    legendre = pow(a, (p-1)//2, p)
    if legendre == 1:
        print(f&quot;Found quadratic residue: {a}&quot;)
        
        sqrt_a = pow(a, (p+1)//4, p)
        
        # Pick the larger of the two roots
        root = max(sqrt_a, p - sqrt_a)
        
        print(f&quot;Flag is: {root}&quot;)
        break
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
By running this script, we get the flag. 🎯
:::&lt;/p&gt;
&lt;h2&gt;Modular Square Root&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;MSR.png&quot; alt=&quot;MSR&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def tonelli_shanks(a, p):
    &quot;&quot;&quot; 
    Find a square root of a mod p using the Tonelli-Shanks algorithm.
    p must be an odd prime.
    &quot;&quot;&quot;
    
    # Step 1: Find Q and S such that p-1 = Q * 2^S
    S = 0  # Initialize S to 0
    Q = p - 1  # Start with Q = p-1
    while Q % 2 == 0:
        Q //= 2  # Keep dividing Q by 2 while it&apos;s even
        S += 1  # Count how many times 2 divides p-1
    
    # Step 2: Find a quadratic non-residue z
    # A quadratic non-residue z is a number such that z^(p-1)/2 ≡ -1 (mod p)
    z = 2  # Start from z = 2 and check if it&apos;s a quadratic non-residue
    while pow(z, (p - 1) // 2, p) != p - 1:  # z^(p-1)/2 mod p should be -1 (p-1 mod p)
        z += 1  # Increment z until a non-residue is found

    # Step 3: Initialize variables for the Tonelli-Shanks algorithm
    M = S  # Set M to S, which is the exponent of 2 in the factorization of p-1
    c = pow(z, Q, p)  # Compute c = z^Q mod p
    t = pow(a, Q, p)  # Compute t = a^Q mod p (this is used to track progress)
    R = pow(a, (Q + 1) // 2, p)  # Compute R = a^((Q+1)//2) mod p as the initial guess for the root

    # Step 4: Loop until t == 1, which means we have found a square root
    while t != 1:
        # Find the smallest i such that t^(2^i) ≡ 1 mod p
        i = 0  # Start the exponent count
        temp = t  # Use a temporary variable to check powers of t
        while temp != 1:
            temp = pow(temp, 2, p)  # Compute t^(2^i) mod p by squaring t
            i += 1  # Increment i (the exponent of 2)
            if i == M:  # If we have tried all possible exponents, no root exists
                return None  # No square root exists, so return None

        # Step 5: Update variables to improve the guess for the root
        b = pow(c, 2 ** (M - i - 1), p)  # Compute b = c^(2^(M-i-1)) mod p
        M = i  # Update M to the current value of i
        c = pow(b, 2, p)  # Update c = b^2 mod p (this helps in the next iteration)
        t = (t * c) % p  # Update t = t * c mod p (this moves us closer to 1)
        R = (R * b) % p  # Update R to the new value, refining the root approximation

    # When t becomes 1, R is the square root of a mod p
    return R  # Return the square root

# Given values for a and p
a = 8479994658316772151941616510097127087554541274812435112009425778595495359700244470400642403747058566807127814165396640215844192327900454116257979487432016769329970767046735091249898678088061634796559556704959846424131820416048436501387617211770124292793308079214153179977624440438616958575058361193975686620046439877308339989295604537867493683872778843921771307305602776398786978353866231661453376056771972069776398999013769588936194859344941268223184197231368887060609212875507518936172060702209557124430477137421847130682601666968691651447236917018634902407704797328509461854842432015009878011354022108661461024768
p = 30531851861994333252675935111487950694414332763909083514133769861350960895076504687261369815735742549428789138300843082086550059082835141454526618160634109969195486322015775943030060449557090064811940139431735209185996454739163555910726493597222646855506445602953689527405362207926990442391705014604777038685880527537489845359101552442292804398472642356609304810680731556542002301547846635101455995732584071355903010856718680732337369128498655255277003643669031694516851390505923416710601212618443109844041514942401969629158975457079026906304328749039997262960301209158175920051890620947063936347307238412281568760161

# Solve for the square root
sqrt_a = tonelli_shanks(a, p)

# Output the result
if sqrt_a is not None:
    # If a square root exists, print the smaller root (between sqrt_a and p - sqrt_a)
    smaller_root = min(sqrt_a, p - sqrt_a)
    print(f&quot;Square root found! The smaller root is:\n{smaller_root}&quot;)
else:
    # If no square root exists, print a message
    print(&quot;No square root exists.&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
By running this script, we get the flag. 🎯
:::&lt;/p&gt;
</content:encoded></item><item><title>🔐 CryptoHack - Introduction to CryptoHack</title><link>https://0xkakashi.com/posts/cryptohack/introduction-to-cryptohack/</link><guid isPermaLink="true">https://0xkakashi.com/posts/cryptohack/introduction-to-cryptohack/</guid><description>This starter course gets you up and running with CryptoHack.</description><pubDate>Tue, 25 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Finding Flags&lt;/h2&gt;
&lt;p&gt;Each challenge is designed to help introduce you to a new piece of cryptography. Solving a challenge will require you to find a &quot;flag&quot;.
These flags will usually be in the format &lt;code&gt;crypto{y0ur_f1rst_fl4g}&lt;/code&gt;. The flag format helps you verify that you found the correct solution.
Try submitting this flag into the form below to solve your first challenge.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;Finding%20Flags.png&quot; alt=&quot;Finding Flags&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::note[FLAG]
The flag is straightforward. Just submit it to complete the challenge! Flag: &lt;code&gt;crypto{y0ur_f1rst_fl4g}&lt;/code&gt;
:::&lt;/p&gt;
&lt;h2&gt;Great Snakes&lt;/h2&gt;
&lt;p&gt;Modern cryptography involves code, and code involves coding. CryptoHack provides a good opportunity to sharpen your skills.
Of all modern programming languages, Python 3 stands out as ideal for quickly writing cryptographic scripts and attacks. For more information about why we think Python is so great for this, please see the &lt;a href=&quot;https://cryptohack.org/faq#python3&quot;&gt;FAQ&lt;/a&gt;.
Run the attached Python script and it will output your flag.&lt;/p&gt;
&lt;p&gt;Challenge files:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://cryptohack.org/static/challenges/great_snakes_35381fca29d68d8f3f25c9fa0a9026fb.py&quot;&gt;great_snakes.py&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.python.org/moin/BeginnersGuide/Download&quot;&gt;Downloading Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;Great%20Snakes.png&quot; alt=&quot;Great Snakes&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;great_snakes.py :&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env python3
import sys
# import this

if sys.version_info.major == 2:
  print(&quot;You are running Python 2, which is no longer supported. Please update to Python 3.&quot;)

ords = [81, 64, 75, 66, 70, 93, 73, 72, 1, 92, 109, 2, 84, 109, 66, 75, 70, 90, 2, 92, 79]

print(&quot;Here is your flag:&quot;)
print(&quot;&quot;.join(chr(o ^ 0x32) for o in ords))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This Python script deciphers an encoded message by XORing a list of numerical values with &lt;code&gt;0x32&lt;/code&gt; (decimal 50) and then converting the result into a readable string.
:::tip
For more details on XOR operations, check out this resource: &lt;a href=&quot;https://www.hackers-arise.com/post/basics-of-xoring&quot;&gt;Basics of XORing&lt;/a&gt;
:::&lt;/p&gt;
&lt;p&gt;:::note[FLAG]
By running this script, we get the flag. 🎯 Flag: &lt;code&gt;crypto{z3n_0f_pyth0n}&lt;/code&gt;
:::&lt;/p&gt;
&lt;h2&gt;ASCII&lt;/h2&gt;
&lt;p&gt;ASCII is a 7-bit encoding standard which allows the representation of text using the integers 0-127.
Using the below integer array, convert the numbers to their corresponding ASCII characters to obtain a flag.
:::tip[]
In Python, the chr() function can be used to convert an ASCII ordinal number to a character (the ord() function does the opposite).
:::&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;ASCII.png&quot; alt=&quot;ASCII&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This challenge involves using the chr() function in Python to convert the given decimal numbers into their corresponding ASCII characters and construct the flag.&lt;/p&gt;
&lt;p&gt;:::tip
For more details on ASCII, check out this resource: &lt;a href=&quot;https://www.techtarget.com/whatis/definition/ASCII-American-Standard-Code-for-Information-Interchange&quot;&gt;ASCII&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For more details on chr() function in Python, check out this resource: For more details check the &lt;a href=&quot;https://www.w3schools.com/python/ref_func_chr.asp&quot;&gt;FAQ&lt;/a&gt;
:::&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ascii_values = [99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125]
flag = &apos;&apos;.join(chr(i) for i in ascii_values)
print(flag)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
By running this script, we get the flag. 🎯 Flag: &lt;code&gt;crypto{ASCII_pr1nt4bl3}&lt;/code&gt;
:::&lt;/p&gt;
&lt;h2&gt;Hex&lt;/h2&gt;
&lt;p&gt;When we encrypt something the resulting ciphertext commonly has bytes which are not printable ASCII characters. If we want to share our encrypted data, it&apos;s common to encode it into something more user-friendly and portable across different systems.&lt;/p&gt;
&lt;p&gt;Hexadecimal can be used in such a way to represent ASCII strings. First each letter is converted to an ordinal number according to the ASCII table (as in the previous challenge). Then the decimal numbers are converted to base-16 numbers, otherwise known as hexadecimal. The numbers can be combined together, into one long hex string.&lt;/p&gt;
&lt;p&gt;Included below is a flag encoded as a hex string. Decode this back into bytes to get the flag.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note
In Python, the &lt;code&gt;bytes.fromhex()&lt;/code&gt; function can be used to convert hex to bytes. The .hex() instance method can be called on byte strings to get the hex representation. For more details check the &lt;a href=&quot;https://www.geeksforgeeks.org/convert-hex-string-to-bytes-in-python/&quot;&gt;FAQ&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;:::
Resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.rapidtables.com/code/text/ascii-table.html&quot;&gt;ASCII table&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Hexadecimal&quot;&gt;Wikipedia: Hexadecimal&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;Hex.png&quot; alt=&quot;HEX&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;
The hexadecimal string can be converted to bytes using Python&apos;s &lt;code&gt;bytes.fromhex()&lt;/code&gt; method, then decoded to a readable string using &lt;code&gt;.decode()&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hex_value = &apos;63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d&apos;
flag = bytes.fromhex(hex_value).decode()
print(flag)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
By running this script, we get the flag. 🎯 Flag: &lt;code&gt;crypto{You_will_be_working_with_hex_strings_a_lot}&lt;/code&gt;
:::&lt;/p&gt;
&lt;h2&gt;Base64&lt;/h2&gt;
&lt;p&gt;Another common encoding scheme is Base64, which allows us to represent binary data as an ASCII string using an alphabet of 64 characters. One character of a Base64 string encodes 6 binary digits (bits), and so 4 characters of Base64 encode three 8-bit bytes.&lt;/p&gt;
&lt;p&gt;Base64 is most commonly used online, so binary data such as images can be easily included into HTML or CSS files.&lt;/p&gt;
&lt;p&gt;Take the below hex string, decode it into bytes and then encode it into Base64.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note
In Python, after importing the base64 module with import base64, you can use the &lt;code&gt;base64.b64encode()&lt;/code&gt; function. Remember to decode the hex first as the challenge description states. For more details check the &lt;a href=&quot;https://www.geeksforgeeks.org/base64-b64encode-in-python/&quot;&gt;FAQ&lt;/a&gt;
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;b64.png&quot; alt=&quot;Base64&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;
We use Python&apos;s &lt;code&gt;base64&lt;/code&gt; module to decode the string.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import base64

base64_value = &apos;72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf&apos;

# Convert hex to bytes
flag = bytes.fromhex(base64_value)

# Encode bytes to standard Base64
flag = base64.b64encode(flag).decode()  # Decode for readability
print(flag)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
By running this script, we get the flag. 🎯 Flag: &lt;code&gt;crypto/Base+64+Encoding+is+Web+Safe/&lt;/code&gt;
:::&lt;/p&gt;
&lt;h2&gt;Bytes and Big Integers&lt;/h2&gt;
&lt;p&gt;Cryptosystems like RSA works on numbers, but messages are made up of characters. How should we convert our messages into numbers so that mathematical operations can be applied&lt;/p&gt;
&lt;p&gt;The most common way is to take the ordinal bytes of the message, convert them into hexadecimal, and concatenate. This can be interpreted as a base-16/hexadecimal number, and also represented in base-10/decimal.&lt;/p&gt;
&lt;p&gt;To illustrate:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;message: HELLO
ascii bytes: [72, 69, 76, 76, 79]
hex bytes: [0x48, 0x45, 0x4c, 0x4c, 0x4f]
base-16: 0x48454c4c4f
base-10: 310400273487
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note
Python&apos;s PyCryptodome library implements this with the methods &lt;code&gt;bytes_to_long()&lt;/code&gt; and &lt;code&gt;long_to_bytes()&lt;/code&gt;. You will first have to install PyCryptodome and import it with &lt;code&gt;from Crypto.Util.number import *&lt;/code&gt;. For more details check the &lt;a href=&quot;https://www.geeksforgeeks.org/what-is-pycryptodome-in-python/&quot;&gt;FAQ&lt;/a&gt;.
:::&lt;/p&gt;
&lt;p&gt;Convert the following integer back into a message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;11515195063862318899931685488813747395775516287289682636499965282714637259206269
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;Bytes%20and%20Big%20Integers.png&quot; alt=&quot;Bytes and Big Integers&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from Crypto.Util.number import *

message = 11515195063862318899931685488813747395775516287289682636499965282714637259206269

flag = long_to_bytes(message) # Converts the large integer into its original byte representation.
print(flag.decode())  # decode
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
By running this script, we get the flag. 🎯 Flag: &lt;code&gt;crypto{3nc0d1n6_4ll_7h3_w4y_d0wn}&lt;/code&gt;
:::&lt;/p&gt;
&lt;h2&gt;XOR Starter&lt;/h2&gt;
&lt;p&gt;XOR is a bitwise operator which returns 0 if the bits are the same, and 1 otherwise. In textbooks the XOR operator is denoted by ⊕, but in most challenges and programming languages you will see the caret ^ used instead.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;A&lt;/th&gt;
&lt;th&gt;B&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For longer binary numbers we XOR bit by bit: &lt;code&gt;0110 ^ 1010 = 1100&lt;/code&gt;. We can XOR integers by first converting the integer from decimal to binary. We can XOR strings by first converting each character to the integer representing the Unicode character.&lt;/p&gt;
&lt;p&gt;Given the string &lt;code&gt;label&lt;/code&gt;, XOR each character with the integer &lt;code&gt;13&lt;/code&gt;. Convert these integers back to a string and submit the flag as &lt;code&gt;crypto{new_string}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;:::tip
The Python &lt;code&gt;pwntools&lt;/code&gt; library has a convenient &lt;code&gt;xor()&lt;/code&gt; function that can XOR together data of different types and lengths. But first, you may want to implement your own function to solve this
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;XOR%20Starter.png&quot; alt=&quot;XOR Starter&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from pwn import *

# Given string
given_string = &quot;label&quot;

# XOR each character with 13 using pwn&apos;s xor function
xor_result = xor(given_string, 13)

# Format the flag
flag = f&quot;crypto{{{xor_result.decode()}}}&quot;
print(flag)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
We XOR each character with 13 using pwn&apos;s xor function. By running this script, we get the flag. 🎯 Flag: &lt;code&gt;crypto{aloha}&lt;/code&gt;
:::&lt;/p&gt;
&lt;h2&gt;XOR Properties&lt;/h2&gt;
&lt;p&gt;In the last challenge, you saw how XOR worked at the level of bits. In this one, we&apos;re going to cover the properties of the XOR operation and then use them to undo a chain of operations that have encrypted a flag. Gaining an intuition for how this works will help greatly when you come to attacking real cryptosystems later, especially in the block ciphers category.&lt;/p&gt;
&lt;p&gt;There are four main properties we should consider when we solve challenges using the XOR operator&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Commutative: A ⊕ B = B ⊕ A
Associative: A ⊕ (B ⊕ C) = (A ⊕ B) ⊕ C
Identity: A ⊕ 0 = A
Self-Inverse: A ⊕ A = 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s break this down. Commutative means that the order of the XOR operations is not important. Associative means that a chain of operations can be carried out without order (we do not need to worry about brackets). The identity is 0, so XOR with 0 &quot;does nothing&quot;, and lastly something XOR&apos;d with itself returns zero.&lt;/p&gt;
&lt;p&gt;Let&apos;s put this into practice! Below is a series of outputs where three random keys have been XOR&apos;d together and with the flag. Use the above properties to undo the encryption in the final line to obtain the flag.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;KEY1 = a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313
KEY2 ^ KEY1 = 37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e
KEY2 ^ KEY3 = c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1
FLAG ^ KEY1 ^ KEY3 ^ KEY2 = 04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip
Before you XOR these objects, be sure to &lt;code&gt;decode from hex to bytes&lt;/code&gt;.
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;XOR%20Properties.png&quot; alt=&quot;XOR Properties&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from pwn import *

# Given values
KEY1 = &quot;a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313&quot;
KEY2_XOR_KEY1 = &quot;37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e&quot;
KEY2_XOR_KEY3 = &quot;c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1&quot;
FLAG_XOR_ALL = &quot;04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf&quot;

# Let&apos;s decode them from hex to bytes first.
KEY1 = bytes.fromhex(KEY1)
KEY2_XOR_KEY1 = bytes.fromhex(KEY2_XOR_KEY1)
KEY2_XOR_KEY3 = bytes.fromhex(KEY2_XOR_KEY3)
FLAG_XOR_ALL = bytes.fromhex(FLAG_XOR_ALL)

# We first derive KEY2 using KEY2 = (KEY2 ^ KEY1) ^ KEY1 since x ^ x = 0
KEY2 = xor(KEY2_XOR_KEY1, KEY1)

# Then we derive key 3
KEY3 = xor(KEY2_XOR_KEY3, KEY2)

# Flag
FLAG = xor(FLAG_XOR_ALL, xor(KEY1, xor(KEY2, KEY3)))

flag = FLAG.decode()
print(flag)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
Using the associative property of XOR, we successfully combined the keys to extract the flag. Running this script reveals the flag: 🎯 Flag: &lt;code&gt;crypto{x0r_i5_ass0c1at1v3}&lt;/code&gt;.
:::&lt;/p&gt;
&lt;h2&gt;Favorite Byte&lt;/h2&gt;
&lt;p&gt;For the next few challenges, you&apos;ll use what you&apos;ve just learned to solve some more XOR puzzles.
I&apos;ve hidden some data using XOR with a single byte, but that byte is a secret. Don&apos;t forget to decode from hex first.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;73626960647f6b206821204f21254f7d694f7624662065622127234f726927756d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;Favorite%20Byte.png&quot; alt=&quot;Favorite Byte&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from pwn import *

# Given hex-encoded data (XOR-encrypted with a single unknown byte)
data = bytes.fromhex(&quot;73626960647f6b206821204f21254f7d694f7624662065622127234f726927756d&quot;)

# Brute-force the single-byte key by trying all possible values (0-255)
for key in range(256):
    decrypted = xor(data, key)  # XOR the data with the key candidate
    
    # Check if the decrypted text starts with &quot;crypto&quot; (expected flag format)
    if decrypted.decode().startswith(&quot;crypto&quot;): 
        print(f&quot;Key: {key}, Flag: {decrypted.decode()}&quot;)  # Print the key and extracted flag
        break  # Stop once the correct key is found
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
Using brute-force,  we successfully identified the single-byte key and decrypted the message to reveal the flag. Running this script reveals the flag: 🎯 Flag: &lt;code&gt;crypto{0x10_15_my_f4v0ur173_by7e}&lt;/code&gt;.
:::&lt;/p&gt;
&lt;h2&gt;You either know, XOR you don&apos;t&lt;/h2&gt;
&lt;p&gt;I&apos;ve encrypted the flag with my secret key, you&apos;ll never be able to guess it.&lt;/p&gt;
&lt;p&gt;:::tip
Remember the &lt;code&gt;flag format&lt;/code&gt; and how it might help you in this challenge!
:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0e0b213f26041e480b26217f27342e175d0e070a3c5b103e2526217f27342e175d0e077e263451150104
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;XOR_Knowledge.png&quot; alt=&quot;You either know, XOR you don&apos;t&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution :&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from pwn import *

# Given encrypted flag in hex format
flag_hex = &quot;0e0b213f26041e480b26217f27342e175d0e070a3c5b103e2526217f27342e175d0e077e263451150104&quot;

# Convert hex-encoded flag to bytes
flag_bytes = bytes.fromhex(flag_hex)

# Since we know the flag format starts with &quot;crypto{&quot;, we use it to determine the XOR key
partial_key = xor(flag_bytes[:7], b&quot;crypto{&quot;)  # Extract part of the key using known plaintext
# Output: b&apos;myXORke+y&apos; (partial key discovered)

# Observing the pattern, I guessed the key is &quot;myXORkey&quot;
key = b&quot;myXORkey&quot;

# Decrypt the flag by XORing with the derived key
decrypted_flag = xor(flag_bytes, key)

# Print the decrypted flag
print(decrypted_flag.decode()) 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note[FLAG]
This demonstrates how XOR encryption can be broken when partial plaintext is known. Running this script reveals the flag: 🎯 Flag: &lt;code&gt;crypto{1f_y0u_Kn0w_En0uGH_y0u_Kn0w_1t_4ll}&lt;/code&gt;.
:::&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This walkthrough covered encoding (Hex, Base64) and basic XOR operations, essential for cryptographic challenges. Understanding these fundamentals helps in tackling more advanced cryptography problems. 🚀&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;finished.png&quot; alt=&quot;Finished&quot; /&gt;&lt;/p&gt;
</content:encoded></item></channel></rss>