KringleCon 4: Four Calling Birds WriteUp - Kerberoasting on an Open Fire
Posted: Jan 26, 2022 | ~ 6 mins read time#ctf #kringlecon-2021 #active-directory
Objective: Kerberoasting on an Open Fire
Obtain the secret sleigh research document from a host on the Elf University domain. What is the first secret ingredient Santa urges each elf and reindeer to consider for a wonderful holiday season? Start by registering as a student on the ElfU Portal.
Summary
This is probably the longest walkthrough I’ve created as this challenge had many steps. With that in mind, here’s a TL;DR in case you just want the high-level stuff.
- Escape Python program
- Escape Python shell
- Enumerate network
- Enumerate open shares
- Enumerate accounts
- Get user SPNs
- Generate wordlist and crack password hash
- Escalate privilege and move laterally
- Add basic user account to privileged AD group
- Access restricted share and exfiltrate data
Details
Once I registered for the ELFU Portal, I got credentials and SSH instructions to access the grading system:
If I entered anything except 1
or e
, the page was just reloaded.
So I wondered if there was a way to escape the program - either via SSH commands when authenticating or a special input once the page was loaded. I went down the rabbit hole of SSH first but without any luck. (But I did learn a lot about SSH escape codes and flags from this SANS article and this SSH.org article.)
Next, I tred to escape the program using a special input once the page was loaded. Hints on Discord mentioned the page was running python so I tried quit()
, eval(quit())
, exit()
, and other similar methods but these attempts either ended the session or just reloaded the page.
The secret was actually the escape sequence CTRL+D to force the end-of-file (EOF) signal. CT +C didn’t interrupt the script but CTRL+D worked like a charm and dropped me into a Python shell.
Mark Baggett demonstrated several different methods to escape a Python shell on YouTube but I kept it simple by running os.system(/bin/bash)
Once I was on the internal network as an authenticated user, I was ready to start prepping to attack AD! (Side note: I referenced Chris Davis’ YouTube video on attacking AD and Michael Koczwara’s writeup on ASEP roasting and Kerberoasting a lot throughout this process.)
My first step was to identify all the routes and recently resolved IPs.
According to the route
output, my current subnet was pretty large: /16 or room for 65534 hosts. This would take way too long to scan the entire subnet. Instead, I used the output from arp
to only target live hosts.
To do that, I saved the output of arp to a text file and formatted it to only include one IP per line:
Then, I ran Nmap against that list to see what ports were open and what services were running on each host.
Out of all of those hosts (and there were over 200), only one stood out as a Windows device with SMB open - SHARE30.
Sometimes, admins don’t lock down shares to specific users and leave it open to all authenticated accounts. In this case, I was able to enumerate shares and view the contents of sysvol
(nothing interesting there but a couple empty directories) but the shares elfu_svc_shr
and research_dep
were locked down.
The share IPC$
caught my attention since that can be used to enumerate account names. Impacket has a nice little script called lookupsid.py
that can do it if you just provide the user account to do the enumeration and the IP of the host with the open share.
After that script ran, I also formatted the output to only capture the user accounts minus the domain. This was so I could use the output with Impacket’s GetUserSPNs.py script to capture ticket info that will include a user account’s encrypted password.
Once I had a hash of elfu_svc’s password, I needed to crack it. Earlier, one of the elves hinted that I could use CeWL (a Customer Word List generator) against the ELFU portal.
With a wordlist in hand, I used Hashcat to crack the password.
I was then able to access the elfu_svc_shr
with these new credentials and copy files to my current directory. I eventually discovered Get-ProcessInfo.ps1
had password information.
I suspected the remote_elf account had special privileges so I modified the PowerShell script to target DC01 (the name was discovered in the lookupsid.py output) and start a remote PowerShell session.
From here, I wanted to enumerate the AD groups. Remembering that my goal was to access the research_dep share, I was looking for a group with the name “research department” or similar.
Then, I needed to check if the remove_elf account could edit that Research Department group membership:
Since I had WriteDacl
access through the remote_elf account, I added my basic account (the one given when I first signed up) to the Research Department group.
Now I was ready to access the share so I exited the PowerShell session and initiated the smbclient
to grab a copy of the file:
But dang it! It was in PDF format so I had to then move the copy off of the ELFU network and on to my own machine. This took some time to figure out but I realized if I could switch the default login shell (which was originally set to the grading Python script) to bash, I would be able to run SCP commands and pull the file down locally.
Opening up the PDF, it was clear the flag was kindness
.
To see my other writeups for this CTF, check out the tag #kringlecon-2021.
References
- SANS SSH info
- SSH.org
- Escaping Pythong Shells with Mark Baggett
- Attacking AD with Chris Davis
- ASEP Roasting and Kerberoasting Walkthrough by Michael Koczwara
- Impacket’s lookupsid.py
- Impacket’s GetUserSPNs.py
- CeWL documentation
- Hashcat documentation -[] PowerShell snippets from Chris Davis](https://github.com/chrisjd20/hhc21_powershell_snippets)
- Default login shell documentation
- SCP documentation