好友
阅读权限10
听众
最后登录1970-1-1
|
转载自看雪 ID:pandaos(无名侠)的解题文档Re2
这道题目也比较简单,比第一题还简单一点,题目用的是 RC4 加密。
RC4 算法如下:
void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len)
{
int i = 0, j = 0;
char k[256] = { 0 };
unsigned char tmp = 0;
for (i = 0; i < 256; i++) {
s[i] = i;
k[i] = key[i%Len];
}
for (i = 0; i < 256; i++) {
j = (j + s[i] + k[i]) % 256;
tmp = s[i];
s[i] = s[j];//交换 s[i]和 s[j]
s[j] = tmp;
}
}
void rc4_crypt(unsigned char*s, unsigned char*Data, unsigned long Len)
{
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for (k = 0; k < Len; k++)
{
i = (i + 1) % 256;
j = (j + s[i]) % 256;
tmp = s[i];
s[i] = s[j];//交换 s[x]和 s[y]
s[j] = tmp;
t = (s[i] + s[j]) % 256;
Data[k] ^= s[t];
}
}
代码刚好可以和 401100、4011B0 处的代码吻合,先用肉眼检测是否被魔改,再带观察数据,
最终可下结论,题目采用的是标准 RC4 算法。
很容易找到密文数据:
7C553E5F0EB4CCB977BF6BD960E0B968FB11CED2154B0EB5F73E51EE514D5A9C01A0C53AD038
可以在 401100 处下断得到密钥:
SimpleCryptography
最后编写程序得到 flag:
void main () {
unsigned char s[256] = { 0 };
unsigned char dst[] =
{ 0x7C,0x55,0x3E,0x5F,0x0E,0xB4,0xCC,0xB9,0x77,0xBF,0x6B,0xD9,0x60,0xE0,0xB9,0x68,0xFB,
0x11,0xCE,0xD2,0x15,0x4B,0x0E,0xB5,0xF7,0x3E,0x51,0xEE,0x51,0x4D,0x5A,0x9C,0x01,0xA0,0x
C5,0x3A,0xD0,0x38 };
char * key = "SimpleCryptography";
rc4_init(s, (unsigned char *)key, strlen (key));
rc4_crypt(s, dst, sizeof(dst));
printf(dst);
}
感想 :rc4 算法的解密代码和加密过程也一样,找出密文和密钥是解题的最快方法。这道
题有三点启示。
第一,二进制安全需要熟练掌握各种基本算法的流程以及原理,对算法的关键常量要敏感。
第二,对于一个未知加密算法,可通过代入密文数据测试是否可逆。
第三,对于一个未知加密算法,如果没有提供加密或解密代码,则需要根据逆向并编程实现
另外一半函数,最简单的方法是 angr 符号执行或利用 z3 进行约束求解。 |
|