LOADING

加载过慢请开启缓存 浏览器默认开启

强网杯青少年赛选拔赛re Writeup

原题提取码:95lk

Flip_over

看java层主逻辑在validateAndEncrypt()函数里,在so文件里找到这个函数,大概逻辑的是取flagflag这个字符串作为密钥把”a4c3f8927d9b8e6d6e483fa2cd0193b0a6e2f19c8b47d5a8f3c7a91e8d4b9f67”先进行RC4加密再进行DES_ECB加密,最后再与0x21和密后的数据进行异或后,与密文比较。解密时提取数据,把异或逆一下,直接用赛博厨师解密。

值得注意的是,我字自己了一个脚本用于获取异或的数据,然后我发现当c语言输出到01 00这类只有一位的十六进制数时,会省略掉前面的0,在用这一大串密钥异或时默认是两位一字节,如果没有前面的0,那么密钥就是错误的,所以我们要把0添加进去。如下面的注释。或者我们在输出十六进制数据时用空格隔开,这在赛博厨师里时不影响的。还有一种解决方案就是用”%.2x”的格式输出,指定输出2个十六进制数。

#include <stdio.h>

unsigned char data[] = { 0x59,0x15,0xc1,0x3f,0x40,0x9a,0x7a,0xe7,0xa6,0x8b,0xb6,0xe3,0xee,0x0d,0x19,0x6d,0xb7,
0x6d,0xca,0xe6,0xda,0x5f,0x0d,0x4b,0xd6,0x0a,0xb2,0xde,0xad,0xaa,0x95,0xeb,0x85,0xb7,0x77,0xc3,0x10,0xbb,0xcf,
0xce,0xf7,0xd2,0x22,0xc9,0xc4,0xf9,0xfc,0xfb,0xab,0x32,0xea,0x31,0x81,0x55,0xaf,0x79,0x52,0x8e,0x80,0xaf,0xc3,
0x18,0x60,0x50,0xf1,0xd8,0x40,0xbb,0xfc,0x1b,0x89,0xa6 };//赛博厨师解密的数据.

int main() {
   unsigned long long a[] = { 0xF462D91A7981581E, 0x780001A9A6A79EE3,0x47141FC8F3C62DA6, 0xAFD0BEA1CBF14F95,0x89DDAB508133AF93,0x8EE2 };
   unsigned char result[42];
   for (int i = 0; i < 42; i++) {
       printf("%x,", *((unsigned char*)a + i));
       result[i] = *((unsigned char*)a + i) ^ 0x21 ^ data[i];
   }
   for (int i = 0; i < 42; i++) {
       printf("%c", *((unsigned char*)result + i));
   }

   //1e5881791ad962f4e39ea7a6a9 1 0 78a62dc6f3c81f1447954ff1cba1bed0af93af338150abdd89e28e  //输出结果
   //1e5881791ad962f4e39ea7a6a9 01 00 78a62dc6f3c81f1447954ff1cba1bed0af93af338150abdd89e28e  //异或要用到的结果
}