新手上路,有不对的地方还请赐教
下载文件,为64位
直接用IDA打开试试
找到主函数,F5查看
大意是输入d或D,调用函数Decry
输入q或Q结束程序
查看函数Decry
flag大概就在这里了
这里的src和v9需要注意,这两个输入的是16进制是高位在前,而内存中是小端序(高位在后)
内存中表示为
低 高
src 4E 44 43 4C 53
v9 68 61 64 6F 77
因为后面的程序中将其当作字符运算(逐个字节,不分高低),所以需要转换
这时如果直接按R使其变为字符串,结果则是直接将十六进制从左到右一个一个转为字符(问题所在)
这时内存中的顺序为
src 53 4C 43 44 4E
v9 77 6F 64 61 68
这与我们的预期正好相反
字符串的使用则是从左往右
所以src和v9正确的字符表示形式应该为
src NDCLS
v9 hadow
key1和key3的值,双击查看
text和key分别是将key3和v9,key1和src连接起来
值为killshadow,ADSFKNDCLS
getchar();
v5 = strlen(key);
for ( i = 0; i < v5; ++i ) //将key中的字符大写转小写
{
if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 )
key[i] = key[v3 % v5] + 32;
++v3;
}
printf("Please input your flag:");
while ( 1 )
{
v1 = getchar(); //接收一个字符
if ( v1 == 10 ) //10对应'\n'
break;
if ( v1 == 32 ) //32对应空格
{
++v2;
}
else
{
if ( v1 <= 96 || v1 > 122 ) //输入字符不为小写字母
{
if ( v1 > 64 && v1 <= 90 ) //输入字符为大写字母
{
str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97; //一顿操作,增加阅读难度
++v3; //v3虽然没有重新赋值,但使用
} //时有取余v5(key的长度)
}
else
{
str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;
++v3;
}
if ( !(v3 % v5) )
putchar(32);
++v2;
}
}
if ( !strcmp(text, str2) ) //判断两字符串是否相等,这里可以看出
puts("Congratulation!\n"); //flag就是使str2等于text的字符串
else
puts("Try again!\n");
return __readfsqword(0x28u) ^ v11;
}
根据程序,通过暴力破解法直接一个一个试
list1 = "killshadow" #test
list2 = "adsfkndcls" #key
flag = ""
for k in range(10):
for i in range(65, 123):
if((i <= ord('Z')) or (i >= ord('a'))): #保证结果为字符
if(list1[k] == chr((i - 39 - ord(list2[k]) + 97) % 26 + 97)):
flag += chr(i)
break
print("flag{"+flag+"}")
结果为flag{KLDQCUDFZO}