Secure Coding mailing list archives
Re: Off-by-one errors: a brief explanation
From: jnf <jnf () datakill org>
Date: Thu, 06 May 2004 14:15:02 +0100
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I will add that a phrack paper, which im pretty sure introduced the concept to the public called 'overwriting the frame pointer', or something similar to that effect explains in all its gruesome detail. Basically if my memory serves me correctly, what happened was because it was a stack based off by one, it allowed you to overwrite the LSB (depending on arch, this was done on a little endian machine) of the frame pointer that is restored into {e}bp when the leave instruction is called, thus the idea was the ability to control where the ret address would actually be called from (look up the leave and ret instructions on intel if you dont understand that), and the idea was to manipulate it in a way that you could alter the base pointer in such a way as for it to point to an address that you could legally store on the stack which pointed to your code, and then the following ret instruction was 'misguided', the phrack article describes it better than i could, and it was called something like 'overwriting the frame pointer', im not sure if it covered off-by-five errors though, and thats an error i never fully understood [how do you miscount the index by five?] so in a short recap, in a normal off by one error (that is exploitable), you can overwrite the LSB of an address on the stack that is restored to ebp when leave is called by a routine, then you would have an address that pointed to your code on the stack that ebp (now affected with one byte overwritten) pointed to thus confusing the ret instruction when its called by the procedure epilogue. If you dont understand the procedure prolog/epilogue, review aleph1's smashing the stack, or run a simple c program through your favorite debugger. anyway hope that helped some. j - -- It is only the great men who are truly obscene. If they had not dared to be obscene, they could never have dared to be great. -- Havelock Ellis On Wed, 5 May 2004, Steven M. Christey wrote:
Mads Rasmussen <[EMAIL PROTECTED]> said:I for one have difficulties understanding the "off-by-one" vulnerability. Maybe a kind soul would step in?I'll try to tackle this. Corrections or additions are most welcome :) In general, off-by-one bugs involve small errors in which an array of size "N" is accessed using an index of N - but since an index is 0-based in C, the maximum index for the array is N-1. So, N is actually one byte outside the range of the array. I haven't dug deeply into the details, but there are probably a couple variants. When manipulating strings using functions like strcpy, this means that the terminating null byte is written outside of the buffer, in some other memory location that might have security implications if that null is interpreted as a 0. Or, that memory location is overwritten after the null was inserted (say, by a string copy to another variable), so the null character is removed. Then, a function that processes that string will keep accessing memory until it hits a 0 byte. Functions like strncpy can also be vulnerable to off-by-ones. If the input is exactly size N, then strncpy doesn't add a terminating null byte. Any kind of C array can be susceptible to off-by-ones, not just strings. And the use of terminators isn't necessarily required. For example, if a programmer has an array of data structures, its length might be stored in a separate variable, rather than relying on a terminator value to signify the last element of the array. The bug isn't always exploitable for code execution. For example, sensitive data could be leaked from "nearby" memory locations due to a missing null terminator. Some documents that touch on off-by-ones include: Halvar Flake's presentation at Black Hat Europe 2001 on "Third Generation Exploits on NT/Win2k Platforms," which includes buffer overflows, heap/free() and off-by-one errors: http://www.blackhat.com/presentations/bh-europe-01/halvar-flake/bh-europe-01-halvarflake.ppt This includes a nice graphic representation of the problem at the stack level, touching on how portions of return addresses can be overwritten. The following Bugtraq post by Vade 79 gives an alternate description of off-by-ones, along with an example that causes potentially sensitive memory to be read and copied into a string because of the missing terminator. BUGTRAQ:20030727 [PAPER]: Address relay fingerprinting. URL:http://marc.theaimsgroup.com/?l=bugtraq&m=105941103709264&w=2 The following Bugtraq post by Jedi/Sector One gives something of a good demonstration if you read between the lines in the code: BUGTRAQ:20020624 Apache mod_ssl off-by-one vulnerability URL:http://marc.theaimsgroup.com/?l=bugtraq&m=102513970919836&w=2 In this example, a buffer is allocated 1024 bytes, and there is a conditional in a loop which tests if i < 1024. However, after that loop exits, index "i" in the array is modified. Olaf Kirch's Bugtraq post "The poisoned NUL byte" seems to be an early report of the security implications of an off-by-one error: BUGTRAQ:19981014 The poisoned NUL byte URL:http://www.securityfocus.com/archive/1/10884 Here are some more source code examples, from Bugtraq posts by Janusz Niewiadomski: BUGTRAQ:20030714 Linux nfs-utils xlog() off-by-one bug URL:http://marc.theaimsgroup.com/?l=bugtraq&m=105820223707191&w=2 BUGTRAQ:20030731 wu-ftpd fb_realpath() off-by-one bug URL:http://marc.theaimsgroup.com/?l=bugtraq&m=105967516807664&w=2 - Steve
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.2 (OpenBSD) iD8DBQFAmWousKAeTAhLiCERAsOkAJ9uk/CRidlxLmtc04vJzBOu2fxSMQCfd6+H EKl+Q2jsCNo6ea7Y4y014wI= =0x7A -----END PGP SIGNATURE-----
Current thread:
- Off-by-one errors: a brief explanation Steven M. Christey (May 05)
- Re: Off-by-one errors: a brief explanation jnf (May 06)
- RE: Off-by-one errors: a brief explanation Dave Paris (May 06)
- Message not available
- Re: Off-by-one errors: a brief explanation Mads Rasmussen (May 07)
- Re: Off-by-one errors: a brief explanation jnf (May 06)
- Re: Off-by-one errors: a brief explanation Pascal Meunier (May 07)
- <Possible follow-ups>
- RE: Off-by-one errors: a brief explanation Gary McGraw (May 06)
- Re: Off-by-one errors: a brief explanation Steven M. Christey (May 06)
- Re: Off-by-one errors: a brief explanation jnf (May 07)