![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Am 18.01.2013 16:58, schrieb Warp:
> Francois Labreque <fla### [at] videotron ca> wrote:
>> In the case of the BMP flaw, the leaked Windows 2000 source code showed
>> that the DLL was using a signed int to read an offset value that was
>> unsigned in the file format, so by crafting a special BMP file you would
>> have the DLL jump to a negative offset, and outside of the actual data
>> structure it was supposed to read.
>
> In 2's complement representation MAX_INT+1 has the exact same bits in
> both signed and unsigned forms. How do you get outside the array with
> that value?
That's wrong. In 2's complement representation, MAX_INT+1 has NO bit
representation at all. What you get instead if you interpret the
respective unsigned representation as signed is MIN_INT.
So take an array with a limited size, an "int" as an index into that
array, a check whether that index into that array is smaller than the
array's size - and you have the recipe for a stack overflow or similar
(unless you also remember to check whether the index is non-negative).
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
>> In 2's complement representation MAX_INT+1 has the exact same bits in
>> both signed and unsigned forms. How do you get outside the array with
>> that value?
>
> That's wrong. In 2's complement representation, MAX_INT+1 has NO bit
> representation at all. What you get instead if you interpret the
> respective unsigned representation as signed is MIN_INT.
Erm... don't you mean -1?
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Orchid Win7 v1 <voi### [at] dev null> wrote:
> >> In 2's complement representation MAX_INT+1 has the exact same bits in
> >> both signed and unsigned forms. How do you get outside the array with
> >> that value?
> >
> > That's wrong. In 2's complement representation, MAX_INT+1 has NO bit
> > representation at all. What you get instead if you interpret the
> > respective unsigned representation as signed is MIN_INT.
> Erm... don't you mean -1?
No. int(-1) has the same bit representation as MAX_UINT.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Am 18.01.2013 18:47, schrieb Orchid Win7 v1:
>>> In 2's complement representation MAX_INT+1 has the exact same bits in
>>> both signed and unsigned forms. How do you get outside the array with
>>> that value?
>>
>> That's wrong. In 2's complement representation, MAX_INT+1 has NO bit
>> representation at all. What you get instead if you interpret the
>> respective unsigned representation as signed is MIN_INT.
>
> Erm... don't you mean -1?
No. That would be MAX_UINT.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
clipka <ano### [at] anonymous org> wrote:
> So take an array with a limited size, an "int" as an index into that
> array, a check whether that index into that array is smaller than the
> array's size - and you have the recipe for a stack overflow or similar
> (unless you also remember to check whether the index is non-negative).
There's no index value that *could* be smaller than MIN_INT, so you would
have a bug certainly (the program wrongly thinks that all indices are
outside the array), but still no out-of-bounds access.
Even if the array size is (interpreted as) something larger than MIN_INT,
thus allowing for indices that are smaller than it, it would still bug
but not access out of the array (because negative indices "wrap around"
when they are converted to memory offsets, ending up at the same place
as the unsigned index with the same bit pattern.)
The only situation that I can think of where an out-of-bounds access will
probably happen is if pointers (and thus array indices) are 64-bit but
the array size is wrongly a signed (32-bit) int. It then gets expanded
to 64-bit when indexing the array, and ends up truly at negative addresses
(from the array's start.)
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Am 18.01.2013 19:30, schrieb Warp:
> clipka <ano### [at] anonymous org> wrote:
>> So take an array with a limited size, an "int" as an index into that
>> array, a check whether that index into that array is smaller than the
>> array's size - and you have the recipe for a stack overflow or similar
>> (unless you also remember to check whether the index is non-negative).
>
> There's no index value that *could* be smaller than MIN_INT, so you would
> have a bug certainly (the program wrongly thinks that all indices are
> outside the array), but still no out-of-bounds access.
Okay, let's do it a bit more specific:
void fubar(int idx)
{
char c[1024];
if (idx < 1024)
fnord(c[idx]);
else
FAIL_SAFE();
}
void main()
{
fubar(INT_MAX+1);
}
No out-of-bounds access? Look at the code again.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
clipka <ano### [at] anonymous org> wrote:
> Okay, let's do it a bit more specific:
> void fubar(int idx)
> {
> char c[1024];
> if (idx < 1024)
> fnord(c[idx]);
> else
> FAIL_SAFE();
> }
> void main()
> {
> fubar(INT_MAX+1);
> }
> No out-of-bounds access? Look at the code again.
But in the original post it was suggested that an array size of INT_MAX+1
in the image file could cause this. Here the array size is just 1024 (which
in this particular contest would have ostensibly been read from the image
file.)
Unless there's an image file where there are actual index values specified.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
> (I suppose that if you use a signed *long* in a 64-bit system where longs
> are 64-bit, then expanding a signed 32-bit int to such a signed 64-bit long
> will result in the wrong value. But was that the case here?)
>
While this one
(http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-0894) didn't use
negative offsets, only out of bounds indexes that weren't checked by the
programmer.
This one, did use negative indexes:
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-0986
More details: http://cxsecurity.com/issue/WLB-2008030020
--
/*Francois Labreque*/#local a=x+y;#local b=x+a;#local c=a+b;#macro P(F//
/* flabreque */L)polygon{5,F,F+z,L+z,L,F pigment{rgb 9}}#end union
/* @ */{P(0,a)P(a,b)P(b,c)P(2*a,2*b)P(2*b,b+c)P(b+c,<2,3>)
/* gmail.com */}camera{orthographic location<6,1.25,-6>look_at a }
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
> clipka <ano### [at] anonymous org> wrote:
>> Okay, let's do it a bit more specific:
>
>> void fubar(int idx)
>> {
>> char c[1024];
>> if (idx < 1024)
>> fnord(c[idx]);
>> else
>> FAIL_SAFE();
>> }
>
>> void main()
>> {
>> fubar(INT_MAX+1);
>> }
>
>> No out-of-bounds access? Look at the code again.
>
> But in the original post it was suggested that an array size of INT_MAX+1
> in the image file could cause this. Here the array size is just 1024 (which
> in this particular contest would have ostensibly been read from the image
> file.)
I was going from memory. Sorry about that. It's not the array size
that's too big. Just accessing elements outside of it.
>
> Unless there's an image file where there are actual index values specified.
>
Bingo.
FWIW, there's a group at the University of Oulu
(https://www.ee.oulu.fi/research/ouspg/), next door to you, who do this
all day long. Try to break devices by sending specially crafted packets
that don't respect the protocol specs. They were really famous for a
while in 2002, when they found out that every single device from every
single network equipment vendor was vulnerable to denial-of-service
attacks using SNMP.
--
/*Francois Labreque*/#local a=x+y;#local b=x+a;#local c=a+b;#macro P(F//
/* flabreque */L)polygon{5,F,F+z,L+z,L,F pigment{rgb 9}}#end union
/* @ */{P(0,a)P(a,b)P(b,c)P(2*a,2*b)P(2*b,b+c)P(b+c,<2,3>)
/* gmail.com */}camera{orthographic location<6,1.25,-6>look_at a }
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
> The only situation that I can think of where an out-of-bounds access will
> probably happen is if pointers (and thus array indices) are 64-bit but
> the array size is wrongly a signed (32-bit) int. It then gets expanded
> to 64-bit when indexing the array, and ends up truly at negative addresses
> (from the array's start.)
You could also have the situation where the code is inconsistent
regarding signed and unsigned (32-bit) values. Couldn't something like
this break with a negative value of imageSize stored in the image file?
void LoadImageFromFile(unsigned int size);
void ReserveMemory(int size);
int headerSize = 1024;
int imageSize = readIntFromFile();
ReserveMemory(headerSize + imageSize);
LoadHeaderFromFile(headerSize);
LoadImageFromFile(imageSize);
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |