这题有错
UPX脱壳后,可以看到逻辑比较简单
先是读入21字节的flag然后进行自定义码表的base64编码,然后与key进行一次异或。再作个加密后与给定串比较
strcpy(v8, "Flag{This_a_Flag}");
v6 = strlen(v8);
strcpy(v9, "E8D8BD91871A1E56F53F4889682F96142AF2AB8FED7ACFD5E");
puts((int)"Please input your flag:");
read(0, &v9[50], 256);
if ( strlen(&v9[50]) != 21 ) // flag长21
exit(0);
v3 = s_base64encode((int)&v9[50]); // 非标码表base64编码
strcpy((int)&v8[18], v3);
v7 = strlen(&v8[18]);
for ( i = 0; i < v7; ++i )
v8[i + 18] ^= v8[i % v6]; // 与Flag{This_a_Flag}异或
crypto((int)&v8[18], v7, (int)v8, v6); // RC4 ???
if ( !strcmp___() )
exit(0);
puts((int)"right!");
加密方法从网上搜的说叫RC4运行,但这里显然与常用的RC4不同。这是从网上搜到的源程序。很明显它是等长加密的。而且生成码表后只对明文进行一次异或运算。
static void rc4_init(unsigned char* s_box, unsigned char* key, unsigned int key_len)
{
unsigned char Temp[256];
int i;
for (i = 0; i < 256; i++)
{
s_box[i] = i;//顺序填充S盒
Temp[i] = key[i%key_len];//生成临时变量T
}
int j = 0;
for (i = 0; i < 256; i++)//打乱S盒
{
j = (j + s_box[i] + Temp[i]) % 256;
unsigned char tmp = s_box[i];
s_box[i] = s_box[j];
s_box[j] = tmp;
}
}
void rc4_crypt(unsigned char* data, unsigned int data_len, unsigned char* key, unsigned int key_len)
{
unsigned char s_box[256];
rc4_init(s_box, key, key_len);
unsigned int i = 0, j = 0, t = 0;
unsigned int Temp;
for (Temp = 0; Temp < data_len; Temp++)
{
i = (i + 1) % 256;
j = (j + s_box[i]) % 256;
unsigned char tmp = s_box[i];
s_box[i] = s_box[j];
s_box[j] = tmp;
t = (s_box[i] + s_box[j]) % 256;
data[Temp] ^= s_box[t];
}
}
网上搜到一个WP显然XXX,给出了4个网上的RC4解密网站,其实肯定解不了,因为就不是一回事。用这个加密方法对flag加密后应该是这个,flag是21字节base64后是28再转16进制是56。题目里给的长度都不对而且给了一个16进制编码后的。(出错的地方是转16进制的时候把01这样的转成1了)
E8D8BD91871A010E560F53F4889682F961420AF2AB08FED7ACFD5E00
用这个密文写的解密程序
#UPX ex.
key0 = b'Flag{This_a_Flag}'
#这个密文解密后得不到flag长度都不对
#E8D8BD91871A1E56F53F4889682F96142AF2AB8FED7ACFD5E
#E8D8BD91871A010E560F53F4889682F961420AF2AB08FED7ACFD5E00 正确的密文
c = bytes.fromhex('E8D8BD91871A010E560F53F4889682F961420AF2AB08FED7ACFD5E00')
#key2 sub_8048CC2
v9 = [i for i in range(256)]
v8 = (key0*50)[:256]
j = 0
for i in range(256):
j = (v9[i] + j + v8[i]) %256
v9[i],v9[j] = v9[j],v9[i]
tab = [0]*28
i,j = 0,0
for t in range(28):
i = (i+1) % 256
j = (v9[i]+ j) % 256
v9[i],v9[j] = v9[j],v9[i]
tab[t] = v9[(v9[i] + v9[j])%256]
#先解密
c = [tab[i]^v for i,v in enumerate(c)]
#再与key0作异或
c = bytes([v8[i]^c[i] for i in range(len(c))])
#再进行转表到标准base64
s1 = b'0123456789+/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ='
s2 = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
c = bytes([s2[s1.index(i)] for i in c])
#base64解码
from base64 import b64decode
print(b64decode(c))
#BJD{0v0_Y0u_g07_1T!}