初识RC4加密逆向

笔记

RC4_decrypt.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import re
import base64
def rc4_decrypt(ciphertext,key):
S=list(range(256))
j=0
res=[]
#初始化S
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 char in ciphertext:
i=(i+1)%256
j=(j+S[i])%256
S[i],S[j]=S[j],S[i]
res.append(char^S[(S[i]+S[j])%256])
return bytes(res)
data='wr3ClVcSw7nCmMOcHcKgacOtMkvDjxZ6asKWw4nChMK8IsK7KMOOasOrdgbDlx3DqcKqwr0hw701Ly57w63CtcOl'
data=base64.b64decode(data.encode()).decode()
data_list=[ord(j) for j in data]
key='As_we_do_as_you_know'
key_list=[ord(c) for c in key]
flag=rc4_decrypt(data_list,key_list)
print(flag)

RC4_endecrypto.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# RC4加密和解密
def KSA(key):
key_length = len(key)
# 初始化S盒
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % key_length]) % 256
# 交换S[i]和S[j]
S[i], S[j] = S[j], S[i]
return S
def PRGA(S):
i = 0
j = 0
while True:
i = (i + 1) % 256
j = (j + S[i]) % 256
# 交换S[i]和S[j]
S[i], S[j] = S[j], S[i]
K = S[(S[i] + S[j]) % 256]
yield K
def RC4(key):
# 加密函数,返回加密后的字节流
def encrypt(data):
data_length = len(data)
keystream = PRGA(KSA(key))
res = []
for i in range(data_length):
res.append(next(keystream) ^ data[i])
return bytes(res)
# 解密函数,返回解密后的字节流
def decrypt(data):
return encrypt(data)
return encrypt, decrypt
# 示例:
key = b'secret_key'
encrypt_func, decrypt_func = RC4(key)
data_to_encrypt=b'Hello World'
encrypted_data=encrypt_func(data_to_encrypt)
print('Encrypted Data:', encrypted_data)
decrypted_data=decrypt_func(encrypted_data)
print('Decrypted Data:', decrypted_data)

RC4_cversion.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
unsigned char s[256];
void rc4_start( char key[],int n){
int j=0;
for(int i=0;i<256;i++){
s[i]=-1-i; //这里是改动的地方
j=(j+s[i]+key[i%n])%256;
swap(s[i],s[j]);
}

}
unsigned char secr[256];
void rc4_enc( unsigned char pub[],int n){
int i=0,j=0;
for(int k=0;k<n;k++){
i=(i+1)%256;
j=(j+s[i])%256;
swap(s[i],s[j]);
unsigned char temp=s[(s[i]+s[j])%256]^pub[k];
secr[k]=temp;

}
}
int main(){
char key[]="THISISAFAKEFLAG";
rc4_start(key,strlen(key));
unsigned char pub[] =
{
0x44, 0x3F, 0x53, 0x2F, 0x73, 0x86, 0x3E, 0xAE, 0x55, 0xBE,
0x18, 0x5F, 0x74, 0x68, 0x33, 0x5F, 0xF2, 0x06, 0x6D, 0x62};
rc4_enc(pub,20);
for(int i=0;i<20;i++)cout<<secr[i];
return 0;
}

做题

[SWPUCTF 2022 新生赛]pypy

rc4加密,原文随便塞个长的,拿生成的密钥流解密,exp就不放了…

rc4加密流程长这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
初始化S和T:
for i=0 to do
S[i]=i;
T[i]=K[i mod keylen];

初始排列S:
j=0;
for i=0 to 255 do
j = (j+S[i]+T[i]mod256;
swap(S[i],S[j];

生成密钥流,利用密钥流和明文进行加密:
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];

[长城杯 2021 政企组]魔鬼凯撒的RC4茶室

第一部分:自定义凯撒加密

第二部分:需要从给定的两个文件中通过凯撒和rc4恢复key,发现key找不到定义…

放弃rc4逆向,直接调试得key[0]地址esp+f4h,发现为0xde,exp:

1
2
3
4
key=0xde
enc=[0x0d,0x0a,0xb2,0xbf,0xb9,0xa5,0xa6,0xef,0xbf,0xb1,0xb3,0xef,0xb0,0xb9,0x81,0xef,0xad,0x81,0xed,0xb1,0x81,0xbb,0xbf,0xad,0xa7,0x81]
for i in enc:
print(chr((i^key)&0xff),end='')

[SWPUCTF 2021 新生赛]PYRE

RC4、MD5、Base64,exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import re
import base64
def rc4_decrypt(ciphertext,key):
S=list(range(256))
j=0
res=[]
#初始化S
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 char in ciphertext:
i=(i+1)%256
j=(j+S[i])%256
S[i],S[j]=S[j],S[i]
res.append(char^S[(S[i]+S[j])%256])
return bytes(res)
s1="w4s1PUYsJ8OYwpRXVjvDkVPCgzIEJ27Dt2I="
s2=base64.b64decode(s1.encode()).decode()
data_list=[ord(i) for i in s2]
key='e3d68926fe0ec451105275d838847bd1'
key_list=[ord(c) for c in key]
flag=rc4_decrypt(data_list,key_list)
print(flag)

[HGAME 2023 week2]stream

rc4,没意思

[HGAME 2022 week1]flagchecker

Base64+RC4解密即可。

[FSCTF 2023]EZRC4

RC4

1
2
3
From_Hex('Auto')
RC4({'option':'UTF8','string':'wanyuanshenwande'},'Latin1','Latin1')
Input:EB 0D 61 29 BF 9B 05 22 F3 32 28 97 E3 86 4D 2D 5A 2A A3 55 AA D5 B4 6C 8B 51 B1

[MoeCTF 2021]RedC4Bomb

一大堆各种花指令,还有些混淆。加密算法是个魔改的RC4:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
unsigned char s[256];
void rc4_start( char key[],int n){
int j=0;
for(int i=0;i<256;i++){
s[i]=-1-i;
j=(j+s[i]+key[i%n])%256;
swap(s[i],s[j]);
}
}
unsigned char secr[256];
void rc4_enc( unsigned char pub[],int n){
int i=0,j=0;
for(int k=0;k<n;k++){
i=(i+1)%256;
j=(j+s[i])%256;
swap(s[i],s[j]);
unsigned char temp=s[(s[i]+s[j])%256]^pub[k];
secr[k]=temp;
}
}
int main(){
char key[]="THISISAFAKEFLAG";
rc4_start(key,strlen(key));
unsigned char pub[] ={
0x44, 0x3F, 0x53, 0x2F, 0x73, 0x86, 0x3E, 0xAE, 0x55, 0xBE,
0x18, 0x5F, 0x74, 0x68, 0x33, 0x5F, 0xF2, 0x06, 0x6D, 0x62
};
rc4_enc(pub,20);
for(int i=0;i<20;i++)cout<<secr[i];
return 0;
}