复现一下2022DefCampCTF
Reverse
cup_of_tea (xxtea+小端)
python实现tea/xtea/xxtea算法传送门:https://qianfei11.github.io/2019/08/22/Python%E5%AE%9E%E7%8E%B0TEA%E3%80%81XTEA%E3%80%81XXTEA%E5%8A%A0%E5%AF%86%E8%A7%A3%E5%AF%86%E7%AE%97%E6%B3%95/
v7字符串经过加密之后是运行后的C7……字符串
1 | We are under attack. |
我们需要做的是通过上面的加密去寻找解密方法,然后把下面的字符串破译出来
ida查看一下:
encrypt函数看了一眼是tea类的加密,sprintf,发送格式化输出到v13字符串,%02x,两位十六进制数,左侧补零。
放C里面调试了一下……
这边就是主要的算法了。
在网上找了一段有关xxtea加密解密的python2版本的代码,然后转成了python3的格式
1 | def shift(z, y, x, k, p, e): |
关键部分做了替换。其中,最为重要的是,题目给出的字符串因为小端模式需要转换
1 | encrypted = [0x68E399CC4DAEA4D0,0x81b8676d9966bdba,0x78adb022d0e2ab59,0xf31ce8b16e9ad6f1,0xd6054099FE3E9B58,0xB7443CFDB29DDEA9,0x2922AC6A31D22876,0x2022E42B93EC38E9,0x0A825546911D6DDD,0x8D3A9936229EC043] |
注意这边的6+52/n换成了6+52/10
1 | [6859953592044237650, 5070864542475440945, 6436263400528900656, 3370575, 0, 0, 0, 0, 0, 0] |
然后将所得的列表,转换成16进制,按每两位一组,拼接成flag
1 | string = '5f33737245763352465f546f4e5f533159523376455f7230336e4f' |
1 | x = [0x5f,0x33,0x73,0x72,0x45,0x76,0x33,0x52,0x46,0x5f,0x54,0x6f,\ |
_3srEv3RF_ToN_S1YR3nO
CTF{3e6a586b00305bc4e74243c66d91525a}
algorithm (dfs plus+暴破 plus)
1 | flag = ' [test]' |
放linux运行了一下,仔细分析之后,得出正向加密的步骤:
将flag字符串中每一个字符都转换为16进制数拼凑起来的数,赋值给hflag,
将hflag开头两位去除后转换的10进制数,赋值为iflag。
依次iflag每两位拆分为n,将n和3分别作为一参和二参放入polinom中进行加密:将n通过while循环根据奇偶转换为z表,对z表中的每个元素*m^i后累加为s,返回值为s。
加密结束后,把最后的结果赋值给nf,转换成str,拼在一起就是加密后的字符。
本人用 “ [hello]”进行了模拟运算
1 | def polinom(n, m): |
若m为99(最大的两位数),while循环后,累加出来的s为1952,所以两位数最多可以被加密成4位数(见以上步骤3)
1 |
|
通过dfs和爆破,求出了列表b,其应当为加密函数polinom(n, m) 返回值s组成的列表:
1 | [31, 11, 38, 2, 44, 3, 54, 68, 8, 14, 45, 91, 44, 91, 69, 12, 29, 25, 23, 10, 1] |
然后通过print_b的填零操作,将列表b转换成iflag
1 | 31113802440354680814459144916912292523101 |
注意,b列表的最后一位不需要在前面加上“0”,
最后通过long_to_bytes将iflag转换为flag
1 | from Crypto.Util.number import * |
关于python Crypto.util 模块的byte_to_long和long_to_bytes的使用:
[ola_th1s_1s_p0l]