<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>blog</title><link>http://blog.rex.wf/</link><description>Recent content on blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Wed, 27 Nov 2024 00:00:00 +0000</lastBuildDate><atom:link href="http://blog.rex.wf/index.xml" rel="self" type="application/rss+xml"/><item><title>GPN CTF 2024 – Parabox</title><link>http://blog.rex.wf/posts/parabox/</link><pubDate>Wed, 27 Nov 2024 00:00:00 +0000</pubDate><guid>http://blog.rex.wf/posts/parabox/</guid><description>Category: Reverse Engineering Points: 500 Solves: 1 This was a very fun (and extremely painful) GameBoy challenge from GPN CTF 2024. In the end, it only had 1 solve, which wasn&amp;rsquo;t ours. We got incredibly close to solving it, but ultimately couldn&amp;rsquo;t. It was primarily me and my teammate, @HalfInchPunisher from team CyberSpace, who dedicated a significant portion of the second day of the CTF to solving this.
Huge props to the challenge author for making such a fun challenge!</description><content>&lt;ul>
&lt;li>&lt;strong>Category:&lt;/strong> Reverse Engineering&lt;/li>
&lt;li>&lt;strong>Points:&lt;/strong> 500&lt;/li>
&lt;li>&lt;strong>Solves:&lt;/strong> 1&lt;/li>
&lt;/ul>
&lt;p>This was a very fun (and extremely painful) GameBoy challenge from GPN CTF 2024. In the end, it only had 1 solve, which wasn&amp;rsquo;t ours. We got incredibly close to solving it, but ultimately couldn&amp;rsquo;t. It was primarily me and my teammate, &lt;code>@HalfInchPunisher&lt;/code> from team &lt;code>CyberSpace&lt;/code>, who dedicated a significant portion of the second day of the CTF to solving this.&lt;/p>
&lt;p>Huge props to the challenge author for making such a fun challenge!&lt;/p>
&lt;h2 id="challenge">Challenge&lt;/h2>
&lt;blockquote>
&lt;p>&lt;a href="https://www.patricksparabox.com/">This game&lt;/a> looked real fun, unfortunately they did not support my platform. I wanted to play it anyway, so I built this small version myself. Some things went wrong (writing assembly is hard), but I&amp;rsquo;m sure you can win nonetheless.
Go push some paraboxes!&lt;/p>
&lt;p>Author: Alkalem&lt;/p>
&lt;p>&lt;a href="https://github.com/rexdotsh/ctf-writeups/raw/refs/heads/main/GPN%20CTF%202024/rev/parabox/handout/parabox.tar.gz">parabox.tar.gz&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;h2 id="setup">Setup&lt;/h2>
&lt;p>The challenge handout contained a folder that had 6 files,&lt;/p>
&lt;pre tabindex="0">&lt;code>└── parabox
├── Dockerfile
├── headless.patch
├── parabox.gbc
├── README.md
├── run
└── server.py
&lt;/code>&lt;/pre>&lt;p>From reading the &lt;code>Dockerfile&lt;/code> and &lt;code>server.py&lt;/code>, we discovered that the remote instance expects moves in the format of &lt;code>UP, DOWN, LEFT, RIGHT, A, B, SELECT, START&lt;/code>. Additionally, it uses &lt;a href="https://github.com/drhelius/Gearboy/">gearboy&lt;/a>, a GameBoy emulator, to process these inputs. A patch has also been applied to allow &lt;a href="https://github.com/drhelius/Gearboy/">gearboy&lt;/a> to run in a headless mode.&lt;/p>
&lt;p>For local testing purposes, we opted to instead use &lt;a href="https://bgb.bircd.org/">BGB&lt;/a> as our emulator of choice, due to its easy setup, and having used it for GameBoy challenges before. Simply loading the &lt;code>parabox.gbc&lt;/code> file into it, and pressing &lt;code>Esc&lt;/code> to launch the debugger, was enough to get set up!&lt;/p>
&lt;blockquote>
&lt;p>We customized the key bindings so that pressing &lt;code>A&lt;/code> on our keyboard will input &lt;code>A&lt;/code> &lt;code>(REDO)&lt;/code> in the game, and pressing &lt;code>B&lt;/code> will input &lt;code>B&lt;/code> &lt;code>(UNDO)&lt;/code>, instead of the default bindings which mapped these keys differently.&lt;/p>
&lt;/blockquote>
&lt;h2 id="scripting">Scripting&lt;/h2>
&lt;p>Before starting our solution, we wrote two Python scripts: one to log our movements while playing the game and store them in a text file called &lt;code>moves.txt&lt;/code>, in the format the remote expects them, and another to simulate those moves, to make working with the game easier.&lt;/p>
&lt;div class="collapsable-code">
&lt;input id="1" type="checkbox" checked />
&lt;label for="1">
&lt;span class="collapsable-code__language">python&lt;/span>
&lt;span class="collapsable-code__title">read_keyboard.py&lt;/span>
&lt;span class="collapsable-code__toggle" data-label-expand="Show" data-label-collapse="Hide">&lt;/span>
&lt;/label>
&lt;pre class="language-python" >&lt;code>
import sys
import keyboard
move_sequence = []
def on_key_event(event):
if event.event_type == keyboard.KEY_DOWN and event.name in [
&amp;#34;up&amp;#34;,
&amp;#34;down&amp;#34;,
&amp;#34;right&amp;#34;,
&amp;#34;left&amp;#34;,
&amp;#34;a&amp;#34;,
&amp;#34;b&amp;#34;,
]:
move_sequence.append(event.name)
print(f&amp;#34;{event.name} key pressed&amp;#34;)
keyboard.hook(on_key_event)
print(&amp;#34;Press ESC to stop.&amp;#34;)
keyboard.wait(&amp;#34;esc&amp;#34;)
file_path = sys.argv[1] if len(sys.argv) &amp;gt; 1 else &amp;#34;moves.txt&amp;#34;
with open(file_path, &amp;#34;w&amp;#34;) as file:
file.write(&amp;#34;\n&amp;#34;.join(move_sequence).upper())
print(f&amp;#34;Final sequence of arrow key moves written to {file_path}.&amp;#34;)
&lt;/code>&lt;/pre>
&lt;/div>
&lt;div class="collapsable-code">
&lt;input id="2" type="checkbox" checked />
&lt;label for="2">
&lt;span class="collapsable-code__language">python&lt;/span>
&lt;span class="collapsable-code__title">simulate_keystrokes.py&lt;/span>
&lt;span class="collapsable-code__toggle" data-label-expand="Show" data-label-collapse="Hide">&lt;/span>
&lt;/label>
&lt;pre class="language-python" >&lt;code>
import sys
import time
import keyboard
def simulate_keystrokes(move_sequence, delay):
for move in move_sequence:
if move != &amp;#34;EOF&amp;#34; and not move.startswith(&amp;#34;#&amp;#34;):
print(move)
keyboard.press(
move.lower()
) # Uppercase &amp;#39;B&amp;#39; was not detected by the emulator
time.sleep(
delay
) # Sleeps are necessary for the emulator to register the keypresses
keyboard.release(move)
time.sleep(delay)
else:
print(move)
def read_moves_from_file(file_name):
with open(file_name, &amp;#34;r&amp;#34;) as file:
return [line.strip() for line in file if line.strip()]
def main():
if len(sys.argv) &amp;lt; 2:
raise ValueError(&amp;#34;Please provide the file name as an argument.&amp;#34;)
speed = &amp;#34;fast&amp;#34; if len(sys.argv) &amp;lt; 3 else sys.argv[2]
delay = 0.1 if speed == &amp;#34;slow&amp;#34; else 0.05
print(
f&amp;#34;Starting in 2 seconds... (Speed: {speed}, Delay: {delay * 2} seconds)&amp;#34; # The delay is doubled when logging because sleep is called both before and after the keypress.
) # Wait for the user to switch to the game window
time.sleep(2)
move_sequence = read_moves_from_file(sys.argv[1])
simulate_keystrokes(move_sequence, delay)
if __name__ == &amp;#34;__main__&amp;#34;:
main()
&lt;/code>&lt;/pre>
&lt;/div>
&lt;hr>
&lt;h2 id="solving">Solving&lt;/h2>
&lt;h3 id="intro">Intro&lt;/h3>
&lt;blockquote>
&lt;p>The moves used for all the showcases in this writeup are using ones uploaded by the challenge author (@Alkalem) after the CTF ended. The same &lt;code>moves.txt&lt;/code> is uploaded in it&amp;rsquo;s entirety in this repository as well, in the &lt;a href="https://github.com/rexdotsh/ctf-writeups/tree/main/GPN%20CTF%202024/rev/parabox/solution">&lt;code>solution&lt;/code>&lt;/a> directory. This can be used to replicate the solutions locally, along with &lt;code>simulate_keystrokes.py&lt;/code>.&lt;/p>
&lt;/blockquote>
&lt;p>The game provides 3 intro levels, to get the player familiarized with the game. The objective of the game was pretty simple, you had to fulfil the level goals, usually by putting the golden coloured blocks in the correct positions, after which you could take the player to the winning tile. Below is a showcase of the solutions for the intro levels.&lt;/p>
&lt;div class="video-wrapper " >
&lt;video controls >
&lt;source src="https://github.com/rex69420/ctf-writeups/assets/65942753/1fe49c68-e18d-4208-88e5-ee456ebb3778" type="video/mp4">
Your browser does not support the video tag.
&lt;/video>
&lt;/div>
&lt;hr>
&lt;h3 id="parabox">Parabox&lt;/h3>
&lt;blockquote>
&lt;p>From here on out, the value of &lt;code>time.sleep&lt;/code> (delay) between keystrokes in &lt;code>simulate_keystrokes.py&lt;/code> is increased, to better showcase the moves.&lt;/p>
&lt;/blockquote>
&lt;p>The first main level, &lt;code>Parabox&lt;/code>, was another simple one, simply demonstrating the use of the blue teleporters. The player had to use the teleporter to get to the winning tile. Below is a showcase of the solution.&lt;/p>
&lt;div class="video-wrapper " >
&lt;video controls >
&lt;source src="https://github.com/rex69420/ctf-writeups/assets/65942753/caab131e-39af-4062-990b-1c5aeda89f51" type="video/mp4">
Your browser does not support the video tag.
&lt;/video>
&lt;/div>
&lt;hr>
&lt;h3 id="impossible">Impossible&lt;/h3>
&lt;p>The second main level, &lt;code>Impossible&lt;/code>, was where the difficulty started to ramp up. The level seemed impossible, with the winning tile being outside the map. However, this is where we found the first bug in the level.&lt;/p>
&lt;p>While trying to solve the level and spam moves, we noticed that after enough spamming, we could get the player to skip the level, but couldn&amp;rsquo;t figure out why, until we loaded up the debugger. From what we understood, we could change the position of the win tile by spamming moves, and thus overflowing it, since the bounds of the move array were not properly configured.&lt;/p>
&lt;p>The coordinates of the win tile were stored at &lt;code>C279&lt;/code> in memory, and we noticed that whenever we moved, &lt;code>C1FE&lt;/code> would get incremented, and once it went back to &lt;code>01&lt;/code>, the winning square&amp;rsquo;s position would be changed to the last move, as the game would overflow the position of the winning tile, with the last move from the moves array.&lt;/p>
&lt;p>We can find out the values for the moves are -&lt;/p>
&lt;ul>
&lt;li>&lt;code>0x10&lt;/code> - &lt;code>RIGHT&lt;/code>&lt;/li>
&lt;li>&lt;code>0x20&lt;/code> - &lt;code>LEFT&lt;/code>&lt;/li>
&lt;li>&lt;code>0x40&lt;/code> - &lt;code>UP&lt;/code>&lt;/li>
&lt;li>&lt;code>0x80&lt;/code> - &lt;code>DOWN&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>The number of moves is stored at &lt;code>C200&lt;/code>, and the moves themselves are stored after that. Here is a video showcasing that behavior.&lt;/p>
&lt;div class="video-wrapper " >
&lt;video controls >
&lt;source src="https://github.com/rex69420/ctf-writeups/assets/65942753/6551e87a-a2f6-431e-be8d-cef622d25036" type="video/mp4">
Your browser does not support the video tag.
&lt;/video>
&lt;/div>
&lt;p>So, we just need the last move to be one that we can reach. Below is a showcase of the level, along with the debugger.&lt;/p>
&lt;div class="video-wrapper " >
&lt;video controls >
&lt;source src="https://github.com/rex69420/ctf-writeups/assets/65942753/c25fdc39-f249-47a1-8868-28c38358f8bc" type="video/mp4">
Your browser does not support the video tag.
&lt;/video>
&lt;/div>
&lt;hr>
&lt;h3 id="small">Small&lt;/h3>
&lt;p>The third main level, &lt;code>Small&lt;/code>, was another simple one, with the player having to use both, the green, and the blue teleporters to fulfil the level goals and get to the winning tile. Below is a showcase of the solution.&lt;/p>
&lt;blockquote>
&lt;p>You might notice &lt;code># Extra moves to store optimal snapshot (stall more if necessary)&lt;/code> show up in the console along with the moves, and there are some extra moves at the end of the solution. These moves were used to initialize a bug which will be used and explained in the next level.&lt;/p>
&lt;/blockquote>
&lt;div class="video-wrapper " >
&lt;video controls >
&lt;source src="https://github.com/rex69420/ctf-writeups/assets/65942753/6cc0cdb1-f36c-43e5-87f0-542e1257e3f2" type="video/mp4">
Your browser does not support the video tag.
&lt;/video>
&lt;/div>
&lt;hr>
&lt;h3 id="missing">Missing&lt;/h3>
&lt;h4 id="our-failed-approach">Our Failed Approach&lt;/h4>
&lt;p>The fourth, and the most difficult level, &lt;code>Missing&lt;/code>, was where we got stuck. We couldn&amp;rsquo;t figure out how to solve the level, and ultimately couldn&amp;rsquo;t. Our first approach is shown in this video, without abusing any bugs, and just trying to solve the level. Even after we put the gold blocks in the correct positions, we couldn&amp;rsquo;t win the level.&lt;/p>
&lt;div class="video-wrapper " >
&lt;video controls >
&lt;source src="https://github.com/rex69420/ctf-writeups/assets/65942753/ee8745a1-88a5-4708-b5a7-b1bbbfe7da12" type="video/mp4">
Your browser does not support the video tag.
&lt;/video>
&lt;/div>
&lt;p>As you can see, the gold blocks are in the correct positions, but the player can&amp;rsquo;t win the level. We tried to debug the level, but couldn&amp;rsquo;t figure out what was wrong. We ultimately tried opening a ticket with the challenge author, and were told this is expected behaviour. We thought we had to replicate the bug used to solve &lt;code>Impossible&lt;/code>, but that didn&amp;rsquo;t work either.&lt;/p>
&lt;p>A few hours later of trying to wrap our heads around the Ghidra decompiled code, using &lt;a href="https://github.com/Gekkio/GhidraBoy">GhidraBoy&lt;/a> and the output from the BGB Debugger, my teammate discovered this.&lt;/p>
&lt;figure class="left" >
&lt;img src="https://github.com/rex69420/ctf-writeups/assets/65942753/0de37980-debc-4c08-ab2b-248dc1b18e73" />
&lt;/figure>
&lt;p>He discovered that there was a &lt;strong>3rd map&lt;/strong> in the level (1st one was the main map, 2nd one was the teleporter map), and our theory was that the player had to push some blocks into the third map as well to win the level. Taking a look at the win conditions for this level, confirmed that theory.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">struct&lt;/span> Block {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">char&lt;/span> correct_position;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">char&lt;/span> map;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">char&lt;/span> value; &lt;span style="color:#75715e">// ?
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [&lt;span style="color:#ae81ff">0x06&lt;/span>, &lt;span style="color:#ae81ff">0&lt;/span>, &lt;span style="color:#ae81ff">0&lt;/span>], &lt;span style="color:#75715e">// Player being on the Win tile in the main (1st) map
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> [&lt;span style="color:#ae81ff">0x24&lt;/span>, &lt;span style="color:#ae81ff">1&lt;/span>, &lt;span style="color:#ae81ff">1&lt;/span>], &lt;span style="color:#75715e">// The first gold block in the blue (2nd) map
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> [&lt;span style="color:#ae81ff">0x25&lt;/span>, &lt;span style="color:#ae81ff">1&lt;/span>, &lt;span style="color:#ae81ff">1&lt;/span>], &lt;span style="color:#75715e">// The second gold block in the blue (2nd) map
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> [&lt;span style="color:#ae81ff">0x25&lt;/span>, &lt;span style="color:#ae81ff">1&lt;/span>, &lt;span style="color:#ae81ff">1&lt;/span>], &lt;span style="color:#75715e">// The third gold block in the blue (2nd) map
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> [&lt;span style="color:#ae81ff">0x04&lt;/span>, &lt;span style="color:#ae81ff">2&lt;/span>, &lt;span style="color:#ae81ff">1&lt;/span>], &lt;span style="color:#75715e">// The first block in the green (3rd) map
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> [&lt;span style="color:#ae81ff">0x07&lt;/span>, &lt;span style="color:#ae81ff">2&lt;/span>, &lt;span style="color:#ae81ff">1&lt;/span>], &lt;span style="color:#75715e">// The second block in the green (3rd) map
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We thought at this point that we had to abuse the &lt;code>UNDO&lt;/code> and &lt;code>REDO&lt;/code> commands to solve the level, but we couldn&amp;rsquo;t figure out how to do that. This is also the point where we ran into a bug which was unintended behavior, causing the game to reset when interacting with the 2nd teleporter block.&lt;/p>
&lt;div class="video-wrapper " >
&lt;video controls >
&lt;source src="https://github.com/rex69420/ctf-writeups/assets/65942753/66691d18-aa5d-4add-8374-141f6d989880" type="video/mp4">
Your browser does not support the video tag.
&lt;/video>
&lt;/div>
&lt;h4 id="the-intended-solution">The Intended Solution&lt;/h4>
&lt;p>After the CTF ended, the challenge author disclosed the intended solution to the level, which was to use a bug in the &lt;code>UNDO&lt;/code> command to solve the level. The &lt;code>UNDO&lt;/code>(s) are not done backwards, but &amp;ldquo;the game loads a checkpoint from up to &lt;strong>32 moves&lt;/strong> earlier and replays forward from there&amp;rdquo; (direct quote from the challenge author). The level is titled &lt;code>Missing&lt;/code>, since it has goals that are impossible to reach without using the snapshots (using &lt;code>UNDO/REDO&lt;/code>).&lt;/p>
&lt;p>The player can access the third map/stage from the &lt;strong>level before&lt;/strong> by loading a snapshot (thus the need for the extra levels from the previous level). The last problem is that the player needs one more box, which can also be solved by loading a snapshot from the level before. So, we can set up our snapshot by doing some extra moves in the &lt;code>Small&lt;/code>, to fulfil the conditions of this level. Below is a showcase of the solution.&lt;/p>
&lt;div class="video-wrapper " >
&lt;video controls >
&lt;source src="https://github.com/rex69420/ctf-writeups/assets/65942753/d00910bb-232b-458e-8529-691dfdf49073" type="video/mp4">
Your browser does not support the video tag.
&lt;/video>
&lt;/div>
&lt;hr>
&lt;h3 id="the-last-hurdle">The Last Hurdle&lt;/h3>
&lt;blockquote>
&lt;p>We solved this level without being able to solve &lt;code>Missing&lt;/code>, since we figured out that setting the address &lt;code>C279&lt;/code> to &lt;code>FF&lt;/code>, lets you skip the level locally. &lt;strong>This is also showcased in the video.&lt;/strong> We would have solved the entire challenge, if not for us missing the snapshot bug in the previous level.&lt;/p>
&lt;/blockquote>
&lt;p>The fifth, and last level, was another one that we &lt;strong>thought&lt;/strong> we solved without using any bugs in the code. I discovered the fact that you could access the green room, by glitching through the blue room pretty fast accidentally (which apparently was the bug), but couldn&amp;rsquo;t figure out how to leave it. After a while, I realised that I could simply move the green box to an area where I could easily exit it, then glitch into it after entering the blue teleporter. Below is a showcase of the solution.&lt;/p>
&lt;div class="video-wrapper " >
&lt;video controls >
&lt;source src="https://github.com/rex69420/ctf-writeups/assets/65942753/8ccfb420-b5d7-4b92-a93e-82094400adfc" type="video/mp4">
Your browser does not support the video tag.
&lt;/video>
&lt;/div>
&lt;hr>
&lt;h2 id="you-win">You win&lt;/h2>
&lt;p>Simply inputting &lt;code>DOWN&lt;/code> twice allowed you to win the level (shown in the previous recording), and submitting these moves to the remote, got you the flag. Below is a simple solve script to get the flag.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-py" data-lang="py">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># solve.py&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">from&lt;/span> pwn &lt;span style="color:#f92672">import&lt;/span> &lt;span style="color:#f92672">*&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>io &lt;span style="color:#f92672">=&lt;/span> remote(&lt;span style="color:#e6db74">&amp;#34;the-final-countdown--shawn-mendes-3474.ctf.kitctf.de&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;443&amp;#34;&lt;/span>, ssl&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#66d9ef">True&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>data &lt;span style="color:#f92672">=&lt;/span> open(&lt;span style="color:#e6db74">&amp;#34;moves.txt&amp;#34;&lt;/span>)&lt;span style="color:#f92672">.&lt;/span>read()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>io&lt;span style="color:#f92672">.&lt;/span>sendlineafter(&lt;span style="color:#e6db74">b&lt;/span>&lt;span style="color:#e6db74">&amp;#34;EOF&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>, data&lt;span style="color:#f92672">.&lt;/span>encode())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>io&lt;span style="color:#f92672">.&lt;/span>interactive()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">You solved the challenge, here is your flag:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">GPNCTF&lt;/span>&lt;span style="color:#e6db74">{p41n_70_d3v3l0p_h0p3fully_l355_p41n_70_50lv3_fd29a4b2833}&lt;/span>&lt;span style="color:#e6db74">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;p>Below is the full showcase of the solutions for all the levels.&lt;/p>
&lt;div class="video-wrapper " >
&lt;video controls >
&lt;source src="https://github.com/rex69420/ctf-writeups/assets/65942753/f5677c77-4681-4f7d-a434-401f05d6c5e6" type="video/mp4">
Your browser does not support the video tag.
&lt;/video>
&lt;/div>
&lt;p>If you&amp;rsquo;ve made it this far, thank you for reading the writeup! I hope you enjoyed it as much as I did attempting to solve this challenge. If you have any questions, suggestions, or improvements, feel free to contact me at &lt;code>@rex.wf&lt;/code> on Discord.&lt;/p></content></item><item><title>hello world</title><link>http://blog.rex.wf/posts/hello/</link><pubDate>Sun, 15 Sep 2024 00:00:00 +0000</pubDate><guid>http://blog.rex.wf/posts/hello/</guid><description>hi! this is just a placeholder post for now. i&amp;rsquo;ll be migrating all my old writeups to this new blog soon™.</description><content>&lt;p>hi! this is just a placeholder post for now. i&amp;rsquo;ll be migrating all my &lt;a href="https://github.com/rexdotsh/ctf-writeups">old writeups&lt;/a> to this new blog soon™.&lt;/p></content></item><item><title>About</title><link>http://blog.rex.wf/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>http://blog.rex.wf/about/</guid><description>hi, i&amp;rsquo;m rex.
i&amp;rsquo;m a high school student, interested in cybersecurity and programming, and i play CTFs with infobahn. this blog will mainly serve as a place for me to publish writeups for various CTF challenges, as well as other projects i&amp;rsquo;m working on.
i hope you enjoy your stay!</description><content>&lt;p>hi, i&amp;rsquo;m &lt;a href="https://rex.wf">rex&lt;/a>.&lt;/p>
&lt;p>i&amp;rsquo;m a high school student, interested in cybersecurity and programming, and i play CTFs with &lt;a href="https://ctftime.org/team/364723">infobahn&lt;/a>. this blog will mainly serve as a place for me to publish writeups for various CTF challenges, as well as other projects i&amp;rsquo;m working on.&lt;/p>
&lt;p>i hope you enjoy your stay!&lt;/p></content></item></channel></rss>