Ⅰ
IDA分析
进行了一次异或操作,然后让输入的v5进入函数sub_A84输出s2;
进入函数之后可以发现运算中存在移位2,4,6,而且有长度控制的判断(v5<=5)让输入的长度变长了;
进入sub_7FA之后是一个有64个case的switch,对应着不同的ascii码,这样的特色让人能联想到base64,因为base64的码表也是64个字符;
把sub_7FA中的码表换成base64的标准码表后,用比较的数据进行一次解码,得到数据:
0xD2,0x51,0xD2,0x34,0xD7,0x1B,0xE5,0x08,0xA0,0x13,0xCE,0x11,0xF0,0x13,0xA2,0x56,0xA5,0x3F,0xF8,0x13,0xCE,0x11,0xF2,0x0A,0xFD,0x24,0xE6,0x07,0xC2,0x1D
再用一次异或便能得到flag:C1CTF{th1s_qas364_is_qcjlDwgS}
1 | key = [0xD2,0x51,0xD2,0x34,0xD7,0x1B,0xE5,0x08,0xA0,0x13,0xCE,0x11,0xF0,0x13,0xA2,0x56,0xA5,0x3F,0xF8,0x13,0xCE,0x11,0xF2,0x0A,0xFD,0x24,0xE6,0x07,0xC2,0x1D] |
没看出是base64的时候,想过根据加密函数的样子来逆推导,考虑到或运算的不可逆性,采用了走迷宫式的算法,用ascii码0~128来模拟129条路径,每个加密数据为一个节点,走出一条明文,经过几次修改代码,但很可惜失败了;
Ⅱ
用输入的字符串与生成好的String1运算得到密文v3,之后使用crpyto函数打印出v3的hex值与字符串比较;
在检查sub_7FF7798A12A0的时候,发现了一个常数表:
对应着标准的aes加密表;
比较字符串有64个字节,打印了32个16进制数,而aes加密的长度是16个16进制数,所以后面的是未加密的数据,而前16个是加密的16进制数据,对前面32字节hex进行解密得到数据:
68 78 62 32 30 31 38 7B 38 35 33 65 63 66 65 35
数据很正常,有数字有字母,还有 7B ( { )应该是flag没错了;
之后加上后32位hex得到flag:hxb2018{853ecfe52aeb60989e8d3351}
AES
不懂AES之前根本就不明白它的内部算法;所以去学习了一下最简单的AES加密;
即为16字节明文配合16字节密钥运算得暗文;
分为很多个步骤,总体的思路便是矩阵运算,让明文和密钥都构成4*4的矩阵;
① 明文矩阵与密钥矩阵对应异或得到矩阵0;
② 密钥矩阵用自身产生很多个轮密钥,特点在于是列的运算;且关于列是从0开始计算,且若列是4的倍数,就会复杂一些,动用到BOX里的数据;
②.⑤ 矩阵0对照BOX表里的值进行替换成为矩阵1;
**③ **矩阵1进行hang行变换,第一行左移0字节,第二行左移1字节,第三行左移2字节,第四行左移3字节,得到矩阵2;
④ 矩阵2左乘一个规定好的特殊矩阵,变为矩阵3;
⑤ 矩阵3与轮密钥运算得到暗文;
⑥ 循环9次执行 ②.⑤ ~ ⑤ ,每次的轮密钥不同;
⑦ 最后执行一遍 ②.⑤,③和⑤(不执行④),得到总共的暗文;
Ⅲ
input和output和i都是全局变量;
使用cry1函数让input变换为output;
变换的规则就是依次读取input的第a1位,然后继续调用cry1,不断读取64个数据;
按照这个思路,output增长是不会有变换的,i一直都会顺着顺序变大,而读取input会有些许顺序;
1 | //跟踪数据 |
但是没关系,因为i顺着变大,所以只需要将赋值顺序变一下,输入比较的数据,不就可以得到输入的数据了吗?
1 |
|
按着思路试了一下,果然用得到的数据就能进入if判断框了,下面的if同理;
得到的flag:nctf{bc2e3b4c2eb03258c5102bf9de77f57dddad9edb70c6c20febc01773e5d81947}