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

David Biggins David_Biggins at usermgmt.com
Tue Aug 10 20:45:10 BST 2010


> -----Original Message-----
> From: ukcrypto-bounces at chiark.greenend.org.uk [mailto:ukcrypto-
> bounces at chiark.greenend.org.uk] On Behalf Of Roland Perry
> Sent: 10 August 2010 11:04
> To: ukcrypto at chiark.greenend.org.uk
> Subject: Re: Being safe on the internet (was Re: Here we go again -
ISP
> DPI,but is it interception?)
> 
> Time to re-write the operating system then. As it's well past the
> classic version 3, how about getting this right in version 6? Failing
> that, version 7 :)

Hi Roland,

Oh, yes. But it's not just the OS (and not just Windows).  And if we're
going to do that, we really ought to fix all the hardware, too....

> But if stacks grow downwards, how can a newer item rise upwards?

Stacks are not the idealised "just push/just pop" system.

Say a function requires two local variables - a fixed string buffer of
256 bytes, and a four-byte integer.

When the function is called, code in the caller, and standard header
code at the function entry point, will push a "stack frame" containing
the parameters to the function, the return address, and the current
value of a register called BP.

The header will then subtract 260 (the total size of your two local
variables) from current stack pointer and set the BP register equal to
the stack pointer.  

Then [BP] (the area pointed to by BP), for 256 bytes upwards, is your
local string, and [BP]+256 for four bytes is your integer.  

+-------------------------------------+
+     Parameter 1                     +
+-------------------------------------+
+     Parameter 2                     +
+-------------------------------------+
+     Return address                  +
+-------------------------------------+
+     Old BP register                 +
+-------------------------------------+
+     Integer local variable          +
+-------------------------------------+
+                                     +
+                                     +
+     256 bytes of string variable    +
+                                     +
+                                     + 
+-------------------------------------+

So anything copying to that string buffer or writing to the integer will
actually be writing to the stack.  

And if the string write, writes more than 256 bytes,  whoops, there goes
your integer...  and if it writes more than 260 bytes, there goes your
subroutine return address....  and so on.

So the standard form of a buffer overflow attack is to find where a
programme is likely to be writing to a local string, stored on the
stack, and to try to fool the code into writing more than 256 bytes to
the string...  and by rigging the bytes that will overwrite the stack
pointer so that when the subroutine returns, the return address points
into your string, and starts executing it as code.  Getting this return
address right, and crafting the string so that the bytes perform some
useful exploit is not quite that trivial.

The problem is not, incidentally, just confined to strings,  though
strcpy is probably on its own a very substantial proportion of such
overflow attacks.

I believe that some of the attacks we've had where "specially crafted
images" in TIFF, GIF and JPEG files, have involved cases where say the
sum of the specified lengths of several "child" blocks, add up to more
than the specified length of a "parent".

The code reserves a new block the same size as the parent specifies, and
then copies each child in turn into it, using the child's stated length
each time... which of course makes the copy overflow the reserved space.

Or...   say a decompression routine which looks at the stated original
size of a compressed block, reserves that, and then decompresses the
compressed block - which has been rigged to decompress to something
longer than the stated size.

The problem is that it requires a very much less trusting view of data,
not just code, than has been traditional in much of the IT market,
particularly the PC market.

The current main mitigations for this are:

"stack canaries" - values written to various locations on the stack;  if
they change, you have a problem.  Various hardware debug mechanisms
could be used to detect such changes without code overhead...

DEP - the ability to mark various parts of memory (once more) as not
being allowed to be executed.

But I might even question whether or not it is safe to continue to use
the same stack for code pointers and for data.


D.




More information about the ukcrypto mailing list