有没有人详细解释如何利用整数?我已经阅读了很多关于这个概念的内容,我理解它是什么,我理解缓冲区溢出,但我不明白如何可靠地修改内存,或者以修改应用程序流的方式,通过使一个大于它定义的记忆......
答案 0 :(得分:17)
绝对可以利用,但当然要视情况而定。
旧版本ssh有一个整数溢出,可以远程利用。该漏洞导致ssh守护进程创建一个大小为零的哈希表,并在尝试在那里存储一些值时覆盖内存。
关于ssh整数溢出的更多细节:http://www.kb.cert.org/vuls/id/945216
有关整数溢出的更多详细信息:http://projects.webappsec.org/w/page/13246946/Integer%20Overflows
答案 1 :(得分:11)
我在60年代后期在IBM 360/40上使用了APL / 370。 APL是一种基本上所有事物都是多维数组的语言,并且有很多用于操作数组的操作符,包括从N维重构为M维等等。
不出所料,N维数组的索引边界为1..k,每个轴的正 k不同。而k在法律上总是小于2 ^ 31(正值为32位签名机器字)。现在,N维的数组在内存中分配了一个位置。使用对于轴来说太大的索引来尝试访问数组插槽将针对APL的数组上限进行检查。当然,这适用于N维的数组,其中N == 1。
APL没有检查你是否用RHO(数组重塑)运算符做了一些非常愚蠢的事情。 APL仅允许最多64个维度。因此,您可以创建1-64维的数组,如果数组维度小于2 ^ 31,则APL会执行此操作。或者,您可以尝试创建 65 维度的数组。在这种情况下,APL蠢蠢欲动,并且令人惊讶地回馈了64维阵列,但是未能检查轴的大小。 (这在“整数溢出发生”的情况下有效)。这意味着你可以创建一个轴大小为2 ^ 31或更大的数组......但是被解释为有符号整数,它们被视为负数。
应用于此类数组的右RHO运算符咒语可以将dimensionaly减小为1,其上限为,得到此值,“ - 1”。将这个矩阵称为“虫洞”(你会在一瞬间看到原因)。这种虫洞阵列有 内存中的一个位置,就像任何其他数组一样。但是所有数组访问都是根据上限检查的......但是数组绑定检查结果是由APL进行的 unsigned 比较完成的。因此,您可以无异议地访问WORMHOLE [1],WORMHOLE [2],... WORMHOLE [2 ^ 32-2]。实际上,您可以访问整个机器的内存。
APL还有一个数组赋值操作,您可以在其中使用值填充数组。 WORMHOLE []< -0因此将所有内存归零。
我只做了一次,因为它擦除了包含我的APL工作区的内存,APL解释器,以及显然启用分时的APL的关键部分(当时它没有受到用户保护)......终端房间 从机械上非常嘈杂的正常状态(我们有2741个Selectric APL终端)到大约2秒钟的静音。 通过玻璃进入计算机房我可以看到操作员抬头看着370上的灯,因为他们全都出去了。随之而来的是大量的奔跑。
当时很有趣,我一直闭嘴。
小心谨慎,显然可能会以任意方式篡改操作系统。
答案 2 :(得分:4)
这取决于变量的使用方式。如果你从未根据整数添加输入整数(其中一个对手可能引起溢出)做出任何安全决策,那么我就不会想到你会遇到什么麻烦(但这种东西可能很微妙)。
然后,我再次看到大量这样的代码不能验证用户输入(尽管这个例子是人为的):
int pricePerWidgetInCents = 3199;
int numberOfWidgetsToBuy = int.Parse(/* some user input string */);
int totalCostOfWidgetsSoldInCents = pricePerWidgetInCents * numberOfWidgetsToBuy; // KA-BOOM!
// potentially much later
int orderSubtotal = whatever + totalCostOfWidgetInCents;
直到您出售671,299个小部件的那一天 - 21,474,817.95美元,一切都很糟糕。老板可能很不高兴。
答案 3 :(得分:3)
一种常见的情况是通过询问将提供的输入数量,然后尝试强制执行该限制来防止缓冲区溢出的代码。考虑一下我声称提供2 ^ 30 + 10个整数的情况。接收系统分配4 *(2 ^ 30 + 10)= 40字节(!)的缓冲区。由于内存分配成功,我可以继续。当我发送第11个输入时,输入缓冲区检查不会阻止我,因为11< 2 ^ 30 + 10。然而,我将溢出实际分配的缓冲区。
答案 4 :(得分:3)
我只是想总结一下我发现的关于我原始问题的一切。
让我困惑的原因是因为我知道缓冲区溢出是如何工作的,并且可以理解如何轻松地利用它。整数溢出是一种不同的情况 - 您无法利用整数溢出来添加任意代码,并强制更改应用程序的流。
但是,可以溢出一个整数(例如,用于索引数组)以访问内存的任意部分。从这里开始,可能会使用错误索引的数组来覆盖内存并导致应用程序的执行变为恶意。
希望这有帮助。