Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 用蛮力克服堆栈随机化_C_X86 64_Buffer Overflow_Callstack_Aslr - Fatal编程技术网

C 用蛮力克服堆栈随机化

C 用蛮力克服堆栈随机化,c,x86-64,buffer-overflow,callstack,aslr,C,X86 64,Buffer Overflow,Callstack,Aslr,我正在读一本书,书中介绍了缓冲区溢出如何攻击,一种阻止缓冲区溢出的技术叫做堆栈随机化,下面引用了书中的内容: 持久攻击者可以通过暴力克服随机性,重复尝试使用不同地址的攻击。一个常见的技巧是在实际攻击代码之前包含一长串nop(发音为“no op”,缩写为“no operation”)指令。执行此指令除了将程序计数器增加到下一条指令之外没有任何效果。只要攻击者能够猜出该序列中的某个地址,程序就会在该序列中运行,然后命中攻击代码。如果我们设置一个256字节(28)的nop底座,那么n=223上的随机化

我正在读一本书,书中介绍了缓冲区溢出如何攻击,一种阻止缓冲区溢出的技术叫做堆栈随机化,下面引用了书中的内容:

持久攻击者可以通过暴力克服随机性,重复尝试使用不同地址的攻击。一个常见的技巧是在实际攻击代码之前包含一长串nop(发音为“no op”,缩写为“no operation”)指令。执行此指令除了将程序计数器增加到下一条指令之外没有任何效果。只要攻击者能够猜出该序列中的某个地址,程序就会在该序列中运行,然后命中攻击代码。如果我们设置一个256字节(28)的nop底座,那么n=223上的随机化可以通过枚举215=32768个起始地址来破解

我理解第一部分,但不理解第二部分关于枚举起始地址的内容。例如,
%rsp
指向当前起始地址,如下图所示(为简单起见,仅显示8个字节,而不是256个字节)

我认为作者的意思是,尝试猜测
%rsp
指向的堆栈内存的不同地址。返回地址和
%rsp
之间的填充都是
nop
,然后用猜测的地址覆盖返回地址,该地址很可能指向填充的一部分(
nop
)。但是,由于堆栈随机化在程序开始时在堆栈上随机分配0到n字节之间的空间量,因此我们只能说成功攻击的概率为215/223=0.78%,那么我们怎么说尝试32768(固定数量)地址,那么它将被破解呢?这和掷硬币一样,你只能说得到一个正面的概率是0.5,你不能说在第二轮你会得到一个正面,因为你可能会得到两个反面

堆栈随机化在程序开始时在堆栈上分配0到n字节之间的随机空间量

不,它不分配。它随机化堆栈在虚拟地址空间中的映射位置,使其他页面未映射。这与页面粒度有关

猜测错误通常会导致受害者程序出错(或操作系统对无效页面错误所做的任何操作)。这对任何入侵检测来说都是噪声和明显的如果程序最终重新启动,您可以重试,它的堆栈地址将被重新随机分配,如您所建议

错误的猜测,在有效内存中着陆,但不是您的NOP底座,通常也会很快崩溃,原因是指令无效或解码为无效内存访问

是的,你是对的,你不能只列举地址空间,这只是一个概率问题。尝试足够多的时间意味着你很可能成功,但不能保证成功。尝试列举可能的ASLR熵并不是特别有用,或者比每次我想的时候都猜测同一页更可能成功

但在单个页面中尝试不同的偏移量是有用的,因为OS驱动的堆栈ASLR只有页面粒度

env变量和命令行参数使用了一定数量的堆栈空间,它们在不同的系统中会有所不同,但我认为,在同一个程序的调用中,它们往往是恒定的。除非从不同的调用链到达易受攻击的函数,或者父函数中存在大小可变的堆栈分配,在这种情况下,每次运行时页面中缓冲区的偏移量都可能不同



当然,现在大多数进程都是使用不可执行堆栈运行的,这使得堆栈缓冲区无法直接注入代码。如果存在任何已知的静态数据或代码地址,则可能发生ROP攻击(将返回地址注入到解码为有趣内容的现有字节序列中)。如果没有,您必须处理ASLR的代码/数据,但您不能注入NOP底座。

您可以看看这些问题吗?