RC4加密

butt3rf1y發表於2024-08-26

一道不是很簡單的 RC4 加密

例題:https://www.nssctf.cn/problem/701

此題涉及:RC4 加密,異或,base64換表,upx 脫殼。

下載附件先用 ex 查殼

32 位的 ELF 檔案,有殼,直接先使用 upx 脫殼

脫完殼拖進 ida 分析,再直接查詢字串

有一個 “right!” 的字串,點進去還可以看見其他的

交叉引用到函式,能看見程式碼資訊

對函式逐步分析:

點進函式sub_8048AC2檢視可以看出是 base 換表

下一個 for 迴圈就是簡單的異或

接下來就是函式sub_8048E24,點進去能看見程式碼開頭有一個函式sub_8048CC2

這些特徵一看就能知道是 RC4 加密了,key=Flag{This_a_Flag},data=E8D....這一串

最後程式碼流程如下

  • RC4解密指令碼
data = [0xE8, 0xD8, 0xBD, 0x91, 0x87,0x1A,
	0x01, 0x0E, 0x56, 0x0F, 0x53, 0xF4,
	0x88, 0x96, 0x82, 0xF9, 0x61,0x42,
	0x0A, 0xF2,0xAB, 0x08, 0xFE, 0xD7,
	0xAC, 0xFD, 0x5E, 0x00]
key = b"Flag{This_a_Flag}"
def rc4(key, data):
	S = list(range(256))
	j = 0
	out = []
	for i in range(256):
		j = (j + S[i] + key[i % len(key)]) % 256
		S[i], S[j] = S[j], S[i]
	i = j = 0
	for T in data:
		i = (i + 1) % 256
		j = (j + S[i]) % 256
		S[i], S[j] = S[j], S[i]
		out.append(T ^ S[(S[i] + S[j]) % 256])
	return out
result = rc4(key, data)
new_result = "".join([chr(t) for t in result])
for x in new_result:
	print(ord(x), end=",")

得到35,21,37,83,8,26,89,56,18,106,57,49,39,91,11,19,19,8,92,51,11,53,97,1,81,31,16,92

  • 異或解密指令碼
a = [35, 21, 37, 83, 8, 26,
     89, 56, 18, 106, 57,
     49, 39, 91, 11, 19,
     19, 8,92, 51, 11, 53,
     97, 1, 81, 31, 16, 92]
key = "Flag{This_a_Flag}"
length = len(key)
for i in range(len(a)):
    a[i] ^= ord(key[i % length])
for i in a:
    print(chr(i), end="")

得到 base64 碼eyD4sN1Qa5Xna7jtnN0RlN5i8lO=

用 Cyberchef 得到 flag =BJD{0v0_Y0u_g07_1T!}

需要注意的是最後用 Cyberchef base64 解碼的時候需要換表,在前面函式sub_8048AC2中可以看到一個a0123456789Abcd,具體值為

RC4加密過程:

  1. 初始化狀態向量 S(256個位元組,作為金鑰流生成的種子 1),按照升序,給每個位元組賦值0,1,2,3,4,5,6.....,254,255

  2. 初始金鑰(使用者輸入),長度任意,小於 256 個位元組,就進行輪轉直到填滿,例如金鑰是 1,2,3,4,填入1,2,3,4,1,2,3,4,1,2,3,4......,輪轉得到 256 個位元組向量 T(金鑰流生成的種子2)

  3. 根據向量 S 和 T 生成的金鑰流與明文進行加密

1.初始化 S 和 T:
    for i=0 to 225 do
	S[i]=i;
	T[i]=key[i mod keylen];		//限制長度
2.初始排列 S
    j=0;
    for i=0 to 255 do
 	j=(j+S[i]+T[i]) mod 256;
 	swap(S[i],S[j]);
3.產生金鑰流,利用金鑰流和明文加密
    i,j=0;
    for r=0 to len do		//r 為明文長度,r 位元組
	i=(i+1) mod 256;
	j=(j+S[i]) mod 256;
	swap(S[i],S[j]);
	t=(S[i]+S[j]) mod 256;
	k[r]=S[t];
	data[r] ^= k[r]; //加密 

ok,over

相關文章