这题是使用c++写的,因为无符号表,ida对c++的解析不是很友好,可以去了解一下c++的string类型的结构,对解题很有帮助,推荐看这篇文章链接: https://bbs.pediy.com/thread-230312.htm.
程序先将长度为17位的输入分为7位和10位两部分
再输入一个数要求满足一定条件
直接爆破
#include
#include
#include
double ff(double a,double b){
double c=pow(a,b-1);
return c/exp(a);
}
int main()
{
int i=0;
while(1){
double v17=0.0;
double v18=0.0;
double v19=(double)i+1.0;
do{
v17=v17+ff(v18,v19)*0.001;
v18=v18+0.001;
}while(v18<=100.0);
double v20=(int)(v17+v17+3.0);
if(v20==0x13B03){
printf("success!! %d\n",i);
break;
}
else{
printf("n0!! %d\n",i);
}
i++;
}
int j=0;
for(;j<12379;j++){
double v16=0.0;
double v21=0;
double v22=(double)j+1.0;
do{
v16=v16+ff(v21,v22)*0.001;
v21=v21+0.001;
}while(v21<=100.0);
if((int)(v16+v16+3.0)==0x5a2){
printf("success!! %d\n",j);
break;
}
else{
printf("n0!! %d\n",j);
}
}
printf("%d",i*12379+j);
return 0;
}
最后得到data=99038
观察程序,发现我们的输入被分成两组后,在分别做一个异或,最后比较,第二组的加密程序似乎是一个RC4,但无所谓,直接找到异或的数值
直接动调找到异或和比较的数据,写脚本解密
first=[0x8,0x4d,0x59,0x6,0x73,0x2,0x40]
key='9903819'
flag=''
for i in range(len(first)):
flag+=chr(ord(key[i])^first[i])
second=[0xe0,0x95,0xba,0x60,0xc9,0x66,0x2a,0x24,0xb2,0x36]
key_pre=[0xb2,0xd6,0x8e,0x3f,0xaa,0x14,0x53,0x54,0xc6,0x6]
for i in range(len(second)):
flag+=chr(second[i]^key_pre[i])
print(flag)
###1ti5K3yRC4_crypt0
mips程序
用ghidra或者ida都可以,个人习惯ida
关键函数
这里我简单推到后发现v4恒等于0?
满足结果时a1和a2的前14位相同,直接将前14位输入发现可以
flag{Ninja Must Die}