CTF-reverse_RC4那些事兒
0x00 RC4加密知識點
推薦看這位up主的視頻https://www.bilibili.com/video/BV1G64y1Y7p4/?spm_id_from=333.1391.0.0&p=2
簡單來說RC4算法包括兩部分KSA(利用Key生成S盒)和PRGA(利用S盒生成密鑰流):
KSA:
- 初始化S(一般是0-255)
- 初始化K(循環填充密鑰key)
- 利用K來打亂S
PRGA:
生成密鑰流進行異或加密
所以我們的思路就是按照原來的KSA和PGRA算法來得到密鑰流,利用異或加密的對稱性求解,下面以幾道題來深入理解ctf中的rc4解密套路
0x01 [GHCTF 2024 新生賽]UP+
1.做題過程
拖入DIE中,32位,upx殼
用upx -d
解殼發現報錯
我們用010editor打開,將ZVM修改為UPX(55 50 58)
再次upx -d
脫殼
在ida中打開,發現是很標準的RC4算法:
于是手搓腳本
2.EXP
key='justfortest'
S=[]
K=[]
enc_flag=[0x42,0xFD,0x55,0x61,0xB9,0x27,0x6F,0xF5,0xB6,0x86,0x23,0xA9,0xEF,0x1C,0x4,0x9F,0xD4,0x16,0x87,0xD6,0x54,0x68,0xBC,0x2,0x15,0x6D,0x30,0x8,0x4B,0x61,0x4C,0x5E]#這里注意xmmword_402140在前面,xmmword_402130在后面
flag=[]
v5=0
for i in range(0,256):S.append(i)K.append(ord(key[i%len(key)]))
for i in range(0,256):v5=(v5+S[i]+K[i])%256temp=S[v5]S[v5]=S[i]S[i]=temp#以上是KSA算法,就是copy偽碼
i,j=0,0
for k in range(0,len(enc_flag)):i=(i+1)%256j=(S[i]+j)%256S[i],S[j]=S[j],S[i]flag.append(enc_flag[k]^S[(S[i]+S[j])%256])#這里是PGRA算法,注意密鑰流并不是一次性生成的,而是邊加密邊生成的
print("".join(map(chr,flag)))
這里值得注意的是剛開始我以為密鑰流是一次性生成的,最后再依次加密,但是加密過程其實是在密鑰流生成的過程中進行的
Get_flag:NSSCTF{4950b6562657477e6685828e537f43e5}
3.其他
當然在cyberchef中可以直接梭(找到密文,密鑰即可)
只是這道題比較典型,手搓腳本可以更好地理解rc4算法的邏輯,今后識別到rc4算法,只需要找到密文和密鑰就可以到cyberchef中一把梭了
0x02 [SWPUCTF 2022 新生賽]pypy
1.做題思路
得到一個pyc文件,在在線網站反編譯python反編譯 - 在線工具
題目比較簡單,直接在源碼的基礎上寫腳本,只需要把輸入的text換為后面的res數組就可以了,這道題先是生成的密鑰流再逐個異或的,而不是邊生成邊異或
2.EXP
def init_S():for i in range(256):S.append(i)
def init_T():global KeyKey = 'abcdefg'keylen = len(Key)for i in range(256):tmp = Key[i % keylen]T.append(tmp)
def swap_S():j = 0for i in range(256):j = (j + S[i] + ord(T[i])) % 256tmp = S[i]S[i] = S[j]S[j] = tmp
def Get_KeyStream():txtlen = len(text)(j, t) = (0, 0)for i in range(txtlen):i = i % 256j = (j + S[i]) % 256tmp = S[i]S[i] = S[j]S[j] = tmpt = (S[i] + S[j]) % 256KeyStream.append(S[t])
def Get_code():res = []for i in range(len(text)):res.append(text[i] ^ KeyStream[i])return res
if __name__ == '__main__':T = []S = []Key = []PlainText = ''CryptoText = ''KeyStream = []# text = input('please input you flag:\n')text=[84,91,254,48,129,210,135,132,112,234,208,15,213,39,108,253,86,118,248]init_S()init_T()swap_S()Get_KeyStream()res = Get_code()print("".join(map(chr, res)))# for i, ele in enumerate(res):# if not ele == [# 84,# 91,# 254,# 48,# 129,# 210,# 135,# 132,# 112,# 234,# 208,# 15,# 213,# 39,# 108,# 253,# 86,# 118,# 248][i]:# print('bad')# exit()# print('good')
Get_flag:NSSCTF{this_is_rc4}
0x03 [LitCTF 2025]easy_rc4
1.做題思路
ida打開
這里看到又是’FenKey!!‘,多留了一個心眼,按x查看引用情況,發現只有這個函數引用了,所以key就是’FenKey!!’
看了rc4_init和標準的KSA是一樣的,但是PRGA魔改了
問題不大,還是提取密文和密鑰,到cyberchef中,多加個異或就行了:
Get_flag:LitCTF{71bb2a06417a5306ba297ddcfce7b1b0}
(www動調還不是很熟練,很多師傅都用的是動調,后面還得學啊)
0x04 寫在最后的
做了幾道RC4的題,其實這就是一個對稱加密,可能會魔改。一般思路就是找到key和密文,上cyberchef梭,或者編寫腳本進行破解,還有就是動調(這個還不太會),但是RC4一般不會作為一個單獨的考點出現,可能會和upx殼,反動調等等其他知識點出現,但是本次練習主要是學習一下RC4的最最最基本原理,后面會學習其他的相關知識。