I was looking at the recent ssh crc32 detetect attack buffer overflow, and noticed that it won't work on Linux. This is due to the fact that Linux returns a null pointer on a when realloc() asks for 0 bytes. From the CORE-SDI advisory: It is worth mentioning that existing standards promote two possible behaviours for malloc() when it is called with an argument of 0: - Failure, returning NULL - Success, returning a valid address pointing at a zero-sized object. Most modern systems implement the later behaviour and are thus vulnerable. Systems which have the older behaviour will abort the connection due to checks within xmalloc(). Linux, apparently, is not modern enough :-/ However, I found that only the realloc() does this, but for some reason, an original malloc(0) works fine. Watch: $ ./test_alloc malloc(0) returns pointer 0x8049710 realloc(0x8049710, 0) returns pointer (nil) malloc(16) returns pointer 0x8049710 realloc(0x8049710,0) returns pointer (nil) $ uname -smr Linux 2.2.14-5.0 i686 (I included test_alloc.c at the end of this message) So, looking at the deattack.c source, it may still be possible on Linux... if (h == NULL) { debug("Installing crc compensation attack detector."); n = l; h = (u_int16_t *) xmalloc(n * HASH_ENTRYSIZE); } else { if (l > n) { n = l; h = (u_int16_t *) xrealloc(h, n * HASH_ENTRYSIZE); } } so, the first time detect_attack() is called is where we must strike... Is this possible??? Paul starzetz first sent a packet of 0xf's to solve some hash conditions, but can we bigpacket from the beginning?? Now, we can even send more big packets, as long as they are always preceded by a big packet which sets h to zero So......: does anyone know of a way to expoit the crc32 overflow by only malloc()ing and not realloc()ing, that is, making sure that whenever a big packet is recieved, h is 0 ??? ************************** Here is the source for test_alloc.c: #include <stdio.h> #include <stdlib.h> int main(void) { int *p, *z; printf ("malloc(0) returns pointer %p\n", z=malloc(0)); printf ("realloc(%p, 0) returns pointer %p\n", z, realloc(z,0)); printf ("malloc(16) returns pointer %p\n", p=malloc(16)); printf ("realloc(%p,0) returns pointer %p\n", p, realloc(p,0)); return 0; } Franklin DeMatto franklinat_private qDefense - DEFENDING THE ELECTRONIC FRONTIER
This archive was generated by hypermail 2b30 : Sat Apr 28 2001 - 10:28:15 PDT