SUSCTF 2022 DigitalCircuits
前置分析
下载是一个main.exe,根据ico可以知道是python生成的exe文件,python中通过pyinstaller进行py转exe,在默认情况下,并且只有一个exe文件,所以猜测应该是-F进行转换,所以此时可以尝试用pyinstxtractor进行解包:

生成一个_extracted文件夹:

进入文件夹找到同名的pyc文件,对比正常的stuct.pyc文件发现少了16个字节的py头:

将py头复制过去即可反编译,这里无法用在线反编译猜测应该是文件过大,所以采用python进行反编译:
|
|
反编译(需要注意python的版本,3.9以上的好像反编译会失败)
|
|
基础功能代码分析
|
|
根据if可以得知传入的参数非0即1,所以可以知道应该是逻辑指令,f1就是&,f2就是|,f3取非,所以这部分就跟题目名称对上了,数电三大基础逻辑运算:
|
|
代入f1-f3得到:(a & ~b) | (~a & b),emm,就是xor,在数电中的基础逻辑语句只有三个,异或虽然在python中是有^这个符号代替的,但实际原理就是题目中的那样进行逻辑操作:
|
|
简化:
|
|
f5同样代入:
|
|
得到,没看懂在干啥:
|
|
找到f6调用的位置:
|
|

测试一下:
|
|
得到res: 10011110001101110111100110111010
可以发现f6其实就是做了个二进制加法,传入的两个参数为二进制字符串,对于二进制字符串,字符串的高位为数据低位,所以传入之后会先对字符串进行翻转:
|
|
那么f5的三次异或就可以理解了,最开始z=0,然后传入的x=1, y=1,s = x ^ y ^ z = 0,然后第二个c是用来检测是否产生进位,明显0b01 + 0b01 = 0b10,会产生进位,所以c = 1,然后将进位值给到z,代入下一轮循环,最终生成

f7,f8都是传入一个二进制字符串,然后传入一个n,很明显,f7就是左移,f8就是右移,n为位数
|
|
f9逐位异或,最终就是整体异或:
|
|
加密代码分析
|
|
首先是限制了flag格式为SUSCTF{xxx},flag正文内容为24字节,进行三次循环,每次循环取8个字节,分成前后4个字节,然后拼接成32位的字符串,bin(ord(flagstr[i]))[2:].zfill(8)字符转二进制字符串
|
|

处理完字符串之后通过f10进行处理,这里传入了k0-k3应该是4个key:
|
|
转成16进制看看:
|
|

将d也转成16进制,发现TEA算法特征

f10代入功能代码进行简化,可以得到f10就是TEA算法的加密过程:
|
|
测试:
|
|
每次循环的结果是二进制字符串的拼接:

每次循环取flag的8个字节,加密结果互不影响,所以最终拼接会得到192个字节的长度,与res进行比较:
那么只需要将res按64字节分成三份,分别进行解密即可得到真正的flag
Exp
|
|
得到flag:
|
|
总结
考点
- pyinstaller打包exe文件的反编译
- 基础TEA算法加解密
比起以往的XCTF联赛逆向,这次的题目感觉像是入门题了,整体难度不高,该题的难点在于将TEA算法用二进制的形式进行描述,但只要将功能代码分析代入简化,便能轻松秒杀