ssh连接后,可查看代码如下:
#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;
}
分析代码得知传入的参数要经过check_password()
的处理,且小于20个字节,且必须等于hashcode
。
分析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*p强制转换成int*p。int类型在32位机里占4字节,char类型占1个字节,所以是将20个字节的字符串转化成了5组,每组4个字节。
因此,最理想的情况下是将hashcode
的值五等份。其值转为10进制为568134124,无法被五整除。
所以考虑(568134124+1)/5=113626825
,这样113626825*4+113626824
就等于568134124了。
因为C语言是小段存储,113626825
转为十六进制为0x6c5cec9
,要写成"C9 CE C5 06"这样的格式。即\xc9\xce\xc5\x06\xc9\xce\xc5\x06\xc9\xce\xc5\x06\xc9\xce\xc5\x06\xc8\xce\xc5\x06
由于ASCII码只包含128位,计算的字符都是不可显示字符,要利用python写入:
./col `python -c 'print "\xc9\xce\xc5\x06\xc9\xce\xc5\x06\xc9\xce\xc5\x06\xc9\xce\xc5\x06\xc8\xce\xc5\x06"'`