- 找到第二个,直接开始,第一篇说清楚了前奏。
- 首先ssh连接到对方服务器。
- 尝试执行./col这个程序,查看结果。
- 查看源码col.c。
#include <stdio.h> #include <string.h> unsigned long hashcode = 0x21DD09EC; unsigned long check_password(const char* p) { int* ip = (int*)p; int i; int res=0; for(i=0; i<5; i++) { res += ip[i]; } return res; } int main(int argc, char* argv[]) { if(argc<2) { printf("usage : %s [passcode] ", argv[0]); return 0; } if(strlen(argv[1]) != 20) { printf("passcode length should be 20 bytes "); return 0; } if(hashcode == check_password( argv[1] )) { system("/bin/cat flag"); return 0; } else printf("wrong passcode. "); return 0; }
- 可以看错,需要输入20个字符,如果输入了20个字符,就进入check_password()函数,进行校验密码,我们仔细看看这个函数。
unsigned long check_password(const char* p) { int* ip = (int*)p; int i; int res=0; for(i=0; i<5; i++) { res += ip[i]; } return res; }
- 这个函数,将传进来的那20个字符p,进行(int *)强制转换也就是会把这20个分成4 个char类型为一组,一共分5组,因为char 是 1个字节,所以4个为一组,一共5组,刚好20个字节,刚好20个输入字符串。
- 然后把没四个字符看成一共int型的数字,进行5次循环相加,结果放入res中。
- 然后分析函数入栈情况。
- 因为
unsigned long hashcode = 0x21DD09EC;
所以只要让我们的输入字符串四个一组加起来等于0x21DD09EC就可以啦,所以没有确定的值,只要符合即可。
- 先用0x21DD09EC减去一个简单的值,例如:0x10101010 乘以 4 等于 0xE19CC9AC。
- 执行 代码 :./col $(python -c "print 'xACxC9x9CxE1'+'x10' * 16") 注意:必须是小端格式
- 十六个'x10' 加上 0xE19CC9AC 刚好是 0x21DD09EC,所以利用成功。