这个问题是关于“黑客:剥削艺术”第二版第121页上的节目笔记研究的利用。
在漏洞利用中有一些我不理解的东西:
当系统执行./notesearch'xyz ....'参数时 'xyz ...'溢出了子程序中的字符串缓冲区 覆盖返回地址......很清楚。
这里的假设是,notesearch程序的堆栈帧位于调用exploit的Stack帧的顶部。当编译版本存在于同一系统上时,这是成立的。
我的第一个问题是1.这是否会作为远程黑客工作?
我的第二个问题是 2.由于缓冲区已用于覆盖包括返回地址在内的所有变量,因此notesearch程序如何按预期工作? 像“打印”等变量位于这个堆栈框架中并决定是否打印消息似乎都能正常工作。 即使调用函数位于相关堆栈帧的顶部,其中正在被泛洪的字符串缓冲区位于其中,也存在某些将被覆盖的关键变量。
问题编号。 3。 鉴于String缓冲区是在执行notesearch开始后推入的新堆栈帧的一部分,缓冲区将覆盖该notesearch程序中的所有给定变量。缓冲区也是搜索字符串的值。由于程序逻辑由于搜索字符串与消息不匹配,因此程序不应输出用户消息的详细信息。在这种情况下,会显示消息。我想知道为什么?
答案 0 :(得分:2)
(供参考:本书为http://www.tinker.tv/download/hacking2_sample.pdf,代码可从http://www.nostarch.com/hacking2.htm免费下载。)
继续读这本书;另一个例子在第122页给出,然后有大量的解释性文本告诉所有有关漏洞的内容。
以下是notesearch
代码的相关部分:
int main(int argc, char *argv[]) {
int userid, printing=1, fd; // file descriptor
char searchstring[100];
if(argc > 1) // If there is an arg
strcpy(searchstring, argv[1]); // that is the search string
else // otherwise
searchstring[0] = 0; // search string is empty
userid = getuid();
fd = open(FILENAME, O_RDONLY); // open the file for read-only access
您写道:
这里的假设是notesearch程序的堆栈帧位于调用exploit的Stack帧的顶部。
不,那是错的。这里只有一个相关的堆栈帧:main()
中notesearch
函数的堆栈帧。我们通过./notesearch xyz...
内的system()
调用调用exploit_notesearch
这一事实无关紧要;我们也可以直接在bash命令行上调用./notesearch xyz...
,或者欺骗其他一些进程(例如,你知道, bash )代表我们执行它。
- 这项工作即使是远程黑客工作吗?
醇>
当然。
- 由于缓冲区已被用于覆盖包括返回地址在内的所有变量,因此notesearch程序如何按预期工作?
醇>
嗯, 再看一下输出:
reader@hacking:~/booksrc $ gcc exploit_notesearch.c
reader@hacking:~/booksrc $ ./a.out
[DEBUG] found a 34 byte note for user id 999
[DEBUG] found a 41 byte note for user id 999
-------[ end of note data ]-------
sh-3.2#
明确给你一个壳不算“按预期工作”。但即便在此之前,该程序声称在/var/notes
中找到了用户ID 999的注释,这可能表明它有点混乱。在我们作为恶意黑客的角色中,我们不关心关于来自notesearch程序的垃圾输出;我们所关心的是最终到达main()
的末尾并返回我们的shellcode,让我们可以访问shell。
但是,如果您想知道我们如何设法覆盖返回地址而不覆盖局部变量userid
,printing
和fd
,那么至少有三种明显的可能性:< / p>
A。也许这些变量分配在堆栈的searchstring
下面。
B。也许这些变量是在寄存器中而不是在堆栈中分配的。
C。绝大多数情况下,这些变量 被覆盖,但它们的初始值与程序无关。例如,userid
可以获得任何值,因为该垃圾值将立即被下一行getuid()
覆盖。唯一一个初始值很重要的变量是printing
。甚至printing
只有在恰好获得值0
时才更改程序的行为 - 并且不能获取值0
,因为根据设计,我们复制的数据完全由非零字节组成。
答案 1 :(得分:0)
我认为你真的不明白什么是缓冲区溢出。该searchstring变量最初位于堆栈上100个字节。现在,您将一大块缓冲区复制到searchstring中,而不检查它的长度。因此缓冲区溢出到notesearch主要功能的堆栈帧的其他部分。返回地址也会被覆盖。这就是它的工作原理。
答案 2 :(得分:0)
我认为这里最重要的假设是 notesearch 堆栈与 exploit_notesearch 的类似。这就是他使用 exploit_notesearch 局部变量(unsigned int i)来计算 ret 的原因。他假设(当然,知道notesearch的源代码),当两个程序都加载到内存中时,它们将具有相似的帧地址(大约为0xffff7 ..) 当然,2个程序不共享内存,它们是不同的过程。