n1cef1sh's Blog

例题

题目提示是常见的加密算法,逻辑很简单,但是没有认出是什么算法,尝试直接破解失败了所以就去做其他题目了(3小时30个题……)

变量名进行了简单的混淆,输入24位flag,经过函数sub_400686加密后和四下划线数组比较,相等则puts成功,但是这个puts不是单纯的puts。它先把key进行了一遍加密。

然后几个变量是这样的,密钥key也就是’Th1sIsTheK3y’

而sub_400686函数则是rc4加密算法 主要特征就是开始部份利用key生成s盒的操作。

不多比比,附上解题脚本下面再深刻理解一下RC4算法。

# coding=utf-8
# bdctf{YOU_CRAKE_THE_RC4}
DEFAULT_KEY = "666666"
def rc4(data, key=DEFAULT_KEY, skip=1024):
x = 0
box = range(256)


x = 0
for i in range(256):
x = (x + box[i] + ord(key[i % len(key)])) % 256
tmp = box[i]
tmp2 = box[x]
box[i] = box[x]
box[x] = tmp

x = 0
y = 0
out = []
if skip > 0:
for i in range(skip):
x = (x + 1) % 256
y = (y + box[x]) % 256
box[x], box[y] = box[y], box[x]
	
for char in data:
x = (x + 1) % 256
y = (y + box[x]) % 256
box[x], box[y] = box[y], box[x]
k = box[(box[x] + box[y]) % 256]
print k
out.append(chr(ord(char) ^ k))

return ''.join(out)

if __name__ == '__main__':
  
import sys
s = [0x1c, 0x61, 0x97, 0x34, 0x28, 0x69, 0xFA, 0X54, 0XDA,0X3A, 0X2B, 0XBB, 0X05, 0X09, 0X16, 0X38, 0XF3, 0XCF, 0XD8, 0XA5, 0X12, 0X7E, 0X67, 0X44]
f = ''
for i in range(len(s)):
f += chr(s[i])
print rc4(f,rc4('Th1sIsTheK3y','Th1sIsTheK3y',0),0)

RC4

先附一个RC4几种语言实现的源码地址 https://github.com/anthonywei/rc4

然后学习几个概念。

RC4算法是一种对称加密算法,所谓对称加密,就是加密和解密的过程是一样的。

转载一张流程图方便理解(源自https://www.cnblogs.com/block2016/p/5601925.html)

S中元素的值按升序被置为0-255,同时建立一个临时向量T。将密钥的值循环复制到T向量中。用T产生S的初始置换,置换伪码如下

  j = 0;

  for (i = 0 ; i < 256 ; i++){

    j = (j + S[i] + T[i]) mod 256;

    swap(S[i] , S[j]);

  }

因为对S的操作仅是交换,S仍然包含所有值为0-255的元素。在初始化的过程中,密钥的主要功能是将S-box搅乱,i确保S-box的每个元素都得到处理,j保证S-box的搅乱是随机的。

最后利用搅乱后的S盒生成密钥流

 i , j = 0;

  while (true){

    i = (i + 1) mod 256;

    j = (j + S[i]) mod 256;

    swap(S[i] , S[j]);

    t = (S[i] + S[j]) mod 256;

    # 这里的K就是当前生成的一个密钥流中的一位
       k = S[t];
       # 可以直接在这里进行加密,当然也可以将密钥流保存在数组中,最后进行异或就ok

    # data[]=data[]^k; 
  }

虽然RC4实现简单,速度快,但是像《加密与解密》里说的那样有一定风险。