How can integer overflow be used?

Does anyone have a detailed explanation of how integers can be used? I read a lot about this concept, and I understand what it is, and I understand that the buffer overflows, but I don’t understand how it is possible to reliably modify the memory or somehow change the application stream, making an integer larger than its specific memory ....

+16
security integer-overflow exploit
May 26 '10 at 14:00
source share
5 answers

It can definitely be used, but of course it depends on the situation.

In older versions of ssh, there was an integer overflow that could be used remotely. This exploit caused the ssh daemon to create a zero-size hash table and overwrite the memory when it tried to store some values ​​there.

Read more about ssh integer overflow: http://www.kb.cert.org/vuls/id/945216

Read more about integer overflow: http://projects.webappsec.org/w/page/13246946/Integer%20Overflows

+14
May 26 '10 at 14:14
source share

I used APL / 370 in the late 60s on an IBM 360/40. APL is a language in which essentially the whole thing is a multidimensional array, and there are amazing operators for managing arrays, including resizing N to sizes M, etc.

It is not surprising that an array of N dimensions had index boundaries 1..k with another positive k for each axis .. and k was legally always less than 2 ^ 31 (positive values ​​in a 32-bit signed machine word). Now an array of N dimensions has a location assigned in memory. An attempt to access an array slot using an index that is too large for the axis is checked on the upper bound of the APL array. And of course, this applies to an array of N dimensions, where N == 1.

The APL did not check if you did something incredibly stupid with the RHO (array reshape) operator. APL allows a maximum of 64 measurements. That way you can make an array of size 1-64, and the APL will do this if the dimensions of the array are less than 2 ^ 31. Or you can try to make an array of 65 dimensions. In this case, the APL goofed and unexpectedly dropped an array of size 64, but was unable to check the dimensions of the axis. (This happens where "integer overflow" occurred). This meant that you could create an array with axis sizes of 2 ^ 31 or more ... but interpreted as signed integers, they were considered negative numbers.

The correct spell of the RHO operator applied to such an array could reduce the dimension to 1, with the upper bound, to get this "-1". Call this matrix a “wormhole” (you'll see why at the moment). Such an array of wormholes takes place in memory, like any other array. But all calls to the array are checked to the upper bound ... but the check for array binding turned out to be performed by unsigned APL comparison. Thus, you can access WORMHOLE [1], WORMHOLE [2], ... WORMHOLE [2 ^ 32-2] without objection. In fact, you can access the entire memory of the computer.

The APL also had an array assignment operation in which you could populate an array with a value. WORMHOLE [] <-0, thus resetting all memory.

I did this only once, since it deleted the memory containing my APL workspace, the APL interpreter and the obvious critical part of the APL, which included temporary marking (in those days it was not protected from users) ... the terminal room went out of its normal state of mechanically very noisy (we had 2741 Selectric APL terminals) to dead silence after about 2 seconds. Through the glass into the computer room, I saw the operator raise his eyes to the lights at 370 when they all went out. Many launches followed.

Although it was funny at the time, I shut my mouth.

With some caution, one could obviously fake the OS arbitrarily.

+11
May 26 '10 at 14:44
source share

It depends on how the variable is used. If you never make security decisions based on integers added with input integers (where the adversary can provoke an overflow), I can't think about how you get into trouble (but this stuff can be subtle).

Then again, I saw many such codes that do not confirm user input (although this example is contrived):

int pricePerWidgetInCents = 3199; int numberOfWidgetsToBuy = int.Parse(/* some user input string */); int totalCostOfWidgetsSoldInCents = pricePerWidgetInCents * numberOfWidgetsToBuy; // KA-BOOM! // potentially much later int orderSubtotal = whatever + totalCostOfWidgetInCents; 

Everything is very difficult until you sell 671,299 widgets for - $ 21,474,817.95. The boss may be upset.

+3
May 26 '10 at 14:17
source share

A common case is code that prevents buffer overflows by asking for the number of inputs that will be provided, and then trying to enforce this restriction. Consider a situation where I claim to provide 2 ^ 30 + 10 integers. The receiving system allocates a buffer 4 * (2 ^ 30 + 10) = 40 bytes (!). Since memory allocation succeeded, I am allowed to continue. Checking the input buffer will not stop me when I send my 11th input, since 11 <2 ^ 30 + 10. Nevertheless, I will overflow the actually allocated buffer.

+3
May 26 '10 at 15:07
source share

I just wanted to summarize everything I found out about my original question.

The reason for me was that I know how buffer overflows work, and can understand how you can easily use this. Integer overflow is another case - you cannot use integer overflow to add arbitrary code and force application flow changes.

However, an integer overflow is possible, which is used, for example, to index an array to access arbitrary parts of the memory. From here, one could use this incorrectly indexed array to override the memory and cause the application to change to your malicious intentions.

Hope this helps.

+2
Jun 01 '10 at 19:00
source share



All Articles