先找到验证点:
006CC088 PUSH KCTF2021.006E29C0 ; 输入的key
006CC08D CALL KCTF2021.006CC0F0 ; 解码
006CC092 ADD ESP,4
006CC095 PUSH 10
006CC097 PUSH KCTF2021.006E28B8 ; name
006CC09C PUSH KCTF2021.006E29C0 ; 解码后的key
006CC0A1 CALL KCTF2021.006CD1F0 ; 比较函数
006CC0A6 ADD ESP,0C
006CC0A9 TEST EAX,EAX
006CC0AB JNZ SHORT KCTF2021.006CC0CB
006CC0AD PUSH KCTF2021.006DC1D8 ; ASCII "Right! You are very clever!"
006CC0B2 CALL KCTF2021.006D08D2
浏览一下解码函数6CC0F0,流程和aes算法类似:
006CC0F0 PUSH EBP
006CC0F1 MOV EBP,ESP
006CC0F3 PUSH ECX
006CC0F4 MOV BYTE PTR SS:[EBP-1],0
006CC0F8 MOV EAX,DWORD PTR SS:[EBP+8]
006CC0FB PUSH EAX
006CC0FC CALL KCTF2021.00401020 ; 龙猫变换
006CC101 ADD ESP,4
006CC104 MOV BYTE PTR SS:[EBP-1],1
006CC108 JMP SHORT KCTF2021.006CC113
006CC10A MOV CL,BYTE PTR SS:[EBP-1]
006CC10D ADD CL,1
006CC110 MOV BYTE PTR SS:[EBP-1],CL
006CC113 MOV EDX,DWORD PTR SS:[EBP+8]
006CC116 PUSH EDX
006CC117 CALL KCTF2021.006CC600 ; 字节代换
006CC11C ADD ESP,4
006CC11F MOV EAX,DWORD PTR SS:[EBP+8]
006CC122 PUSH EAX
006CC123 CALL KCTF2021.006CC3D0 ; 行移位
006CC128 ADD ESP,4
006CC12B MOVZX ECX,BYTE PTR SS:[EBP-1]
006CC12F CMP ECX,0E
006CC132 JNZ SHORT KCTF2021.006CC136
006CC134 JMP SHORT KCTF2021.006CC150
006CC136 MOV EDX,DWORD PTR SS:[EBP+8]
006CC139 PUSH EDX
006CC13A CALL KCTF2021.006CC160 ; 列混合
006CC13F ADD ESP,4
006CC142 MOV EAX,DWORD PTR SS:[EBP+8]
006CC145 PUSH EAX
006CC146 CALL KCTF2021.00401020 ; 龙猫变换
006CC14B ADD ESP,4
006CC14E JMP SHORT KCTF2021.006CC10A
006CC150 MOV ECX,DWORD PTR SS:[EBP+8]
006CC153 PUSH ECX
006CC154 CALL KCTF2021.00401020 ; 龙猫变换
006CC159 ADD ESP,4
006CC15C MOV ESP,EBP
006CC15E POP EBP
006CC15F RETN
重点就是401020这个龙猫变换了,首先把16个BYTE转成128个bit,最后在超级长的函数401610里实现门电路逻辑阵列变换
因为都是位运算,后面我不用~表示取反运算,而是用^1,因为取反会影响字节里其它7位
代码还是很有规律的,先列举一下几种单元门
单元门1:
00401651 MOV EAX,1
00401656 IMUL ECX,EAX,0
00401659 ADD ECX,DWORD PTR SS:[EBP+C]
0040165C MOVZX EDX,BYTE PTR DS:[ECX]
0040165F TEST EDX,EDX
00401661 JNZ SHORT KCTF2021.0040166F
00401663 MOV DWORD PTR SS:[EBP-A5C],1
0040166D JMP SHORT KCTF2021.00401679
0040166F MOV DWORD PTR SS:[EBP-A5C],0
等价于:t = a ^ 1
单元门2:
00401679 MOV EAX,1
0040167E SHL EAX,0
00401681 ADD EAX,DWORD PTR SS:[EBP+C]
00401684 MOVZX ECX,BYTE PTR DS:[EAX]
00401687 CMP DWORD PTR SS:[EBP-A5C],ECX
0040168D JGE SHORT KCTF2021.0040169B
0040168F MOV DWORD PTR SS:[EBP-A60],1
00401699 JMP SHORT KCTF2021.004016A5
0040169B MOV DWORD PTR SS:[EBP-A60],0
等价于:t = a & (b ^ 1)
单元门3:
004016CC MOV ECX,1
004016D1 IMUL EDX,ECX,0
004016D4 ADD EDX,DWORD PTR SS:[EBP+C]
004016D7 MOVZX EAX,BYTE PTR DS:[EDX]
004016DA CMP EAX,DWORD PTR SS:[EBP-A64]
004016E0 JGE SHORT KCTF2021.004016EE
004016E2 MOV DWORD PTR SS:[EBP-A68],1
004016EC JMP SHORT KCTF2021.004016F8
004016EE MOV DWORD PTR SS:[EBP-A68],0
等价于:t = (a ^ 1) & b
单元门4:
004017C3 MOV EAX,DWORD PTR SS:[EBP-A74]
004017C9 CMP EAX,DWORD PTR SS:[EBP-A7C]
004017CF JL SHORT KCTF2021.004017DD
004017D1 MOV DWORD PTR SS:[EBP-A80],1
004017DB JMP SHORT KCTF2021.004017E7
004017DD MOV DWORD PTR SS:[EBP-A80],0
等价于:t = ((a ^ 1) & b) ^ 1
单元门5:
00401A7D MOV EDX,DWORD PTR SS:[EBP-AB0]
00401A83 CMP EDX,DWORD PTR SS:[EBP-AB8]
00401A89 JGE SHORT KCTF2021.00401A97
00401A8B MOV DWORD PTR SS:[EBP-ABC],1
00401A95 JMP SHORT KCTF2021.00401AA1
00401A97 MOV DWORD PTR SS:[EBP-ABC],0
等价于:t = (a ^ 1) & b
单元门6:
00401805 MOVZX EAX,BYTE PTR SS:[EBP-1]
00401809 MOVZX ECX,BYTE PTR SS:[EBP-2]
0040180D XOR EAX,ECX
0040180F MOV BYTE PTR SS:[EBP-1],AL
等价于:t = t ^ a
单元门7:
00401FC8 MOV EAX,1
00401FCD IMUL ECX,EAX,0A
00401FD0 ADD ECX,DWORD PTR SS:[EBP+C]
00401FD3 MOVZX EDX,BYTE PTR DS:[ECX]
00401FD6 AND EDX,DWORD PTR SS:[EBP-B2C]
00401FDC MOV EAX,1
00401FE1 IMUL ECX,EAX,0B
00401FE4 ADD ECX,DWORD PTR SS:[EBP+C]
00401FE7 MOVZX EAX,BYTE PTR DS:[ECX]
00401FEA AND EAX,DWORD PTR SS:[EBP-B30]
00401FF0 XOR EDX,EAX
00401FF2 MOV BYTE PTR SS:[EBP-2],DL
等价于:t = (a & b) ^ (c & d)
单元门8:
004027EB MOV EDX,1
004027F0 IMUL EAX,EDX,1F
004027F3 ADD EAX,DWORD PTR SS:[EBP+C]
004027F6 MOVZX ECX,BYTE PTR DS:[EAX]
004027F9 MOV EDX,1
004027FE SHL EDX,5
00402801 ADD EDX,DWORD PTR SS:[EBP+C]
00402804 MOVZX EAX,BYTE PTR DS:[EDX]
00402807 AND ECX,EAX
00402809 XOR ECX,DWORD PTR SS:[EBP-BE4]
0040280F MOV BYTE PTR SS:[EBP-2],CL
等价于:t = (a & b) ^ c
然后由上面这些单元门组成两种复合型的功能门
第1种功能门g1:
t1 = a ^ 1;
t2 = b & (t1 ^ 1);
t3 = c ^ 1;
t4 = (a ^ 1) & t3;
t5 = (t2 ^ 1) & t4;
t6 = c ^ 1;
t7 = (a ^ 1) & t6;
t8 = a ^ 1;
t9 = b & (t8 ^ 1);
t10 = ((t7 ^ 1) & t9) ^ 1;
t11 = ((t5 ^ 1) & t10) ^ 1;
等价于:
t = (a | c) ^ (a & b) ^ 1
第2种功能门g2:
t1 = a ^ 1;
t2 = b & (t1 ^ 1);
t3 = a ^ 1;
t4 = c & (t3 ^ 1);
t5 = (t2 ^ 1) & t4;
t6 = a ^ 1;
t7 = c & (t6 ^ 1);
t8 = a ^ 1;
t9 = b & (t8 ^ 1);
t10 = ((t7 ^ 1) & t9) ^ 1;
t11 = ((t5 ^ 1) & t10) ^ 1;
t = (b & c) ^ t11;
等价于:
t = (a & b) ^ (b & c) ^ (c & a)
按照上述规则,进行一翻代换得到一万多行全是xor操作的代码
把128位的输入,3位一组,一共42组,最后再单独补两位
每组3位(a,b,c),选择变换或不变换,如果变换,则得到新的3位: g1(a,b,c), g2(a,b,c), b^c
这里浪费了很多时间,开始一直没把b^c组合起来看待,那样的话是170个变量的非齐次方程组,各种尝试都解不出来
最后观察发现b和c从来都是成对出现的,这才决定组合起来看待
全xor操作可以按128*128的矩阵解GF2的线性方程组
然后这个g1(a,b,c), g2(a,b,c), b^c三位组还原到a,b,c我用真值表枚举了一下,刚好是一一映射,对应关系:
0 0 0 : 1 0 0
0 0 1 : 0 0 1
0 1 0 : 0 1 1
0 1 1 : 1 0 1
1 0 0 : 0 0 0
1 0 1 : 0 1 0
1 1 0 ; 1 1 1
1 1 1 : 1 1 0
最后得到:
KCTF
2D3FE4FB28EC609C4B7090BB9451CF85
kg和整理后的龙猫变换函数见附件
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2021-5-30 10:59
被ccfer编辑
,原因: