Being safe on the internet (was Re: Here we go again - ISP DPI, but is it interception?)

David Biggins David_Biggins at usermgmt.com
Fri Aug 6 19:27:31 BST 2010


> -----Original Message-----
> From: ukcrypto-bounces at chiark.greenend.org.uk [mailto:ukcrypto-
> bounces at chiark.greenend.org.uk] On Behalf Of Tom Thomson
> Sent: 05 August 2010 01:56
> To: 'UK Cryptography Policy Discussion Group'
> Subject: RE: Being safe on the internet (was Re: Here we go again - ISP
> DPI,but is it interception?)
> 
> There are indeed appropriate techniques, but these techniques involve
> either or both of using hardware which supports memory management 

<>snip<>

> However, all this sound practise was thrown away - following the
> "cheaper is better, regardless of safety and security, and theoretical
> soundness is undesirable because it costs more" philosophy which was
> illustrated by the invention of insecure (and indeed un-securable)
> languages like C, operating systems like Unix, and hardware that was
> designed to support only these minimal cost languages and operating
> systems.

<>snip<>

> The result is a bunch of
> excessively vulnerable software, which mostly can't rely on any useful
> security support from the underlying hardware, that we have to live
> with today.
> 

Three such factors in particular formed an interesting collision of decisions by three separate groups, that combined to form a serious security problem.

The first is the classic 'C' "null terminated string" in which there is no standard (or efficient) tracking in the language of either the current length of a string or the space allocated to it.  

For non-programmers here, that means that the standard library operations to copy or concatenate a string have no intrinsic way of knowing whether or not the space that a string is being copied to, is actually big enough to hold it.  They just copy bytes until one of the bytes is a zero.  So if you have a kilobyte of string before that zero, and there's only 256 bytes of space reserved where you're copying to, then tough.  768 bytes of whatever follows, are going to get trampled.

It is perhaps a pity that a "strcpy() considered harmful" didn't appear before billions of lines of code were written using it.

The second was adoption by Intel of the "top down" hardware stack

In this, the "base" of the stack is high in memory and the stack grows downwards as you push values, rather than starting at the bottom of memory and growing upwards.

The nasty effect of this was that if you overflow the target buffer in a string copy as above, when the destination is a local variable on the stack, you don't just overwrite a few values then unused stack space - which would have been far harder to exploit.

Instead, you can overwrite much of the existing stack.  

Which includes the place where the currently-executing subroutine's own return address is stored.  Which means that provided the current subroutine does not crash as a result of the overwriting of the other values, when it comes to return, its return address will be whatever the values from the overflow were... which an attacker can choose.  These are normally picked to point into another part of that same string data that caused the overflow, which lets the attacker effectively get the program running his/her own code.

The third was Microsoft giving in to some unfortunate market pressure.  

For some time, Apple/Motorola proponents had ridiculed the segmented architecture of the Intel CPUs (particularly in the way that 16-bit code used it), in which memory was accessed by a segment address pointing to a segment descriptor, and an offset within the block that the segment descriptor described.  

The frequent criticism that "you can't address all the memory in one go" was rarely answered with any reasoned discussion, but mostly a sheepish "sure, well, maybe one day...".  

When 32-bit Windows 95 came out, one of the more trumpeted features of the day was that they had allowed this criticism to push them into using the "flat memory model", in which all the segment registers pointed to the same segment descriptor, and the single segment descriptor was set to cover the full range of memory.  

This of course meant that you could ignore the segment system, and memory appeared as a single linear block, just as critics had demanded.  After that, of course, every other 32-bit x86 operating system maker, did the same thing;  after all... "If MS do it"...

It's just such a great pity that Intel hardware's read/write/execute permission settings were in the segment descriptor...  

Since the single descriptor was being used for all purposes, it had to be given all rights.

So sadly, this move completely bypassed the hardware protection mechanisms that were actually in the CPU.   This has given rise to the claim that there was no security support in the underlying hardware - that's not quite true,  it's just that a single misguided marketing decision in the OS design did such a magnificent job of trashing it.  Otherwise, even if an attacker had managed to get their own code onto the stack, it would not have been executable.

The combination of these three made a "perfect storm" for buffer overflow - a widespread data copying mechanism that lacked overflow protection, a stack system that made overflows far more exploitable, and a design decision that effectively disabled the hardware protection.

The vast majority of overflows use this combination.

It wasn't until modern 64-bit CPUs that hardware protection  mechanisms were added (again) into the memory management system - this time in the virtual memory page tables, so that they could be used in flat model systems.
 
{I'll forestall one criticism if I may:  It's been suggested that upward growing stacks are not part of the problem;  a buffer overflow from a subroutine when copying back to parameters on a parent stack frame could still overwrite the current subroutine's return address.  This is true, but such copies of a string back to a parent's stacked variables are very much rarer than string copies to local variables;  while I agree the upward stack does not prevent such vulnerabilities, the downward stack most assuredly massively increases the number of exploitable opportunities}


D.


More information about the ukcrypto mailing list