Studying meets enjoyable on the 2022 SANS Vacation Hack Problem – strap your self in for a crackerjack experience on the North Pole as I foil Grinchum’s foul plan and get better the 5 golden rings
That is my first 12 months collaborating within the SANS Vacation Hack Problem and it was a blast. By way of a sequence of 16 challenges starting from simple to troublesome, I practiced analyzing suspicious community site visitors and PowerShell logs, writing Suricata guidelines, breaking out of a Docker container, discovering leaked keys to take advantage of a GitLab CI/CD pipeline and an AWS person, conducting XML Exterior Entity assaults, and hacking a wise contract to purchase a non-fungible token.
The most effective a part of this expertise was that it launched me to new instruments and applied sciences, thus stretching my cybersecurity data that a lot additional. Right here, I share just a few highlights from fixing the challenges.
Orientation
Each participant receives an avatar to navigate an in-browser online game atmosphere set on the North Pole:
Throughout orientation, you obtain a cryptocurrency pockets that the sport makes use of to award KringleCoins for finishing challenges and that you simply use within the final problem to hack a wise contract. Curiously, the sport retains monitor of all KringleCoin transactions in an Ethereum blockchain, which means a whole document of your progress is saved on this blockchain too.
On to the primary ring of the sport.
1. Tolkien Ring
Discovering the Tolkien Ring required flexing my logs evaluation muscle mass.
Wireshark phishing
First, I used Wireshark to investigate the supplied .pcap file that exposed a server at adv.epostoday[.]uk downloading the file Ref_Sept24-2020.zip to a pc:
Peeking contained in the ZIP file, I discovered an executable known as Ref_Sept24-2020.scr that triggered two detections in ESET Endpoint Safety: BAT/Runner.ES and Generik.TAGTBG. This malware ultimately result in a malicious executable working in reminiscence known as config.dll and detected by ESET’s Superior Reminiscence Scanner as Win32/Dridex.DD.
Home windows occasion logs
Subsequent, I analyzed the supplied .evtx file containing PowerShell logs with Occasion Viewer. Whereas there are different instruments to investigate PowerShell logs, if attackers know easy methods to use living-off-the-land binaries to remain below the radar, defenders must also be well-versed within the native instruments an working system offers.
Because the logs contained 10,434 occasions, I grouped the occasions by date after which ran the Discover motion to search for any occasions containing the $ character. In PowerShell, $ is used to create and reference variables. I discovered an assault taking place on December 24, 2022, when the attacker ran the next script:
It seems to be just like the attacker discovered a secret recipe, switched out the key ingredient of honey for fish oil, after which created a brand new recipe file. This triggered an occasion with an ID of 4104, which stands for the execution of distant PowerShell instructions. So, I filtered the occasions by this ID, serving to me to seek out extra malicious occasions extra shortly.
Suricata Regatta
The final train for the Tolkien Ring was writing 4 Suricata guidelines to watch community site visitors for a Dridex infestation:
alert dns $HOME_NET any -> any any (msg:”Recognized dangerous DNS lookup, doable Dridex an infection”; dns.question; content material:”adv.epostoday.uk”; nocase; sid:1; rev:1;)
alert http 192.185.57.242 any <> any any (msg:”Examine suspicious connections, doable Dridex an infection”; sid:2; rev:1;)
alert tls any any -> any any (msg:”Examine dangerous certificates, doable Dridex an infection”; tls.cert_subject; content material:”CN=heardbellith.Icanwepeh.nagoya”; sid:3; rev:1;)
alert http any any -> any any (msg:”Suspicious JavaScript operate, doable Dridex an infection”; file_data; content material:”let byteCharacters = atob”; sid:4; rev:1;)
So as, these guidelines catch DNS lookups for adv.epostoday[.]uk, connections to the IP handle 192.185.57[.]242, the usage of the malicious server heardbellith.Icanwepeh[.]nagoya recognized by way of the widespread title (CN) in a TLS certificates, and the usage of the JavaScript atob() operate to decode a binary string containing base64-encoded information on the consumer.
Finishing these three challenges earned me the Tolkien Ring:
On to the second ring.
2. Elfen Ring
Essentially the most distinguished challenges for the Elfen Ring have been Jail Escape and Jolly CI/CD.
Jail Escape
Jail Escape was a stern reminder that granting root privileges to a person in a Docker container is simply nearly as good as granting root privileges on the host system. The problem was to interrupt out of the container. Effectively, simply executed if you end up root:
As the foundation person, I listed the partition tables for the gadget after which mounted the host filesystem, granting me full entry to the host. Now I may seek for the important thing, which ought to be situated within the residence listing as revealed by the in-game hints:
Jolly CI/CD
Whereas that was fast, Jolly CI/CD took me the longest of any problem to determine. First, we got a Git repository to clone over HTTP:
From the URL, I may see that the title of the repository was wordpress.flag.internet.inside, so I moved to the repository and located a WordPress web site. I checked if the web site was reside:
Yup, the web site was practical. I used to be curious if there have been any leaked keys within the supply code historical past. If sure, I ought to be capable to push edits to the supply code. So I ran git log:
From the commit messages, it seems to be like a commit was made after including property to repair a whoops. Time to take a look at the pre-whoops commit:
Glorious, I discovered a .ssh listing with keys. Let’s copy these keys over and configure an SSH agent and a Git person to see if I can impersonate the proprietor of these keys:
Now let’s return to the principle department and check if we are able to push a trivial change to the supply code (utilizing nano, I merely added an area to one of many recordsdata):
So, I achieved the primary a part of the problem by impersonating one of many WordPress builders, however did the web site nonetheless work after my push?
My push modified one thing as a result of now the web site redirected to port 8080.
Till now, I had ignored the CI/CD portion of the problem, which ought to be the important thing to finishing it. The repository accommodates a .gitlab-ci.yml file, which offers the configuration for a GitLab CI/CD pipeline. Each time you push to the repository, the CI/CD system kicks in, and a GitLab Runner executes the scripts on this YML file. That’s nearly as good as reaching distant code execution on the server the place GitLab Runner is put in, I assumed.
Wanting nearer, I noticed an rsync script copying all of the recordsdata from the Git repository to the listing on the internet server from which the web site was being served. At first, I attempted to make use of rsync to reverse the information circulate by copying all of the recordsdata from the net server to the Git repository, however with out success.
After quite a lot of speculation testing, I finally had my breakthrough perception: As an alternative of attempting to “repair” the WordPress web site or run malicious scripts by way of the construct system, serve an internet site that leaks data from the net server. Inside index.php (situated on the prime stage of the repository), I can remark out the code that hundreds the WordPress web site and run PHP instructions that probe the net server.
Certainly, I may even run shell instructions with PHP. I discovered that passthru() labored simply.
In index.php, I used // to remark out two strains and I added passthru(‘ls -la /’); on the final line. This creates an internet site that lists all of the recordsdata within the root listing of the net server:
Then I pushed this transformation to the Git repository and the GitLab CI/CD system took care of updating the web site for me:
Ah, the Elfen Ring should be in flag.txt! I repeated the earlier steps, however this time utilizing passthru(‘cat /flag.txt’); revealing the Elfen Ring the subsequent time I requested the web site:
On to the third ring.
3. Internet Ring
Essentially the most enjoyable problem for me was Open Boria Mine Door, though Glamtariel’s Fountain was attention-grabbing whereas additionally presenting riddles.
Open Boria Mine Door
In Open Boria Mine Door, we have been offered with six pins or mini-challenges to bypass enter validation or a Content material Safety Coverage to attach the entry and exit pipes between the pins, together with matching the pipe colours. For many pins, I used HTML to put in writing an inventory of connecting letter ‘o’s. Right here is my ultimate answer:
Pin 1
There was no validation for Pin 1, so it was a easy matter of HTML and inline CSS:
<p fashion=”letter-spacing: -4px; margin: 0; padding: 0;”>oooooooooooooo</p>
<p fashion=“letter-spacing: -4px; margin: 0; padding: 0;”>oooooooooooooo</p>
Pin 2
Pin 2 had a Content material Safety Coverage that disallowed JavaScript however allowed inline CSS, in order that was no drawback for my methodology:
<ul fashion=”list-style: none; line-height:0.5; letter-spacing: -4px; margin: 0; padding: 0;”>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>oooooooooooooo</li>
</ul>
<ul fashion=“list-style: none; line-height:0.5; letter-spacing: -4px; margin: 0; padding: 0;”>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>oooooooooooooo</li>
</ul>
Pin 3
Pin 3 had a Content material Safety Coverage that disallowed CSS however allowed inline JavaScript, so I used JavaScript to alter the kinds as a substitute:
<script>
doc.write(“” +
“<ul id=’o’>” +
“<li>o</li>” +
“<li>oooooooooooooooooooooo</li>” +
“<li>o</li><li>o</li><li>o</li><li>o</li>” +
“</ul>”);
const o = doc.getElementById(‘o’);
o.fashion.colour = “blue”;
o.fashion.listStyle = “none”;
o.fashion.lineHeight = “0.5”;
o.fashion.letterSpacing = “-4px”;
o.fashion.margin = “0”;
o.fashion.padding = “0”;
</script>
<script>
doc.write(“” +
“<ul id=’o’>” +
“<li>o</li>” +
“<li>oooooooooooooooooooooo</li>” +
“<li>o</li><li>o</li><li>o</li><li>o</li>” +
“</ul>”);
const o = doc.getElementById(‘o’);
o.fashion.colour = “blue”;
o.fashion.listStyle = “none”;
o.fashion.lineHeight = “0.5”;
o.fashion.letterSpacing = “-4px”;
o.fashion.margin = “0”;
o.fashion.padding = “0”;
</script>
Pin 4
Pin 4 had no Content material Safety Coverage, however it had a sanitizeInput operate on the consumer aspect that may strip double quotes, single quotes, left angle brackets, and proper angle brackets. The trick right here was to appreciate that this operate wasn’t triggered by submitting the shape, however by the onblur occasion. In different phrases, transferring the mouse away from the enter subject triggered the onblur occasion, sanitizing any enter. The answer was to submit the shape by urgent the Enter key, whereas taking care to not transfer the mouse cursor outdoors the bounds of the enter subject:
<ul fashion=”list-style: none; line-height:0.5; letter-spacing: -4px; margin: 0; padding: 0;”>
<li>o</li>
<li>o</li>
<li>oooooooooooooo</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li fashion=”colour: blue;”>oooooooooooooo</li>
</ul>
<ul fashion=“list-style: none; line-height:0.5; letter-spacing: -4px; margin: 0; padding: 0;”>
<li>o</li>
<li>o</li>
<li>oooooooooooooo</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li>o</li>
<li fashion=“colour: blue;”>oooooooooooooo</li>
</ul>
Pin 5
Pin 5 had the identical sanitizeInput operate and bypass together with a Content material Safety Coverage forbidding inline CSS, however permitting inline JavaScript:
<script>
doc.write(“” +
“<ul id=’o’>” +
“<li>o</li>” +
“<li>o</li>” +
“<li class=”purple”>oooooooooooooo</li>” +
“<li><span class=”purple”>o</span></li>” +
“<li><span class=”purple”>o</span></li>” +
“<li><span class=”purple”>o</span>” +
“<span class=”blue”> ooooooooooo</span></li>” +
“<li><span class=”purple”>o</span>” +
“<span class=”blue”> oo</span></li>” +
“<li><span class=”purple”>o</span>” +
“<span class=”blue”> oo</span></li>” +
“<li><span class=”purple”>o</span>” +
“<span class=”blue”> oo</span></li>” +
“<li>o<span class=”blue”> oo</span></li>” +
“<li>o<span class=”blue”> B</span></li>” +
“</ul>”);
const o = doc.getElementById(‘o’);
o.fashion.listStyle = “none”;
o.fashion.lineHeight = “0.5”;
o.fashion.letterSpacing = “-4px”;
o.fashion.margin = “0”;
o.fashion.padding = “0”;
o.fashion.fontSize = “xx-large”;
const reds = doc.getElementsByClassName(“purple”);
for (let purple of reds) {
purple.fashion.colour = “purple”;
}
const blues = doc.getElementsByClassName(“blue”);
for (let blue of blues) {
blue.fashion.colour = “blue”;
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<script>
doc.write(“” +
“<ul id=’o’>” +
“<li>o</li>” +
“<li>o</li>” +
“<li class=”purple”>oooooooooooooo</li>” +
“<li><span class=”purple”>o</span></li>” +
“<li><span class=”purple”>o</span></li>” +
“<li><span class=”purple”>o</span>” +
“<span class=”blue”> ooooooooooo</span></li>” +
“<li><span class=”purple”>o</span>” +
“<span class=”blue”> oo</span></li>” +
“<li><span class=”purple”>o</span>” +
“<span class=”blue”> oo</span></li>” +
“<li><span class=”purple”>o</span>” +
“<span class=”blue”> oo</span></li>” +
“<li>o<span class=”blue”> oo</span></li>” +
“<li>o<span class=”blue”> B</span></li>” +
“</ul>”);
const o = doc.getElementById(‘o’);
o.fashion.listStyle = “none”;
o.fashion.lineHeight = “0.5”;
o.fashion.letterSpacing = “-4px”;
o.fashion.margin = “0”;
o.fashion.padding = “0”;
o.fashion.fontSize = “xx-large”;
const reds = doc.getElementsByClassName(“purple”);
for (let purple of reds) {
purple.fashion.colour = “purple”;
}
const blues = doc.getElementsByClassName(“blue”);
for (let blue of blues) {
blue.fashion.colour = “blue”;
}
</script>
Pin 6
Lastly, Pin 6 didn’t sanitize the enter, however it used a stricter Content material Safety Coverage forbidding each inline CSS and JavaScript. My answer was to make use of deprecated HTML to get the kinds I wanted and use a desk as a substitute of an inventory:
<desk border=”0″ body=”void” guidelines=”none” cellpadding=”0″ cellspacing=”0″ width=”100%”>
<tr bgcolor=”#00FF00″>
<td><font colour=”#00FF00″ measurement=”7″>o</font></td>
<td><font colour=”#00FF00″ measurement=”7″>o</font></td>
<td><font colour=”#00FF00″ measurement=”7″>o</font></td>
<td><font colour=”#00FF00″ measurement=”7″>o</font></td>
</tr>
<tr bgcolor=”purple”>
<td><font colour=”purple” measurement=”5″>o</font></td>
<td><font colour=”purple” measurement=”5″>o</font></td>
<td><font colour=”purple” measurement=”5″>o</font></td>
<td><font colour=”purple” measurement=”5″>o</font></td>
</tr>
<tr bgcolor=”blue”>
<td><font colour=”blue” measurement=”9″>o</font></td>
<td><font colour=”blue” measurement=”9″>o</font></td>
<td><font colour=”blue” measurement=”9″>o</font></td>
<td bgcolor=”purple”><font colour=”purple” measurement=”9″>o</font></td>
</tr>
<tr bgcolor=”blue”>
<td><font colour=”blue” measurement=”9″>o</font></td>
<td><font colour=”blue” measurement=”9″>o</font></td>
<td><font colour=”blue” measurement=”9″>o</font></td>
<td><font colour=”blue” measurement=”9″>o</font></td>
</tr>
</desk>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<desk border=“0” body=“void” guidelines=“none” cellpadding=“0” cellspacing=“0” width=“100%”>
<tr bgcolor=“#00FF00”>
<td><font colour=“#00FF00” measurement=“7”>o</font></td>
<td><font colour=“#00FF00” measurement=“7”>o</font></td>
<td><font colour=“#00FF00” measurement=“7”>o</font></td>
<td><font colour=“#00FF00” measurement=“7”>o</font></td>
</tr>
<tr bgcolor=“purple”>
<td><font colour=“purple” measurement=“5”>o</font></td>
<td><font colour=“purple” measurement=“5”>o</font></td>
<td><font colour=“purple” measurement=“5”>o</font></td>
<td><font colour=“purple” measurement=“5”>o</font></td>
</tr>
<tr bgcolor=“blue”>
<td><font colour=“blue” measurement=“9”>o</font></td>
<td><font colour=“blue” measurement=“9”>o</font></td>
<td><font colour=“blue” measurement=“9”>o</font></td>
<td bgcolor=“purple”><font colour=“purple” measurement=“9”>o</font></td>
</tr>
<tr bgcolor=“blue”>
<td><font colour=“blue” measurement=“9”>o</font></td>
<td><font colour=“blue” measurement=“9”>o</font></td>
<td><font colour=“blue” measurement=“9”>o</font></td>
<td><font colour=“blue” measurement=“9”>o</font></td>
</tr>
</desk>
Glamtariel’s Fountain
Glamtariel’s Fountain was a possibility to follow XML Exterior Entity (XXE) assaults. Determining easy methods to outline a customized XML entity, defining an entity that requests a file from the server, and including that entity as a payload to an HTTP request was not arduous. The toughest half was determining the in-game riddles to divine the trail to the recordsdata that the server would leak. Right here is the breakthrough request revealing the situation of the gold ring:
I might supply two classes realized from this problem. First, use the Content material Kind Converter extension in Burp to transform JSON payloads to XML. Second, strive inserting the XXE payload in several tags – it took me a very long time to determine that every one I needed to do was place the &xxe; payload within the reqType tag as a substitute of the imgDrop tag.
On to the fourth ring.
4. Cloud Ring
Enjoying for the Cloud Ring was a newbie’s foray into the Amazon Internet Companies (AWS) Command Line Interface (CLI).
The spotlight of this set of challenges was utilizing trufflehog to seek out AWS credentials in a Git repository after which exploiting them to authenticate as an AWS person. An attacker that will get to this place can use aws iam instructions to question the insurance policies that apply to the person, and thus which cloud property will be accessed and abused.
On to the fifth ring.
5. Burning Ring of Fireplace
Essentially the most instructive a part of this set of challenges was studying about Merkle Timber to take advantage of a wise contract and get on the presale listing for buying a non-fungible token (NFT). Right here the problem was to find the proof values that, together with my pockets handle and the foundation worth of a Merkle Tree, proved my inclusion on the presale listing.
After just a few unsuccessful makes an attempt to offer proof values, I noticed that I might by no means be capable to work out the proof values for the supplied root worth as a result of there was no method to know all of the leaf values used to calculate it. I wanted to alter the foundation worth in order that I may present a sound Merkle Tree.
Utilizing Professor QPetabyte’s software, I created a Merkle Tree from two leaves consisting of my pockets handle and the handle for the BSRS_nft good contract, which I discovered utilizing the in-game Blockchain Explorer in block two of the sport’s Ethereum blockchain. The software generated the foundation worth of this tree and the proof worth for my pockets handle. Then I used Burp to intercept the request to the server and adjusted the default root worth in order that I may submit a sound Merkle Tree. Right here is my NFT sporc purchased at a hard and fast worth of 100 KringleCoins:
An unpleasant specimen certainly.
Finale
A giant thanks to the organizers of the SANS Vacation Hack Problem for stretching my thoughts in new methods and serving to to deepen my cybersecurity data. Not solely am I trying ahead to subsequent 12 months’s problem, however I’ll even be attempting out the 2020 and 2021 editions of this problem. And in the event you haven’t participated on this problem earlier than, I hope these highlights have piqued your curiosity.