计算NOP雪橇中的地址

时间:2015-01-12 02:34:15

标签: buffer-overflow aslr nop

我目前正在阅读计算机系统简介:程序员的观点(http://www.amazon.com/Computer-Systems-Programmers-Perspective-2nd/dp/0136108040/ref=sr_1_2?s=books&ie=UTF8&qid=1421029641&sr=1-2&keywords=introduction+to+computer+systems)并试图了解阻止缓冲区溢出的方法。

我理解为什么在使用地址随机化时我们需要NOP雪橇以及如何编写漏洞利用但我在理解本书中给出的与NOP雪橇相关的地址计算时遇到了麻烦。我会在这里引用它: -

(假设堆栈上程序的起始地址在32位系统上的范围为2 ^ 23,在64位系统上的范围为2 ^ 32)

“如果我们设置一个256字节的NOP sled,则可以通过枚举2 ^ 15个起始地址来破解n = 2 ^ 23上的随机化,这对于确定的攻击者来说是完全可行的。对于64位情况,尝试枚举2 ^ 24个地址更令人生畏。“

作者如何分别为32位和64位情况提出数字2 ^ 15和2 ^ 24?解释会非常有用。

2 个答案:

答案 0 :(得分:1)

他们只假设32位系统上的最大总共享内存(kbytes),8388608就是2^23

2^15由以下公式计算:

(8388608 / 256) = 32768 == 2^15

换句话说:

total_memory_size / NOP_sled_length = total_iterations_to_find_NOP_sled_in_memory

他们根据我们的NOP雪橇可以在从0x0一直到0x80000083886082^23的范围内的任何位置进行计算)。因为我们的NOP雪橇长度为256字节,所以我们不需要为每个猜测/迭代/蛮力增加1,而是我们计算每次增加256,从而给出我们上面等式0x800000 / 256 = 32768 == 2^15的结果。所以我们只需要强制32768个可能的地址,因为其中一个地址将在我们的NOP雪橇开始处落地,并一直向下滑动到我们的有效载荷。

如果我们的NOP雪橇是500字节(假设我们的攻击允许我们适合那么大的NOP雪橇),那么等式将是:

0x8000000 / 500 = 268435次迭代,找到我们的NOP雪橇的起始地址。

这种方法对于64位系统来说不是那么好的原因是因为以下等式:

2^32 / 256 = 16,777,216(超过1600万个可能的地址,我们的NOP雪橇可以开始!即使你的NOP雪橇是500字节而你除以500,你仍然会有超过850万个地址你的NOP雪橇可以开始!)

0000
0000
NNNN
NNNN
NNNN
PPPP
PPPP
PPPP
0000
0000

如果您认为上面是我的堆栈,我的总内存大小为40.我有一个12字节的NOP底座(N' s)和12字节的有效负载(P' s) 。所以这个可利用场景的等式是:

40 / 12 = 3给我3个可能的地址,我的NOP雪橇可以在尽可能少的尝试中找到(12,24,32或十六进制0x0c,0x18和0x20)。

因此,如果我的漏洞利用只是从堆栈的开头开始并以12为增量计数,那么它将在第一次尝试时找到我的NOP雪橇(将4个字节放入我的NOP底座)。

根据评论进行更新

对于地址随机化的旁路技术,NOP雪橇背后的想法不是猜测NOP雪橇的 start - 它计算的最小量地址 ,可以保证你将降落在你的NOP雪橇内,尽可能少地解决猜测/暴力。当然,如果你想找到你的NOP雪橇的开头,你可以使用下面的等式:

total_mem_size / NOP_size = least_amount_of_guesses_to_land_inside_payload + 1

但请记住,通过添加额外的地址来尝试,在获得有效负载之前不再计算最少量的地址(这就是我和你正在读的书)正在计算,因为这是使用NOP雪橇背后的想法)。

如果我们再次访问我的小型堆栈"在上面确实可以有4个总地址,NOP雪橇可以在这个地址开始,但是这个等式计算了3个保证的地址来找到NOP雪橇(尽可能少的猜测是关键)。为了更清楚,你可以说漏洞开发者会试图通过增加NOP雪橇的尺寸(尽可能)来使这个数字尽可能小,这样他们就不用担心找到NOP的开头了。雪橇 - 他们只想降落在NOP雪橇内。

索引12的猜测将使你的4个字节进入你的NOP雪橇,在你到达有效载荷之前只能执行8个NOP。索引24的猜测将使您在有效负载中占据几个字节而导致崩溃,并且索引32的猜测将使您越过有效负载也导致崩溃。

让我们使用您的方法(使用总共4个地址)来说明为什么额外地址没有在等式中考虑:

0000
0000
NNNN
NNNN
NNNN
PPPP
PPPP
PPPP
0000
0000

让我们的等式加1,给出4个可能的地址,堆栈布局与以前相同:

40 / 12 = 3 + 1 = 4

所以现在我们有4个地址蛮力登陆我们的NOP雪橇0, 12, 24, 32。因为我们有一个12字节的NOP底座,所以仍然只有一个地址(索引12处的地址,原始等式所找到的地址)将落入我们的NOP底座,让我们在shellcode的开头执行shellcode。在我们的NOP雪橇之前,我们无法控制的数据将索引0放在堆栈上。因此,通过在混音中添加1个地址并不能帮助我们找到NOP雪橇 - 它只会增加尝试/暴力/猜测的地址数量。

是的,你是对的 - 我只是增加了更直观的地址,以便更有意义但是"计算"或者"递增"实际执行期间堆栈上的地址将从高地址开始。

答案 1 :(得分:0)

不确定这是否对您有所帮助:

对于32位系统,如果你的NOP雪橇是256字节(即2 ^ 8),如果你的堆栈的范围是2 ^ 23字节,你只需要2 ^ 15个实例(即2 ^ 23/2 ^ 8 = 2 ^ 15)(非重叠)雪橇。

64位系统也是如此