题目来源:www.pwnable.kr
题目在网站提供的服务器上面,需要用终端连接进入题目,查看文件目录,发现有三个文件:
查看flag,发现权限不够(要是够,还要做什么题。。。。)。查看源码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]\n", argv[0]); return 0; } if(strlen(argv[1]) != 20){ printf("passcode length should be 20 bytes\n"); return 0; } if(hashcode == check_password( argv[1] )){ system("/bin/cat flag"); return 0; } else printf("wrong passcode.\n"); return 0; }
源码的逻辑是从终端运行程序,输入一个值,第一步检查其长度是否为20,然后把这个数据经过一个check_password函数变化之后进行比较,所以突破点在于check_password这个函数。
现在我们看看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; }
函数功能是将char类型的指针,转为int类型的指针,然后在将其相加,返回这五个值的和。char类型的为1个字节,int类型指针所占为4个字节,所以这用户输入的20个字符串将被分为5个组,然后相加值为0x21DD09EC,所以我们只需要构造一个字符串,这个字符串由五个16进制数据拼接而成:
payload为:
Tips:
这个地方有个坑点,就是数据输入的时候要使用小端序,所以我们的payload要逆序。