I was reading this question and one of the comments mentioned C signed-integer-based attacks.
I know what is an int
overflow is, but I don't understand how can this be used to attack
a program.
what exactly is meant by attacking a program ? and if you know the program has this bug, how can you use it ?
Is this only limited to signed int
.
If yes then why?
and what is the case in C++ ?
my apologies if the question is trivial
For example, there was a bug in the getpeername function from FreeBSD.
To illustrate it, let's take a function void copyFromKernel(char* dest, int size)
that copies from a restricted memory area size
bytes.
As you might already know, the memcpy function is declared like that:
void * memcpy ( void * destination, const void * source, size_t num );
Where size_t is an unsigned type. If in our function, we do something like:
void copy_from_kernel(void *user_dest, int maxlen) {
int len = KSIZE < maxlen ? KSIZE : maxlen;
memcpy(user_dest, kbuf, len);
}
, where KSIZE is the maximum number of bytes we want to allow for the user to copy. If the caller sends a positive value for maxlen, the function works as expected. But if the caller sends a negative value for maxlen, then the comparison would pass and memcpy's third parameter would be that negative value. As it is converted to unsigned, the number of bytes copied would be huge, thus the caller may get restricted data.
A very simple case could be an overflow on id
in the following example. Imagine that id
is the id of a user. And you create a ton of fake users or I don't know to create an overflow. And 0 is the id of the administrator.
if (id > 0) {
// you don't have many privileges
} else {
// you are basically root and can do evil stuff.
}
Most "anti-overflow" code is a combination of a range check followed by using the index to access memory. So if you can use int wrap-around to pass the range check (e.g. "if (index < max)" with index being negative) then you can access memory outside the intended target (e.g. "array[index] = value"). This coding mistake is less likely using unsigned.
read about bit representations of signed and unsigned integers.
basically if the int is signed... and if it is accessible by the user (for example, it is loaded from user input)... if the user puts a bigger number then the integer can contain, the int will be in result negative...
if this int is the size of something in the program, it will turn out negative.
there is no such problem with unsigned ints
You can compare it with sql injection.
You supply the input with a very large no which the integer can't store and the program may show undefined behavior.
Whenever we store a bigger no that the capacity of int
it wraps around and can turn out to be a negative no, which can be used by attacker. for eg:-
int j ;
cin>>j ;
for(i=0;i<j;++i)
{
// Do some stuff
}
Now if the attacker enters a bigger no j becomes negative beacuse of wrapping around, and the for loop code is skipped by the program.