一、题目原题

题目脚本是这样子的(注释是我自己加的

大牛 SDK android 大牛密码箱_python

二、分析源码

大概看了一下,应该是首先将明文填充后再划分成长度为16的块encrypt1函数看似做了对块内元素的交换操作,实则函数运行完根本就没换……这里大概类似于大一学C语言时候的那种,运行了交换a、b的函数之后,再输出a、b的值发现并没交换,而真正要交换的话需要用指针(指C语言中)?encrypt2函数则是将原m内的所有元素按照S_BOX中的数字重新排列位置,因为最后给出了S_BOX,我们可以知道,是下标0处放下标9处的元素,下标1处放下标31处的元素……依此类推,并且重复16次这种变换元素位置的操作。

其实encrypt1函数“什么都没做”这个事情我是后来拿到flag之后才注意到的,做题时候就想着先把encrypt2这个函数逆过来再说。

怎么逆呢?很简单,现在我们可以知道,下标0处的99,原本是在下标为9的位置,下标1处的111,原本是在下标为31的位置……依此类推,以S_BOX中的元素作下标,将c中的元素按顺序与之对应即可,并且重复16次这个操作,这里我借用了第三个变量存放中间值,因为直接在c中操作的话在过程中元素值就变了……(一开始犯了这个错误然后输出了奇怪的东西

如果把encrypt2函数逆过来的操作正确,就能得到flag了,下面给出脚本。

三、解题脚本

c=[99, 111, 102, 11, 107, 49, 11, 53, 121, 48, 114, 117, 11, 95, 112, 95, 109, 115, 11, 95, 101, 95, 119, 117, 79, 123, 111, 48, 110, 95, 121, 116, 121, 125, 116, 11, 119, 11, 97, 67, 11, 11, 11, 11, 11, 99, 110, 104]
sbox=[9, 31, 32, 38, 20, 1, 22, 4, 8, 2, 11, 21, 7, 18, 46, 23, 34, 3, 19, 12, 45, 30, 27, 37, 5, 47, 28, 36, 0, 43, 39, 10, 29, 14, 40, 24, 33, 16, 17, 6, 42, 15, 26, 41, 44, 25, 35, 13]
c1=[0]*len(c)
for j in range(16):
    for i in range(len(sbox)):
        c1[sbox[i]]=c[i]
    c=c1
    c1=[0]*len(c)
#c=[99, 116, 102, 115, 104, 111, 119, 123, 121, 48, 117, 95, 99, 53, 110, 95, 109, 97, 107, 101, 95, 121, 48, 117, 49, 95, 111, 119, 110, 95, 67, 114, 121, 112, 116, 79, 125, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11]
print(bytes(c))
#b'ctfshow{y0u_c5n_make_y0u1_own_CryptO}\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'

忽略后面的填充即可。

最后留个当时做题拿到flag的截图作纪念吧~我做题的习惯可能比较随意,喜欢直接在命令行写Python。本来还有点愁觉得还要去研究下encrypt1,结果逆encrypt2的结果输出后看着就很像flag,输入后真的显示correct了,就很惊喜。

大牛 SDK android 大牛密码箱_网络安全_02


flag:ctfshow{y0u_c5n_make_y0u1_own_CryptO}