babyre

又开始口胡了

这个题是18年SUCTF的题,我当时当然一下子就看出来放弃了,毕竟那时候比现在还要菜(现在也很菜就是了)。。。

看题

题目说的是现有一个加密后的密文和加密程序,需要得到明文

这次会长抛给这道题的时候我以为是那种把加密过程逆一下的那种加密(之前做过逆加密的题),然后看那段加密看了很久,很久,很久,妈耶完全做不出来好嘛(ノ=Д=)ノ┻━┻

然后,会长说这不是逆加密,用爆破就好了。。。

然后,好的,我这就去试试。。。

一顿分析

打开ida,熟练地按下F5

虽说之前逆加密过程的想法是错的,但至少得到了点东西,比如

img1.jpg

这么多函数连同srand在内只有operate有用。。。看了挺久才发现233333

进入operate函数就能看到我们的加密函数了,进去看看就会发现

img2.jpg

它是单字节加密的,所以就可以爆破,四个字节以内的都能爆破。

脚本

我把out里的密文按照unsigned int 的大小分开了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
unsigned int num[]={
0xB80C91FE,0x70573EFE,0xBEED92AE,0x7F7A8193,
0x7390C17B,0x90347C6C,0xAA7A15DF,0xAA7A15DF,
0x526BA076,0x153F1A32,0x545C15AD,0x7D8AA463,
0x526BA076,0xFBCB7AA0,0x7D8AA463,0x9C513266,
0x526BA076,0x6D7DF3E1,0xAA7A15DF,0x9C513266,
0x1EDC3864,0x9323BC07,0x7D8AA463,0xFBCB7AA0,
0x153F1A32,0x526BA076,0xF5650025,0xAA7A15DF,
0x1EDC3864,0xB13AD888,0};
unsigned __int64 constant = 0x1D082C23A72BE4C1;
unsigned __int64 v5;
unsigned int res;
for(unsigned int i=0;num[i]!=0;i++)
{
int ans;
for(ans=0x20;ans<0x7f;ans++)
{
res = ans;
for(unsigned int j=0;j<=0x20f;++j)
{
v5 = constant >> (j & 0x1f);
if(j & 0x20)
LODWORD(v5) = HIDWORD(v5);
res = (res >> 1) ^ (((unsigned int)v5 ^ res ^ (res >> 16) ^ (1551120942 >> (((res >> 1) & 1)
+ 2
* (2
* (((v9 >> 20) & 1)
+ 2 * (2 * (v9 >> 31) + ((v9 >> 26) & 1)))
+ ((v9 >> 9) & 1))))) << 31);
}
if(res == num[i])
{
printf("%c",ans); //跑完flag就出来了
break;
}
}
}

另外一个石乐志的做法

我开始写脚本的时候,把ans循环里0x7F中把F看成跟L这类符号一样的符号了,本着化简的想法(然而我下面一行的0x1F却完全没有化简的想法),就把F删了。。。删了。。。删了。。。正当我看着跑出来的乱码迷得一比的时候,我发现,我可以把ASCII码表加密一遍啊!卧槽,我真机(shi)智!

由之前的分析,进入加密函数之前有两次输入,第一次是输入任意字符串,第二次输入一个数seed,必须满足9<n<=32。然后每次只能加密30个字符。

然后就开始了快(you)乐(du)的加密,把ASCII码表从0x21开始到0x7F的可打印字符加密出来,然后一个个和密文比对,也能得出flag。

1
2
3
4
5
6
for(int i=0;num[i]!=0;i++)
{
for(int j=0;j<95;j++) //num储存ASCII可打印字符加密结果
if(num[i] == ans[j]) //ans储存密文
printf("%c",j+33); //ASCII可打印字符(不算空格,空格是0x20)从0x21(33)开始,
}

总结

这个题,貌似是签到题,所以并不是很复杂,我找对方向以后也就用了一个晚上的时间(当然,没找对方向的时候用了几天。。。也没做出来)

果然,reverse的题花样还是很多的,而且一道题说不定有比较简单的方式,比如这道题可以啥也不管直接加密ASCII码表然后对比2333333,当然这是事后才知道哈哈哈