(05-02-2014, 03:07 PM)Lorax Wrote: It's a sneaky-ass little backdoor that's affected a good 2/3rds of the internet. As far as I know, it's entirely unfixable.
Its very fixable, there was a patch before it was even publicly announced.
The fix:
http://pastebin.com/5PP8JVqA
Code:
hbtype = *p++;
n2s(p, payload);
pl = p;
n2s grabs 2 bytes from p and places tehm into payload. Those two bytes are the user-supplied size of the payload. Which is then used to copy the the data from the heartbeat request into the response payload(the heartbeat is basically just supposed to echo w/e the user inputs)
Code:
memcpy(bp, pl, payload);
bp is the output buffer, pl is the original input payload, and payload is the result 2 bytes after the hbtype in the original request(the user-supplied size)
So it copies a user-supplied number of bytes from the original payload into the new payload. In the attack a user supplies a size larger than what they actually input causeing memory to be copied from the following blocks of memory beyond their own input.
--------------
So the fix, is pretty simple. Just check that the user-supplied input is not larger than the supplied payload length.
Code:
if (1 + 2 + 16 > s->s3->rrec.length)
return 0; /* silently discard */
hbtype = *p++;
n2s(p, payload);
if (1 + 2 + payload + 16 > s->s3->rrec.length)
return 0; /* silently discard per RFC 6520 se
pl = p;
First line is just a minimum bounds check to ensure the payload that was recieved is atleast the min length to work with.
Next is grabs teh request type as before
Followed by the user-supplied size
Now the main fix is that it checks if the user-supplied size againsts the actual record length that was read in. If the user-supplied size is greater than the actual size is drops the packet.
Rest of the code remains the same.
See that fix wasn't very hard ^_^