Notesearch漏洞利用异常(黑客:漏洞利用的艺术)

Notesearch漏洞利用异常(黑客:漏洞利用的艺术),c,C,这个问题是关于黑客攻击:第二版剥削的艺术第121页上的程序notesearch的剥削 在这个漏洞中有一点我不明白: 当系统执行./notesearch“xyz…”时,参数 “xyz…”溢出子程序中的字符串缓冲区 覆盖返回地址…这一点很清楚 这里的假设是notesearch程序的堆栈帧位于调用漏洞的堆栈帧之上。当编译版本存在于同一系统上时,这一点成立 我的第一个问题是1。即使是远程黑客也能用吗 我的第二个问题是 2.由于缓冲区已用于覆盖所有变量,包括返回地址和返回地址之外的变量,notesearc

这个问题是关于黑客攻击:第二版剥削的艺术第121页上的程序notesearch的剥削

在这个漏洞中有一点我不明白:

当系统执行./notesearch“xyz…”时,参数 “xyz…”溢出子程序中的字符串缓冲区 覆盖返回地址…这一点很清楚

这里的假设是notesearch程序的堆栈帧位于调用漏洞的堆栈帧之上。当编译版本存在于同一系统上时,这一点成立

我的第一个问题是1。即使是远程黑客也能用吗

我的第二个问题是 2.由于缓冲区已用于覆盖所有变量,包括返回地址和返回地址之外的变量,notesearch程序如何按预期工作? 像“打印”之类的变量位于这个堆栈框架中,它们决定消息是否被打印,所有这些变量似乎都工作正常。 即使调用函数位于相关stackframe的顶部,也就是被淹没的字符串缓冲区所在的位置,但仍有某些关键变量会被覆盖

问题3。 假设字符串缓冲区是notesearch开始执行后推入的新堆栈帧的一部分,则缓冲区将覆盖notesearch程序中的所有给定变量。缓冲区也是搜索字符串的值。根据程序逻辑,由于搜索字符串与消息不匹配,程序不应输出用户消息的详细信息。在这种情况下,将显示消息。我想知道为什么?

(参考:这本书是免费的,代码可以从免费下载。)

继续读这本书;第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程序的堆栈帧位于调用漏洞的堆栈帧之上

不,那是错的。这里只有一个相关的堆栈帧:
notesearch
中的
main()
函数的堆栈帧。我们通过
system()
内部调用
漏洞利用\u notesearch
调用
/notesearch xyz…
这一事实与此无关;我们也可以直接在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()
    的末尾,并返回到外壳代码,让我们能够访问外壳

    但是,如果您想知道我们是如何在不覆盖局部变量
    userid
    printing
    fd
    的情况下覆盖返回地址的,那么至少有三种明显的可能性:

    A.这些变量可能分配在堆栈的
    searchstring
    下面

    B.这些变量可能是在寄存器中而不是在堆栈中分配的


    C.这些变量极有可能被覆盖,但它们的初始值对程序来说并不重要。例如,
    userid
    可以获取任何值,因为该垃圾值将立即被下一行的
    getuid()
    覆盖。初始值重要的唯一变量是
    打印
    。即使是
    打印
    也只会在程序碰巧得到值
    0
    时才改变程序的行为,而它不能得到值
    0
    ,因为我们复制的数据完全是由非零字节组成的,这是出于设计考虑。

    我想你还不太明白什么是缓冲区溢出。searchstring变量最初位于堆栈上100字节的位置。现在,您正在将一大块缓冲区复制到searchstring中,而不检查其长度。因此,缓冲区会溢出到notesearch主功能堆栈框架的其他部分。返回地址也会被覆盖。这就是它的工作原理。

    我认为这里最重要的假设是notesearch堆栈类似于exploit\u notesearch。这就是为什么他使用一个exploit_notesearch局部变量(unsigned int i)来计算ret。他假设(当然,知道notesearch的源代码)当两个程序都加载到内存中时,它们将具有相似的帧地址(大约0xffff7..)
    当然,这两个程序不共享内存,它们是不同的进程。

    这个问题似乎离题了,因为它涉及非法/不道德的黑客攻击/恶意软件/利用。这个问题是Jon Erickson撰写的一本著名的黑客攻击和it安全书的一部分。我不认为黑客行为本身是非法或不道德的,恰恰相反:黑客只是聪明的人,他们热衷于计算机编程,就像古希腊的数学家对待数字一样。这本书是那些愿意开始黑客攻击的乞丐们的主要参考资料。既然黑客行为与编程和修补代码有关,我认为这个问题并不离题。我也是那本书的主人