{"id":4,"date":"2018-01-19T11:46:45","date_gmt":"2018-01-19T11:46:45","guid":{"rendered":"http:\/\/devel0pment.de\/?p=4"},"modified":"2018-05-20T19:52:00","modified_gmt":"2018-05-20T19:52:00","slug":"rpisec-mbe-writeup-lab01","status":"publish","type":"post","link":"https:\/\/devel0pment.de\/?p=4","title":{"rendered":"RPISEC\/MBE: writeup lab01 (Reverse Engineering)"},"content":{"rendered":"<p>RPISEC is the resident computer security club at <a href=\"http:\/\/www.rpi.edu\/\" target=\"_blank\" rel=\"noopener\">Rensselaer Polytechnic Institute<\/a>. They developed a university course to teach skills in vulnerability research, reverse engineering and binary exploitation. The course material can be found on github including a detailed explanation on how to run the provided VM: <a href=\"https:\/\/github.com\/RPISEC\/MBE\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/RPISEC\/MBE<\/a>.<\/p>\n<p>This article contains my writeup for the first lab (lab01). The lab&#8217;s topic is <i>Reverse Engineering<\/i> and it consists of the following levels:<br \/>\n&#8211;&gt; <a href=\"https:\/\/devel0pment.de\/?p=4#lab1C\">lab1C<\/a><br \/>\n&#8211;&gt; <a href=\"https:\/\/devel0pment.de\/?p=4#lab1B\">lab1B<\/a><br \/>\n&#8211;&gt; <a href=\"https:\/\/devel0pment.de\/?p=4#lab1A\">lab1A<\/a><\/p>\n<p><!--more--><\/p>\n<hr \/>\n<h1 id=\"lab1C\">lab1C<\/h1>\n<p>We start by connecting to the first level using ssh. There are three levels within each lab ranging from C to A. The username for the first level is <span style=\"color: #ff0000;\">lab1C<\/span> with the password <span style=\"color: #ff0000;\">lab01start<\/span>:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\ngameadmin@warzone:~$ sudo ssh lab1C@localhost\r\nlab1C@localhost's password: (lab01start)\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                       Challenges are in \/levels                        \r\n                   Passwords are in \/home\/lab*\/.pass                    \r\n            You can create files or work directories in \/tmp            \r\n                    \r\n         -----------------&#x5B; contact@rpis.ec ]-----------------          \r\n\r\nLast login: Thu Jan 18 10:28:34 2018 from 192.168.187.130\r\n<\/pre>\n<p>The challenges are located at <code><span style=\"color: #0000ff;\">\/levels\/lab0X\/<\/span><\/code>:<\/p>\n<pre class=\"brush: bash; highlight: [3,10]; title: ; notranslate\" title=\"\">\r\nlab1C@warzone:~$ pwd\r\n\/home\/lab1C\r\nlab1C@warzone:~$ cd \/levels\/lab01\/\r\nlab1C@warzone:\/levels\/lab01$ ls -al\r\ntotal 40\r\ndrwxr-xr-x  2 root    root  4096 Jun 21  2015 .\r\ndrwxr-xr-x 14 root    root  4096 Sep 28  2015 ..\r\n-r-sr-x---  1 lab1end lab1A 9672 Jun 21  2015 lab1A\r\n-r-sr-x---  1 lab1A   lab1B 9672 Jun 21  2015 lab1B\r\n-r-sr-x---  1 lab1B   lab1C 7414 Jun 21  2015 lab1C\r\nlab1C@warzone:\/levels\/lab01$ file lab1\r\nlab1A  lab1B  lab1C  \r\nlab1C@warzone:\/levels\/lab01$ file lab1C\r\nlab1C: setuid ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU\/Linux 2.6.24, BuildID&#x5B;sha1]=1522352e3de50fd6d180831ba18e2bca16be4204, not stripped\r\n<\/pre>\n<p>Let&#8217;s examine the binary using radare2:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nlab1C@warzone:\/levels\/lab01$ r2 lab1C \r\n -- Do not try to sploit that binary - that's impossible. Instead, only try to realize the truth: the is no binary.\r\n&#x5B;0x080485b0]&gt;\r\n<\/pre>\n<p>The first thing I do is to let r2 analyze all (<code>aaa<\/code>) and list all functions (<code>afl<\/code>):<\/p>\n<pre class=\"brush: python; highlight: [22]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x080485b0]&gt; aaa\r\n&#x5B;0x080485b0]&gt; afl\r\n0x080485b0  34  1  entry0\r\n0x08048590  6  1  sym.imp.__libc_start_main\r\n0x08048596  10  2  fcn.08048596\r\n0x08048540  12  1  section..plt\r\n0x0804854c  10  1  sub.printf_12_54c\r\n0x08048556  10  1  fcn.08048556\r\n0x08048560  6  1  sym.imp.puts\r\n0x08048566  10  1  fcn.08048566\r\n0x08048570  6  1  sym.imp.system\r\n0x08048576  10  1  fcn.08048576\r\n0x08048580  6  1  sym.imp.__gmon_start__\r\n0x08048586  10  1  fcn.08048586\r\n0x080485a0  6  1  sym.imp.__isoc99_scanf\r\n0x080485a6  10  1  fcn.080485a6\r\n0x080485e0  4  1  sym.__x86.get_pc_thunk.bx\r\n0x080485f0  42  4  sym.deregister_tm_clones\r\n0x0804861a  61  4  fcn.0804861a\r\n0x08048657  39  3  fcn.08048657\r\n0x08048680  45  8  sym.frame_dummy\r\n0x080486ad  138  4  sym.main\r\n0x08048740  97  4  sym.__libc_csu_init\r\n0x080487a1  17  2  fcn.080487a1\r\n0x080487b2  22  1  section_end..text\r\n0x0804851c  35  3  section..init\r\n0x0804853f  13  1  section_end..init\r\n<\/pre>\n<p>The main-function (<code>sym.main<\/code>) sounds like a good point to start. Let&#8217;s have a loot at it using print disassembled function (<code>pdf<\/code>):<\/p>\n<pre class=\"brush: python; highlight: [19,20,23,24,25,28,33,34]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x080485b0]&gt; pdf @ sym.main\r\n\u2552 (fcn) sym.main 138\r\n\u2502          ; DATA XREF from 0x080485c7 (entry0)\r\n\u2502          ;-- main:\r\n\u2502          ;-- sym.main:\r\n\u2502          0x080486ad    55             push ebp\r\n\u2502          0x080486ae    89e5           mov ebp, esp\r\n\u2502          0x080486b0    83e4f0         and esp, 0xfffffff0\r\n\u2502          0x080486b3    83ec20         sub esp, 0x20\r\n\u2502          0x080486b6    c70424d08704.  mov dword &#x5B;esp], str._____________________________  ; &#x5B;0x80487d0:4]=0x2d2d2d2d  ; &quot;-----------------------------&quot; @ 0x80487d0\r\n\u2502          0x080486bd    e89efeffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x080486c2    c70424ee8704.  mov dword &#x5B;esp], str.____RPISEC___CrackMe_v1.0____  ; &#x5B;0x80487ee:4]=0x202d2d2d  ; &quot;--- RPISEC - CrackMe v1.0 ---&quot; @ 0x80487ee\r\n\u2502          0x080486c9    e892feffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x080486ce    c70424d08704.  mov dword &#x5B;esp], str._____________________________  ; &#x5B;0x80487d0:4]=0x2d2d2d2d  ; &quot;-----------------------------&quot; @ 0x80487d0\r\n\u2502          0x080486d5    e886feffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x080486da    c704240c8804.  mov dword &#x5B;esp], str._nPassword:  ; &#x5B;0x804880c:4]=0x7361500a  ; str._nPassword:\r\n\u2502          0x080486e1    e86afeffff     call sym.imp.printf             ; sub.printf_12_54c+0x4\r\n\u2502            ^- sub.printf_12_54c() ; sym.imp.printf\r\n\u2502          0x080486e6    8d44241c       lea eax, &#x5B;esp + 0x1c]           ; 0x1c\r\n\u2502          0x080486ea    89442404       mov dword &#x5B;esp + 4], eax        ; &#x5B;0x4:4]=0x10101\r\n\u2502          0x080486ee    c70424188804.  mov dword &#x5B;esp], 0x8048818      ; &#x5B;0x8048818:4]=0xa006425  ; &quot;%d&quot; @ 0x8048818\r\n\u2502          0x080486f5    e8a6feffff     call sym.imp.__isoc99_scanf\r\n\u2502            ^- sym.imp.__isoc99_scanf()\r\n\u2502          0x080486fa    8b44241c       mov eax, dword &#x5B;esp + 0x1c]     ; &#x5B;0x1c:4]=52\r\n\u2502          0x080486fe    3d9a140000     cmp eax, 0x149a\r\n\u2502      \u250c\u2500&lt; 0x08048703    751f           jne 0x8048724\r\n\u2502      \u2502   0x08048705    c704241b8804.  mov dword &#x5B;esp], str._nAuthenticated_  ; &#x5B;0x804881b:4]=0x7475410a  ; str._nAuthenticated_\r\n\u2502      \u2502   0x0804870c    e84ffeffff     call sym.imp.puts\r\n\u2502      \u2502     ^- sym.imp.puts()\r\n\u2502      \u2502   0x08048711    c704242b8804.  mov dword &#x5B;esp], str._bin_sh    ; &#x5B;0x804882b:4]=0x6e69622f  ; &quot;\/bin\/sh&quot; @ 0x804882b\r\n\u2502      \u2502   0x08048718    e853feffff     call sym.imp.system\r\n\u2502      \u2502     ^- sym.imp.system()\r\n\u2502      \u2502   0x0804871d    b800000000     mov eax, 0\r\n\u2502     \u250c\u2500\u2500&lt; 0x08048722    eb11           jmp 0x8048735\r\n\u2502     \u2502\u2514   ; JMP XREF from 0x08048703 (sym.main)\r\n\u2502     \u2502\u2514\u2500&gt; 0x08048724    c70424338804.  mov dword &#x5B;esp], str._nInvalid_Password___  ; &#x5B;0x8048833:4]=0x766e490a  ; str._nInvalid_Password___\r\n\u2502     \u2502    0x0804872b    e830feffff     call sym.imp.puts\r\n\u2502     \u2502      ^- sym.imp.puts()\r\n\u2502     \u2502    0x08048730    b801000000     mov eax, 1\r\n\u2502     \u2514    ; JMP XREF from 0x08048722 (sym.main)\r\n\u2502     \u2514\u2500\u2500&gt; 0x08048735    c9             leave\r\n\u2558          0x08048736    c3             ret\r\n<\/pre>\n<p>After a few calls to <code>puts<\/code> a password-prompt (&#8220;Password: &#8220;) is displayed using <code>printf<\/code> (line 19-20). The user input is read by a call to <code>scanf<\/code> (line 25). The arguments passed to <code>scanf<\/code> are a string (line 24) located at 0x8048818 (which is &#8220;%d&#8221; as already displayed by r2 right after the address) and a local variable at <code>esp+0x1c<\/code> (line 23).<\/p>\n<p>On line 28 the user input stored in <code>eax<\/code> is compared to <code>0x149a<\/code>. If the comparison fails, the <code>jne<\/code> to <code>0x8048724<\/code> is taken resulting in the output &#8220;Invalid Password!!!&#8221;. If the comparison succeeds the jump is not taken. In this case the string &#8220;Authenticated!&#8221; is printed and the function <code>system<\/code> is called with <code>\"\/bin\/sh\"<\/code> as argument (line 33-34).<\/p>\n<p>Thus we only have to enter <code>0x149a<\/code> as decimal and we get a shell \ud83d\ude42<\/p>\n<p>In r2 you can run shell commands using <code>!!<\/code>. This way we can easily convert the hex value to decimal using rax2:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n&#x5B;0x080485b0]&gt; !!rax2 0x149a\r\n5274\r\n<\/pre>\n<p>Now we only have to run the binary and enter the password we found:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nlab1C@warzone:\/levels\/lab01$ .\/lab1C \r\n-----------------------------\r\n--- RPISEC - CrackMe v1.0 ---\r\n-----------------------------\r\n\r\nPassword: 5274\r\n\r\nAuthenticated!\r\n$ cat \/home\/lab1B\/.pass\t\r\nn0_str1ngs_n0_pr0bl3m\r\n$ exit\r\nlab1C@warzone:\/levels\/lab01$\r\n<\/pre>\n<p>Done \ud83d\ude42 The password for the next level is <code>n0_str1ngs_n0_pr0bl3m<\/code>.<\/p>\n<hr \/>\n<h1 id=\"lab1B\">lab1B<\/h1>\n<p>With the password we gained in the last level we can connect to the next level using ssh again. This time the username is <span style=\"color: #ff0000;\">lab1B<\/span> with the password <span style=\"color: #ff0000;\">n0_str1ngs_n0_pr0bl3m<\/span>:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\ngameadmin@warzone:~$ sudo ssh lab1B@localhost\r\nlab1B@localhost's password: (n0_str1ngs_n0_pr0bl3m)\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                       Challenges are in \/levels                        \r\n                   Passwords are in \/home\/lab*\/.pass                    \r\n            You can create files or work directories in \/tmp            \r\n                    \r\n         -----------------&#x5B; contact@rpis.ec ]-----------------          \r\n\r\nLast login: Thu Jan 18 10:44:33 2018 from 192.168.187.130\r\nlab1B@warzone:~$ cd \/levels\/lab01\/\r\nlab1B@warzone:\/levels\/lab01$ file lab1B\r\nlab1B: setuid ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU\/Linux 2.6.24, BuildID&#x5B;sha1]=c9f07b581bd8d97cdc7c0ff1a288e20aea2df0f5, stripped\r\n<\/pre>\n<p>Let&#8217;s start up radare2 again, &#8230;<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nlab1B@warzone:\/levels\/lab01$ r2 lab1B\r\n -- Press 'C' in visual mode to toggle colors\r\n<\/pre>\n<p>&#8230; analyze all (<code>aaa<\/code>) &#8230;<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048850]&gt; aaa\r\n<\/pre>\n<p>&#8230; and list all functions (<code>afl<\/code>):<\/p>\n<pre class=\"brush: python; highlight: [33]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048850]&gt; afl\r\n0x08048850  34  1  entry0\r\n0x08048820  6  1  sym.imp.__libc_start_main\r\n0x08048826  10  2  fcn.08048826\r\n0x08048760  12  1  section..plt\r\n0x0804876c  10  1  sub.strcmp_12_76c\r\n0x08048776  10  1  fcn.08048776\r\n0x08048780  6  1  sym.imp.printf\r\n0x08048786  10  1  fcn.08048786\r\n0x08048790  6  1  sym.imp.fflush\r\n0x08048796  10  1  fcn.08048796\r\n0x080487a0  6  1  sym.imp.getchar\r\n0x080487a6  10  1  fcn.080487a6\r\n0x080487b0  6  1  sym.imp.time\r\n0x080487b6  10  1  fcn.080487b6\r\n0x080487c0  6  1  sym.imp.__stack_chk_fail\r\n0x080487c6  10  1  fcn.080487c6\r\n0x080487d0  6  1  sym.imp.puts\r\n0x08048830  6  1  sym.imp.rand\r\n0x08048836  10  1  fcn.08048836\r\n0x08048840  6  1  sym.imp.__isoc99_scanf\r\n0x08048846  10  1  fcn.08048846\r\n0x08048880  4  1  fcn.08048880\r\n0x08048890  42  4  fcn.08048890\r\n0x080488ba  61  4  fcn.080488ba\r\n0x080488f7  39  3  fcn.080488f7\r\n0x08048920  45  8  fcn.08048920\r\n0x0804894d  34  5  sym.clear_stdin\r\n0x0804896f  55  1  sym.get_unum\r\n0x080489a6  17  1  sym.prog_timeout\r\n0x080489b7  189  11  sym.decrypt\r\n0x08048a74  368  3  sym.test\r\n0x08048be4  133  3  sym.main\r\n0x08048800  6  1  sym.imp.srand\r\n0x08048806  10  1  fcn.08048806\r\n0x08048810  6  1  sym.imp.strlen\r\n0x08048816  10  1  fcn.08048816\r\n0x08048c70  97  4  sym.__libc_csu_init\r\n0x08048cd1  17  2  fcn.08048cd1\r\n0x08048ce2  22  1  section_end..text\r\n0x08048738  35  3  section..init\r\n0x080487f0  6  1  sym.imp.__gmon_start__\r\n0x080487f6  10  1  fcn.080487f6\r\n0x0804875b  17  1  section_end..init\r\n0x080487e0  6  1  sym.imp.system\r\n0x080487e6  10  1  fcn.080487e6\r\n<\/pre>\n<p>Yet again the main-function (<code>sym.main<\/code>) is a good point to start:<\/p>\n<pre class=\"brush: python; highlight: [31,32,35,36,37,40,41,42]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048850]&gt; pdf @ sym.main\r\n\u2552 (fcn) sym.main 133\r\n\u2502          ; DATA XREF from 0x08048867 (entry0)\r\n\u2502          ;-- main:\r\n\u2502          ;-- sym.main:\r\n\u2502          0x08048be4    55             push ebp\r\n\u2502          0x08048be5    89e5           mov ebp, esp\r\n\u2502          0x08048be7    83e4f0         and esp, 0xfffffff0\r\n\u2502          0x08048bea    83ec20         sub esp, 0x20\r\n\u2502          0x08048bed    50             push eax\r\n\u2502          0x08048bee    31c0           xor eax, eax\r\n\u2502      \u250c\u2500&lt; 0x08048bf0    7403           je 0x8048bf5                  \r\n\u2502      \u2502   0x08048bf2    83c404         add esp, 4\r\n\u2502      \u2514   ; JMP XREF from 0x08048bf0 (sym.main)\r\n\u2502      \u2514\u2500&gt; 0x08048bf5    58             pop eax\r\n\u2502          0x08048bf6    c70424000000.  mov dword &#x5B;esp], 0\r\n\u2502          0x08048bfd    e8aefbffff     call sym.imp.time\r\n\u2502            ^- sym.imp.time()\r\n\u2502          0x08048c02    890424         mov dword &#x5B;esp], eax\r\n\u2502          0x08048c05    e8f6fbffff     call sym.imp.srand\r\n\u2502            ^- sym.imp.srand()\r\n\u2502          0x08048c0a    c70424888d04.  mov dword &#x5B;esp], 0x8048d88      ; &#x5B;0x8048d88:4]=0x2d2d2d2e \r\n\u2502          0x08048c11    e8bafbffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x08048c16    c70424a68d04.  mov dword &#x5B;esp], str.____RPISEC___CrackMe_v2.0____  ; &#x5B;0x8048da6:4]=0x202d2d7c  ; &quot;|-- RPISEC - CrackMe v2.0 --|&quot; @ 0x8048da6\r\n\u2502          0x08048c1d    e8aefbffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x08048c22    c70424c48d04.  mov dword &#x5B;esp], str._____________________________  ; &#x5B;0x8048dc4:4]=0x2d2d2d27  ; &quot;'---------------------------'&quot; @ 0x8048dc4\r\n\u2502          0x08048c29    e8a2fbffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x08048c2e    c70424e28d04.  mov dword &#x5B;esp], str._nPassword:  ; &#x5B;0x8048de2:4]=0x7361500a  ; str._nPassword:\r\n\u2502          0x08048c35    e846fbffff     call sym.imp.printf\r\n\u2502            ^- sym.imp.printf()\r\n\u2502          0x08048c3a    8d44241c       lea eax, &#x5B;esp + 0x1c]           ; 0x1c \r\n\u2502          0x08048c3e    89442404       mov dword &#x5B;esp + 4], eax        ; &#x5B;0x4:4]=0x10101 \r\n\u2502          0x08048c42    c70424ee8d04.  mov dword &#x5B;esp], 0x8048dee      ; &#x5B;0x8048dee:4]=0x6425 \r\n\u2502          0x08048c49    e8f2fbffff     call sym.imp.__isoc99_scanf\r\n\u2502            ^- sym.imp.__isoc99_scanf()\r\n\u2502          0x08048c4e    8b44241c       mov eax, dword &#x5B;esp + 0x1c]     ; &#x5B;0x1c:4]=52\r\n\u2502          0x08048c52    c74424040dd0.  mov dword &#x5B;esp + 4], 0x1337d00d  ; &#x5B;0x1337d00d:4]=-1\r\n\u2502          0x08048c5a    890424         mov dword &#x5B;esp], eax\r\n\u2502          0x08048c5d    e812feffff     call sym.test\r\n\u2502            ^- sym.test()\r\n\u2502          0x08048c62    b800000000     mov eax, 0\r\n\u2502          0x08048c67    c9             leave\r\n\u2558          0x08048c68    c3             ret\r\n<\/pre>\n<p>The usual password-prompt is displayed by a call to <code>printf<\/code> (line 31-32). Right after this <code>scanf<\/code> is called on line 37. The content of the string passed to the function (line 36) located at <code>0x8048dee<\/code> is not automatically displayed by r2. We can print it using print string (<code>ps<\/code>):<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048850]&gt; ps @ 0x8048dee\r\n%d\r\n<\/pre>\n<p>The string contains <code>%d<\/code> meaning that the input to <code>scanf<\/code> is interpreted as an integer, which is stored in a local variable at <code>esp+0x1c<\/code> (line 35 main-function).<\/p>\n<p>After the call to <code>scanf<\/code> follows a call to the user-defined function <code>sym.test<\/code> on line 42. Before the call two arguments are moved on the stack. Remember that arguments are pushed on the stack in reverse order. Thus the first argument of the function is the local variable stored at <code>esp+0x1c<\/code> on line 41. This is the variable formerly passed to scanf (the integer the user entered). The second argument is the constant <code>0x1337d00d<\/code> on line 40.<\/p>\n<p>Thus the relevant part of our main-function looks like this:<\/p>\n<pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\r\nint userinput;\r\nprintf(&quot;Password: &quot;);\r\nscanf(&quot;%d&quot;, &amp;userinput);\r\ntest(userinput, 0x1337d00d);\r\n<\/pre>\n<p>Now we can proceed with the function <code>sym.test<\/code>:<\/p>\n<pre class=\"brush: python; highlight: [3,4,9,10]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048850]&gt; pdf @ sym.test\r\n\u2552 (fcn) sym.test 368\r\n\u2502           ; arg int arg_2        @ ebp+0x8\r\n\u2502           ; arg int arg_3        @ ebp+0xc\r\n\u2502           ; arg int arg_5_1      @ ebp+0x15\r\n\u2502           ; var int local_3      @ ebp-0xc\r\n\u2502           ; CALL XREF from 0x08048c5d (sym.main)\r\n\u2502           ;-- sym.test:\r\n\u2502           0x08048a74    55             push ebp\r\n\u2502           0x08048a75    89e5           mov ebp, esp\r\n\u2502           0x08048a77    83ec28         sub esp, 0x28\r\n\u2502           0x08048a7a    8b4508         mov eax, dword &#x5B;ebp + 8]       ; &#x5B;0x8:4]=0\r\n\u2502           0x08048a7d    8b550c         mov edx, dword &#x5B;ebp + 0xc]     ; &#x5B;0xc:4]=0\r\n\u2502           0x08048a80    29c2           sub edx, eax\r\n\u2502           0x08048a82    89d0           mov eax, edx\r\n\u2502           0x08048a84    8945f4         mov dword &#x5B;ebp-local_3], eax\r\n\u2502           0x08048a87    837df415       cmp dword &#x5B;ebp-local_3], 0x15  ; &#x5B;0x15:4]=0x50000000 \r\n\u2502       \u250c\u2500&lt; 0x08048a8b    0f8744010000   ja 0x8048bd5                 \r\n\u2502       \u2502   0x08048a91    8b45f4         mov eax, dword &#x5B;ebp-local_3]\r\n\u2502       \u2502   0x08048a94    c1e002         shl eax, 2\r\n\u2502       \u2502   0x08048a97    05308d0408     add eax, 0x8048d30\r\n\u2502       \u2502   0x08048a9c    8b00           mov eax, dword &#x5B;eax]\r\n\u2502       \u2502   0x08048a9e    ffe0           jmp eax\r\n\u2502       \u2502   0x08048aa0    8b45f4         mov eax, dword &#x5B;ebp-local_3]\r\n\u2502       \u2502   0x08048aa3    890424         mov dword &#x5B;esp], eax\r\n\u2502       \u2502   0x08048aa6    e80cffffff     call sym.decrypt\r\n\u2502       \u2502     ^- sym.decrypt()\r\n\u2502      \u250c\u2500\u2500&lt; 0x08048aab    e932010000     jmp 0x8048be2                \r\n\u2502      \u2502\u2502   0x08048ab0    8b45f4         mov eax, dword &#x5B;ebp-local_3]\r\n\u2502      \u2502\u2502   0x08048ab3    890424         mov dword &#x5B;esp], eax\r\n\u2502      \u2502\u2502   0x08048ab6    e8fcfeffff     call sym.decrypt\r\n\u2502      \u2502\u2502     ^- sym.decrypt()\r\n\r\n...\r\n\r\n\u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&lt; 0x08048bc6    eb1a           jmp 0x8048be2                \r\n\u2502 \u2502\u2502\u2502\u2502\u2502\u2502\u2502   0x08048bc8    8b45f4         mov eax, dword &#x5B;ebp-local_3]\r\n\u2502 \u2502\u2502\u2502\u2502\u2502\u2502\u2502   0x08048bcb    890424         mov dword &#x5B;esp], eax\r\n\u2502 \u2502\u2502\u2502\u2502\u2502\u2502\u2502   0x08048bce    e8e4fdffff     call sym.decrypt\r\n\u2502 \u2502\u2502\u2502\u2502\u2502\u2502\u2502     ^- sym.decrypt()\r\n\u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&lt; 0x08048bd3    eb0d           jmp 0x8048be2                \r\n\u2502 \u2502\u2502\u2502\u2502\u2502\u2502\u2514   ; JMP XREF from 0x08048a8b (sym.test)\r\n\u2502 \u2502\u2502\u2502\u2502\u2502\u2502\u2514\u2500&gt; 0x08048bd5    e856fcffff     call sym.imp.rand\r\n\u2502 \u2502\u2502\u2502\u2502\u2502\u2502\u2514     ^- sym.imp.rand()\r\n\u2502 \u2502\u2502\u2502\u2502\u2502\u2502    0x08048bda    890424         mov dword &#x5B;esp], eax\r\n\u2502 \u2502\u2502\u2502\u2502\u2502\u2502    0x08048bdd    e8d5fdffff     call sym.decrypt\r\n\u2502 \u2502\u2502\u2502\u2502\u2502\u2502      ^- sym.decrypt()\r\n\u2502 \u2514\u2514\u2514\u2514\u2514\u2514\u2500\u2500&gt; 0x08048be2    c9             leave\r\n\u2558           0x08048be3    c3             ret\r\n<\/pre>\n<p>At first we should locate the arguments passed to the function. You can already see that r2 identified <code>ebp+0x8<\/code> and <code>ebp+0xc<\/code> as <code>arg_2<\/code> and <code>arg_3<\/code> (line 3-4). Let&#8217;s quickly review why this should be the formerly passed arguments having a look at the stack-layout:<\/p>\n<pre>ebp+0x0  [     saved ebp     ]  &lt;-- pushed ebp (line 9)\r\nebp+0x4  [   return address  ]  &lt;-- return address pushed by call-instrunction\r\nebp+0x8  [ integer userinput ]  &lt;-- 1st argument\r\nebp+0xc  [constant 0x1337d00d]  &lt;-- 2nd argument\r\n<\/pre>\n<p>As the stack grows from the bottom (high addresses) to the top (low addresses) the first element moved to the stack is the constant <code>0x1337d00d<\/code> followed by the local integer. After this the function <code>test<\/code> is called. The call-instruction implictly pushes the return address on the stack in order to proceed code execution after the function call. The first thing that happens in the function <code>test<\/code> is that the base pointer (<code>ebp<\/code>) is saved on the stack. After this <code>ebp<\/code> is set to the value of the stack pointer (<code>esp<\/code>) on line 10. Thus we can access our arguments with <code>ebp+0x8<\/code> and <code>ebp+0xc<\/code>.<\/p>\n<p>So what does the function do?<\/p>\n<pre class=\"brush: python; first-line: 12; title: ; notranslate\" title=\"\">\r\n\u2502           0x08048a7a    8b4508         mov eax, dword &#x5B;ebp + 8]       ; &#x5B;0x8:4]=0\r\n\u2502           0x08048a7d    8b550c         mov edx, dword &#x5B;ebp + 0xc]     ; &#x5B;0xc:4]=0\r\n\u2502           0x08048a80    29c2           sub edx, eax\r\n\u2502           0x08048a82    89d0           mov eax, edx\r\n\u2502           0x08048a84    8945f4         mov dword &#x5B;ebp-local_3], eax\r\n\u2502           0x08048a87    837df415       cmp dword &#x5B;ebp-local_3], 0x15  ; &#x5B;0x15:4]=0x50000000 \r\n\u2502       \u250c\u2500&lt; 0x08048a8b    0f8744010000   ja 0x8048bd5                 \r\n<\/pre>\n<p>In the lines 12-13 the passed arguments are stored in <code>eax<\/code> (userinput) and <code>edx<\/code> (constant). After this <code>eax<\/code> is subtracted from <code>edx<\/code> (line 14). The result is stored in <code>eax<\/code> (line 15) and then moved to a local variable (<code>ebp-local_3<\/code>) on line 16. This local variable is compared to <code>0x15<\/code> on line 17 followed by a jump above (<code>ja<\/code>) to <code>0x8048bd5<\/code> on line 18. So far the function looks like this:<\/p>\n<pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\r\nvoid test(int userinput, int constant) {\r\n\r\n  int result;\r\n\r\n  result = constant - userinput;\r\n\r\n  if (result &lt;= 0x15) {\r\n\r\n  }\r\n  else {\r\n\r\n0x8048bd5:\r\n  ...\r\n\r\n  }\r\n\r\n  return;\r\n}\r\n<\/pre>\n<p>If the jump on line 18 is not taken meaning that the difference of the constant <code>0x1337d00d<\/code> and the userinput is less than or equal to <code>0x15<\/code>, the difference is moved to <code>eax<\/code> (line 19). Then the value is left-shifted 2 bits (line 20) and <code>0x8048d30<\/code> is added (line 21). On line 22 the resulting value is used as a reference to a DWORD, which is stored in <code>eax<\/code>. The following jump lets the code execution proceed at the stored DWORD in eax (line 23):<\/p>\n<pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\n  if (result &lt;= 0x15) {\r\n\r\n    void *ptr = (void*)(result &lt;&lt; 2);\r\n    ptr += 0x8048d30;\r\n    goto *ptr;\r\n\r\n  }\r\n...\r\n<\/pre>\n<p>Before we have a closer look at the addresses where the code execution may proceed, notice the instructions which follow from line 24 onwards. I truncated the output of the function <code>sym.test<\/code> because the 4 instructions beginning at <code>0x08048aa0<\/code> (lines 24-28) repeat a few times:<\/p>\n<pre class=\"brush: python; first-line: 24; title: ; notranslate\" title=\"\">\r\n\u2502       \u2502   0x08048aa0    8b45f4         mov eax, dword &#x5B;ebp-local_3]\r\n\u2502       \u2502   0x08048aa3    890424         mov dword &#x5B;esp], eax\r\n\u2502       \u2502   0x08048aa6    e80cffffff     call sym.decrypt\r\n\u2502       \u2502     ^- sym.decrypt()\r\n\u2502      \u250c\u2500\u2500&lt; 0x08048aab    e932010000     jmp 0x8048be2   \r\n<\/pre>\n<p>The instructions place the local variable <code>ebp-local_3<\/code> as an argument on the stack and call the user-defined function <code>sym.decrypt<\/code>. After the function call a jump to <code>0x8048be2<\/code> follows, which is the end of the function <code>sym.test<\/code>.<\/p>\n<p>Now let&#8217;s have a look at the addresses where the code execution may proceed when the difference of the subtraction is less than or equal to 0x15:<\/p>\n<table>\n<tbody>\n<tr style=\"background-color: #cccccc; font-weight: bold;\">\n<td>result<\/td>\n<td>result &lt;&lt; 2<\/td>\n<td>ptr (+0x8048d30)<\/td>\n<\/tr>\n<tr>\n<td>0x15<\/td>\n<td>0x54<\/td>\n<td>0x8048d84<\/td>\n<\/tr>\n<tr>\n<td>0x14<\/td>\n<td>0x50<\/td>\n<td>0x8048d80<\/td>\n<\/tr>\n<tr>\n<td>0x13<\/td>\n<td>0x4c<\/td>\n<td>0x8048d7c<\/td>\n<\/tr>\n<tr>\n<td>0x12<\/td>\n<td>0x48<\/td>\n<td>0x8048d78<\/td>\n<\/tr>\n<tr>\n<td colspan=\"3\">&#8230;<\/td>\n<\/tr>\n<tr>\n<td>0x01<\/td>\n<td>0x04<\/td>\n<td>0x8048d34<\/td>\n<\/tr>\n<tr>\n<td>0x00<\/td>\n<td>0x00<\/td>\n<td>0x8048d30<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Note that the value is used as a pointer to the address we jump to. Thus we have to look which addresses are stored at these location. As we can see in the right column these locations range from <code>0x8048d30<\/code> (<code>result = 0x00<\/code>) to <code>0x8048d84<\/code> (<code>result = 0x15<\/code>). In r2 we can print words using print hexdump of words (<code>pwx<\/code>):<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048850]&gt; pxw 88 @ 0x8048d30\r\n0x08048d30  0x08048bd5 0x08048aa0 0x08048ab0 0x08048ac0  ................\r\n0x08048d40  0x08048ad0 0x08048ae0 0x08048af0 0x08048b00  ................\r\n0x08048d50  0x08048b10 0x08048b20 0x08048b30 0x08048b40  .... ...0...@...\r\n0x08048d60  0x08048b50 0x08048b60 0x08048b6d 0x08048b7a  P...`...m...z...\r\n0x08048d70  0x08048b87 0x08048b94 0x08048ba1 0x08048bae  ................\r\n0x08048d80  0x08048bbb 0x08048bc8                      ........        \r\n<\/pre>\n<p>The <code>88<\/code> specifies that we want to print 88 bytes (= 22 dwords). The addresses stored here look similar somehow! These are offsets into the function <code>sym.test<\/code>. We can disassemble the addressed locations with print disassembled (<code>pd<\/code>). Let&#8217;s begin with <code>0x8048d30<\/code> (<code>result = 0x00<\/code>):<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048850]&gt; pd 5 @ &#x5B;0x8048d30]\r\n           ; JMP XREF from 0x08048a8b (sym.test)\r\n\u2502          0x08048bd5    e856fcffff     call sym.imp.rand\r\n\u2502            ^- sym.imp.rand(unk)\r\n\u2502          0x08048bda    890424         mov dword &#x5B;esp], eax\r\n\u2502          0x08048bdd    e8d5fdffff     call sym.decrypt\r\n\u2502            ^- sym.decrypt()\r\n\u2502          0x08048be2    c9             leave\r\n\u2558          0x08048be3    c3             ret\r\n<\/pre>\n<p>The square brackets around the <code>0x8048d30<\/code> tell r2 not to disassemble the code at <code>0x8048d30<\/code> but rather take the value stored at <code>0x8048d30<\/code> and disassamble the code at that value. Thus for <code>0x8048d30<\/code> the code at <code>0x08048bd5<\/code> is diassembled. In the disassembled code a call to <code>sym.imp.rand<\/code> is made to generate a random value which is then passed as argument for the following call to <code>sym.decrypt<\/code>.<\/p>\n<p>The other addresses for <code>result = 0x01, 0x02, 0x03, ... <\/code> look like this:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048850]&gt; pd 4 @ &#x5B;0x8048d34]\r\n\u2502          0x08048aa0    8b45f4         mov eax, dword &#x5B;ebp-local_3]\r\n\u2502          0x08048aa3    890424         mov dword &#x5B;esp], eax\r\n\u2502          0x08048aa6    e80cffffff     call sym.decrypt\r\n\u2502            ^- sym.decrypt()\r\n\u2502      \u250c\u2500&lt; 0x08048aab e932010000 jmp 0x8048be2 &#x5B;0x08048850]&gt; pd 4 @ &#x5B;0x8048d38]\r\n\u2502          0x08048ab0    8b45f4         mov eax, dword &#x5B;ebp-local_3]\r\n\u2502          0x08048ab3    890424         mov dword &#x5B;esp], eax\r\n\u2502          0x08048ab6    e8fcfeffff     call sym.decrypt\r\n\u2502            ^- sym.decrypt()\r\n\u2502      \u250c\u2500&lt; 0x08048abb e922010000 jmp 0x8048be2 &#x5B;0x08048850]&gt; pd 4 @ &#x5B;0x8048d3c]\r\n\u2502          0x08048ac0    8b45f4         mov eax, dword &#x5B;ebp-local_3]\r\n\u2502          0x08048ac3    890424         mov dword &#x5B;esp], eax\r\n\u2502          0x08048ac6    e8ecfeffff     call sym.decrypt\r\n\u2502            ^- sym.decrypt()\r\n\u2502      \u250c\u2500&lt; 0x08048acb    e912010000     jmp 0x8048be2                 \r\n<\/pre>\n<p>The disassambled instructions are the 4 instructions we have already seen in the function <code>sym.test<\/code>. The function <code>sym.decrypt<\/code> is called and the local variable <code>ebp-local_3<\/code> is passed as argument. After the call there is a jump to the end of the function <code>sym.test<\/code> (<code>0x8048be2<\/code>).<\/p>\n<p>So let&#8217;s have a look at the function <code>sym.decrypt<\/code>:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048850]&gt; pdf @ sym.decrypt\r\n\u2552 (fcn) sym.decrypt 189\r\n\u2502          ; arg int arg_2        @ ebp+0x8\r\n\u2502          ; arg int arg_215506719_1 @ ebp+0x33617c7d\r\n\u2502          ; arg int arg_433691864 @ ebp+0x67667360\r\n\u2502          ; arg int arg_492773204_1 @ ebp+0x757c7d51\r\n\u2502          ; arg int arg_517577951_2 @ ebp+0x7b66737e\r\n\u2502          ; var int local_3      @ ebp-0xc\r\n\u2502          ; var int local_3_1    @ ebp-0xd\r\n\u2502          ; var int local_7_1    @ ebp-0x1d\r\n\u2502          ; var int local_9      @ ebp-0x24\r\n\u2502          ; var int local_10     @ ebp-0x28\r\n\u2502          ; CALL XREF from 0x08048bdd (sym.test)\r\n\u2502          ;-- sym.decrypt:\r\n\u2502          0x080489b7    55             push ebp\r\n\u2502          0x080489b8    89e5           mov ebp, esp\r\n\u2502          0x080489ba    83ec38         sub esp, 0x38\r\n\u2502          0x080489bd    65a114000000   mov eax, dword gs:&#x5B;0x14]        ; &#x5B;0x14:4]=1\r\n\u2502          0x080489c3    8945f4         mov dword &#x5B;ebp-local_3], eax\r\n\u2502          0x080489c6    31c0           xor eax, eax\r\n\u2502          0x080489c8    c745e3517d7c.  mov dword &#x5B;ebp-local_7_1], 0x757c7d51  ; &#x5B;0x757c7d51:4]=-1\r\n\u2502          0x080489cf    c745e7607366.  mov dword &#x5B;ebp - 0x19], 0x67667360  ; &#x5B;0x67667360:4]=-1\r\n\u2502          0x080489d6    c745eb7e7366.  mov dword &#x5B;ebp - 0x15], 0x7b66737e  ; &#x5B;0x7b66737e:4]=-1\r\n\u2502          0x080489dd    c745ef7d7c61.  mov dword &#x5B;ebp - 0x11], 0x33617c7d  ; &#x5B;0x33617c7d:4]=-1\r\n\u2502          0x080489e4    c645f300       mov byte &#x5B;ebp-local_3_1], 0\r\n\u2502          0x080489e8    50             push eax\r\n\u2502          0x080489e9    31c0           xor eax, eax\r\n\u2502      \u250c\u2500&lt; 0x080489eb    7403           je 0x80489f0                  \r\n\u2502      \u2502   0x080489ed    83c404         add esp, 4\r\n\u2502      \u2514   ; JMP XREF from 0x080489eb (sym.decrypt)\r\n\u2502      \u2514\u2500&gt; 0x080489f0    58             pop eax\r\n\u2502          0x080489f1    8d45e3         lea eax, &#x5B;ebp-local_7_1]\r\n\u2502          0x080489f4    890424         mov dword &#x5B;esp], eax\r\n\u2502          0x080489f7    e814feffff     call sym.imp.strlen\r\n\u2502            ^- sym.imp.strlen()\r\n\u2502          0x080489fc    8945dc         mov dword &#x5B;ebp-local_9], eax\r\n\u2502          0x080489ff    c745d8000000.  mov dword &#x5B;ebp-local_10], 0\r\n\u2502     \u250c\u2500\u2500&lt; 0x08048a06    eb20           jmp 0x8048a28                 \r\n\u2502    \u250c     ; JMP XREF from 0x08048a2e (sym.decrypt)\r\n\u2502    \u250c\u2500\u2500\u2500&gt; 0x08048a08    8d55e3         lea edx, &#x5B;ebp-local_7_1]\r\n\u2502    \u2502\u2502    0x08048a0b    8b45d8         mov eax, dword &#x5B;ebp-local_10]\r\n\u2502    \u2502\u2502    0x08048a0e    01d0           add eax, edx\r\n\u2502    \u2502\u2502    0x08048a10    0fb600         movzx eax, byte &#x5B;eax]\r\n\u2502    \u2502\u2502    0x08048a13    89c2      44   mov edx, eax\r\n\u2502    \u2502\u2502    0x08048a15    8b4508         mov eax, dword &#x5B;ebp + 8]        ; &#x5B;0x8:4]=0\r\n\u2502    \u2502\u2502    0x08048a18    31d0      46   xor eax, edx\r\n\u2502    \u2502\u2502    0x08048a1a    8d4de3         lea ecx, &#x5B;ebp-local_7_1]\r\n\u2502    \u2502\u2502    0x08048a1d    8b55d8    48   mov edx, dword &#x5B;ebp-local_10]\r\n\u2502    \u2502\u2502    0x08048a20    01ca           add edx, ecx\r\n\u2502    \u2502\u2502    0x08048a22    8802      50   mov byte &#x5B;edx], al\r\n\u2502    \u2502\u2502    0x08048a24    8345d801       add dword &#x5B;ebp-local_10], 1\r\n\u2502    \u2502\u2514    ; JMP XREF from 0x08048a06 (sym.decrypt)\r\n\u2502    \u2502\u2514\u2500\u2500&gt; 0x08048a28    8b45d8         mov eax, dword &#x5B;ebp-local_10]\r\n\u2502    \u2502     0x08048a2b    3b45dc    54   cmp eax, dword &#x5B;ebp-local_9]\r\n\u2502    \u2514\u2500\u2500\u2500&lt; 0x08048a2e    72d8           jb 0x8048a08                  \r\n\u2502          0x08048a30    c7442404038d.  mov dword &#x5B;esp + 4], str.Congratulations_  ; &#x5B;0x8048d03:4]=0x676e6f43  ; &quot;Congratulations!&quot; @ 0x8048d03\r\n\u2502          0x08048a38    8d45e3    58   lea eax, &#x5B;ebp-local_7_1]\r\n\u2502          0x08048a3b    890424         mov dword &#x5B;esp], eax\r\n\u2502          0x08048a3e    e82dfdffff     call sym.imp.strcmp             ; sub.strcmp_12_76c+0x4\r\n\u2502            ^- sub.strcmp_12_76c() ; sym.imp.strcmp\r\n\u2502          0x08048a43    85c0           test eax, eax\r\n\u2502   \u250c\u2500\u2500\u2500\u2500&lt; 0x08048a45    750e           jne 0x8048a55                 \r\n\u2502   \u2502      0x08048a47    c70424148d04.  mov dword &#x5B;esp], str._bin_sh    ; &#x5B;0x8048d14:4]=0x6e69622f  ; &quot;\/bin\/sh&quot; @ 0x8048d14\r\n\u2502   \u2502      0x08048a4e    e88dfdffff     call sym.imp.system\r\n\u2502   \u2502        ^- sym.imp.system()\r\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500&lt; 0x08048a53    eb0c           jmp 0x8048a61                 \r\n\u2502  \u2502\u2514      ; JMP XREF from 0x08048a45 (sym.decrypt)\r\n\u2502  \u2502\u2514\u2500\u2500\u2500\u2500&gt; 0x08048a55    c704241c8d04.  mov dword &#x5B;esp], str._nInvalid_Password_  ; &#x5B;0x8048d1c:4]=0x766e490a  ; str._nInvalid_Password_\r\n\u2502  \u2502       0x08048a5c    e86ffdffff     call sym.imp.puts\r\n\u2502  \u2502         ^- sym.imp.puts()\r\n\u2502  \u2514       ; JMP XREF from 0x08048a53 (sym.decrypt)\r\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500&gt; 0x08048a61    8b45f4         mov eax, dword &#x5B;ebp-local_3]\r\n\u2502          0x08048a64    653305140000.  xor eax, dword gs:&#x5B;0x14]\r\n\u2502          0x08048a6b    7405           je 0x8048a72                  \r\n\u2502          0x08048a6d    e84efdffff     call sym.imp.__stack_chk_fail\r\n\u2502            ^- sym.imp.__stack_chk_fail()\r\n\u2502          ; JMP XREF from 0x08048a6b (sym.decrypt)\r\n\u2502          0x08048a72    c9             leave\r\n\u2558          0x08048a73    c3             ret\r\n<\/pre>\n<p>As we have already seen the function takes one argument which can be accessed with <code>ebp+0x8<\/code>. On lines 21-24 four dwords (4 byte) and single 1 byte (line 24) are moved on the stack. The output above is a little bit confusing because r2 replaced the offset to ebp with the local_ aliases. The corresponding lines look like this:<\/p>\n<pre class=\"brush: python; first-line: 21; title: ; notranslate\" title=\"\">\r\n\u2502          0x080489c8    c745e3517d7c.  mov dword &#x5B;ebp - 0x1d], 0x757c7d51  ; &#x5B;0x757c7d51:4]=-1\r\n\u2502          0x080489cf    c745e7607366.  mov dword &#x5B;ebp - 0x19], 0x67667360  ; &#x5B;0x67667360:4]=-1\r\n\u2502          0x080489d6    c745eb7e7366.  mov dword &#x5B;ebp - 0x15], 0x7b66737e  ; &#x5B;0x7b66737e:4]=-1\r\n\u2502          0x080489dd    c745ef7d7c61.  mov dword &#x5B;ebp - 0x11], 0x33617c7d  ; &#x5B;0x33617c7d:4]=-1\r\n\u2502          0x080489e4    c645f300       mov byte  &#x5B;ebp - 0xd], 0\r\n<\/pre>\n<p>The values are placed sequently on the stack. After the executing of the instructions the memory region looks like the following:<\/p>\n<pre>ebp-0x1d: 517d7c75607366677e73667b7d7c613300\r\n<\/pre>\n<p>Looks like a null-terminated string:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048850]&gt; !!python -c 'print(&quot;517d7c75607366677e73667b7d7c613300&quot;.decode(&quot;hex&quot;))'\r\nQ}|u`sfg~sf{}|a3\r\n<\/pre>\n<p>We will keep this in mind and continue reversing the function <code>sym.decrypt<\/code>.<\/p>\n<p>On line 34 the function <code>strlen<\/code> is called. The passed argument is a reference the string we just found (<code>ebp-local_7_1<\/code>):<\/p>\n<pre class=\"brush: python; first-line: 32; title: ; notranslate\" title=\"\">\r\n\u2502          0x080489f1    8d45e3         lea eax, &#x5B;ebp-local_7_1]\r\n\u2502          0x080489f4    890424         mov dword &#x5B;esp], eax\r\n\u2502          0x080489f7    e814feffff     call sym.imp.strlen\r\n\u2502            ^- sym.imp.strlen()\r\n<\/pre>\n<p>The returned length of the string stored in <code>eax<\/code> is moved to a local variable (<code>ebp-local_9<\/code>). Another local variable (<code>ebp-local_10<\/code>) is initialized with 0:<\/p>\n<pre class=\"brush: python; first-line: 36; title: ; notranslate\" title=\"\">\r\n\u2502          0x080489fc    8945dc         mov dword &#x5B;ebp-local_9], eax\r\n\u2502          0x080489ff    c745d8000000.  mov dword &#x5B;ebp-local_10], 0\r\n<\/pre>\n<p>On lines 38-55 follows a loop iterating every character in the string:<\/p>\n<pre class=\"brush: python; first-line: 38; title: ; notranslate\" title=\"\">\r\n\u2502     \u250c\u2500\u2500&lt; 0x08048a06    eb20           jmp 0x8048a28                 \r\n\u2502    \u250c     ; JMP XREF from 0x08048a2e (sym.decrypt)\r\n\u2502    \u250c\u2500\u2500\u2500&gt; 0x08048a08    8d55e3         lea edx, &#x5B;ebp-local_7_1]\r\n\u2502    \u2502\u2502    0x08048a0b    8b45d8         mov eax, dword &#x5B;ebp-local_10]\r\n\u2502    \u2502\u2502    0x08048a0e    01d0           add eax, edx\r\n\u2502    \u2502\u2502    0x08048a10    0fb600         movzx eax, byte &#x5B;eax]\r\n\u2502    \u2502\u2502    0x08048a13    89c2      44   mov edx, eax\r\n\u2502    \u2502\u2502    0x08048a15    8b4508         mov eax, dword &#x5B;ebp + 8]        ; &#x5B;0x8:4]=0\r\n\u2502    \u2502\u2502    0x08048a18    31d0      46   xor eax, edx\r\n\u2502    \u2502\u2502    0x08048a1a    8d4de3         lea ecx, &#x5B;ebp-local_7_1]\r\n\u2502    \u2502\u2502    0x08048a1d    8b55d8    48   mov edx, dword &#x5B;ebp-local_10]\r\n\u2502    \u2502\u2502    0x08048a20    01ca           add edx, ecx\r\n\u2502    \u2502\u2502    0x08048a22    8802      50   mov byte &#x5B;edx], al\r\n\u2502    \u2502\u2502    0x08048a24    8345d801       add dword &#x5B;ebp-local_10], 1\r\n\u2502    \u2502\u2514    ; JMP XREF from 0x08048a06 (sym.decrypt)\r\n\u2502    \u2502\u2514\u2500\u2500&gt; 0x08048a28    8b45d8         mov eax, dword &#x5B;ebp-local_10]\r\n\u2502    \u2502     0x08048a2b    3b45dc    54   cmp eax, dword &#x5B;ebp-local_9]\r\n\u2502    \u2514\u2500\u2500\u2500&lt; 0x08048a2e    72d8           jb 0x8048a08                 \r\n<\/pre>\n<p>At first (line 38) there is a jump to the loop-condition beginning on line 53. These three instructions simply test if <code>ebp-local_10<\/code> (loop-counter) has reached the value of <code>ebp-local_9<\/code> (string length) and jump to the loop-body on line 40 when the loop-counter is still smaller.<\/p>\n<p>The loop-body loads the baseaddress of the string (line 40) and adds the loop-counter. After the execution of line 44 edx contains a single character of the formerly stored string at the position indicated by the loop-counter. This character is XORed with the value stored at <code>ebp+0x8<\/code> (line 46). Do You remember what value that was? Yes! The argument passed to the function <code>sym.decrypt<\/code>. On lines 47-50 the XORed character is written back to the string. At last (line 51) the loop-counter is incremented.<\/p>\n<p>Until now the <code>decrypt<\/code> function looks like the following:<\/p>\n<pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\r\nvoid decrypt(int v) {\r\n\r\n  char str&#x5B;] = &quot;Q}|u`sfg~sf{}|a3&quot;;\r\n\r\n  int len = strlen(str);\r\n\r\n  for (int i = 0; i &lt; len; i++) {\r\n\r\n    str&#x5B;i] = str&#x5B;i] ^ v;\r\n\r\n  }\r\n  ...\r\n}\r\n<\/pre>\n<p>After the loop there is a call to <code>strcmp<\/code>:<\/p>\n<pre class=\"brush: python; first-line: 56; title: ; notranslate\" title=\"\">\r\n\u2502          0x08048a30    c7442404038d.  mov dword &#x5B;esp + 4], str.Congratulations_  ; &#x5B;0x8048d03:4]=0x676e6f43  ; &quot;Congratulations!&quot; @ 0x8048d03\r\n\u2502          0x08048a38    8d45e3         lea eax, &#x5B;ebp-local_7_1]\r\n\u2502          0x08048a3b    890424         mov dword &#x5B;esp], eax\r\n\u2502          0x08048a3e    e82dfdffff     call sym.imp.strcmp             ; sub.strcmp_12_76c+0x4\r\n\u2502            ^- sub.strcmp_12_76c() ; sym.imp.strcmp\r\n<\/pre>\n<p>r2 already displays that the first string being compared contains <code>Congratulations!<\/code>. The second string stored at <code>ebp-local_7_1<\/code> is the string that has just been XORed in the loop. After the call to <code>strcmp<\/code> the result is evaluted:<\/p>\n<pre class=\"brush: python; first-line: 61; title: ; notranslate\" title=\"\">\r\n\u2502          0x08048a43    85c0           test eax, eax\r\n\u2502   \u250c\u2500\u2500\u2500\u2500&lt; 0x08048a45    750e           jne 0x8048a55                 \r\n\u2502   \u2502      0x08048a47    c70424148d04.  mov dword &#x5B;esp], str._bin_sh    ; &#x5B;0x8048d14:4]=0x6e69622f  ; &quot;\/bin\/sh&quot; @ 0x8048d14\r\n\u2502   \u2502      0x08048a4e    e88dfdffff     call sym.imp.system\r\n\u2502   \u2502        ^- sym.imp.system()\r\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500&lt; 0x08048a53    eb0c           jmp 0x8048a61                 \r\n\u2502  \u2502\u2514      ; JMP XREF from 0x08048a45 (sym.decrypt)\r\n\u2502  \u2502\u2514\u2500\u2500\u2500\u2500&gt; 0x08048a55    c704241c8d04.  mov dword &#x5B;esp], str._nInvalid_Password_  ; &#x5B;0x8048d1c:4]=0x766e490a  ; str._nInvalid_Password_\r\n\u2502  \u2502       0x08048a5c    e86ffdffff     call sym.imp.puts\r\n<\/pre>\n<p>If the strings are not equal <code>Invalid Password!<\/code> is printed and the function returns. If the strings match a call to <code>system<\/code> spawns our desired shell. Thus we can complete your <code>decrypt<\/code> function:<\/p>\n<pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\r\nvoid decrypt(int v) {\r\n  ...\r\n\r\n  \/\/ str contains &quot;Q}|u`sfg~sf{}|a3&quot; XORed with v\r\n\r\n  if (strcmp(&quot;Congratulations!&quot;, str) == 0) {\r\n\r\n    system(&quot;\/bin\/sh&quot;);\r\n\r\n  }\r\n  else {\r\n\r\n    puts(&quot;Invalid Password!&quot;);\r\n\r\n  }\r\n}\r\n<\/pre>\n<p>Summing it all up we have to find a value which turns the string <code>Q}|u`sfg~sf{}|a3<\/code> into <code>Congratulations!<\/code> when being XORed with this value. This is quite easy because we can just XOR both strings and see what the result is:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\nlab1B@warzone:~$ python\r\n...\r\n&gt;&gt;&gt; s1 = &quot;Q}|u`sfg~sf{}|a3&quot;\r\n&gt;&gt;&gt; s2 = &quot;Congratulations!&quot;\r\n&gt;&gt;&gt; &#x5B;ord(a) ^ ord(b) for a,b in zip(s1,s2)]\r\n&#x5B;18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18]\r\n<\/pre>\n<p>So the value we are looking for is <code>18<\/code> (= <code>0x12<\/code>). As we already figured out the value passed to the function <code>decrypt<\/code> is calculated by subtracting our input value from <code>0x1337d00d<\/code>. Thus we need to enter:<\/p>\n<pre>0x1337d00d - 0x12 = 0x1337cffb = <b>322424827<\/b>\r\n<\/pre>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\nlab1B@warzone:\/levels\/lab01$ .\/lab1B \r\n.---------------------------.\r\n|-- RPISEC - CrackMe v2.0 --|\r\n'---------------------------'\r\n\r\nPassword: 322424827\r\n$ whoami\r\nlab1A\r\n$ cat \/home\/lab1A\/.pass\r\n1337_3nCRyptI0n_br0\r\n<\/pre>\n<p>Done \ud83d\ude42 The password for the next level is <code>1337_3nCRyptI0n_br0<\/code>.<\/p>\n<hr \/>\n<h1 id=\"lab1A\">lab1A<\/h1>\n<p>Now we can proceed to the last level of this lab. The username is <span style=\"color: #ff0000;\">lab1A<\/span> with the password <span style=\"color: #ff0000;\">1337_3nCRyptI0n_br0<\/span>:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\ngameadmin@warzone:~$ sudo ssh lab1A@localhost\r\nlab1A@localhost's password: (1337_3nCRyptI0n_br0)\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                       Challenges are in \/levels                        \r\n                   Passwords are in \/home\/lab*\/.pass                    \r\n            You can create files or work directories in \/tmp            \r\n                    \r\n         -----------------&#x5B; contact@rpis.ec ]-----------------          \r\n\r\nLast login: Fri Jan 19 01:45:32 2018 from localhost\r\nlab1A@warzone:~$\r\n<\/pre>\n<p>As usual we start up r2:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nlab1A@warzone:~$ cd \/levels\/lab01\r\nlab1A@warzone:\/levels\/lab01$ r2 lab1A\r\n<\/pre>\n<p>Have a quick look at the functions within the binary:<\/p>\n<pre class=\"brush: python; highlight: [8]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048880]&gt; aaa\r\n&#x5B;0x08048880]&gt; afl\r\n0x08048880  34  1  entry0\r\n0x08048840  6  1  sym.imp.__libc_start_main\r\n0x08048846  10  2  fcn.08048846\r\n...\r\n0x08048a0f  309  15  sym.auth\r\n0x08048b44  298  8  sym.main\r\n0x08048c70  97  4  sym.__libc_csu_init\r\n0x08048cd1  17  2  fcn.08048cd1\r\n0x08048ce2  22  1  section_end..text\r\n0x0804876c  35  3  section..init\r\n0x08048830  6  1  sym.imp.__gmon_start__\r\n0x08048836  10  1  fcn.08048836\r\n0x0804878f  13  1  section_end..init\r\n0x08048810  6  1  sym.imp.puts\r\n0x08048816  10  1  fcn.08048816\r\n0x08048820  6  1  sym.imp.system\r\n0x08048826  10  1  fcn.08048826\r\n<\/pre>\n<p>And start analyzing the main-function:<\/p>\n<pre class=\"brush: python; highlight: [34,35,40,41,42,43,44,45,56,57,62,63,64,65,67,68,69,70,71,73,74,78,79]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048880]&gt; pdf @ sym.main\r\n\u2552 (fcn) sym.main 298\r\n\u2502          ; arg int arg_3        @ ebp+0xc\r\n\u2502          ; DATA XREF from 0x08048897 (entry0)\r\n\u2502          ;-- main:\r\n\u2502          ;-- sym.main:\r\n\u2502          0x08048b44    55             push ebp\r\n\u2502          0x08048b45    89e5           mov ebp, esp\r\n\u2502          0x08048b47    83e4f0         and esp, 0xfffffff0\r\n\u2502          0x08048b4a    83ec40         sub esp, 0x40\r\n\u2502          0x08048b4d    8b450c         mov eax, dword &#x5B;ebp + 0xc]      ; &#x5B;0xc:4]=0\r\n\u2502          0x08048b50    8944240c       mov dword &#x5B;esp + 0xc], eax      ; &#x5B;0xc:4]=0\r\n\u2502          0x08048b54    65a114000000   mov eax, dword gs:&#x5B;0x14]        ; &#x5B;0x14:4]=1\r\n\u2502          0x08048b5a    8944243c       mov dword &#x5B;esp + 0x3c], eax     ; &#x5B;0x3c:4]=0x8048034 section_end.ehdr ; '&lt;'\r\n\u2502          0x08048b5e    31c0           xor eax, eax\r\n\u2502          0x08048b60    50             push eax\r\n\u2502          0x08048b61    31c0           xor eax, eax\r\n\u2502      \u250c\u2500&lt; 0x08048b63    7403           je 0x8048b68                  \r\n\u2502      \u2502   0x08048b65    83c404         add esp, 4\r\n\u2502      \u2514   ; JMP XREF from 0x08048b63 (sym.main)\r\n\u2502      \u2514\u2500&gt; 0x08048b68    58             pop eax\r\n\u2502          0x08048b69    c70424738d04.  mov dword &#x5B;esp], str..___________________________.  ; &#x5B;0x8048d73:4]=0x2d2d2d2e  ; &quot;.---------------------------.&quot; @ 0x8048d73\r\n\u2502          0x08048b70    e89bfcffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x08048b75    c70424918d04.  mov dword &#x5B;esp], str.____________RPISEC___________  ; &#x5B;0x8048d91:4]=0x2d2d2d7c  ; &quot;|---------  RPISEC  --------|&quot; @ 0x8048d91\r\n\u2502          0x08048b7c    e88ffcffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x08048b81    c70424af8d04.  mov dword &#x5B;esp], str.___SECURE_LOGIN_SYS_v._3.0___  ; &#x5B;0x8048daf:4]=0x53202b7c  ; &quot;|+ SECURE LOGIN SYS v. 3.0 +|&quot; @ 0x8048daf\r\n\u2502          0x08048b88    e883fcffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x08048b8d    c70424cd8d04.  mov dword &#x5B;esp], 0x8048dcd      ; &#x5B;0x8048dcd:4]=0x2d2d2d7c \r\n\u2502          0x08048b94    e877fcffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x08048b99    c70424eb8d04.  mov dword &#x5B;esp], str.____Enter_your_Username:_____  ; &#x5B;0x8048deb:4]=0x202d7e7c  ; &quot;|~- Enter your Username:  ~-|&quot; @ 0x8048deb\r\n\u2502          0x08048ba0    e86bfcffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x08048ba5    c70424098e04.  mov dword &#x5B;esp], str._____________________________  ; &#x5B;0x8048e09:4]=0x2d2d2d27  ; &quot;'---------------------------'&quot; @ 0x8048e09\r\n\u2502          0x08048bac    e85ffcffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x08048bb1    a160b00408     mov eax, dword &#x5B;sym.stdin]      ; &#x5B;0x804b060:4]=0x3a434347  ; &quot;GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2&quot; @ 0x804b060\r\n\u2502          0x08048bb6    89442408       mov dword &#x5B;esp + 8], eax        ; &#x5B;0x8:4]=0\r\n\u2502          0x08048bba    c74424042000.  mov dword &#x5B;esp + 4], 0x20       ; &#x5B;0x20:4]=0x2168  ; &quot;h!&quot; 0x00000020 \r\n\u2502          0x08048bc2    8d44241c       lea eax, &#x5B;esp + 0x1c]           ; 0x1c \r\n\u2502          0x08048bc6    890424         mov dword &#x5B;esp], eax\r\n\u2502          0x08048bc9    e802fcffff     call sym.imp.fgets\r\n\u2502            ^- sym.imp.fgets()\r\n\u2502          0x08048bce    c70424738d04.  mov dword &#x5B;esp], str..___________________________.  ; &#x5B;0x8048d73:4]=0x2d2d2d2e  ; &quot;.---------------------------.&quot; @ 0x8048d73\r\n\u2502          0x08048bd5    e836fcffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x08048bda    c70424278e04.  mov dword &#x5B;esp], str._____NEW_ACCOUNT_DETECTED____  ; &#x5B;0x8048e27:4]=0x2121207c  ; &quot;| !! NEW ACCOUNT DETECTED !!|&quot; @ 0x8048e27\r\n\u2502          0x08048be1    e82afcffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x08048be6    c70424cd8d04.  mov dword &#x5B;esp], 0x8048dcd      ; &#x5B;0x8048dcd:4]=0x2d2d2d7c \r\n\u2502          0x08048bed    e81efcffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x08048bf2    c70424458e04.  mov dword &#x5B;esp], str.____Input_your_serial:_______  ; &#x5B;0x8048e45:4]=0x202d7e7c  ; &quot;|~- Input your serial:    ~-|&quot; @ 0x8048e45\r\n\u2502          0x08048bf9    e812fcffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x08048bfe    c70424098e04.  mov dword &#x5B;esp], str._____________________________  ; &#x5B;0x8048e09:4]=0x2d2d2d27  ; &quot;'---------------------------'&quot; @ 0x8048e09\r\n\u2502          0x08048c05    e806fcffff     call sym.imp.puts\r\n\u2502            ^- sym.imp.puts()\r\n\u2502          0x08048c0a    8d442418       lea eax, &#x5B;esp + 0x18]           ; 0x18 \r\n\u2502          0x08048c0e    89442404       mov dword &#x5B;esp + 4], eax        ; &#x5B;0x4:4]=0x10101 \r\n\u2502          0x08048c12    c70424008d04.  mov dword &#x5B;esp], 0x8048d00      ; &#x5B;0x8048d00:4]=0xa007525 \r\n\u2502          0x08048c19    e842fcffff     call sym.imp.__isoc99_scanf\r\n\u2502            ^- sym.imp.__isoc99_scanf()\r\n\u2502          0x08048c1e    8b442418       mov eax, dword &#x5B;esp + 0x18]     ; &#x5B;0x18:4]=0x8048880 entry0\r\n\u2502          0x08048c22    89442404       mov dword &#x5B;esp + 4], eax        ; &#x5B;0x4:4]=0x10101 \r\n\u2502          0x08048c26    8d44241c       lea eax, &#x5B;esp + 0x1c]           ; 0x1c \r\n\u2502          0x08048c2a    890424         mov dword &#x5B;esp], eax\r\n\u2502          0x08048c2d    e8ddfdffff     call sym.auth\r\n\u2502            ^- sym.auth()\r\n\u2502          0x08048c32    85c0           test eax, eax\r\n\u2502     \u250c\u2500\u2500&lt; 0x08048c34    751f           jne 0x8048c55                 \r\n\u2502     \u2502    0x08048c36    c70424638e04.  mov dword &#x5B;esp], str.Authenticated_  ; &#x5B;0x8048e63:4]=0x68747541  ; &quot;Authenticated!&quot; @ 0x8048e63\r\n\u2502     \u2502    0x08048c3d    e8cefbffff     call sym.imp.puts\r\n\u2502     \u2502      ^- sym.imp.puts()\r\n\u2502     \u2502    0x08048c42    c70424728e04.  mov dword &#x5B;esp], str._bin_sh    ; &#x5B;0x8048e72:4]=0x6e69622f  ; &quot;\/bin\/sh&quot; @ 0x8048e72\r\n\u2502     \u2502    0x08048c49    e8d2fbffff     call sym.imp.system\r\n\u2502     \u2502      ^- sym.imp.system()\r\n\u2502     \u2502    0x08048c4e    b800000000     mov eax, 0\r\n\u2502    \u250c\u2500\u2500\u2500&lt; 0x08048c53    eb05           jmp 0x8048c5a                 \r\n\u2502    \u2502\u2514    ; JMP XREF from 0x08048c34 (sym.main)\r\n\u2502    \u2502\u2514\u2500\u2500&gt; 0x08048c55    b801000000     mov eax, 1\r\n\u2502    \u2514     ; JMP XREF from 0x08048c53 (sym.main)\r\n\u2502    \u2514\u2500\u2500\u2500&gt; 0x08048c5a    8b54243c       mov edx, dword &#x5B;esp + 0x3c]     ; &#x5B;0x3c:4]=0x8048034 section_end.ehdr ; '&lt;'\r\n\u2502          0x08048c5e    653315140000.  xor edx, dword gs:&#x5B;0x14]\r\n\u2502          0x08048c65    7405           je 0x8048c6c                  \r\n\u2502          0x08048c67    e894fbffff     call sym.imp.__stack_chk_fail\r\n\u2502            ^- sym.imp.__stack_chk_fail()\r\n\u2502          ; JMP XREF from 0x08048c65 (sym.main)\r\n\u2502          0x08048c6c    c9             leave\r\n\u2558          0x08048c6d    c3             ret\r\n<\/pre>\n<p>This time the first thing the program asks for is not a password but a username by calling <code>puts<\/code> (line 34-35). This username is read using <code>fgets<\/code> on line 45. The first argument passed (=last argument pushed) on line 44 is the address of the string where the user-input should be stored (line 43: <code>esp+0x1c<\/code>). The second argument is the maximum count of bytes to read (line 42). In this case the value is set to 0x20 = 32 bytes. The third argument is the stream from where to read. In this case this is simply <code>stdin<\/code> (lines 40-41).<\/p>\n<p>After the username-prompt there is another prompt asking for a serial (lines 56-57). The user-input is read using <code>scanf<\/code> (lines 62-65). The first argument passed to <code>scanf<\/code> on line 64 is the format string to be used (<code>0x8048d00<\/code>):<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048880]&gt; ps @ 0x8048d00\r\n%u\r\n<\/pre>\n<p>The format-string <code>%u<\/code> specifies that an unsigned integer is read. This is stored at the address passed as the second argument. As can be seen in lines 62-63 the unsigned integer will be stored at <code>esp+0x18<\/code>.<\/p>\n<p>After the username and the serial are read the function <code>sym.auth<\/code> is called on line 71. There are two arguments passed to the function (lines 67-70): <code>esp+0x1c<\/code> and <code>esp+0x18<\/code>. As we have already figured out <code>esp+0x1c<\/code> holds the username entered and <code>esp+0x18<\/code> contains the serial read by <code>scanf<\/code>.<\/p>\n<p>After the call to <code>sym.auth<\/code> the instruction <code>test eax, eax<\/code> on line 73 checks if the return value of <code>sym.auth<\/code> stored in <code>eax<\/code> is 0. When <code>sym.auth<\/code> does not return 0 the <code>jne<\/code> on line 74 is taken and the function is quit. If <code>sym.auth<\/code> returns 0 <code>\"Authenticated!\"<\/code> is printed and we get a shell (line 78-79).<\/p>\n<p>Summing this up the main-function looks like this:<\/p>\n<pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\r\nint main() {\r\n\r\n  ...\r\n\r\n  char username&#x5B;32];\r\n  unsigned int serial;\r\n\r\n  puts(&quot;Enter username: &quot;);\r\n  fgets(username, 32, stdin);\r\n\r\n  puts(&quot;Enter serial: &quot;);\r\n  scanf(&quot;%u&quot;, &amp;serial);\r\n\r\n  if (auth(username, serial) == 0) {\r\n\r\n    puts(&quot;Authenticated!&quot;);\r\n    system(&quot;\/bin\/sh&quot;);\r\n\r\n  }\r\n\r\n}\r\n<\/pre>\n<p>Thus we have to find a <code>username<\/code> \/ <code>serial<\/code> combination which makes <code>auth<\/code> return 0:<\/p>\n<pre class=\"brush: python; highlight: [14,15,16,17]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048880]&gt; pdf @ sym.auth\r\n\u2552 (fcn) sym.auth 309\r\n\u2502           ; arg int arg_1_1      @ ebp+0x5\r\n\u2502           ; arg int arg_2        @ ebp+0x8\r\n\u2502           ; arg int arg_3        @ ebp+0xc\r\n\u2502           ; var int local_3      @ ebp-0xc\r\n\u2502           ; var int local_4      @ ebp-0x10\r\n\u2502           ; var int local_5      @ ebp-0x14\r\n\u2502           ; CALL XREF from 0x08048c2d (sym.main)\r\n\u2502           ;-- sym.auth:\r\n\u2502           0x08048a0f    55             push ebp\r\n\u2502           0x08048a10    89e5           mov ebp, esp\r\n\u2502           0x08048a12    83ec28         sub esp, 0x28\r\n\u2502           0x08048a15    c7442404038d.  mov dword &#x5B;esp + 4], 0x8048d03  ; &#x5B;0x8048d03:4]=10\r\n\u2502           0x08048a1d    8b4508         mov eax, dword &#x5B;ebp + 8]       ; &#x5B;0x8:4]=0\r\n\u2502           0x08048a20    890424         mov dword &#x5B;esp], eax\r\n\u2502           0x08048a23    e878fdffff     call sym.imp.strcspn           ; sub.strcspn_12_79c+0x4\r\n\u2502             ^- sub.strcspn_12_79c() ; sym.imp.strcspn\r\n\u2502           0x08048a28    8b5508         mov edx, dword &#x5B;ebp + 8]       ; &#x5B;0x8:4]=0\r\n\u2502           0x08048a2b    01d0           add eax, edx\r\n\u2502           0x08048a2d    c60000         mov byte &#x5B;eax], 0\r\n\u2502           0x08048a30    c74424042000.  mov dword &#x5B;esp + 4], 0x20      ; &#x5B;0x20:4]=0x2168  ; &quot;h!&quot; 0x00000020 \r\n\u2502           0x08048a38    8b4508         mov eax, dword &#x5B;ebp + 8]       ; &#x5B;0x8:4]=0\r\n\u2502           0x08048a3b    890424         mov dword &#x5B;esp], eax\r\n\u2502           0x08048a3e    e80dfeffff     call sym.imp.strnlen\r\n\u2502             ^- sym.imp.strnlen()\r\n\u2502           0x08048a43    8945f4         mov dword &#x5B;ebp-local_3], eax\r\n\u2502           0x08048a46    50             push eax\r\n\u2502           0x08048a47    31c0           xor eax, eax\r\n\u2502       \u250c\u2500&lt; 0x08048a49    7403           je 0x8048a4e                 \r\n\u2502       \u2502   0x08048a4b    83c404         add esp, 4\r\n\u2502       \u2514   ; JMP XREF from 0x08048a49 (sym.auth)\r\n\u2502       \u2514\u2500&gt; 0x08048a4e    58             pop eax\r\n\u2502           0x08048a4f    837df405       cmp dword &#x5B;ebp-local_3], 5     ; &#x5B;0x5:4]=257\r\n\u2502      \u250c\u2500\u2500&lt; 0x08048a53    7f0a           jg 0x8048a5f                 \r\n\u2502      \u2502    0x08048a55    b801000000     mov eax, 1\r\n\u2502     \u250c\u2500\u2500\u2500&lt; 0x08048a5a    e9e3000000     jmp 0x8048b42                \r\n\u2502     \u2502\u2514    ; JMP XREF from 0x08048a53 (sym.auth)\r\n\u2502     \u2502\u2514\u2500\u2500&gt; 0x08048a5f    c744240c0000.  mov dword &#x5B;esp + 0xc], 0       ; &#x5B;0xc:4]=0\r\n\u2502     \u2502     0x08048a67    c74424080100.  mov dword &#x5B;esp + 8], 1         ; &#x5B;0x8:4]=0\r\n\u2502     \u2502     0x08048a6f    c74424040000.  mov dword &#x5B;esp + 4], 0         ; &#x5B;0x4:4]=0x10101 \r\n\u2502     \u2502     0x08048a77    c70424000000.  mov dword &#x5B;esp], 0\r\n\u2502     \u2502     0x08048a7e    e8edfdffff     call sym.imp.ptrace\r\n\u2502     \u2502       ^- sym.imp.ptrace()\r\n\u2502     \u2502     0x08048a83    83f8ff         cmp eax, 0xff\r\n\u2502    \u250c\u2500\u2500\u2500\u2500&lt; 0x08048a86    752e           jne 0x8048ab6                \r\n\u2502    \u2502\u2502     0x08048a88    c70424088d04.  mov dword &#x5B;esp], str._e_32m.___________________________.  ; &#x5B;0x8048d08:4]=0x32335b1b  ; str._e_32m.___________________________.\r\n\u2502    \u2502\u2502     0x08048a8f    e87cfdffff     call sym.imp.puts\r\n\u2502    \u2502\u2502       ^- sym.imp.puts()\r\n\u2502    \u2502\u2502     0x08048a94    c704242c8d04.  mov dword &#x5B;esp], str._e_31m_____TAMPERING_DETECTED______  ; &#x5B;0x8048d2c:4]=0x31335b1b  ; str._e_31m_____TAMPERING_DETECTED______\r\n\u2502    \u2502\u2502     0x08048a9b    e870fdffff     call sym.imp.puts\r\n\u2502    \u2502\u2502       ^- sym.imp.puts()\r\n\u2502    \u2502\u2502     0x08048aa0    c70424508d04.  mov dword &#x5B;esp], str._e_32m_____________________________  ; &#x5B;0x8048d50:4]=0x32335b1b  ; str._e_32m_____________________________\r\n\u2502    \u2502\u2502     0x08048aa7    e864fdffff     call sym.imp.puts\r\n\u2502    \u2502\u2502       ^- sym.imp.puts()\r\n\u2502    \u2502\u2502     0x08048aac    b801000000     mov eax, 1\r\n\u2502   \u250c\u2500\u2500\u2500\u2500\u2500&lt; 0x08048ab1    e98c000000     jmp 0x8048b42                \r\n\u2502   \u2502\u2514      ; JMP XREF from 0x08048a86 (sym.auth)\r\n\u2502   \u2502\u2514\u2500\u2500\u2500\u2500&gt; 0x08048ab6    8b4508         mov eax, dword &#x5B;ebp + 8]       ; &#x5B;0x8:4]=0\r\n\u2502   \u2502 \u2502     0x08048ab9    83c003         add eax, 3\r\n\u2502   \u2502 \u2502     0x08048abc    0fb600         movzx eax, byte &#x5B;eax]\r\n\u2502   \u2502 \u2502     0x08048abf    0fbec0         movsx eax, al\r\n\u2502   \u2502 \u2502     0x08048ac2    3537130000     xor eax, 0x1337\r\n\u2502   \u2502 \u2502     0x08048ac7    05eded5e00     add eax, 0x5eeded\r\n\u2502   \u2502 \u2502     0x08048acc    8945f0         mov dword &#x5B;ebp-local_4], eax\r\n\u2502   \u2502 \u2502     0x08048acf    c745ec000000.  mov dword &#x5B;ebp-local_5], 0\r\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500&lt; 0x08048ad6    eb4e           jmp 0x8048b26                \r\n\u2502           ; JMP XREF from 0x08048b2c (sym.auth)\r\n\u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&gt; 0x08048ad8    8b55ec         mov edx, dword &#x5B;ebp-local_5]\r\n\u2502  \u2502\u2502 \u2502     0x08048adb    8b4508         mov eax, dword &#x5B;ebp + 8]       ; &#x5B;0x8:4]=0\r\n\u2502  \u2502\u2502 \u2502     0x08048ade    01d0           add eax, edx\r\n\u2502  \u2502\u2502 \u2502     0x08048ae0    0fb600         movzx eax, byte &#x5B;eax]\r\n\u2502  \u2502\u2502 \u2502     0x08048ae3    3c1f           cmp al, 0x1f\r\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500&lt; 0x08048ae5    7f07           jg 0x8048aee                 \r\n\u2502 \u2502\u2502\u2502 \u2502     0x08048ae7    b801000000     mov eax, 1\r\n\u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&lt; 0x08048aec    eb54           jmp 0x8048b42                \r\n\u2502 \u2514         ; JMP XREF from 0x08048ae5 (sym.auth)\r\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500&gt; 0x08048aee    8b55ec         mov edx, dword &#x5B;ebp-local_5]\r\n\u2502  \u2502\u2502 \u2502     0x08048af1    8b4508         mov eax, dword &#x5B;ebp + 8]       ; &#x5B;0x8:4]=0\r\n\u2502  \u2502\u2502 \u2502     0x08048af4    01d0           add eax, edx\r\n\u2502  \u2502\u2502 \u2502     0x08048af6    0fb600         movzx eax, byte &#x5B;eax]\r\n\u2502  \u2502\u2502 \u2502     0x08048af9    0fbec0         movsx eax, al\r\n\u2502  \u2502\u2502 \u2502     0x08048afc    3345f0         xor eax, dword &#x5B;ebp-local_4]\r\n\u2502  \u2502\u2502 \u2502     0x08048aff    89c1           mov ecx, eax\r\n\u2502  \u2502\u2502 \u2502     0x08048b01    ba2b3b2388     mov edx, 0x88233b2b\r\n\u2502  \u2502\u2502 \u2502     0x08048b06    89c8           mov eax, ecx\r\n\u2502  \u2502\u2502 \u2502     0x08048b08    f7e2           mul edx\r\n\u2502  \u2502\u2502 \u2502     0x08048b0a    89c8           mov eax, ecx\r\n\u2502  \u2502\u2502 \u2502     0x08048b0c    29d0           sub eax, edx\r\n\u2502  \u2502\u2502 \u2502     0x08048b0e    d1e8           shr eax, 1\r\n\u2502  \u2502\u2502 \u2502     0x08048b10    01d0           add eax, edx\r\n\u2502  \u2502\u2502 \u2502     0x08048b12    c1e80a         shr eax, 0xa\r\n\u2502  \u2502\u2502 \u2502     0x08048b15    69c039050000   imul eax, eax, 0x539\r\n\u2502  \u2502\u2502 \u2502     0x08048b1b    29c1           sub ecx, eax\r\n\u2502  \u2502\u2502 \u2502     0x08048b1d    89c8           mov eax, ecx\r\n\u2502  \u2502\u2502 \u2502     0x08048b1f    0145f0         add dword &#x5B;ebp-local_4], eax\r\n\u2502  \u2502\u2502 \u2502     0x08048b22    8345ec01       add dword &#x5B;ebp-local_5], 1\r\n\u2502  \u2514        ; JMP XREF from 0x08048ad6 (sym.auth)\r\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500&gt; 0x08048b26    8b45ec         mov eax, dword &#x5B;ebp-local_5]\r\n\u2502   \u2502 \u2502     0x08048b29    3b45f4         cmp eax, dword &#x5B;ebp-local_3]\r\n\u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&lt; 0x08048b2c    7caa           jl 0x8048ad8                 \r\n\u2502   \u2502 \u2502     0x08048b2e    8b450c         mov eax, dword &#x5B;ebp + 0xc]     ; &#x5B;0xc:4]=0\r\n\u2502   \u2502 \u2502     0x08048b31    3b45f0         cmp eax, dword &#x5B;ebp-local_4]\r\n\u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&lt; 0x08048b34    7407           je 0x8048b3d                 \r\n\u2502   \u2502 \u2502     0x08048b36    b801000000     mov eax, 1\r\n\u2502   \u2502 \u2502     0x08048b3b    eb05           jmp 0x8048b42                \r\n\u2502           ; JMP XREF from 0x08048b34 (sym.auth)\r\n\u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&gt; 0x08048b3d    b800000000     mov eax, 0\r\n\u2502   \u2514 \u2514     ; JMP XREF from 0x08048b3b (sym.auth)\r\n\u2502   \u2514 \u2514     ; JMP XREF from 0x08048aec (sym.auth)\r\n\u2502   \u2514 \u2514     ; JMP XREF from 0x08048ab1 (sym.auth)\r\n\u2502   \u2514 \u2514     ; JMP XREF from 0x08048a5a (sym.auth)\r\n\u2502 \u2500\u2500\u2514\u2500\u2514\u2500\u2500\u2500&gt; 0x08048b42    c9             leave\r\n\u2558           0x08048b43    c3             ret\r\n<\/pre>\n<p>As we have already pointed out during the other levels, the arguments passed to the function are accessed with <code>ebp+0x8<\/code> (username) and <code>ebp+0xc<\/code> (serial). On line 17 the function <code>strcspn<\/code> is called. This function takes two arguments. The first argument is a string, in which the first occurence of a character being part of the string passed as second argument is searched. In the call on line 17 the username (<code>esp+0x8<\/code>) and a string located at <code>0x8048d03<\/code> is passed (lines 14-16). Let&#8217;s examine what this string contains:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048880]&gt; ps @ 0x8048d03\r\n\r\n\r\n&#x5B;0x08048880]&gt;\r\n<\/pre>\n<p>Oh, seems not to be an alphanumeric character:<\/p>\n<pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048880]&gt; px 1 @ 0x8048d03\r\n- offset -   0 1   2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF\r\n0x08048d03  0a                                        .\r\n<\/pre>\n<p>Okay, it is a newline (<code>0xa<\/code>). Let&#8217;s review what happens after the call to <code>strcspn<\/code>:<\/p>\n<pre class=\"brush: python; first-line: 19; title: ; notranslate\" title=\"\">\r\n\u2502           0x08048a28    8b5508         mov edx, dword &#x5B;ebp + 8]       ; &#x5B;0x8:4]=0\r\n\u2502           0x08048a2b    01d0           add eax, edx\r\n\u2502           0x08048a2d    c60000         mov byte &#x5B;eax], 0\r\n<\/pre>\n<p>Because the username has been read using <code>fgets<\/code> there is a newline at the end of the string (<code>fgets<\/code> does not truncate the newline). The call to <code>strcspn<\/code> returns the index of this newline character in <code>eax<\/code>. On line 19 the address of the username-string is moved to <code>edx<\/code>, which is then added to <code>eax<\/code> (line 20). Thus <code>eax<\/code> points to the newline character within the string. On line 21 the newline character is overwritten with a null-byte. This way the newline character is truncated. After this there is a call to <code>strnlen<\/code> on line 25:<\/p>\n<pre class=\"brush: python; first-line: 22; title: ; notranslate\" title=\"\">\r\n\u2502           0x08048a30    c74424042000.  mov dword &#x5B;esp + 4], 0x20      ; &#x5B;0x20:4]=0x2168  ; &quot;h!&quot; 0x00000020 \r\n\u2502           0x08048a38    8b4508         mov eax, dword &#x5B;ebp + 8]       ; &#x5B;0x8:4]=0\r\n\u2502           0x08048a3b    890424         mov dword &#x5B;esp], eax\r\n\u2502           0x08048a3e    e80dfeffff     call sym.imp.strnlen\r\n\u2502           0x08048a3e    e80dfeffff     call sym.imp.strnlen\r\n\u2502             ^- sym.imp.strnlen()\r\n\u2502           0x08048a43    8945f4         mov dword &#x5B;ebp-local_3], eax\r\n<\/pre>\n<p>The passed arguments are the username-string (<code>ebp+0x8<\/code>) and a max-length of 0x20 (32). The return-value of the call (<code>eax<\/code>) is stored in a local variable (<code>ebp-local_3<\/code>). This value is compared to <code>5<\/code> on line 34:<\/p>\n<pre class=\"brush: python; first-line: 34; title: ; notranslate\" title=\"\">\r\n\u2502           0x08048a4f    837df405       cmp dword &#x5B;ebp-local_3], 5     ; &#x5B;0x5:4]=257\r\n\u2502      \u250c\u2500\u2500&lt; 0x08048a53    7f0a           jg 0x8048a5f                 \r\n\u2502      \u2502    0x08048a55    b801000000     mov eax, 1\r\n\u2502     \u250c\u2500\u2500\u2500&lt; 0x08048a5a    e9e3000000     jmp 0x8048b42                \r\n\u2502     \u2502\u2514    ; JMP XREF from 0x08048a53 (sym.auth)\r\n<\/pre>\n<p>If the string length is less than or equal to 5, the <code>jg<\/code> on line 35 is not taken, 1 is moved to <code>eax<\/code> (line 36) and the function is quit on line 37 (<code>0x8048b42<\/code> is the address of the function&#8217;s epilogue). Remember that the return value is stored in <code>eax<\/code> and we want to achieve that the function returns 0 and not 1. If the string length is greater than 5 the code execution proceeds on line 39:<\/p>\n<pre class=\"brush: python; first-line: 39; title: ; notranslate\" title=\"\">\r\n\u2502     \u2502\u2514\u2500\u2500&gt; 0x08048a5f    c744240c0000.  mov dword &#x5B;esp + 0xc], 0       ; &#x5B;0xc:4]=0\r\n\u2502     \u2502     0x08048a67    c74424080100.  mov dword &#x5B;esp + 8], 1         ; &#x5B;0x8:4]=0\r\n\u2502     \u2502     0x08048a6f    c74424040000.  mov dword &#x5B;esp + 4], 0         ; &#x5B;0x4:4]=0x10101 \r\n\u2502     \u2502     0x08048a77    c70424000000.  mov dword &#x5B;esp], 0\r\n\u2502     \u2502     0x08048a7e    e8edfdffff     call sym.imp.ptrace\r\n\u2502     \u2502       ^- sym.imp.ptrace()\r\n\u2502     \u2502     0x08048a83    83f8ff         cmp eax, 0xff\r\n\u2502    \u250c\u2500\u2500\u2500\u2500&lt; 0x08048a86    752e           jne 0x8048ab6                \r\n\u2502    \u2502\u2502     0x08048a88    c70424088d04.  mov dword &#x5B;esp], str._e_32m.___________________________.  ; &#x5B;0x8048d08:4]=0x32335b1b  ; str._e_32m.___________________________.\r\n\u2502    \u2502\u2502     0x08048a8f    e87cfdffff     call sym.imp.puts\r\n\u2502    \u2502\u2502       ^- sym.imp.puts()\r\n\u2502    \u2502\u2502     0x08048a94    c704242c8d04.  mov dword &#x5B;esp], str._e_31m_____TAMPERING_DETECTED______  ; &#x5B;0x8048d2c:4]=0x31335b1b  ; str._e_31m_____TAMPERING_DETECTED______\r\n\u2502    \u2502\u2502     0x08048a9b    e870fdffff     call sym.imp.puts\r\n\u2502    \u2502\u2502       ^- sym.imp.puts()\r\n\u2502    \u2502\u2502     0x08048aa0    c70424508d04.  mov dword &#x5B;esp], str._e_32m_____________________________  ; &#x5B;0x8048d50:4]=0x32335b1b  ; str._e_32m_____________________________\r\n\u2502    \u2502\u2502     0x08048aa7    e864fdffff     call sym.imp.puts\r\n\u2502    \u2502\u2502       ^- sym.imp.puts()\r\n\u2502    \u2502\u2502     0x08048aac    b801000000     mov eax, 1\r\n\u2502   \u250c\u2500\u2500\u2500\u2500\u2500&lt; 0x08048ab1    e98c000000     jmp 0x8048b42                  \r\n<\/pre>\n<p>On line 43 there is a call to <code>ptrace<\/code> which is a common anti-debugging technique. A debugger typically uses <code>ptrace<\/code> to attach to a process. Since there can only be one attached process at a time, the <code>ptrace<\/code> call will fail if there is already a debugger attached. In this case the function would return <code>0xff<\/code> and the <code>jne<\/code> on line 46 would not be taken. This would lead to the ouput <code>\"TAMPERING DETECTED\"<\/code> followed by a jump to the function epilogue returning 1 (line 56-57). To bypass this we could copy the binary and patch the code with NOPs (<code>0x90<\/code>). For learning purpose we proceed to statically reverse the binary:<\/p>\n<pre class=\"brush: python; first-line: 59; title: ; notranslate\" title=\"\">\r\n\u2502   \u2502\u2514\u2500\u2500\u2500\u2500&gt; 0x08048ab6    8b4508         mov eax, dword &#x5B;ebp + 8]       ; &#x5B;0x8:4]=0\r\n\u2502   \u2502 \u2502     0x08048ab9    83c003         add eax, 3\r\n\u2502   \u2502 \u2502     0x08048abc    0fb600         movzx eax, byte &#x5B;eax]\r\n\u2502   \u2502 \u2502     0x08048abf    0fbec0         movsx eax, al\r\n\u2502   \u2502 \u2502     0x08048ac2    3537130000     xor eax, 0x1337\r\n\u2502   \u2502 \u2502     0x08048ac7    05eded5e00     add eax, 0x5eeded\r\n\u2502   \u2502 \u2502     0x08048acc    8945f0         mov dword &#x5B;ebp-local_4], eax\r\n\u2502   \u2502 \u2502     0x08048acf    c745ec000000.  mov dword &#x5B;ebp-local_5], 0      \r\n<\/pre>\n<p>On line 59 the address of the username string is moved to <code>eax<\/code>. On the next line (60) the value 3 is added and the resulting address is used as a byte pointer, which targeted byte is moved to <code>eax<\/code> using the instruction <code>movzx<\/code>. This instructions is called <code>move with zero-extend<\/code> meaning that the smaller value (in this case 1 byte) is moved to eax (4 byte) and all upper bytes are set to 0. The next instruction on line 62 is called <code>move with sign-extension<\/code> and is quite equal to <code>movzx<\/code>. The difference is that the upper bytes are not filled with 0 but with the sign-extension of the source. Since we are dealing with an ASCII string which bytes range from 0x00 to 0x7f the sign-extension is always 0. On line 63 the value stored in <code>eax<\/code> (3rd byte of the username string) is XORed with <code>0x1337<\/code> and <code>0x5eeded<\/code> is added on line 64. The result is stored in a local variable (<code>ebp-local_4<\/code>). Another local variable (<code>ebp-local_5<\/code>) is set to 0. Time to quickly reassemble our function code so far:<\/p>\n<pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\r\nint auth(char *username, unsigned int serial) {\r\n\r\n  int idx = strcspn(username, '\\n');\r\n  username&#x5B;idx] = 0x00;\r\n\r\n  int len = strnlen(username, 32);\r\n  if (len &lt;= 5) return 1;\r\n\r\n  if (ptrace(0, 0, 1, 0) == 0xff) {\r\n    puts(&quot;TAMPERING DETECTED!&quot;);\r\n    return 1;\r\n  }\r\n\r\n  unsigned int v1 = (username&#x5B;3] ^ 0x1337) + 0x5eeded;\r\n\r\n  int i = 0;\r\n\r\n  ...\r\n\r\n}\r\n<\/pre>\n<p>The assembly proceeds on line 67:<\/p>\n<pre class=\"brush: python; first-line: 67; title: ; notranslate\" title=\"\">\r\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500&lt; 0x08048ad6    eb4e           jmp 0x8048b26                \r\n\u2502           ; JMP XREF from 0x08048b2c (sym.auth)\r\n\u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&gt; 0x08048ad8    8b55ec         mov edx, dword &#x5B;ebp-local_5]\r\n\u2502  \u2502\u2502 \u2502     0x08048adb    8b4508         mov eax, dword &#x5B;ebp + 8]       ; &#x5B;0x8:4]=0\r\n\u2502  \u2502\u2502 \u2502     0x08048ade    01d0           add eax, edx\r\n\u2502  \u2502\u2502 \u2502     0x08048ae0    0fb600         movzx eax, byte &#x5B;eax]\r\n\u2502  \u2502\u2502 \u2502     0x08048ae3    3c1f           cmp al, 0x1f\r\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500&lt; 0x08048ae5    7f07           jg 0x8048aee                 \r\n\u2502 \u2502\u2502\u2502 \u2502     0x08048ae7    b801000000     mov eax, 1\r\n\u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&lt; 0x08048aec    eb54           jmp 0x8048b42                \r\n\u2502 \u2514         ; JMP XREF from 0x08048ae5 (sym.auth)\r\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500&gt; 0x08048aee    8b55ec         mov edx, dword &#x5B;ebp-local_5]\r\n\u2502  \u2502\u2502 \u2502     0x08048af1    8b4508         mov eax, dword &#x5B;ebp + 8]       ; &#x5B;0x8:4]=0\r\n\u2502  \u2502\u2502 \u2502     0x08048af4    01d0           add eax, edx\r\n\u2502  \u2502\u2502 \u2502     0x08048af6    0fb600         movzx eax, byte &#x5B;eax]\r\n\u2502  \u2502\u2502 \u2502     0x08048af9    0fbec0         movsx eax, al\r\n\u2502  \u2502\u2502 \u2502     0x08048afc    3345f0         xor eax, dword &#x5B;ebp-local_4]\r\n\u2502  \u2502\u2502 \u2502     0x08048aff    89c1           mov ecx, eax\r\n\u2502  \u2502\u2502 \u2502     0x08048b01    ba2b3b2388     mov edx, 0x88233b2b\r\n\u2502  \u2502\u2502 \u2502     0x08048b06    89c8           mov eax, ecx\r\n\u2502  \u2502\u2502 \u2502     0x08048b08    f7e2           mul edx\r\n\u2502  \u2502\u2502 \u2502     0x08048b0a    89c8           mov eax, ecx\r\n\u2502  \u2502\u2502 \u2502     0x08048b0c    29d0           sub eax, edx\r\n\u2502  \u2502\u2502 \u2502     0x08048b0e    d1e8           shr eax, 1\r\n\u2502  \u2502\u2502 \u2502     0x08048b10    01d0           add eax, edx\r\n\u2502  \u2502\u2502 \u2502     0x08048b12    c1e80a         shr eax, 0xa\r\n\u2502  \u2502\u2502 \u2502     0x08048b15    69c039050000   imul eax, eax, 0x539\r\n\u2502  \u2502\u2502 \u2502     0x08048b1b    29c1           sub ecx, eax\r\n\u2502  \u2502\u2502 \u2502     0x08048b1d    89c8           mov eax, ecx\r\n\u2502  \u2502\u2502 \u2502     0x08048b1f    0145f0         add dword &#x5B;ebp-local_4], eax\r\n\u2502  \u2502\u2502 \u2502     0x08048b22    8345ec01       add dword &#x5B;ebp-local_5], 1\r\n\u2502  \u2514        ; JMP XREF from 0x08048ad6 (sym.auth)\r\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500&gt; 0x08048b26    8b45ec         mov eax, dword &#x5B;ebp-local_5]\r\n\u2502   \u2502 \u2502     0x08048b29    3b45f4         cmp eax, dword &#x5B;ebp-local_3]\r\n\u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&lt; 0x08048b2c    7caa           jl 0x8048ad8                              \r\n<\/pre>\n<p>On line 67 there is a <code>jmp<\/code> to the end of the output above (line 99). On lines 99-101 the local variables <code>ebp-local_5<\/code> and <code>ebp-local_3<\/code> are compared. If <code>ebp-local_5<\/code> is less than <code>ebp-local_3<\/code> the <code>jl<\/code> to line 69 is taken. This is simply a for-loop:<\/p>\n<pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\r\n  ...\r\n\r\n  for (int i = 0; i &lt; len; i++) {\r\n\r\n    ...\r\n\r\n  }\r\n<\/pre>\n<p>In the loop-body the character indexed by <code>ebp-local_5<\/code> is moved to <code>eax<\/code> (lines 69-72) and compared to <code>0x1f<\/code> (line 73). If the value is less than or equal to <code>0x1f<\/code> the function returns 1. This way control-characters within the username are obviated.<\/p>\n<p>In lines 78-82 the character indexed by <code>ebp-local_5<\/code> is moved to <code>eax<\/code> again. Then on line 83 the character is XORed with the local variable <code>ebp-local_4<\/code>, which contains the previously manipulated 3rd character. In lines 84-95 follow a few more mathematical operations and moves. One instruction which could need some explanation is <code>mul<\/code> (line 88). While you can guess that <code>mul<\/code> stands for multiply, you are may wondering why there is only one operand (<code>edx<\/code>). The reason is that <code>mul<\/code> implicitly uses the <code>eax<\/code> register. The operand is multiplied by <code>eax<\/code> and the result is stored in <code>eax<\/code> <u>and<\/u> the operand register because the product of two 32-bit registers may exceed 32-bit. The lower bits are stored in <code>eax<\/code> and the upper bits are stored in the operand register. Taking this into account the reversed loop looks like this:<\/p>\n<pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\r\n  ...\r\n\r\n  for (int i = 0; i &lt; len; i++) {\r\n  \r\n    unsigned int v2, v3, v4;\r\n\r\n    if (username&#x5B;i] &lt;= 0x1f) return 1;\r\n    v2 = username&#x5B;i];\r\n    v2 ^= v1;\r\n    v3 = (0x88233b2b * v2) &gt;&gt; 32;\r\n    v4 = v2 - v3;\r\n    v4 = v4 &gt;&gt; 1;\r\n    v4 += v3;\r\n    v4 = v4 &gt;&gt; 10;\r\n    v4 *= 0x539;\r\n    v4 = v2 - v4;\r\n\r\n    v1 += v4;\r\n\t\r\n  }\r\n<\/pre>\n<p>As you may have noticed only the upper bits of the <code>mul<\/code> instruction on line 87 are actually used. In order to get those upper bits we can simply right-shift the product 32 bits. The other instructions should be already familiar.<\/p>\n<p>Right after the loop there are only a few lines left:<\/p>\n<pre class=\"brush: python; first-line: 102; title: ; notranslate\" title=\"\">\r\n\u2502   \u2502 \u2502     0x08048b2e    8b450c         mov eax, dword &#x5B;ebp + 0xc]     ; &#x5B;0xc:4]=0\r\n\u2502   \u2502 \u2502     0x08048b31    3b45f0         cmp eax, dword &#x5B;ebp-local_4]\r\n\u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&lt; 0x08048b34    7407           je 0x8048b3d                 \r\n\u2502   \u2502 \u2502     0x08048b36    b801000000     mov eax, 1\r\n\u2502   \u2502 \u2502     0x08048b3b    eb05           jmp 0x8048b42                \r\n\u2502           ; JMP XREF from 0x08048b34 (sym.auth)\r\n\u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&gt; 0x08048b3d    b800000000     mov eax, 0\r\n\u2502   \u2514 \u2514     ; JMP XREF from 0x08048b3b (sym.auth)\r\n\u2502   \u2514 \u2514     ; JMP XREF from 0x08048aec (sym.auth)\r\n\u2502   \u2514 \u2514     ; JMP XREF from 0x08048ab1 (sym.auth)\r\n\u2502   \u2514 \u2514     ; JMP XREF from 0x08048a5a (sym.auth)\r\n\u2502 \u2500\u2500\u2514\u2500\u2514\u2500\u2500\u2500&gt; 0x08048b42    c9             leave\r\n\u2558           0x08048b43    c3             ret\r\n<\/pre>\n<p>The comparison on line 103 tests if <code>ebp+0xc<\/code> (the serial entered) and <code>ebp-local_4<\/code> (the calculated serial) match. Depending on the result of this comparison the function returns 1 (failed) or 0 (match).<\/p>\n<p>With the reversed function fragments we can now write a little key-generator:<\/p>\n<pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdint.h&gt;\r\n\r\nint genKey(char *username) {\r\n  \r\n  int idx = strcspn(username, &quot;\\n&quot;);\r\n  username&#x5B;idx] = 0x00;\r\n  \r\n  int len = strnlen(username, 32);\r\n  if (len &lt;= 5) return 0;\r\n  \r\n  unsigned int v1 = (username&#x5B;3] ^ 0x1337) + 0x5eeded;\r\n\r\n  int i = 0;  \r\n\r\n  for (i = 0; i &lt; len; i++) {\r\n   \r\n    unsigned int v2, v3, v4;\r\n \r\n    if (username&#x5B;i] &lt;= 0x1f) return 0;\r\n    v2 = username&#x5B;i];\r\n    v2 ^= v1;\r\n    v3 = (uint64_t)v2*0x88233b2b &gt;&gt; 32;\r\n    v4 = v2 - v3;\r\n    v4 = v4 &gt;&gt; 1;\r\n    v4 += v3;\r\n    v4 = v4 &gt;&gt; 10;\r\n    v4 *= 0x539;\r\n    v4 = v2 - v4;\r\n     \r\n    v1 += v4;\r\n    v1 &amp;= 0xffffffff;\r\n     \r\n  }\r\n   \r\n  return v1;\r\n}\r\n \r\n \r\nint main() {\r\n  \r\n  char username&#x5B;32];\r\n  unsigned int serial;\r\n  \r\n  printf(&quot;Enter username: &quot;);\r\n  fgets(username, 32, stdin);\r\n   \r\n  serial = genKey(username);\r\n  if (serial &gt; 0) printf(&quot;serial: %u\\n&quot;, serial);\r\n  \r\n}\r\n<\/pre>\n<p>Now we can generate your own serial:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~$ gcc lab1A.c -o lab1A\r\nroot@kali:~$ .\/lab1A\r\nEnter username: dummyuser\r\nserial: 6235758\r\n<\/pre>\n<p>And enter it to get a shell:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nlab1A@warzone:\/levels\/lab01$ .\/lab1A\r\n.---------------------------.\r\n|---------  RPISEC  --------|\r\n|+ SECURE LOGIN SYS v. 3.0 +|\r\n|---------------------------|\r\n|~- Enter your Username:  ~-|\r\n'---------------------------'\r\ndummyuser\r\n.---------------------------.\r\n| !! NEW ACCOUNT DETECTED !!|\r\n|---------------------------|\r\n|~- Input your serial:    ~-|\r\n'---------------------------'\r\n6235758\r\nAuthenticated!\r\n$ whoami\r\nlab1end\r\n$ cat \/home\/lab1end\/.pass\r\n1uCKy_Gue55\r\n<\/pre>\n<p>Done \ud83d\ude42 The final password is <code>1uCKy_Gue55<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>RPISEC is the resident computer security club at Rensselaer Polytechnic Institute. They developed a university course to teach skills in vulnerability research, reverse engineering and binary exploitation. The course material can be found on github including a detailed explanation on how to run the provided VM: https:\/\/github.com\/RPISEC\/MBE. This article contains my writeup for the first &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/devel0pment.de\/?p=4\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;RPISEC\/MBE: writeup lab01 (Reverse Engineering)&#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":[26,7],"tags":[8,9,13,10,11,12,14],"class_list":["post-4","post","type-post","status-publish","format-standard","hentry","category-rpisec-mbe","category-writeup","tag-assembly","tag-binary","tag-elf","tag-pwn","tag-r2","tag-reversing","tag-x86"],"_links":{"self":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/4"}],"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=4"}],"version-history":[{"count":58,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/4\/revisions"}],"predecessor-version":[{"id":172,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/4\/revisions\/172"}],"wp:attachment":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}