質問

Would it be accurate to call the Heartbleed bug a stack overflow? In my understanding, this is quite a typical example. Is this technically correct?

役に立ちましたか?

解決

A stack is a data structure with "last in, first out" as its primary characteristic. It allows a caller (a piece of a program) to "push" information onto the stack, and to "pop" off the last item pushed. For a strict stack, no other operations are allowed.

The stack is used for programs when they call subprograms (functions, methods, subroutines are all subprograms, they have different names in different contexts). When a program calls a subprogram, a bunch of information needs to be saved so that it's available when the subprogram returns. So this "execution context" is pushed onto the stack, and then retrieved on return. This operation is so vital to computers that computer hardware supports it directly; in other words, there are machine instructions to do this so that it doesn't have to be done (slower) in software.

There is usually an amount of memory in the computer dedicated to this runtime stack, and even usually to a stack for each program running and a few for the operating system, etc. If subroutines calls get so "deep" that the amount of stack space allocated won't hold all the information needed for a call that occurs, that is a stackoverflow error.

This was not what the heartbleed problem was about. It allowed an exertnal program to set an amount of buffer space to be returned to it, and returned whatever happened to be in the memory beyond the little bit of data that this external program sent.

So the real answer to the question is "no", and I cannot imagine who would have thought that this was a typical example.

他のヒント

The heartbleed bug is not a stack overflow error, but a type of a buffer overrun error. A stack overflow error happens when a program runs out of stack space. This usually results in a crash, and is not directly exploitable.

Technically, yes. But not in the traditional overflow sense where you try to smash the stack and fiddle with return values and try to execute code. This was purely a "leak private data" problem.

The OpenSSL specification requires that a client sent a chunk of randomish data in its heartbeat packet. The server is required to turn that data exactly as is to the client.

The bug is that the client basically sends two bits of data:

size_of_heartbeat (16bit integer presenting heartbeat data size) heartbeat_data (up to 64k of data)

A malicious client can LIE about the data it's sending, and say:

size_of_hearbeat = 64k
heartbeat_data = ''   (1 byte)

OpenSSL failed to verify that the size_of_hearbeat == actual_size(heartbeat_data), and would trust the size_of_heartbeat, so basically you'd have:

 -- allocate as much memory as the client claims they sent to you
 -- copy the user's heartbeat packet into the response packet.

Since the user claims they sent you 64k, OpenSSL properly allocated a 64k buffer, but then then did an unbounded memcpy() and would happily copy up to 64k of ram past where there client's heartbeat data actually occurred.

Given enough attempts at this, you could build up a pretty complete picture of what's in the server's memory, 64k at a time, and eventually be able to extract things like the server's SSL certificates, temporary data from previous users who'd passed through the encryption layers, etc...

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top