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算法用二进制的形式进行描述,但只要将功能代码分析代入简化,便能轻松秒杀