写入以空字节开头的内存

Writing to memory beginning by null bytes

假设这段代码:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    int main(int argc, char** argv){
    char fonction[50] = "/usr/bin/passwd ";
    char messageAccueil[100] = "changement du mot de passe de  : ";
    if(argc == 1){
        printf("vous devez passer un username en parametre \n");
        return 1;
    }
    printf(messageAccueil);
    printf(argv[1]); //<-- format string vulnerability here !!
    if(strcmp(argv[1], "root")==0){
        printf("vous ne pensiez quand meme pas pouvoir changer le mot de passe de root si facilement ?\n");
        return 1;
    }
    printf("\n");
    strncat(fonction,argv[1],38);
    system(fonction);
    return 0;
}

我想利用格式化字符串漏洞执行shell, 因此,我想通过存储在环境变量中的 shell 代码地址重写 GOT 中的 strcmp 函数地址。

gdb 给我:

(gdb) info functions
0x0000000000400570  strcmp@plt
(gdb) disas 0x400570
Dump of assembler code for function strcmp@plt:
0x0000000000400570 <+0>:    jmp    QWORD PTR [rip+0x20070a]#0x600c80 <strcmp@got.plt>
0x0000000000400576 <+6>:    push   0x6
0x000000000040057b <+11>:   jmp    0x400500
End of assembler dump.

所以我想把我的shell代码地址写到0x00600c80

如何将 nullbyte 传递到我的 ./changepasswd 文件?

我实际上正在尝试这个漏洞:

/changepasswd $(echo -e '\x80\x0c\x60\x00____\x84\x0c\x60\x00')%65527d%136$x%59017d%137$x

这个给我地址600c845f

但是\x00没有影响,没有入栈。

我发现以 00 开头的地址可能是 ascii 装甲问题,但我的系统中完全没有 exec-shield 选项。

所以我正在寻找一种方法将 00 写入我的堆栈让我的 GOT 地址由 00 以外的其他内容启动。 ..

这里有两个问题。或者,更好地说,两种不可能。

首先,有一个 shell 问题:如何将包含 NUL 的字符串作为命令行参数传递给实用程序。

Shell变量不能包含NULs,所以没有办法构造参数字符串并将其作为参数传递。 [注 1] 但是,您可以构造一个包含 NUL 的流并将其通过管道传输到某些实用程序的 stdin 中。剩下的只是找到一个实用程序,将其输入转换为其他实用程序的命令行参数;那将是 xargs。因此,您可以尝试以下操作:

printf '[=10=]This is an argument' | xargs -I{} ./victim {}

然而,那是行不通的(大多数 xargs 的实现甚至不允许你尝试 [注 2]),因为第二个问题:argv 参数main 是一个由 NUL 终止的 字符串组成的数组,因此每个命令行参数都以第一个 NUL 终止。因此,即使您设法找到将所有字节传递到 argv 数组的方法,实用程序也会将 NUL 视为参数的终止,而不是参数的一部分。 (例如,printf(argv[1]) 将从第一个参数开始打印字节,直到到达 NULNUL 表示格式字符串结束。)

但是你不会找到这样做的方法,因为 exec* 系统库函数(其中一个是将参数传递给另一个可执行文件所必需的)也会处理 NUL作为终止相应的论点。由于exec*函数需要将参数复制到新的可执行映像的地址space中,当到达参数末尾时,复制将终止, NUL 之后的任何字节将不被复制。


备注:

  1. Shells 有不同的方法来处理使用命令替换插入 NULs 的尝试。例如,Bash 只删除 NUL,但其他 shell 可能会在第一个 NUL.

    处终止替换
  2. 郑重声明,xargs 的 Gnu 实现将产生以下有用的消息:

    xargs: Warning: a NUL character occurred in the input. It cannot be passed through in the argument list. Did you mean to use the --null option?