Ulf Bahrenfuss wrote: > Hi! > > Does anyone know, if the chunk handling vulnerability carries through > a proxy i.e. Squid or Webcache? (Updating is currently not possible, > because it is not the plain apache, but the Oracle IAS flavour...) > > Or has anyone further information how this vulnerabilty really works? Here's an analysis I wrote for iternal use at the ASF - it doesn't go into detail on the shellcode (which is just the usual shellcode), but does explain how the expected SEGV from overrunning the stack is avoided. Note that someone (sorry, forgotten who) posted a similar generic analyis a day or two ago - this one was independently arrived at and refers to the Gobbles attack specifically. First, the exploit code puts stuff on the stack (legitimately, in buffers). It then arranges a negative offset, as previously described, to be handed to memcpy. Here's where it gets cute. memcpy has memmove semantics (i.e., it copies in the correct direction to handle overlapping source/dest) on both OpenBSD and FreeBSD (in fact, I believe this is a requirement for this exploit to work on any system where the stack grows downwards). As a result, when the memcpy is attempted, it is done backwards (i.e. the copy starts at source+length-1 -> dest+length-1 and downwards for length bytes). Now, here's the cute bit. memmove (et al) are optimised to copy in 4 byte chunks, for speed. This means that they have to copy the leftover bytes separately. This is handled by copying the odd 0-3 bytes before the remaining bytes. So, if you arrange for the negative offset of the buffer to point at where the length is stored on the stack, then when these odd bytes are copied, you can modify the length. What they do is modify an initial length of 0xffffxxxx to 0x0000xxxx - note that the length is also the offset, so there is also a certain amount of luck involved, but all that is needed is for the offset to be small enough that the length remains big enough to zap enough stack (since the offset is a few hundred, that leaves the length at near to 64k, which is plenty to zap a few return addresses). Then, when the length is reloaded to do the second copy, it is miraculously smaller (I boggled first time I saw this in the debugger), and doesn't cause the expected SEGV, just nice corruption of the stack, as required![1] So, to illustrate with source: 0x400f9d6c <memcpy>: push %esi 0x400f9d6d <memcpy+1>: push %edi 0x400f9d6e <memcpy+2>: mov 0xc(%esp,1),%edi 0x400f9d72 <memcpy+6>: mov 0x10(%esp,1),%esi 0x400f9d76 <memcpy+10>: mov 0x14(%esp,1),%ecx 0x400f9d7a <memcpy+14>: cmp %esi,%edi 0x400f9d7c <memcpy+16>: jae 0x400f9d94 <memcpy+40> ... at this point, we've decided to go backwards, edi is dest, esi is source and ecx is count (aka -146 aka ffffff6e) 0x400f9d94 <memcpy+40>: add %ecx,%edi 0x400f9d96 <memcpy+42>: add %ecx,%esi Now we are pointing at the "end" of the buffers (i.e. somewhere down the stack from them, and, lo and behold, edi now points at the two MS bytes of the count) 0x400f9d98 <memcpy+44>: std 0x400f9d99 <memcpy+45>: and $0x3,%ecx calculate spare bytes (2 in this case) 0x400f9d9c <memcpy+48>: dec %edi 0x400f9d9d <memcpy+49>: dec %esi 0x400f9d9e <memcpy+50>: repz movsb %ds:(%esi),%es:(%edi) and copy them - in fact two zeroes are copied, so the length is now 0000ff6e. 0x400f9da0 <memcpy+52>: mov 0x14(%esp,1),%ecx load the length again (now ff6e) 0x400f9da4 <memcpy+56>: shr $0x2,%ecx divide by 4 0x400f9da7 <memcpy+59>: sub $0x3,%esi 0x400f9daa <memcpy+62>: sub $0x3,%edi 0x400f9dad <memcpy+65>: repz movsl %ds:(%esi),%es:(%edi) and copy that many longs (i.e. just shy of 64k bytes). Here is where we would have gone bang with a SEGV, but don't coz of the cunningness. 0x400f9daf <memcpy+67>: mov 0xc(%esp,1),%eax 0x400f9db3 <memcpy+71>: pop %edi 0x400f9db4 <memcpy+72>: pop %esi 0x400f9db5 <memcpy+73>: cld 0x400f9db6 <memcpy+74>: ret return to a corrupted return address (or is it the next one up that's corrupted? not sure, don't care). And hey presto, remote shell. Note that glibc is _not_ vulnerable in this way, so I have no idea how the Linux attack works. I have not examined Solaris. Cheers, Ben. [1] For those not familiar with this class of exploit, the stack is corrupted such that the return address for some function call points to code which spawns a shell, which is then used by the attacker to have his or her evil way with your machine. -- http://www.apache-ssl.org/ben.html http://www.thebunker.net/ "There is no limit to what a man can do or how far he can go if he doesn't mind who gets the credit." - Robert Woodruff