diff --git a/content/posts/liveoverflow-minecraft-server.md b/content/posts/liveoverflow-minecraft-server.md index b59c5aa..4d14535 100644 --- a/content/posts/liveoverflow-minecraft-server.md +++ b/content/posts/liveoverflow-minecraft-server.md @@ -25,7 +25,6 @@ During one of his earlier videos, LiveOverflow challenged his viewers to find th In LiveOverflow's eighth video, [he told his viewers that the server has been opened to the public](https://youtu.be/QradKmQ27JY?t=1246). I immediately started looking for ways to find it. After researching for a while, I found multiple ways to find it, but I thought they would all take a fair bit of time (I'll get back to this later). So, instead of spending time actually learning stuff, I rewatched his videos to see if there would be a clue in there. Luckily it worked out. In [one video](https://youtu.be/Hmmr1oLt-V8?t=28) he blurred the IP inside the terminal, but forgot about the terminal title bar :smile:. I notified him of this, as it was obviously unintended, and the IP was changed shortly after, as many people apparently found it. - {{< figure src="/img/posts/liveoverflow-minecraft-server/first_ip_screenshot.png" title="Screenshot of video containing the IP address" >}} ### IP change @@ -36,7 +35,7 @@ During my research, I came across masscan. This is a piece of software that lets I got to work and wrote a script that scans the IP range in which the old IP was located. It starts by using masscan to scan the entire range of IP addresses, and saves it to a file to use later. I then read this file, and request basic Minecraft server information like its MOTD, players and favicon. This information was saved in another file, in which, I could easily search for LiveOverflow. In the end, the new IP only had one digit changed. -{{< code language="python" title="scan.py" isCollapsed="true" >}} +{{< collapsible-block badge="python" title="scan.py" isCollapsed="true" >}} ```py import masscan @@ -261,7 +260,7 @@ print(len(current_servers)) print(len(valid_servers)) ``` -{{< /code >}} +{{< /collapsible-block >}} _This code is copied from a Jupyter Notebook, so it's not the most efficient and may not even work, the [here for the Github Gist of the Notebook](https://gist.github.com/maikka39/8019e2f1a45e1021fff05bd1e1688e14)_ @@ -354,7 +353,7 @@ if ((delta > 1f / 256 || deltaAngle > 10f) && !this.player.isImmobile()) { } ``` -In short, this code means we can move around a tiny bit before a `PlayerMoveEvent` is sent. This caught my interest, as I thought there might be a way to change the `lastPos`. After reading more code, I found out there was! +In short, this code means we can move around a tiny bit before a `PlayerMoveEvent` is sent. This caught my interest, as I thought there might be a way to change the `lastPos`. After reading more code, I found out there was! If we send a position that is far away, like x+100, y+100, the player will be teleported back before the `PlayerMoveEvent` gets sent. During this teleport action, `lastPos` get set to the position the player had before the “far away packet” was sent. diff --git a/content/writeups/adventofctf/2020/challenge_13.md b/content/writeups/adventofctf/2020/challenge_13.md index 8394917..85796ac 100644 --- a/content/writeups/adventofctf/2020/challenge_13.md +++ b/content/writeups/adventofctf/2020/challenge_13.md @@ -24,7 +24,7 @@ aliases = [ ] +++ -- Points: 1300 +- Points: 1300 ## Description @@ -117,7 +117,7 @@ Let's try to use the previous attack but with the flag file: We get a big error: -{{< code language="html" title="Error message" >}} +{{< collapsible-block badge="html" title="Error message" >}} ```html
@@ -183,7 +183,7 @@ line: 3 in /var/www/html/index.php on line 40
/var/www/html/index.php on line 43
``` -{{< /code >}} +{{< /collapsible-block >}} We probably got it because PHP is actually handling the PHP file as a PHP file 😀. This means we have to get it in some other way. diff --git a/content/writeups/adventofctf/2020/challenge_16.md b/content/writeups/adventofctf/2020/challenge_16.md index 693b9ab..e1375cc 100644 --- a/content/writeups/adventofctf/2020/challenge_16.md +++ b/content/writeups/adventofctf/2020/challenge_16.md @@ -25,7 +25,7 @@ aliases = [ ] +++ -- Points: 1600 +- Points: 1600 ## Description @@ -41,12 +41,12 @@ When opening the source of the page we also find the following comment: "Here is ```js function send() { - let emoji = $("#emoji")[0].value; - if (emoji.length > 0) { - $.post("/", { emoji: emoji }, function (data) { - $("#msg")[0].innerHTML = "" + data + ""; - }); - } + let emoji = $("#emoji")[0].value; + if (emoji.length > 0) { + $.post("/", { emoji: emoji }, function (data) { + $("#msg")[0].innerHTML = "" + data + ""; + }); + } } ``` @@ -74,7 +74,7 @@ This means the server is most likely using either Jinja2 of Twig. Now that we found the vulnerability, we can start exploiting it. Let's start by getting the config. We can try to get it by entering `{{config}}` or `{{config.items()}}` as the emoji. -{{< code language="python" title="Result" >}} +{{< collapsible-block badge="python" title="Result" >}} ```python dict_items([ @@ -224,7 +224,7 @@ dict_items([ ]) ``` -{{< /code >}} +{{< /collapsible-block >}} If we take a look at it we find an item called 'flag' but it looks like it is encrypted in some way: @@ -282,7 +282,7 @@ The source of the server is probably `app.py` as it's the default for flask appl config.__class__.__init__.__globals__['os'].popen('cat app.py').read() ``` -{{< code language="python" title="app.py" >}} +{{< collapsible-block badge="python" title="app.py" >}} ```python import random @@ -332,7 +332,7 @@ if __name__ == '__main__': ``` -{{< /code >}} +{{< /collapsible-block >}} When looking at the file, we see that the flag variable is set to the output of the `magic` function: diff --git a/content/writeups/adventofctf/2020/challenge_17.md b/content/writeups/adventofctf/2020/challenge_17.md index ef35eba..5730ab4 100644 --- a/content/writeups/adventofctf/2020/challenge_17.md +++ b/content/writeups/adventofctf/2020/challenge_17.md @@ -25,7 +25,7 @@ aliases = [ ] +++ -- Points: 1700 +- Points: 1700 ## Description @@ -41,12 +41,12 @@ When opening the source of the page we also find the following comment: "Here is ```js function send() { - let emoji = $("#emoji")[0].value; - if (emoji.length > 0) { - $.post("/", { emoji: emoji }, function (data) { - $("#msg")[0].innerHTML = "" + data + ""; - }); - } + let emoji = $("#emoji")[0].value; + if (emoji.length > 0) { + $.post("/", { emoji: emoji }, function (data) { + $("#msg")[0].innerHTML = "" + data + ""; + }); + } } ``` @@ -154,7 +154,7 @@ To get the subclasses, we first have to convert `''.__class__.__mro__[1].__subcl After submitting this, we get the following result: -{{< code language="text" title="Result" >}} +{{< collapsible-block badge="text" title="Result" >}} ```js [ @@ -643,7 +643,7 @@ After submitting this, we get the following result: ] ``` -{{< /code >}} +{{< /collapsible-block >}} In this result we find the following class: ``. This is the `os` module and it is on index `127`. We can verify it's index by getting it from the submodules list using the following input: @@ -680,7 +680,7 @@ Now let's grab the contents of `app.py`: {{ [[[""|attr("\x5f\x5fclass\x5f\x5f")|attr("\x5f\x5fmro\x5f\x5f")][0][1]|attr("\x5f\x5fsubclasses\x5f\x5f")()][0][127]|attr("\x5f\x5finit\x5f\x5f")|attr("\x5f\x5fglobals\x5f\x5f")][0]["popen"]("cat app\x2epy")|attr("read")() }} ``` -{{< code language="python" title="app.py" >}} +{{< collapsible-block badge="python" title="app.py" >}} ```py import random @@ -732,7 +732,7 @@ if __name__ == '__main__': app.run(host='0.0.0.0', port=8000) ``` -{{< /code >}} +{{< /collapsible-block >}} ## Magic function diff --git a/content/writeups/adventofctf/2020/challenge_22.md b/content/writeups/adventofctf/2020/challenge_22.md index ce69bdc..3074056 100644 --- a/content/writeups/adventofctf/2020/challenge_22.md +++ b/content/writeups/adventofctf/2020/challenge_22.md @@ -25,7 +25,7 @@ aliases = [ ] +++ -- Points: 2200 +- Points: 2200 ## Description @@ -49,8 +49,8 @@ When opening the page, we will see a broken image, this is expected as the file ```html ``` @@ -80,64 +80,71 @@ Alas, we get the cat picture again. That's weird. There might be a filter on the Using the same decoding method, we get the following result: -{{< code language="php" title="index.php" >}} +{{< collapsible-block badge="php" title="index.php" >}} ```html - - - - Advent of CTF 22 - - - - - - - - -
-
-
-
-

- Advent of CTF 22 -

-
- Your daily dose of CTF for December -
- -
-
-
-
-

The big reveal

-
-
- + + + Advent of CTF 22 + + + + + + + + +
+
+
+
+

+ Advent of CTF 22 +

+
+ Your daily dose of CTF for December +
+ +
+
+
+
+

The big reveal

+
+
+ - Is this santa? - Is this santa? + '; - } ?> -
- -
-
-
-
-
-
-
-
- -
-
-

- - The Advent of CTF is brought to you by - NOVI Hogeschool. It - is built by - @credmp. If you are looking for a Dutch Cyber Security - Bachelor degree or bootcamp, - check us out. - -

+ } ?> +
+ +
+
+
+
+
+
+
+
+ +
+
+

+ + The Advent of CTF is brought + to you by + NOVI Hogeschool. It is built by + + @credmp. If you are looking for a + Dutch Cyber Security + Bachelor degree or bootcamp, + check us out. + +

+
+
+
+
+
-
-
-
-
-
- + ``` -{{< /code >}} +{{< /collapsible-block >}} Just the PHP part: diff --git a/content/writeups/adventofctf/2020/challenge_24.md b/content/writeups/adventofctf/2020/challenge_24.md index c840e7c..6ba60f8 100644 --- a/content/writeups/adventofctf/2020/challenge_24.md +++ b/content/writeups/adventofctf/2020/challenge_24.md @@ -26,7 +26,7 @@ aliases = [ ] +++ -- Points: 2400 +- Points: 2400 ## Description @@ -97,7 +97,7 @@ In [3]: pickle.loads(base64.b64decode("gAN9cQAoWAUAAABib2FyZHEBXXECKF1xAyhYAQAAA This time our board is quite a bit larger: -{{< code language="py" title="Board" >}} +{{< collapsible-block badge="py" title="Board" >}} ```py { @@ -179,7 +179,7 @@ This time our board is quite a bit larger: } ``` -{{< /code >}} +{{< /collapsible-block >}} We can see that a `chain` value has been added. From the title of this challenge, we can say that this is the blockchain that we likely have to bypass. @@ -230,7 +230,7 @@ We can see that, to verify the game, the function loops through all the blocks i To crack this, we can simply reverse this algorithm. To do this, I grabbed the script from the HTML source, and added a crack method like so: -{{< code language="py" title="solve.py" >}} +{{< collapsible-block badge="py" title="solve.py" >}} ```python import hashlib @@ -304,7 +304,7 @@ if __name__ == "__main__": print(export_base64(game)) ``` -{{< /code >}} +{{< /collapsible-block >}} After running this script, we get the following result: diff --git a/content/writeups/adventofctf/2020/challenge_4.md b/content/writeups/adventofctf/2020/challenge_4.md index 96c469a..36f6214 100644 --- a/content/writeups/adventofctf/2020/challenge_4.md +++ b/content/writeups/adventofctf/2020/challenge_4.md @@ -24,7 +24,7 @@ aliases = [ ] +++ -- Points: 400 +- Points: 400 ## Description @@ -36,64 +36,64 @@ Visit to start the challenge. When opening the website we're (for the first time) not provided with a login form. It is still authentication though as we are greeted with a message: "If you have access to it the special present will be shown below:". Also, I noticed the URL changed after about five seconds. That hints at some javascript, so let's open the sources tab in devtools. We find `login.js`. -{{< code language="js" title="login.js" >}} +{{< collapsible-block badge="js" title="login.js" >}} ```js function startup() { - key = localStorage.getItem("key"); + key = localStorage.getItem("key"); - if (key === null) { - localStorage.setItem("key", "eyJ1c2VyaWQiOjB9.1074"); - } + if (key === null) { + localStorage.setItem("key", "eyJ1c2VyaWQiOjB9.1074"); + } } var _0x1fde = ["charCodeAt"]; (function (_0x93ff3a, _0x1fded8) { - var _0x39b47b = function (_0x54f1d3) { - while (--_0x54f1d3) { - _0x93ff3a["push"](_0x93ff3a["shift"]()); - } - }; - _0x39b47b(++_0x1fded8); + var _0x39b47b = function (_0x54f1d3) { + while (--_0x54f1d3) { + _0x93ff3a["push"](_0x93ff3a["shift"]()); + } + }; + _0x39b47b(++_0x1fded8); })(_0x1fde, 0x192); var _0x39b4 = function (_0x93ff3a, _0x1fded8) { - _0x93ff3a = _0x93ff3a - 0x0; - var _0x39b47b = _0x1fde[_0x93ff3a]; - return _0x39b47b; + _0x93ff3a = _0x93ff3a - 0x0; + var _0x39b47b = _0x1fde[_0x93ff3a]; + return _0x39b47b; }; function calculate(_0x54f1d3) { - var _0x58628b = _0x39b4, - _0xc289d4 = 0x0; - for (let _0x19ddf3 in text) { - _0xc289d4 += text[_0x58628b("0x0")](_0x19ddf3); - } - return _0xc289d4; + var _0x58628b = _0x39b4, + _0xc289d4 = 0x0; + for (let _0x19ddf3 in text) { + _0xc289d4 += text[_0x58628b("0x0")](_0x19ddf3); + } + return _0xc289d4; } function check() { - key = localStorage.getItem("key"); - hash = window.location.search.split("?")[1]; + key = localStorage.getItem("key"); + hash = window.location.search.split("?")[1]; - if (key !== null && hash != "token=" + key) { - parts = key.split("."); - text = atob(parts[0]); - checksum = parseInt(parts[1]); + if (key !== null && hash != "token=" + key) { + parts = key.split("."); + text = atob(parts[0]); + checksum = parseInt(parts[1]); - count = calculate(text); + count = calculate(text); - if (count == checksum) { - setTimeout(function () { - window.location = "index.php?token=" + key; - }, 5000); + if (count == checksum) { + setTimeout(function () { + window.location = "index.php?token=" + key; + }, 5000); + } } - } } startup(); check(); ``` -{{< /code >}} +{{< /collapsible-block >}} This looks like some obfuscated code. So I started with de-obfuscating the code. After a few minutes of reading the code, I remembered to always start at the output. And after looking at the `check()` function I found out I had wasted my time. @@ -101,42 +101,42 @@ As it turns out, we don't need to know what the obfuscated code does. If we read ```js function check() { - // Get key from localStorage - // The key is initialized in startup() - // > "eyJ1c2VyaWQiOjB9.1074" - key = localStorage.getItem("key"); - - // Get the token from the url - // > "token=eyJ1c2VyaWQiOjB9.1074" - hash = window.location.search.split("?")[1]; - - // If key and hash are not empty: - if (key !== null && hash != "token=" + key) { - // Split the key by a . - // > (2) ["eyJ1c2VyaWQiOjB9", "1074"] - parts = key.split("."); - - // Decode the base64 from the first part of the key - // > "{"userid":0}" - text = atob(parts[0]); - - // Get the value of the second part of the key as an int - // > 1074 - checksum = parseInt(parts[1]); - - // Calculate the value of text - // > 1074 - count = calculate(text); - - // If the last part of the key is correct: - if (count == checksum) { - // Execute this function after 5000ms - setTimeout(function () { - // Execute a get request with the token parameter - window.location = "index.php?token=" + key; - }, 5000); + // Get key from localStorage + // The key is initialized in startup() + // > "eyJ1c2VyaWQiOjB9.1074" + key = localStorage.getItem("key"); + + // Get the token from the url + // > "token=eyJ1c2VyaWQiOjB9.1074" + hash = window.location.search.split("?")[1]; + + // If key and hash are not empty: + if (key !== null && hash != "token=" + key) { + // Split the key by a . + // > (2) ["eyJ1c2VyaWQiOjB9", "1074"] + parts = key.split("."); + + // Decode the base64 from the first part of the key + // > "{"userid":0}" + text = atob(parts[0]); + + // Get the value of the second part of the key as an int + // > 1074 + checksum = parseInt(parts[1]); + + // Calculate the value of text + // > 1074 + count = calculate(text); + + // If the last part of the key is correct: + if (count == checksum) { + // Execute this function after 5000ms + setTimeout(function () { + // Execute a get request with the token parameter + window.location = "index.php?token=" + key; + }, 5000); + } } - } } ``` @@ -148,14 +148,14 @@ Let's turn this into some code: ```js function generateHash(input) { - // Set the global text variable defined in - // login.js, otherwise calculate doesn't work - text = input; + // Set the global text variable defined in + // login.js, otherwise calculate doesn't work + text = input; - let count = calculate(text); - let key = btoa(text) + "." + count; + let count = calculate(text); + let key = btoa(text) + "." + count; - console.log(key); + console.log(key); } generateHash('{"userid":0}'); diff --git a/content/writeups/adventofctf/2020/challenge_6.md b/content/writeups/adventofctf/2020/challenge_6.md index c095a29..e63f08f 100644 --- a/content/writeups/adventofctf/2020/challenge_6.md +++ b/content/writeups/adventofctf/2020/challenge_6.md @@ -24,7 +24,7 @@ aliases = [ ] +++ -- Points: 600 +- Points: 600 ## Description @@ -72,7 +72,7 @@ As you can see the string is escaped and the result of this query will have the When submitting it I got the following result: -{{< code language="text" title="Result" >}} +{{< collapsible-block badge="text" title="Result" >}} ```markdown | id | Description | Proof | @@ -244,7 +244,7 @@ When submitting it I got the following result: | secrets | 2-------- | 3------- | ``` -{{< /code >}} +{{< /collapsible-block >}} ## Solution diff --git a/content/writeups/google-ctf/2021/beginners-quest/3.md b/content/writeups/google-ctf/2021/beginners-quest/3.md index 7ce1517..0618744 100644 --- a/content/writeups/google-ctf/2021/beginners-quest/3.md +++ b/content/writeups/google-ctf/2021/beginners-quest/3.md @@ -58,9 +58,9 @@ Upon opening the website, we're greeted with a code editor and some text: > > The controlCar function takes a single parameter – `scanArray` – which is an array containing 17 integers denoting distance > from your car to the nearest obstacle: > -> - [indexes 0-7]: on the left side of the car (index 7 is the measurement at the left headlight), -> - [index 8]: at the center of the car, -> - [indexes 9-16]: on the right side of the car (index 9 is the measurement at the right headlight). +> - [indexes 0-7]: on the left side of the car (index 7 is the measurement at the left headlight), +> - [index 8]: at the center of the car, +> - [indexes 9-16]: on the right side of the car (index 9 is the measurement at the right headlight). > > See also [this image]({{< ref "#radar-image" >}}) (it's not precise, but will give you an idea what you are looking at). > @@ -72,9 +72,9 @@ Upon opening the website, we're greeted with a code editor and some text: > > The `controlCar` must return an integer denoting where the car should drive: > -> - -1 (or any other negative value): drive more to the left, -> - 0: continue straight / straighten up the car, -> - 1 (or any other positive value): drive more to the right. +> - -1 (or any other negative value): drive more to the left, +> - 0: continue straight / straighten up the car, +> - 1 (or any other positive value): drive more to the right. When opening the source, we also find the following comment: @@ -92,66 +92,66 @@ When opening the source, we also find the following comment: To solve this challenge, I came up with the following script: -{{< code language="js" title="solve.js" >}} +{{< collapsible-block badge="js" title="solve.js" >}} ```js function controlCar(scanArray) { - if (!window.has_reset_game) { - window.has_reset_game = true; - window.car_position = 0; - window.queue = []; - } - - if (window.queue.length === 0) { - let left, center, right; - - if (window.car_position === -1) { - left = 8; - center = 12; - right = 15; - } else if (window.car_position === 0) { - left = 4; - center = 8; - right = 12; - } else if (window.car_position === 1) { - left = 1; - center = 4; - right = 8; + if (!window.has_reset_game) { + window.has_reset_game = true; + window.car_position = 0; + window.queue = []; } - left = scanArray[left]; - center = scanArray[center]; - right = scanArray[right]; - - let furthest = Math.max(left, center, right); - let closest = Math.min(left, center, right); - - console.log(left, center, right); - - let moveInDirection = (direction) => { - console.log("Going in direction", direction); - if (direction === window.car_position) { - window.queue.push(0); - } else if (direction > window.car_position) { - window.queue.push(1, 1, 1, 1); - window.car_position += 1; - } else if (direction < window.car_position) { - window.queue.push(-1, -1, -1, -1); - window.car_position -= 1; - } - }; - - if (closest < 0) moveInDirection(window.car_position); - else if (furthest === left) moveInDirection(-1); - else if (furthest === center) moveInDirection(0); - else if (furthest === right) moveInDirection(1); - } - - return window.queue.pop(); + if (window.queue.length === 0) { + let left, center, right; + + if (window.car_position === -1) { + left = 8; + center = 12; + right = 15; + } else if (window.car_position === 0) { + left = 4; + center = 8; + right = 12; + } else if (window.car_position === 1) { + left = 1; + center = 4; + right = 8; + } + + left = scanArray[left]; + center = scanArray[center]; + right = scanArray[right]; + + let furthest = Math.max(left, center, right); + let closest = Math.min(left, center, right); + + console.log(left, center, right); + + let moveInDirection = (direction) => { + console.log("Going in direction", direction); + if (direction === window.car_position) { + window.queue.push(0); + } else if (direction > window.car_position) { + window.queue.push(1, 1, 1, 1); + window.car_position += 1; + } else if (direction < window.car_position) { + window.queue.push(-1, -1, -1, -1); + window.car_position -= 1; + } + }; + + if (closest < 0) moveInDirection(window.car_position); + else if (furthest === left) moveInDirection(-1); + else if (furthest === center) moveInDirection(0); + else if (furthest === right) moveInDirection(1); + } + + return window.queue.pop(); } ``` -{{< /code >}} +{{< /collapsible-block >}} It starts off by initializing some global variables if the game is running for the first time (or after a restart). After which, it check if there are still moves in the queue. If so, it grabs the last item out of the queue and returns it. diff --git a/content/writeups/google-ctf/2021/beginners-quest/4.md b/content/writeups/google-ctf/2021/beginners-quest/4.md index 0111d4c..a179ec9 100644 --- a/content/writeups/google-ctf/2021/beginners-quest/4.md +++ b/content/writeups/google-ctf/2021/beginners-quest/4.md @@ -43,7 +43,7 @@ You’re taking a stroll in the lab, when Dr. Klostermann is calling your name: [attachment.zip](/files/writeups/google-ctf/2021/beginners-quest/4/attachment.zip) -{{< code language="c" title="chal.c" isCollapsed="true" >}} +{{< collapsible-block badge="c" title="chal.c" isCollapsed="true" >}} ```c #include @@ -208,7 +208,7 @@ int main(void) } ``` -{{< /code >}} +{{< /collapsible-block >}} ## Recon @@ -308,7 +308,7 @@ for set_mask, clr_mask in zip(set_masks, clr_masks): print(flag.strip()) ``` -{{< code language="py" title="Full code" isCollapsed="true" >}} +{{< collapsible-block badge="py" title="Full code" isCollapsed="true" >}} ```py set_mask_str = "gpio_set_mask" @@ -343,7 +343,7 @@ for set_mask, clr_mask in zip(set_masks, clr_masks): print(flag.strip()) ``` -{{< /code >}} +{{< /collapsible-block >}} ## Solution diff --git a/content/writeups/google-ctf/2021/beginners-quest/5.md b/content/writeups/google-ctf/2021/beginners-quest/5.md index 9d01a0b..6c90caa 100644 --- a/content/writeups/google-ctf/2021/beginners-quest/5.md +++ b/content/writeups/google-ctf/2021/beginners-quest/5.md @@ -50,7 +50,7 @@ As you and Gökhan are leaving the crates to enter a car, you spot the tough guy [attachment.zip](/files/writeups/google-ctf/2021/beginners-quest/5/attachment.zip) -{{< code language="py" title="RoboCaller1337.py" isCollapsed="true" >}} +{{< collapsible-block badge="py" title="RoboCaller1337.py" isCollapsed="true" >}} ```py import random @@ -103,9 +103,9 @@ if __name__ == "__main__": main() ``` -{{< /code >}} +{{< /collapsible-block >}} -{{< code language="txt" title="robo_numbers_list.txt" isCollapsed="true" >}} +{{< collapsible-block badge="txt" title="robo_numbers_list.txt" isCollapsed="true" >}} ```txt 263-170-6234 @@ -734,7 +734,7 @@ if __name__ == "__main__": 446-996-9104 ``` -{{< /code >}} +{{< /collapsible-block >}} ## Recon @@ -793,7 +793,7 @@ for a,b in zip(key, secret): print(flag) ``` -{{< code language="py" title="Full code" isCollapsed="true" >}} +{{< collapsible-block badge="py" title="Full code" isCollapsed="true" >}} ```py from mt19937predictor import MT19937Predictor @@ -816,7 +816,7 @@ for a,b in zip(key, secret): print(flag) ``` -{{< /code >}} +{{< /collapsible-block >}} ## Solution diff --git a/content/writeups/google-ctf/2021/beginners-quest/6.md b/content/writeups/google-ctf/2021/beginners-quest/6.md index f754863..b6c9bd9 100644 --- a/content/writeups/google-ctf/2021/beginners-quest/6.md +++ b/content/writeups/google-ctf/2021/beginners-quest/6.md @@ -50,7 +50,7 @@ After having climbed through the window, you wait for a while on the ground. The [attachment.zip](/files/writeups/google-ctf/2021/beginners-quest/6/attachment.zip) -{{< code language="txt" title="encodings" isCollapsed="true" >}} +{{< collapsible-block badge="txt" title="encodings" isCollapsed="true" >}} ```text I made a super secret encoder. I remember using: @@ -64,15 +64,15 @@ I made a super secret encoder. I remember using: I also use gzip and zlib (to compress the stuff) and I like hiding things in files... ``` -{{< /code >}} +{{< /collapsible-block >}} -{{< code language="txt" title="chall.txt" isCollapsed="true" >}} +{{< collapsible-block badge="txt" title="chall.txt" isCollapsed="true" >}} ```txt File is too large to display here. ``` -{{< /code >}} +{{< /collapsible-block >}} ## Recon @@ -336,7 +336,7 @@ for line in data: print(line) ``` -{{< code language="text" title="output" >}} +{{< collapsible-block badge="text" title="output" >}} ```text nyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyya~ @@ -776,7 +776,7 @@ nyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyya~ nyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyya~ ``` -{{< /code >}} +{{< /collapsible-block >}} ### nya~ @@ -841,43 +841,43 @@ Then, let's follow the steps to convert brainfuck to Unary in reverse. 1. Remove the leading `1` - ```py - unary_code = unary_code[1:] - ``` + ```py + unary_code = unary_code[1:] + ``` 2. Replace unary with brainfuck - ```py - for i in range(0, len(unary_code), 3): - operation = unary_code[i:i+3] - - if operation == "000": - brainfuck_code += ">" - elif operation == "001": - brainfuck_code += "<" - elif operation == "010": - brainfuck_code += "+" - elif operation == "011": - brainfuck_code += "-" - elif operation == "100": - brainfuck_code += "." - elif operation == "101": - brainfuck_code += "," - elif operation == "110": - brainfuck_code += "[" - elif operation == "111": - brainfuck_code += "]" - ``` + ```py + for i in range(0, len(unary_code), 3): + operation = unary_code[i:i+3] + + if operation == "000": + brainfuck_code += ">" + elif operation == "001": + brainfuck_code += "<" + elif operation == "010": + brainfuck_code += "+" + elif operation == "011": + brainfuck_code += "-" + elif operation == "100": + brainfuck_code += "." + elif operation == "101": + brainfuck_code += "," + elif operation == "110": + brainfuck_code += "[" + elif operation == "111": + brainfuck_code += "]" + ``` 3. Print the result: - ```py - print(brainfuck_code) - ``` + ```py + print(brainfuck_code) + ``` - ```bf - [-]>[-]<++++++[>++++++++++<-]>+++++++.<+[>++++++++++<-]>+++++++.<+[>----------<-]>----.<+++++[>++++++++++<-]>+++.<+[>----------<-]>-.<[>----------<-]>----.<+++++[>----------<-]>-------.<[>++++++++++<-]>+.<++++++[>++++++++++<-]>+++.<++++++[>----------<-]>----.<++++[>++++++++++<-]>++++.<+[>++++++++++<-]>+++++.<++++++[>----------<-]>--.<++++[>++++++++++<-]>+++++++.<+[>++++++++++<-]>++++.<++++++[>----------<-]>-.<[>++++++++++<-]>++++.<++++++[>++++++++++<-]>++.<+[>++++++++++<-]>+.< - ``` + ```bf + [-]>[-]<++++++[>++++++++++<-]>+++++++.<+[>++++++++++<-]>+++++++.<+[>----------<-]>----.<+++++[>++++++++++<-]>+++.<+[>----------<-]>-.<[>----------<-]>----.<+++++[>----------<-]>-------.<[>++++++++++<-]>+.<++++++[>++++++++++<-]>+++.<++++++[>----------<-]>----.<++++[>++++++++++<-]>++++.<+[>++++++++++<-]>+++++.<++++++[>----------<-]>--.<++++[>++++++++++<-]>+++++++.<+[>++++++++++<-]>++++.<++++++[>----------<-]>-.<[>++++++++++<-]>++++.<++++++[>++++++++++<-]>++.<+[>++++++++++<-]>+.< + ``` ### Brainfuck @@ -903,7 +903,7 @@ CTF{pl34s3_n0_m04r} As for most ctf problems, I've written a script that executes all the step automatically and returns the flag. -{{< code language="py" title="solve.py" isCollapsed="true" >}} +{{< collapsible-block badge="py" title="solve.py" isCollapsed="true" >}} ```py # pip install brainfuck-interpreter @@ -1065,7 +1065,7 @@ flag = brainfuck.evaluate(brainfuck_code) print(flag) ``` -{{< /code >}} +{{< /collapsible-block >}} ## Solution diff --git a/content/writeups/google-ctf/2021/beginners-quest/7.md b/content/writeups/google-ctf/2021/beginners-quest/7.md index ca11559..c6fc97a 100644 --- a/content/writeups/google-ctf/2021/beginners-quest/7.md +++ b/content/writeups/google-ctf/2021/beginners-quest/7.md @@ -42,7 +42,7 @@ Nowak is very impressed by your skills. You and him sit down by a table, and you [attachment.zip](/files/writeups/google-ctf/2021/beginners-quest/7/attachment.zip) -{{< code language="python" title="chall.py" isCollapsed="true" >}} +{{< collapsible-block badge="python" title="chall.py" isCollapsed="true" >}} ```py from Crypto.Util.number import * @@ -63,7 +63,7 @@ print(n) #21034814455172467787319632067588541051616978031477984909593707891829600195022041640200088624987623056713604514239406145871910044808006741636513624835862657042742260288941962019533183418661144639940608960169440421588092324928046033370735375447302576018460809597788053566456538713152022888984084306297869362373871810139948930387868426850576062496427583397660227337178607544043400076287217521751017970956067448273578322298078706011759257235310210160153287198740097954054080553667336498134630979908988858940173520975701311654172499116958019179004876438417238730801165613806576140914402525031242813240005791376093215124477 ``` -{{< /code >}} +{{< /collapsible-block >}} ## Recon diff --git a/content/writeups/holiday-hack-challenge/2024/act1/curling.md b/content/writeups/holiday-hack-challenge/2024/act1/curling.md index 248a909..271847b 100644 --- a/content/writeups/holiday-hack-challenge/2024/act1/curling.md +++ b/content/writeups/holiday-hack-challenge/2024/act1/curling.md @@ -3,7 +3,7 @@ author = "Maik de Kruif" title = "Curling" subtitle = "Act 1 - SANS Holiday Hack Challenge 2024" date = 2024-11-23T11:44:53+01:00 -description = "In the fourth challenge of the Holiday Hack Challenge 2024, we'll explore how to use curl using the Linux manpages." +description = "In the Curling challenge, we join Bow Ninecandle to learn how to use the curl command for sending web requests. The silver tasks include sending basic requests, handling self-signed certificates, posting data, and more. Afterwards, we use our knowledge to solve extra tasks involving file paths and redirects, completing the challenge for the gold medal!" cover = "img/writeups/holiday-hack-challenge/2024/act1/curling/cover.png" tags = [ "Holiday Hack Challenge", diff --git a/content/writeups/holiday-hack-challenge/2024/act1/frosty-keypad.md b/content/writeups/holiday-hack-challenge/2024/act1/frosty-keypad.md index 1c2415e..7b60410 100644 --- a/content/writeups/holiday-hack-challenge/2024/act1/frosty-keypad.md +++ b/content/writeups/holiday-hack-challenge/2024/act1/frosty-keypad.md @@ -3,7 +3,7 @@ author = "Maik de Kruif" title = "Frosty Keypad" subtitle = "Act 1 - SANS Holiday Hack Challenge 2024" date = 2024-11-24T18:23:54+01:00 -description = "In the fourth challenge of the Holiday Hack Challenge 2024, we'll explore how to use curl using the Linux manpages." +description = "In this challenge, we help Morcel Nougat recover a shredded document by decoding clues from a book and using an old-school telephone keypad. After enabling a hidden flashlight, we script a solution to bypass rate limits and crack the final code, solving both the Silver and Gold challenges!" cover = "img/writeups/holiday-hack-challenge/2024/act1/frosty-keypad/cover.png" tags = [ "Holiday Hack Challenge", diff --git a/content/writeups/holiday-hack-challenge/2024/prologue/elf-connect.md b/content/writeups/holiday-hack-challenge/2024/prologue/elf-connect.md index 25453dd..bad04f9 100644 --- a/content/writeups/holiday-hack-challenge/2024/prologue/elf-connect.md +++ b/content/writeups/holiday-hack-challenge/2024/prologue/elf-connect.md @@ -3,7 +3,7 @@ author = "Maik de Kruif" title = "Elf Connect" subtitle = "Prologue - SANS Holiday Hack Challenge 2024" date = 2024-11-21T14:23:34+01:00 -description = "Let's play our first game of the Holiday Hack Challenge. To win, we'll have to use the DevTools to read some code, and figure out how the scoring mechanism works." +description = "In Elf Connect, we help Angel Candysalt solve a word-matching puzzle. After earning the silver medal by finding groups of related words, we dig into the game’s code using DevTools. By analyzing the scoring logic, we bypass the normal gameplay and directly trigger the gold medal with a simple code execution in the browser console!" cover = "img/writeups/holiday-hack-challenge/2024/prologue/elf-connect/cover.png" tags = [ "Holiday Hack Challenge", @@ -98,7 +98,7 @@ Object.keys(wordSets).map((round) => This might look a little complicated, so let me explain it for you. We start by looping over `wordSets`, this contains all the words for a specific round. We then look at the correct sets, and map the four indices to the actual word in the list. If we execute this code, we get the following output: -{{< code language="json" title="Results" isCollapsed="true" >}} +{{< collapsible-block badge="json" title="Results" isCollapsed="true" >}} ```json [ @@ -129,7 +129,7 @@ This might look a little complicated, so let me explain it for you. We start by ] ``` -{{< /code >}} +{{< /collapsible-block >}} This just get us the correct answer though, and we'll need more for gold. diff --git a/content/writeups/holiday-hack-challenge/2024/prologue/elf-minder.md b/content/writeups/holiday-hack-challenge/2024/prologue/elf-minder.md index 9871be5..265a227 100644 --- a/content/writeups/holiday-hack-challenge/2024/prologue/elf-minder.md +++ b/content/writeups/holiday-hack-challenge/2024/prologue/elf-minder.md @@ -3,7 +3,7 @@ author = "Maik de Kruif" title = "Elf Minder" subtitle = "Prologue - SANS Holiday Hack Challenge 2024" date = 2024-11-21T15:18:53+01:00 -description = "On to our second game of the Holiday Hack Challenge. This time we'll have to find some routes." +description = "In Elf Minder, we guide an elf through twelve levels of maze-like puzzles. Silver is straightforward; solve the puzzles normally. For gold, we inspect the game’s code with DevTools and find hidden admin controls. By enabling them, we can clear obstacles and draw a path directly to the finish. Alternatively, we manipulate springs to bounce the elf straight to the end. Both methods secure the gold medal!" cover = "img/writeups/holiday-hack-challenge/2024/prologue/elf-minder/cover.png" tags = [ "Holiday Hack Challenge", @@ -113,7 +113,7 @@ From the hint given in the conversation with the elf Poinsettia, we got the foll A good starting point here would be to first figure out how the springs work. -{{< code language="js" title="guide.js (getSpringTarget)" isCollapsed="true" >}} +{{< collapsible-block badge="js" title="guide.js (getSpringTarget)" isCollapsed="true" >}} ```js getSpringTarget(springCell) { @@ -157,7 +157,7 @@ getSpringTarget(springCell) { } ``` -{{< /code >}} +{{< /collapsible-block >}} In one of the source files, `guide.js`, there is a function called `getSpringTarget`. This function, as the name suggests, returns the location where the elf should go after encountering a spring. diff --git a/content/writeups/holiday-hack-challenge/2024/prologue/orientation.md b/content/writeups/holiday-hack-challenge/2024/prologue/orientation.md index 061ba50..3e350c7 100644 --- a/content/writeups/holiday-hack-challenge/2024/prologue/orientation.md +++ b/content/writeups/holiday-hack-challenge/2024/prologue/orientation.md @@ -3,7 +3,7 @@ author = "Maik de Kruif" title = "Holiday Hack Orientation" subtitle = "Prologue - SANS Holiday Hack Challenge 2024" date = 2024-11-21T13:46:55+01:00 -description = "An easy start of the Holiday Hack Challenge 2024." +description = "In the Holiday Hack Orientation, we meet Jingle Ringford, who introduces us to the 2024 SANS Holiday Hack Challenge. Our first task is simple; enter the correct answer in the “First Terminal” to unlock the gold medal and begin the adventure!" cover = "img/writeups/holiday-hack-challenge/2024/prologue/orientation/cover.png" tags = [ "Holiday Hack Challenge", diff --git a/themes/maik-blog/assets/scss/_buttons.scss b/themes/maik-blog/assets/scss/_buttons.scss index 0c71070..e484a4b 100644 --- a/themes/maik-blog/assets/scss/_buttons.scss +++ b/themes/maik-blog/assets/scss/_buttons.scss @@ -71,31 +71,3 @@ a.button { padding: 14px 24px; } } - -.code-toolbar { - margin-bottom: 20px; - - .toolbar-item a { - position: relative; - display: inline-flex; - align-items: center; - justify-content: center; - padding: 3px 8px; - margin-bottom: 5px; - background: $light-background-secondary; - text-decoration: none; - text-align: center; - font-size: 13px; - font-weight: 500; - border-radius: 8px; - border: 1px solid transparent; - appearance: none; - cursor: pointer; - outline: none; - - .dark-theme & { - background: $dark-background-secondary; - color: inherit; - } - } -} diff --git a/themes/maik-blog/assets/scss/_code.scss b/themes/maik-blog/assets/scss/_collapsible-block.scss similarity index 68% rename from themes/maik-blog/assets/scss/_code.scss rename to themes/maik-blog/assets/scss/_collapsible-block.scss index cf52ad7..329d581 100644 --- a/themes/maik-blog/assets/scss/_code.scss +++ b/themes/maik-blog/assets/scss/_collapsible-block.scss @@ -1,4 +1,4 @@ -.collapsable-code { +.collapsible-block { position: relative; width: 100%; margin: 40px 0; @@ -8,41 +8,50 @@ visibility: hidden; } - .highlight, - .code-toolbar .highlight { + &__content { max-height: 80vh; overflow: auto; - transition: max-height 0.15s ease; + transition: max-height 0.15s ease, padding-top 0.15s ease, + padding-bottom 0.15s ease; border-bottom-left-radius: 10px; border-bottom-right-radius: 10px; + + background-color: lighten($light-background-secondary, 5%); + + .dark-theme & { + background-color: darken($dark-background-secondary, 6%); + } + + padding: 0 1em; + + &:has(> :last-child:nth-child(1)), + &:not(:has(*)) { + padding: 1em; + } + + &:has(.highlight) { + padding: 0 !important; + } } input[type="checkbox"]:checked { - ~ .highlight, - ~ .code-toolbar .highlight { + ~ .collapsible-block__content { max-height: 0; - padding: 0; + padding-top: 0; + padding-bottom: 0; border-top: none; overflow: hidden; } - ~ .code-toolbar { - padding: 0; - border-top: none; - - .toolbar { - display: none; - } - } - ~ label { border-radius: 10px; + transition: border-radius 0.15s ease 0.1s; } - ~ label .collapsable-code__toggle:after { + ~ label .collapsible-block__toggle:after { content: attr(data-label-expand); } } @@ -59,6 +68,7 @@ min-height: 30px; margin: 0; cursor: pointer; + transition: border-radius 0s ease 0s; .dark-theme & { background: $dark-background-secondary; @@ -79,7 +89,7 @@ } } - &__language { + &__badge { background: $light-background; color: $light-color; border-radius: 10px; @@ -112,8 +122,4 @@ margin-bottom: 0; border-radius: 0; } - - .code-toolbar { - margin: 0; - } } diff --git a/themes/maik-blog/assets/scss/_main.scss b/themes/maik-blog/assets/scss/_main.scss index 2a62962..fdc64cd 100644 --- a/themes/maik-blog/assets/scss/_main.scss +++ b/themes/maik-blog/assets/scss/_main.scss @@ -304,8 +304,9 @@ pre { } blockquote { + position: relative; border-left: 2px solid; - margin: 40px; + margin: 20px 40px; padding: 10px 20px; @media #{$media-size-phone} { @@ -315,12 +316,12 @@ blockquote { &:before { content: "”"; - font-family: Georgia, serif; + // font-family: Georgia, serif; font-display: auto; font-size: 3.875rem; position: absolute; left: -40px; - top: -20px; + top: -13px; } p:first-of-type { diff --git a/themes/maik-blog/assets/scss/main.scss b/themes/maik-blog/assets/scss/main.scss index fc28aa7..177cefd 100644 --- a/themes/maik-blog/assets/scss/main.scss +++ b/themes/maik-blog/assets/scss/main.scss @@ -16,5 +16,5 @@ @import "portfolios"; @import "footer"; @import "sharing-buttons"; -@import "code"; +@import "collapsible-block"; @import "masonry"; diff --git a/themes/maik-blog/layouts/shortcodes/code.html b/themes/maik-blog/layouts/shortcodes/code.html deleted file mode 100644 index 8682d8a..0000000 --- a/themes/maik-blog/layouts/shortcodes/code.html +++ /dev/null @@ -1,17 +0,0 @@ -{{ $id := delimit (shuffle (seq 1 9)) "" }} - -{{ if .Get "language" }} -
- - - {{ .Inner | markdownify }} -
-{{ else }} -{{ errorf "If you want to use the \"collapsable code\" shortcode, you need to pass a mandatory \"language\" param. The issue occured in %q (%q)" .Page.File .Page.Permalink }} -{{ end }} \ No newline at end of file diff --git a/themes/maik-blog/layouts/shortcodes/collapsible-block.html b/themes/maik-blog/layouts/shortcodes/collapsible-block.html new file mode 100644 index 0000000..e969bb5 --- /dev/null +++ b/themes/maik-blog/layouts/shortcodes/collapsible-block.html @@ -0,0 +1,17 @@ +{{ $id := delimit (shuffle (seq 1 9)) "" }} + +
+ + +
+ {{ .Inner | markdownify }} +
+