<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vedant Kulkarni</title>
    <description>The latest articles on DEV Community by Vedant Kulkarni (@vedant_kulkarni_e1a6cdf3c).</description>
    <link>https://dev.to/vedant_kulkarni_e1a6cdf3c</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2271825%2Fac54d352-80f5-4411-860e-4f848cc7cae7.png</url>
      <title>DEV Community: Vedant Kulkarni</title>
      <link>https://dev.to/vedant_kulkarni_e1a6cdf3c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vedant_kulkarni_e1a6cdf3c"/>
    <language>en</language>
    <item>
      <title>CTF Writeup: Autorev 1 — picoCTF</title>
      <dc:creator>Vedant Kulkarni</dc:creator>
      <pubDate>Sat, 30 May 2026 08:24:23 +0000</pubDate>
      <link>https://dev.to/vedant_kulkarni_e1a6cdf3c/ctf-writeup-autorev-1-picoctf-345i</link>
      <guid>https://dev.to/vedant_kulkarni_e1a6cdf3c/ctf-writeup-autorev-1-picoctf-345i</guid>
      <description>&lt;h2&gt;
  
  
  1. Executive Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Challenge Name&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Autorev 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Platform&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;picoCTF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Category&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Reverse Engineering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Difficulty&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Beginner-Intermediate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Key Technique&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Automated Binary Analysis via Opcode Pattern Matching&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Flag&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;picoCTF{4u7o_r3v_g0_brrr_78c345aa}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Overview:&lt;/strong&gt; This challenge tests a fundamental reverse engineering skill — the ability to &lt;strong&gt;automate analysis at scale&lt;/strong&gt;. The remote service sends 20 unique ELF binaries, one at a time, as raw hex-encoded byte streams. For each binary, you have exactly &lt;strong&gt;1 second&lt;/strong&gt; to extract a hardcoded "secret" integer and send it back. The challenge is impossible to solve manually and teaches the critical lesson that a good reverse engineer isn't just someone who &lt;em&gt;can&lt;/em&gt; read assembly — it's someone who can &lt;strong&gt;script their way through it&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Reconnaissance &amp;amp; Enumeration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 — Initial Connection: Understanding the Protocol
&lt;/h3&gt;

&lt;p&gt;Before writing any exploit, the very first step is always to &lt;strong&gt;understand what you're interacting with&lt;/strong&gt;. The challenge description gives us a simple &lt;code&gt;netcat&lt;/code&gt; command to connect to the service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nc mysterious-sea.picoctf.net 57369
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why &lt;code&gt;netcat&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;nc&lt;/code&gt; (netcat) is the most basic tool for raw TCP communication. It's the right first choice here because the challenge description explicitly tells us to use it, and we have no reason to believe any higher-level protocol (like HTTP) is involved. We just need to see the raw data the server sends.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2.2 — Analyzing the Server's Handshake
&lt;/h3&gt;

&lt;p&gt;Upon connecting, the server reveals its rules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Welcome! I think I'm pretty good at reverse enginnering.
There's NO WAY anyone's better than me.
Wanna try? I have 20 binaries I'm going to send you and you
have 1 second EACH to get the secret in each one. Good luck &amp;gt;:)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This immediately tells us three critical things:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Observation&lt;/th&gt;
&lt;th&gt;Implication&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;20 binaries&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;We need a loop, not a one-shot script.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1 second EACH&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manual analysis (e.g., opening in Ghidra) is impossible. We must automate.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"get the secret"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Each binary has a single hardcoded value we need to find.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Following the banner, the server dumps a massive hex string — this is the raw bytes of an &lt;strong&gt;ELF (Executable and Linkable Format)&lt;/strong&gt; binary, the standard executable format for Linux. It then prompts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What's the secret?:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.3 — Static Analysis: Finding the Secret in the Hex
&lt;/h3&gt;

&lt;p&gt;This is the most critical analytical step. Instead of trying to &lt;em&gt;run&lt;/em&gt; the binary (which would be slow and complex to automate), we need to find the secret directly in the raw bytes. To do this, we need to understand the binary's logic.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Concept: What Does the Binary Do?
&lt;/h4&gt;

&lt;p&gt;Every one of these binaries is compiled from a simple C template that looks conceptually like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// The "secret" is a hardcoded 32-bit integer&lt;/span&gt;
    &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mh"&gt;0xb174cbbb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- This value changes each time&lt;/span&gt;
    &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;guess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"What's the secret?&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;scanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%u"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;guess&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;guess&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Correct!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Nice try :(&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  The Concept: How Does C Become Assembly?
&lt;/h4&gt;

&lt;p&gt;When the C compiler (&lt;code&gt;gcc&lt;/code&gt;) compiles &lt;code&gt;unsigned int secret = 0xb174cbbb;&lt;/code&gt;, it translates it into an x86_64 assembly instruction that stores that value onto the function's &lt;strong&gt;stack frame&lt;/strong&gt;. The specific instruction is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mov DWORD PTR [rbp-0x4], 0xb174cbbb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break this instruction down piece by piece, as this is the heart of the entire challenge:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Assembly Component&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mov&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;"Move" — copy a value into a destination.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DWORD PTR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The destination is a 4-byte (32-bit) memory location.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[rbp-0x4]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The destination address: 4 bytes below the base pointer (&lt;code&gt;rbp&lt;/code&gt;), which is where local variable &lt;code&gt;secret&lt;/code&gt; lives on the stack.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0xb174cbbb&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The immediate (hardcoded) value — &lt;strong&gt;our secret!&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  The Concept: How Does Assembly Become Bytes (Opcodes)?
&lt;/h4&gt;

&lt;p&gt;The CPU doesn't read text like &lt;code&gt;mov DWORD PTR [rbp-0x4], ...&lt;/code&gt;. It reads &lt;strong&gt;machine code&lt;/strong&gt; — raw bytes called &lt;strong&gt;opcodes&lt;/strong&gt;. The x86_64 encoding for &lt;code&gt;mov DWORD PTR [rbp-0x4], &amp;lt;imm32&amp;gt;&lt;/code&gt; is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nasm"&gt;&lt;code&gt;&lt;span class="nf"&gt;c7&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt; &lt;span class="nv"&gt;fc&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="nv"&gt;s&lt;/span&gt; &lt;span class="nv"&gt;of&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt; &lt;span class="nv"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;Little&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;Endian&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's decode this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Byte(s)&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;c7&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Opcode for &lt;code&gt;MOV r/m32, imm32&lt;/code&gt; (move a 32-bit immediate value into a memory location).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;45&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ModR/M byte: indicates the addressing mode is &lt;code&gt;[rbp + disp8]&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The signed 8-bit displacement: &lt;code&gt;0xfc&lt;/code&gt; is &lt;code&gt;-4&lt;/code&gt; in two's complement, giving us &lt;code&gt;[rbp-0x4]&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Next 4 bytes&lt;/td&gt;
&lt;td&gt;The 32-bit immediate value, stored in &lt;strong&gt;Little-Endian&lt;/strong&gt; byte order.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What is Little-Endian?&lt;/strong&gt; x86 processors store multi-byte integers with the &lt;strong&gt;least significant byte first&lt;/strong&gt;. So the value &lt;code&gt;0xb174cbbb&lt;/code&gt; is stored in memory as &lt;code&gt;bb cb 74 b1&lt;/code&gt;. This is a common "gotcha" in reverse engineering — if you read the bytes left-to-right, you get the &lt;em&gt;wrong&lt;/em&gt; number. You must reverse the byte order.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Verification in the First Binary
&lt;/h4&gt;

&lt;p&gt;Let's find this pattern in the first binary's hex stream. Searching for &lt;code&gt;c745fc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nasm"&gt;&lt;code&gt;&lt;span class="nf"&gt;...c745fcbbcb74b1...&lt;/span&gt;
         &lt;span class="o"&gt;^^^^^^^^&lt;/span&gt;
         &lt;span class="nf"&gt;bb&lt;/span&gt; &lt;span class="nv"&gt;cb&lt;/span&gt; &lt;span class="mi"&gt;74&lt;/span&gt; &lt;span class="nv"&gt;b1&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Little&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;Endian&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="nv"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Converting &lt;code&gt;bb cb 74 b1&lt;/code&gt; from Little-Endian:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reverse the bytes: b1 74 cb bb
Hex value: 0xb174cbbb
Decimal: 2977221563
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server helpfully displayed &lt;code&gt;2977221563&lt;/code&gt; as the expected answer for the first binary — &lt;strong&gt;our analysis is confirmed!&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4 — The Road Not Taken: Why Not Use a Disassembler?
&lt;/h3&gt;

&lt;p&gt;You might be thinking: &lt;em&gt;"Why not save the binary to a file, run &lt;code&gt;objdump -d&lt;/code&gt; or load it into Ghidra?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is a perfectly valid instinct for a &lt;em&gt;single&lt;/em&gt; binary. However, here's why it fails for this challenge:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ghidra/IDA&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;These are GUI tools. Opening, analyzing, and reading the output of 20 binaries in 20 seconds is humanly impossible.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;objdump -d&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;This &lt;em&gt;could&lt;/em&gt; be automated, but it adds unnecessary complexity. You'd need to: (1) decode the hex to a file, (2) run &lt;code&gt;objdump&lt;/code&gt;, (3) parse the text output with regex. This is slower and more fragile than just searching the raw bytes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Running the binary&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You'd need to decode, save, &lt;code&gt;chmod +x&lt;/code&gt;, and then somehow brute-force or debug it. Far too slow for a 1-second window.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The optimal path&lt;/strong&gt; — and the lesson of this challenge — is that &lt;strong&gt;pattern matching on raw bytes is the fastest, most elegant solution&lt;/strong&gt;. We don't need a full disassembler; we just need a 3-byte search key (&lt;code&gt;c745fc&lt;/code&gt;).&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Initial Foothold (Exploitation)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 — The Automation Strategy
&lt;/h3&gt;

&lt;p&gt;With our analysis complete, the exploitation plan is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────┐
│              AUTOMATION LOOP (x20)           │
│                                              │
│  1. READ data from socket until prompt       │
│     "What's the secret?:"                    │
│                                              │
│  2. SEARCH the received data for the regex   │
│     pattern: c745fc([0-9a-f]{8})             │
│                                              │
│  3. EXTRACT the 8 hex chars (4 bytes)        │
│                                              │
│  4. CONVERT from Little-Endian hex to        │
│     unsigned 32-bit decimal integer          │
│                                              │
│  5. SEND the decimal integer + newline       │
│     back to the server                       │
│                                              │
└──────────────────────────────────────────────┘
              │
              ▼
   After 20 rounds, READ the flag
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 — The Exploit Script (Fully Annotated)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;   &lt;span class="c1"&gt;# For raw TCP connections (like netcat, but programmable)
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;       &lt;span class="c1"&gt;# For Regular Expressions (pattern matching in text)
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;   &lt;span class="c1"&gt;# For converting between Python values and C structs (byte packing)
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;solve&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Connects to the Autorev 1 challenge server, automatically extracts
    the hardcoded secret from 20 binaries, and retrieves the flag.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="c1"&gt;# --- STEP 1: Establish Connection ---
&lt;/span&gt;    &lt;span class="c1"&gt;# socket.create_connection() is like running `nc host port`.
&lt;/span&gt;    &lt;span class="c1"&gt;# It returns a socket object we can read from and write to.
&lt;/span&gt;    &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;mysterious-sea.picoctf.net&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;57369&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_connection&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[*] Connected to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# --- Helper Function: Read Until a Specific Suffix ---
&lt;/span&gt;    &lt;span class="c1"&gt;# The server sends data in chunks. We need to keep reading
&lt;/span&gt;    &lt;span class="c1"&gt;# until we see the specific prompt "What's the secret?:".
&lt;/span&gt;    &lt;span class="c1"&gt;# This ensures we've captured the ENTIRE binary hex stream
&lt;/span&gt;    &lt;span class="c1"&gt;# before we try to parse it.
&lt;/span&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;recv_until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;suffix&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Reads from the socket byte-by-byte until `suffix` is found.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;''&lt;/span&gt;  &lt;span class="c1"&gt;# Use bytes, not string, for raw socket data
&lt;/span&gt;        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;endswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;suffix&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Read one byte at a time (simple &amp;amp; reliable)
&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# If recv returns empty bytes, the connection was closed.
&lt;/span&gt;                &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ConnectionError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Server closed the connection prematurely.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# Convert bytes to a Python string for regex
&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="c1"&gt;# --- STEP 2: Receive Data Until the Prompt ---
&lt;/span&gt;            &lt;span class="c1"&gt;# We read everything the server sends until we see the question.
&lt;/span&gt;            &lt;span class="c1"&gt;# This blob of text contains the hex-encoded ELF binary.
&lt;/span&gt;            &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;recv_until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s the secret?:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# --- STEP 3: Extract the Secret Using Regex ---
&lt;/span&gt;            &lt;span class="c1"&gt;# Pattern breakdown:
&lt;/span&gt;            &lt;span class="c1"&gt;#   c745fc     - The 3 opcode bytes for `mov DWORD PTR [rbp-0x4], ...`
&lt;/span&gt;            &lt;span class="c1"&gt;#   (          - Start of a "capture group" (the part we want to extract)
&lt;/span&gt;            &lt;span class="c1"&gt;#   [0-9a-f]   - Any single hexadecimal digit (lowercase)
&lt;/span&gt;            &lt;span class="c1"&gt;#   {8}        - Exactly 8 of them (representing 4 bytes = 32 bits)
&lt;/span&gt;            &lt;span class="c1"&gt;#   )          - End of capture group
&lt;/span&gt;            &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;c745fc([0-9a-f]{8})&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;hex_val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# e.g., "bbcb74b1"
&lt;/span&gt;
                &lt;span class="c1"&gt;# --- STEP 4: Convert Little-Endian Hex to Decimal ---
&lt;/span&gt;                &lt;span class="c1"&gt;# bytes.fromhex("bbcb74b1") -&amp;gt; b'\xbb\xcb\x74\xb1'
&lt;/span&gt;                &lt;span class="c1"&gt;# struct.unpack('&amp;lt;I', ...) unpacks as:
&lt;/span&gt;                &lt;span class="c1"&gt;#   '&amp;lt;' = Little-Endian byte order
&lt;/span&gt;                &lt;span class="c1"&gt;#   'I' = Unsigned 32-bit Integer
&lt;/span&gt;                &lt;span class="c1"&gt;# Result is a tuple, so we take the first element with [0].
&lt;/span&gt;                &lt;span class="n"&gt;raw_bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromhex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hex_val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unpack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;I&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;raw_bytes&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

                &lt;span class="c1"&gt;# --- STEP 5: Send the Answer ---
&lt;/span&gt;                &lt;span class="n"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
                &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[+] Round &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/20: Found secret = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; | Sent!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# If the pattern isn't found, something unexpected happened.
&lt;/span&gt;                &lt;span class="c1"&gt;# Print the data for debugging.
&lt;/span&gt;                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[!] Round &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: Pattern &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;c745fc&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; NOT FOUND!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;    Raw data (last 200 chars): ...&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;  &lt;span class="c1"&gt;# Stop, because continuing would be pointless.
&lt;/span&gt;
        &lt;span class="c1"&gt;# --- STEP 6: Receive the Flag ---
&lt;/span&gt;        &lt;span class="c1"&gt;# After all 20 rounds, the server should send a congratulations
&lt;/span&gt;        &lt;span class="c1"&gt;# message containing the flag. We read generously.
&lt;/span&gt;        &lt;span class="n"&gt;final_output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[*] SERVER RESPONSE:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;final_output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[!] Error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Always close the socket cleanly.
&lt;/span&gt;        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[*] Connection closed.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# --- Entry Point ---
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;solve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3 — Execution Output
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;[*] Connected to mysterious-sea.picoctf.net:57369
[+] Round 1/20:  Found secret = 3406797415 | Sent!
[+] Round 2/20:  Found secret = 4233232755 | Sent!
[+] Round 3/20:  Found secret = 2312384779 | Sent!
[+] Round 4/20:  Found secret = 2250124380 | Sent!
[+] Round 5/20:  Found secret = 826731480  | Sent!
[+] Round 6/20:  Found secret = 1642351210 | Sent!
[+] Round 7/20:  Found secret = 3796822336 | Sent!
[+] Round 8/20:  Found secret = 2986324885 | Sent!
[+] Round 9/20:  Found secret = 2400094377 | Sent!
[+] Round 10/20: Found secret = 1885613138 | Sent!
[+] Round 11/20: Found secret = 1143096664 | Sent!
[+] Round 12/20: Found secret = 1757652120 | Sent!
[+] Round 13/20: Found secret = 3300608193 | Sent!
[+] Round 14/20: Found secret = 3072272321 | Sent!
[+] Round 15/20: Found secret = 1763129777 | Sent!
[+] Round 16/20: Found secret = 128687777  | Sent!
[+] Round 17/20: Found secret = 957976931  | Sent!
[+] Round 18/20: Found secret = 2093904350 | Sent!
[+] Round 19/20: Found secret = 2320907858 | Sent!
[+] Round 20/20: Found secret = 790478185  | Sent!

==================================================
[*] SERVER RESPONSE:
Correct!
Woah, how'd you do that??
Here's your flag: picoCTF{4u7o_r3v_g0_brrr_78c345aa}
==================================================
[*] Connection closed.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Privilege Escalation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Not applicable.&lt;/strong&gt; This was a pure reverse engineering and scripting challenge. There was no shell to obtain and no system to escalate privileges on. The "escalation" here was conceptual: escalating from &lt;em&gt;understanding one binary&lt;/em&gt; to &lt;em&gt;automating the analysis of twenty&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Lessons Learned &amp;amp; Mitigation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 — Key Takeaways for CTF Players
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Lesson&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Automation is a core RE skill.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The flag literally says it: &lt;code&gt;4u7o_r3v_g0_brrr&lt;/code&gt;. Real-world malware analysis often involves triaging hundreds of samples. The ability to write scripts that extract Indicators of Compromise (IOCs) from binaries programmatically is invaluable.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Learn your opcodes.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You don't need to memorize every x86 instruction, but recognizing common patterns like &lt;code&gt;c7 45&lt;/code&gt; (stack variable assignment) or &lt;code&gt;48 8d&lt;/code&gt; (LEA) will dramatically speed up your analysis, even when using tools like Ghidra.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Little-Endian is not optional knowledge.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Almost every binary exploitation and reverse engineering challenge on x86 requires you to correctly handle Little-Endian byte order. Misunderstanding this is the #1 source of "off-by-everything" errors. Python's &lt;code&gt;struct&lt;/code&gt; module is your best friend.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Start simple, then optimize.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;We connected with &lt;code&gt;nc&lt;/code&gt; first to &lt;em&gt;understand the problem&lt;/em&gt; before writing a single line of Python. Resist the urge to start coding before you know what you're coding for.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  5.2 — Blue Team / Mitigation Perspective
&lt;/h3&gt;

&lt;p&gt;While this is a CTF game, the underlying concepts map to real-world scenarios:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vulnerability&lt;/th&gt;
&lt;th&gt;Real-World Parallel&lt;/th&gt;
&lt;th&gt;Mitigation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hardcoded secrets in binaries&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;API keys, passwords, or encryption keys compiled directly into client-side applications. Attackers routinely use tools like &lt;code&gt;strings&lt;/code&gt;, &lt;code&gt;binwalk&lt;/code&gt;, or custom scripts to extract them.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Never hardcode secrets.&lt;/strong&gt; Use environment variables, secure vaults (e.g., HashiCorp Vault), or runtime configuration. If a secret &lt;em&gt;must&lt;/em&gt; be in a binary, use obfuscation (though this only slows attackers, it doesn't stop them).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Predictable binary structure&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Using the same code template across many builds makes automated analysis trivial (as we just demonstrated). This is relevant to malware families that share a common builder.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Introduce variability.&lt;/strong&gt; If generating challenge binaries, randomize variable offsets (different stack layouts via compiler flags like &lt;code&gt;-fstack-protector&lt;/code&gt;), use different registers, or add junk code to break simple pattern matching.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>automation</category>
      <category>beginners</category>
      <category>cybersecurity</category>
      <category>infosec</category>
    </item>
  </channel>
</rss>
