前言:算法学习 —— RC4 。
算法原理:
C语言写法:
C语言实现RC4序列密码_rc4加密算法c语言实现-CSDN博客
python写法:
RC4加密算法及Python实现_rc4算法python-CSDN博客
总结:
基于,我自己的理解,RC4 对于脚本的编写 一个S和T的生成 初始化,为密钥流生成提供环境
一个生成密钥流。
资源下载:
https://static2.ichunqiu.com/icq/resources/exp_file/NU1L-CTF/Re/2.zip
看实际题目:
一、re
下载 查壳;
32ida打开。
通过定位main找到关键函数。
但是发现反汇编不出来,进而查看ASM。
涉及花指令的处理。 NOP掉就好。
函数正常显示、分析:
##ida
memset(v27, 0, sizeof(v27));
strcpy(v26, "tallmewhy");
memset(&v26[10], 0, 0xF6u);
v19[0] = xmmword_4021B0;
v19[1] = xmmword_4021C0;
v20 = 1424414361;
v21 = 340807546;
v22 = -4891;
puts("Hello, this is my world.If you want flag, give me something I like.");
sub_401010("\n", v16);
memset(v24, 0, sizeof(v24));
gets(v24);
v3 = strlen(v24);
v4 = strlen(v26);
memset(v25, 0, sizeof(v25));
for ( i = 0; i < 256; ++i )
{
v27[i] = i;
v25[i] = v26[i % v4];
}
v6 = 0;
v7 = 0;
do
{
v8 = v27[v6];
v7 = (v7 + v25[v6] + v8) % 256;
v27[v6++] = v27[v7];
v27[v7] = v8 ^ 0x37;
}
while ( v6 < 256 );
sub_401010("\n\n", v17);
v9 = 0;
v23 = 0;
v10 = 0;
if ( v3 )
{
do
{
v9 = (v9 + 1) % 256;
v11 = v27[v9];
v10 = (v11 + v10) % 256;
v27[v9] = v27[v10];
v27[v10] = v11;
v12 = v23;
v24[v23] ^= v27[(unsigned __int8)(v11 + v27[v9])];
v23 = v12 + 1;
}
while ( v12 + 1 < v3 );
v10 = 0;
}
for ( j = 0; j < v3; ++j )
v10 = v24[j] == *((_BYTE *)v19 + j);
v14 = (char *)&unk_402184;
if ( v10 == 1 )
v14 = aGood;
sub_401010(v14, v18);
return 0;
}
通过 %256 大致可以判断为RC4 进行看算法特征 S、T 替换。 XOR
区别点:
进行逆向:
重点:抓住 RC4是一个对称密钥(加解密用同一个脚本。
def rc4_decrypt_modified(ciphertext, key):
# 初始化 S 盒
S = [i for i in range(256)]
j = 0
# 密钥调度算法(KSA),与加密时的操作相同,重新初始化 S 盒
key_length = len(key)
for i in range(256):
j = (j + S[i] + ord(key[i % key_length])) % 256
S[i], S[j] = S[j], S[i] ^ 0x37 # 魔改。
i = j = 0
plaintext = []
# 伪随机生成算法(PRGA)及解密操作
for char_code in ciphertext:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
k = S[(S[i] + S[j]) % 256]
# 异或操作进行解密
plain_char = chr(char_code ^ k)
plaintext.append(plain_char)
return ''.join(plaintext)
//flag{c5e0f5f6-f79e-5b9b-988f-28f046117802}
总结: 对于S、T替换的魔改。
二、2021极客大挑战 easypyc
下载 查壳
使用了pyinstaller 打包器 进行解包。
能联网就 使用在线解包就好:
能得到源文件:
pyc 反编译得到;
# Visit https://www.lddgo.net/string/pyc-compile-decompile for more information
# Version : Python 3.8
whatbox = [
0] * 256
def aaaaaaa(a, b):
k = [
0] * 256
t = 0
for m in range(256):
whatbox[m] = m
k[m] = ord(a[m % b])
for i in range(256):
t = (t + whatbox[i] + k[i]) % 256
temp = whatbox[i]
whatbox[i] = whatbox[t]
whatbox[t] = temp
//S 和 T
def bbbbbbbbbb(a, b):
q = 0
w = 0
e = 0
for k in range(b):
q = (q + 1) % 256
w = (w + whatbox[q]) % 256
temp = whatbox[q]
whatbox[q] = whatbox[w]
whatbox[w] = temp
e = (whatbox[q] + whatbox[w]) % 256
a[k] = a[k] ^ whatbox[e] ^ 102
def ccccccccc(a, b):
for i in range(b):
a[i] ^= a[(i + 1) % b]
for j in range(1, b):
a[j] ^= a[j - 1]
if __name__ == '__main__':
kkkkkkk = 'Geek2021'
tttttt = [117,62,240,152,195,117,103,74,240,151,173,162,17,75,141,165,136,117,113,33,98,151,174,4,48,25,254,101,185,127,131,87]
ssss = input('Please input your flag:')
inp = [
0] * len(ssss)
if len(ssss) != 32:
print('Length Error!!!!')
exit(0)
for i in range(len(ssss)):
inp[i] = ord(ssss[i])
aaaaaaa(kkkkkkk, len(kkkkkkk))
bbbbbbbbbb(inp, 32)
ccccccccc(inp, 32)
for m in range(32):
if tttttt[m] != inp[m]:
raise Exception('sorry your flag is wrong')
print('success!!!!!!')
print('your flag is {}'.format(ssss))
return None
看程序 执行 流程 在 密钥流生成时,进行了再XOR 也就是魔改了密钥生成算法。
且 将程序进行了 XOR置换。
切入点
程序最终的密文 已知。 关于初始化的操作为魔改,可以提取RC4的256个字节数。
对
whatbox = [
0] * 256
def aaaaaaa(a, b):
k = [
0] * 256
t = 0
for m in range(256):
whatbox[m] = m
k[m] = ord(a[m % b])
for i in range(256):
t = (t + whatbox[i] + k[i]) % 256
temp = whatbox[i]
whatbox[i] = whatbox[t]
whatbox[t] = temp
print(whatbox)
kkkkkkk = 'Geek2021'
aaaaaaa(kkkkkkk, len(kkkkkkk))
先得出最终初始化的结果:
whatbox = [41, 244, 181, 212, 184, 237, 95, 117, 193, 26, 137, 126, 65, 122, 239, 250, 214, 112, 62, 207, 240, 227, 120, 48, 36, 148, 234, 150, 228, 165, 129, 174, 56, 190,, 255, 168, 90, 139, 203, 2, 242, 32, 111, 22, 220, 102, 107, 138, 37, 169, 116, 28, 35, 156, 89, 173, 235, 185, 136, 31, 252, 29, 78, 63, 170, 25, 222, 19, 99, 44, 100, 124, 229, 144, 20, 221, 177, 232, 82, 163, 3, 249, 40, 93, 83, 68, 152, 223, 60, 54, 96, 97, 166, 94, 21, 16, 230, 154, 109, 178, 254, 92, 132, 155, 142, 1, 182, 243, 215, 197, 13, 0, 79, 151, 84, 187, 216, 180, 188, 175, 59, 66, 10, 106, 121, 183, 205, 42, 105, 204, 87, 86, 134, 189, 23, 241, 248, 118, 110, 211, 57, 158, 247, 231, 24, 218, 38, 149, 33, 15, 164, 217, 128, 115, 17, 233, 53, 236, 140, 51, 11, 208, 196, 55, 39, 172, 9, 76, 80, 226, 4, 70, 195, 108, 201, 69, 238, 123, 88, 145, 162, 125, 192, 219, 74, 161, 81, 198, 209, 73, 133, 186, 119, 251, 143, 200, 194, 171, 141, 104, 213, 113, 6, 159, 199, 167, 75, 191]
对密文,进行处理。——> 先逆魔改RC4之后的处理
def reverse_ccccccccc(a):
b = len(a)
# 逆向执行第二个循环
for j in range(b - 1, 0, -1):
a[j] ^= a[j - 1]
# 逆向执行第一个循环
for i in range(b - 1, -1, -1):
a[i] ^= a[(i + 1) % b]
return a
tttttt = [117, 62, 240, 152, 195, 117, 103, 74, 240, 151, 173, 162, 17, 75, 141, 165, 136, 117, 113, 33, 98, 151, 174, 4, 48, 25, 254, 101, 185, 127, 131, 87]
reversed_list = reverse_ccccccccc(tttttt.copy())
print(reversed_list)
最终脚本:
# Visit https://www.lddgo.net/string/pyc-compile-decompile for more information
# Version : Python 3.8
whatbox = [
0] * 256
def aaaaaaa(a, b):
k = [
0] * 256
t = 0
for m in range(256):
whatbox[m] = m
k[m] = ord(a[m % b])
for i in range(256):
t = (t + whatbox[i] + k[i]) % 256
temp = whatbox[i]
whatbox[i] = whatbox[t]
whatbox[t] = temp
print(whatbox)
kkkkkkk = 'Geek2021'
aaaaaaa(kkkkkkk, len(kkkkkkk))
def reverse_ccccccccc(a):
b = len(a)
# 逆向执行第二个循环
for j in range(b - 1, 0, -1):
a[j] ^= a[j - 1]
# 逆向执行第一个循环
for i in range(b - 1, -1, -1):
a[i] ^= a[(i + 1) % b]
return a
tttttt = [117, 62, 240, 152, 195, 117, 103, 74, 240, 151, 173, 162, 17, 75, 141, 165, 136, 117, 113, 33, 98, 151, 174, 4, 48, 25, 254, 101, 185, 127, 131, 87]
reversed_list = reverse_ccccccccc(tttttt.copy())
print(reversed_list)
def bbbbbbbbbb(a, b):
q = 0
w = 0
e = 0
for k in range(b):
q = (q + 1) % 256
w = (w + whatbox[q]) % 256
temp = whatbox[q]
whatbox[q] = whatbox[w]
whatbox[w] = temp
e = (whatbox[q] + whatbox[w]) % 256
a[k] = a[k] ^ whatbox[e] ^ 102
print(chr(a[k]),end='')
tttttt = [117,62,240,152,195,117,103,74,240,151,173,162,17,75,141,165,136,117,113,33,98,151,174,4,48,25,254,101,185,127,131,87]
bbbbbbbbbb(reversed_list, 32)
//SYC{Just_a_Eeeeeeasy_Rc4_right?}