第十五届极客大挑战部分WP(主Re)

极客2024 部分题WP
队伍名:不只是来看看题

分数:10023
image-20241124143216479

高斯有言:“当一幢建筑物完成时,应该把脚手架拆除干净。”

从建筑物的角度出发,移除脚手架无疑是有益的,因为它使得建筑本身更加美观,呈现出设计者所追求的艺术效果;对于未来的设计师与建造师而言,这却是不利的。因为脚手架不仅是施工过程中的辅助工具,更是建筑创意与技术实现之间的重要桥梁,它承载了建筑设计的原始思路与实现路径。这些理念和方法是构建过程中不可或缺的组成部分,对后续的设计与施工有着重要的参考价值。

所以WP写得有些过于详细(


Reverse

week1

先来一道签到题

知识点:汇编语言

image-20241114083416795

打开压缩包,是一个.s文件,不懂,双击看看

image-20241114083510088

打开发现是汇编语言,分析转.c(用的GPT,还没系统学汇编-😥)

源码如下:

#include <stdio.h>
#include <string.h>

char target_data[] = "TTDv^jrZu`Gg6tXfi+pZojpZSjXmbqbmt.&x";

int main() {
	char input[80]; // 用于存储输入
	int i = 0; // 计数器
	
	// 从标准输入读取字符串
	scanf("%s", input);
	
	// 对输入字符串进行处理
	while (i < 18) { // 18是36 / 2
		input[i * 2] ^= 7;       // 每个字符异或7
		input[i * 2 + 1] -= 5;   // 每个后续字符减去5
		i++;
	}
	// 比较处理后的字符串和目标数据
	if (strcmp(input, target_data) == 0) {
		printf("good job!\n");
	} else {
		printf("maybe try again!\n");
	}
	
	return 0;
}

exp:

#include <stdio.h>
#include <string.h>

char target_data[] = "TTDv^jrZu`Gg6tXfi+pZojpZSjXmbqbmt.&x";

void generate_input(char *output) {
	int i;
	for (i = 0; i < 18; i++) {
		output[i * 2] = target_data[i * 2] ^ 7; // 反转异或操作
		output[i * 2 + 1] = target_data[i * 2 + 1] + 5; // 反转加法操作
	}
	output[36] = '\0'; // 结束字符串
}

int main() {
	char input[80];
	
	// 生成匹配目标字符串的用户输入
	generate_input(input);
	
	printf("生成的输入内容是:%s\n", input);
	
	return 0;
}

image-20241114083955320

#SYC{You_re@l1y_kn0w_how_To_revers3!}

hello_re

知识点:------

拿到exe文件,无壳,ida分析,找到主函数

int __fastcall main(int argc, const char **argv, const char **envp)
{
  int v4[34]; // [rsp+20h] [rbp-60h] BYREF
  __int64 v5; // [rsp+A8h] [rbp+28h] BYREF
  char v6[32]; // [rsp+B0h] [rbp+30h] BYREF
  int v7[34]; // [rsp+D0h] [rbp+50h]
  int i; // [rsp+158h] [rbp+D8h]
  int v9; // [rsp+15Ch] [rbp+DCh]

  sub_14000173E();
  v7[0] = 0;
  v7[1] = 1;
  v7[2] = 2;
  v7[3] = 52;
  v7[4] = 3;
  v7[5] = 96;
  v7[6] = 47;
  v7[7] = 28;
  v7[8] = 107;
  v7[9] = 15;
  v7[10] = 9;
  v7[11] = 24;
  v7[12] = 45;
  v7[13] = 62;
  v7[14] = 60;
  v7[15] = 2;
  v7[16] = 17;
  v7[17] = 123;
  v7[18] = 39;
  v7[19] = 58;
  v7[20] = 41;
  v7[21] = 48;
  v7[22] = 96;
  v7[23] = 26;
  v7[24] = 8;
  v7[25] = 52;
  v7[26] = 63;
  v7[27] = 100;
  v7[28] = 33;
  v7[29] = 106;
  v7[30] = 122;
  v7[31] = 48;
  v5 = 'REVOLCYS';
  printf("Please enter your flag:\n");
  scanf("%32s", v6);
  sub_140001408((__int64)v6, (__int64)&v5, (__int64)v4);
  v9 = 1;
  for ( i = 0; i <= 31; ++i )
  {
    if ( v4[i] != v7[i] )
    {
      v9 = 0;
      break;
    }
  }
  if ( v9 )
    printf("Congratulations!\n");
  else
    printf("Try again!\n");
  return 0;
}

关注加密函数sub_140001408((__int64)v6, (__int64)&v5, (__int64)v4);

__int64 __fastcall sub_140001408(__int64 a1, __int64 a2, __int64 a3)
{
  __int64 result; // rax
  int j; // [rsp+8h] [rbp-8h]
  int i; // [rsp+Ch] [rbp-4h]

  for ( i = 0; i <= 31; ++i )
  {
    result = (unsigned int)*(char *)(i + a1);
    *(_DWORD *)(4i64 * i + a3) = result;
  }
  for ( j = 0; j <= 31; ++j )
  {
    result = j ^ *(_DWORD *)(4i64 * j + a3) ^ (unsigned int)*(char *)(j % 8 + a2);
    *(_DWORD *)(4i64 * j + a3) = result;
  }
  return result;
}

整体逻辑就是将输入的字符串用密钥'REVOLCYS'进行加密,最终与v7逐位比较。加密逻辑是将输入的字符串依次与key[i%8]和i进行异或

exp:

#include<stdio.h>
int main(){
	char v5[]={"SYCLOVER"}; // [rsp+A8h] [rbp+28h] BYREF
	int v7[34]; // [rsp+D0h] [rbp+50h]
	v7[0] = 0;
	v7[1] = 1;
	v7[2] = 2;
	v7[3] = 52;
	v7[4] = 3;
	v7[5] = 96;
	v7[6] = 47;
	v7[7] = 28;
	v7[8] = 107;
	v7[9] = 15;
	v7[10] = 9;
	v7[11] = 24;
	v7[12] = 45;
	v7[13] = 62;
	v7[14] = 60;
	v7[15] = 2;
	v7[16] = 17;
	v7[17] = 123;
	v7[18] = 39;
	v7[19] = 58;
	v7[20] = 41;
	v7[21] = 48;
	v7[22] = 96;
	v7[23] = 26;
	v7[24] = 8;
	v7[25] = 52;
	v7[26] = 63;
	v7[27] = 100;
	v7[28] = 33;
	v7[29] = 106;
	v7[30] = 122;
	v7[31] = 48;

	for(int i=0;i<32;i++){
		v7[i]^=v5[i%8]^i;
		printf("%c",v7[i]);
	}	
	return 0;
}

image-20241114084545214

#SYC{H3lI0_@_new_R3vers3_Ctf3r!!}

ezzzzz

知识点:安卓逆向,Tea算法

解压后是一个apk文件,安卓逆向,放jadx里分析

image-20241114084802106

定位到MainActivity

image-20241114084856950

大概是将输入的字符串用Enc.encrypt进行加密后与R.string.target进行比较

先找目标字符串R.string.target

找了一圈没找到,搜字符串"target",找到可疑点

image-20241114090018551

复制下来

/*f1f186b25a96c782e6c63a0b70b61b5ced6bf84889700d6b09381b5ccb2f24fab1c79e796d822d9cdcc55f760f780e750d65c4afb89084a9e978c3827a8dd81091f28df3a84dbacab4d75f75f19af8e5b90f80fcfc10a5c3d20679fb2bc734c8ccb31c921ac52ad3e7f922b72e24d923fb4ce9f53548a9e571ebc25adf38862e10059186327509463dd4d54c905abc36c26d5312d2cd42c0772d99e50cd4c4665c3178d63a7ffe71ada251c070568d5a5798c2921ec0f7fc3ae9d8418460762930ca6a2dccef51d2a1a8085491b0f82d686ca34774c52d0f0f26449fc28d362c86f3311b8adc4fb1a4497e34e0f0915d*/

再找加密函数encrypto

package com.example.ezzzz;

/* loaded from: classes.dex */
public class Enc {
    private static final int DELTA = -1640531527;

    public static String encrypt(String str) {
        int length = str.length();
        int[] iArr = new int[length];
        for (int i = 0; i < length; i++) {
            iArr[i] = str.charAt(i);
        }
        int[] iArr2 = new int[4];
        for (int i2 = 0; i2 < 4; i2++) {
            iArr2[i2] = "GEEK".charAt(i2);
        }
        for (int i3 = 0; i3 < length; i3 += 2) {
            int i4 = i3 + 1;
            int[] iArr3 = {iArr[i3], iArr[i4]};
            encrypt(iArr3, iArr2);
            iArr[i3] = iArr3[0];
            iArr[i4] = iArr3[1];
        }
        StringBuilder sb = new StringBuilder();
        for (int i5 = 0; i5 < length; i5++) {
            sb.append(String.format("%08x", Integer.valueOf(iArr[i5])));
        }
        return sb.toString();
    }

    private static void encrypt(int[] iArr, int[] iArr2) {
        int i = iArr[0];
        int i2 = iArr[1];
        int i3 = 0;
        for (int i4 = 0; i4 < 32; i4++) {
            i += ((((i2 << 4) ^ (i2 >> 5)) + i2) ^ (iArr2[i3 & 3] + i3)) ^ (i3 + i4);
            i3 -= 1640531527;
            i2 += ((((i << 4) ^ (i >> 5)) + i) ^ (iArr2[(i3 >>> 11) & 3] + i3)) ^ (i3 + i4);
        }
        iArr[0] = i;
        iArr[1] = i2;
    }
}

经典Tea加密,密钥是"GEEK"

exp:

先把那一串转成单字节的hex

a="f1f186b25a96c782e6c63a0b70b61b5ced6bf84889700d6b09381b5ccb2f24fab1c79e796d822d9cdcc55f760f780e750d65c4afb89084a9e978c3827a8dd81091f28df3a84dbacab4d75f75f19af8e5b90f80fcfc10a5c3d20679fb2bc734c8ccb31c921ac52ad3e7f922b72e24d923fb4ce9f53548a9e571ebc25adf38862e10059186327509463dd4d54c905abc36c26d5312d2cd42c0772d99e50cd4c4665c3178d63a7ffe71ada251c070568d5a5798c2921ec0f7fc3ae9d8418460762930ca6a2dccef51d2a1a8085491b0f82d686ca34774c52d0f0f26449fc28d362c86f3311b8adc4fb1a4497e34e0f0915d"
#每8位一组,以逗号隔开,前面加上0x
for i in range(0,len(a),8):
    print("0x"+a[i:i+8],end=",")
'''
输出:
0xf1f186b2,0x5a96c782,0xe6c63a0b,0x70b61b5c,0xed6bf848,0x89700d6b,0x09381b5c,0xcb2f24fa,0xb1c79e79,0x6d822d9c,0xdcc55f76,0x0f780e75,0x0d65c4af,0xb89084a9,0xe978c382,0x7a8dd810,0x91f28df3,0xa84dbaca,0xb4d75f75,0xf19af8e5,0xb90f80fc,0xfc10a5c3,0xd20679fb,0x2bc734c8,0xccb31c92,0x1ac52ad3,0xe7f922b7,0x2e24d923,0xfb4ce9f5,0x3548a9e5,0x71ebc25a,0xdf38862e,0x10059186,0x32750946,0x3dd4d54c,0x905abc36,0xc26d5312,0xd2cd42c0,0x772d99e5,0x0cd4c466,0x5c3178d6,0x3a7ffe71,0xada251c0,0x70568d5a,0x5798c292,0x1ec0f7fc,0x3ae9d841,0x84607629,0x30ca6a2d,0xccef51d2,0xa1a80854,0x91b0f82d,0x686ca347,0x74c52d0f,0x0f26449f,0xc28d362c,0x86f3311b,0x8adc4fb1,0xa4497e34,0xe0f0915d,
'''

解密函数

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include<stdint.h>
// 解析十六进制字符串并返回整数数组

// 解密函数
void decrypt(unsigned int *iArr, int *iArr2) {
	int i = iArr[0];
	int i2 = iArr[1];
	int i3 = 0xc6ef3720;
	for (int i4 = 31; i4 >= 0; i4--) {
		i2 -= ((((i << 4) ^ (i >> 5)) + i) ^ (iArr2[((uint32_t)i3 >> 11) & 3] + i3)) ^ (i3 + i4);

		i3 += 1640531527;
		i -= ((((i2 << 4) ^ (i2 >> 5)) + i2) ^ (iArr2[i3 & 3] + i3)) ^ (i3 + i4);
	}
	iArr[0] = i;
	iArr[1] = i2;
}

int main() {
	// 解密
	int *keyArray = (int  *)malloc(4 * sizeof(int));
	if (!keyArray) {
		fprintf(stderr, "Memory allocation failed.\n");
		exit(EXIT_FAILURE);
	}
	keyArray[0] = 'G';
	keyArray[1] = 'E';
	keyArray[2] = 'E';
	keyArray[3] = 'K';
	unsigned intArray[]={0xf1f186b2,0x5a96c782,0xe6c63a0b,0x70b61b5c,0xed6bf848,0x89700d6b,
		0x09381b5c,0xcb2f24fa,0xb1c79e79,0x6d822d9c,0xdcc55f76,0x0f780e75,0x0d65c4af,
		0xb89084a9,0xe978c382,0x7a8dd810,0x91f28df3,0xa84dbaca,0xb4d75f75,0xf19af8e5,
		0xb90f80fc,0xfc10a5c3,0xd20679fb,0x2bc734c8,0xccb31c92,0x1ac52ad3,0xe7f922b7,
		0x2e24d923,0xfb4ce9f5,0x3548a9e5,0x71ebc25a,0xdf38862e,0x10059186,0x32750946,
		0x3dd4d54c,0x905abc36,0xc26d5312,0xd2cd42c0,0x772d99e5,0x0cd4c466,0x5c3178d6,
		0x3a7ffe71,0xada251c0,0x70568d5a,0x5798c292,0x1ec0f7fc,0x3ae9d841,0x84607629,
		0x30ca6a2d,0xccef51d2,0xa1a80854,0x91b0f82d,0x686ca347,0x74c52d0f,0x0f26449f,
		0xc28d362c,0x86f3311b,0x8adc4fb1,0xa4497e34,0xe0f0915d,};
	int length=60;
	for (int i = 0; i < length; i += 2) {
		unsigned int temp[2] = {intArray[i], intArray[i + 1]};
		decrypt(temp, keyArray);
		intArray[i] = temp[0];
		intArray[i + 1] = temp[1];
	}
	// 将解密后的整数数组转换为字符串
	
	for (int i = 0; i < length; i++) {
		printf("%c",intArray[i]);
	}
	
	return 0;
}

image-20241114090603569

#SYC{g0od_j0b_wweLCoMeToooSSSyC_zz_1_et3start_yoUr_j0urney!!}

让我康康你的调试

知识点:RC4加解密

ELF文件,无壳

image-20241114090759346

定位到主函数

int __fastcall main(int argc, const char **argv, const char **envp)
{
  unsigned int i; // [rsp+4h] [rbp-7Ch]
  char v5[57]; // [rsp+17h] [rbp-69h] BYREF
  __int64 s2[4]; // [rsp+50h] [rbp-30h] BYREF
  char v7; // [rsp+70h] [rbp-10h]
  unsigned __int64 v8; // [rsp+78h] [rbp-8h]

  v8 = __readfsqword(0x28u);
  strcpy(v5, "syclover");
  s2[0] = 0xA67A02C9047D5B94LL;
  s2[1] = 0x7EF9680DBC980739LL;
  s2[2] = 0x7104F81698BFBD08LL;
  s2[3] = 0x61DB8498B686155FLL;
  v7 = 'm';
  puts(s);
  __isoc99_scanf("%33s", &v5[9]);
  for ( i = 0; i <= 32; ++i )
    v5[i + 9] ^= 0x14u;
  sub_5655290194A6((__int64)&v5[9], 0x21uLL, (__int64)v5, 8uLL);// rc4加密
  if ( !memcmp(&v5[9], s2, 0x21uLL) )
    puts(asc_56552901A048);
  else
    puts(asc_56552901A090);
  puts("Press Enter to exit...");
  getchar();
  getchar();
  return 0;
}

关注加密函数sub_5655290194A6是RC4加密,也没有魔改

unsigned __int64 __fastcall sub_5655290194A6(__int64 a1, unsigned __int64 a2, __int64 a3, unsigned __int64 a4)
{
  char v5; // [rsp+2Bh] [rbp-125h]
  int v6; // [rsp+2Ch] [rbp-124h]
  int v7; // [rsp+30h] [rbp-120h]
  unsigned __int64 i; // [rsp+38h] [rbp-118h]
  char v9[264]; // [rsp+40h] [rbp-110h] BYREF
  unsigned __int64 v10; // [rsp+148h] [rbp-8h]

  v10 = __readfsqword(0x28u);
  sub_5655290191C9((__int64)v9, a3, a4);        // a3=syclover
                                                // a4=8
  v6 = 0;
  v7 = 0;
  for ( i = 0LL; i < a2; ++i )
  {
    v6 = (v6 + 1) % 256;
    v7 = (v7 + (unsigned __int8)v9[v6]) % 256;
    v5 = v9[v6];
    v9[v6] = v9[v7];
    v9[v7] = v5;
    *(_BYTE *)(a1 + i) ^= v9[(unsigned __int8)(v9[v6] + v9[v7])];
  }
  return __readfsqword(0x28u) ^ v10;
}

再看sub_5655290191C9显然是在生成S盒

unsigned __int64 __fastcall sub_5655290191C9(__int64 a1, __int64 a2, unsigned __int64 a3)
{
  char v4; // [rsp+27h] [rbp-119h]
  int i; // [rsp+28h] [rbp-118h]
  int j; // [rsp+28h] [rbp-118h]
  int v7; // [rsp+2Ch] [rbp-114h]
  __int64 v8[33]; // [rsp+30h] [rbp-110h] BYREF
  unsigned __int64 v9; // [rsp+138h] [rbp-8h]
                                                // a2=syclover
                                                // a3=8
  v9 = __readfsqword(0x28u);                    // v9=
  v7 = 0;
  memset(v8, 0, 256);
  for ( i = 0; i <= 255; ++i )
  {
    *(_BYTE *)(i + a1) = i;
    *((_BYTE *)v8 + i) = *(_BYTE *)(i % a3 + a2);
  }
  for ( j = 0; j <= 255; ++j )
  {
    v7 = (*((char *)v8 + j) + v7 + *(unsigned __int8 *)(j + a1)) % 256;
    v4 = *(_BYTE *)(j + a1);
    *(_BYTE *)(j + a1) = *(_BYTE *)(v7 + a1);
    *(_BYTE *)(a1 + v7) = v4;
  }
  return __readfsqword(0x28u) ^ v9;
}

整体逻辑就是将输入的字符串先逐位异或0x14,然后用RC4加密,最终与s2(目标字符串)比较

exp(屯的脚本再加个异或功能):

#include <stdio.h>
#include <string.h>

// 初始化 S 盒
void rc4_init(unsigned char *s, const unsigned char *key, int keylen) {
	int i, j = 0;
	for (i = 0; i < 256; ++i) {
		s[i] = i;
	}
	for (i = 0; i < 256; ++i) {
		j = (j + s[i] + key[i % keylen]) % 256;
		// 交换 s[i] 和 s[j]
		unsigned char tmp = s[i];
		s[i] = s[j];
		s[j] = tmp;
	}
}

// 加密/解密数据
void rc4_crypt(unsigned char *s, unsigned char *data, int len) {
	int i = 0, j = 0, t = 0;
	for (int k = 0; k < len; k++) {
		i = (i + 1) % 256;
		j = (j + s[i]) % 256;
		// 交换 s[i] 和 s[j]
		unsigned char tmp = s[i];
		s[i] = s[j];
		s[j] = tmp;
		
		t = (s[i] + s[j]) % 256;
		data[k] ^= s[t];
	}
}

int main() {
	

	// 密钥
	const char *key = "syclover";
	int keylen = strlen(key);
	
	// 状态数组(S盒)
	unsigned char s[256];
	
	// 密文
	unsigned char v4[] = {
		0x94, 0x5B, 0x7D, 0x04, 0xC9, 0x02, 0x7A, 0xA6,  
		// 0x7EF9680DBC980739LL in little-endian  
		0x39, 0x07, 0x98, 0xBC, 0x0D, 0x68, 0xF9, 0x7E, 
		// 0x7104F81698BFBD08LL in little-endian  
		0x08, 0xBD, 0xBF, 0x98, 0x16, 0xF8, 0x04, 0x71,  
		// 0x61DB8498B686155FLL in little-endian  
		0x5F, 0x15, 0x86, 0xB6, 0x98, 0x84, 0xDB, 0x61 };
	int len = sizeof(v4) / sizeof(v4[0]);
//	 初始化 S 盒
	rc4_init(s, (const unsigned char *)key, keylen);
	
	// 解密数据
	rc4_crypt(s, v4, len);
	
	// 输出解密后的数据
	for (int i = 0; i < len; i++) {
		printf("%c", v4[i]^0x14u);
	}
	printf("\n");
	
	return 0;
}

image-20241114091524619

#SYC{we1come_t0_Geek's_3asy_rc4!}

我勒个z3

知识点:z3求解,算法逆向

无壳,ida分析

image-20241114091738744

定位到main

image-20241114091830117

逻辑大概就是

[1] 验证输入的key:将输入的字符串逐个赋值给v4[i++],调用sub_401B7B((const char *)v4)验证key

[2] 验证flag:将输入的字符串逐个赋值给v6[i++],然后调用sub_401AAC(v6, v4)对v6进行加密,最终通过sub_40179A(v6)进行验证

验证key:

image-20241114092611403

Str2就是a0123456789abcd[]的下标,a0123456789abcd[Str2[i]]就是key

unsigned char Str2[] =
{
	0x2A, 0x0E, 0x0E, 0x14, 0x3F, 0x3F, 0x3F, 0x26, 0x11, 0x0A, 
	0x15, 0x15, 0x0E, 0x17, 0x10, 0x0E
};
unsigned char a0123456789abcd[] =
{
	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 
	0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 
	0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 
	0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x41, 0x42, 0x43, 0x44, 
	0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 
	0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 
	0x59, 0x5A, 0x3F, 0x5F, 0x00
};
int dword_4040A0[32] = {411, 275, 393, 457, 592, 1334, 1246, 444, 1051, 1828, 1744, 1185, 1605, 
1141, 1226, 1676, 997, 455, 829, 1463, 653, 580, 782, 657, 625, 769, 1119, 1135, 1303, 1054, 1062, 1205};
#include<stdio.h>
#include<string.h>
int main(){
	char key[16];
	for(int i=0;i<16;i++){
		key[i]=a0123456789abcd[Str2[i]];
	}
	printf("%s",key);
	//Geek___Challenge
	return 0;
}
//key:Geek___Challenge

关注加密函数sub_401AAC和验证函数sub_40179A

image-20241114092100622

其中a2是刚刚解出来的key

再看sub_4019EB

image-20241114093204900

其中

v2 = *(_BYTE *)(a1 + 4 * i);
for ( k = 0; k <= 2; ++k )
    *(_BYTE *)(a1 + 4 * i + k) = *(_BYTE *)(4 * i + k + 1i64 + a1);
    *(_BYTE *)(a1 + 4 * i + 3i64) = v2;

意思是a1的每四个字节进行换位,顺序是

a[0]=v2,a[0]=a[1],a[1]=a[2],a[2]=a[3],a[3]=v2

再看加密函数sub_401AAC

result = (const char *)strlen(a1);
  v3 = (int)result;
  for ( i = 0; i <= 31; ++i )
  {
    a1[i] ^= a1[(v3 + i - 1) % v3];             // v3=32,将a1[i]与它的前一位异或并赋值给a1[i],最开始是a[0]^=a1[31],a1[1]^=a[0],最后是a[31]^=a1[30]
    result = &a1[i];
    *result ^= *(_BYTE *)(a2 + (47 - i) % 16) ^ (unsigned __int8)i;//a1循环异或a2的每一位
  }

最后看验证函数sub_40179A

image-20241114094337885

经典解方程,去请z3老祖

from z3 import *
a1=[]
str = [411, 275, 393, 457, 592, 1334, 1246, 444, 1051, 1828, 1744, 1185, 1605, 
1141, 1226, 1676, 997, 455, 829, 1463, 653, 580, 782, 657, 625, 769, 1119, 1135, 1303, 1054, 1062, 1205]
a,b,c,d,=Ints('a b c d')
for i in range(0,32,4):
    s1=Solver()
    s1.add(a   +8*b  +6*c+d==str[i])
    s1.add(a   +b    +8*c+6*d==str[i+1])
    s1.add(6*a +b    +c  +8*d==str[i+2])
    s1.add(8*a +6*b  +c  +d==str[i+3])
    if s1.check() == sat:
        result = s1.model()
        a1.append(result[a])
        a1.append(result[b])
        a1.append(result[c])
        a1.append(result[d])
        print(a1)
#[23, 40, 7, 26, 29, 3, 69, 125, 111, 9, 125, 118, 99, 126, 74, 54, 112, 89, 28, 5, 25, 63, 9, 70, 111, 26, 43, 48, 58, 102, 60, 69]

逆加密函数sub_401AAC

exp:

#include <stdint.h>  
#include <string.h>  
#include<stdio.h>
void decrypt_401AAC(uint8_t *encrypted_a1, const char *a2) {  
	uint8_t decrypted_a1[32]; // 用于存储解密后的数据  
	memcpy(decrypted_a1, encrypted_a1, 32); // 复制加密后的数据到解密数组  
	
	int v3 = 32; // 与加密过程中使用的v3值相同  
	for (int i = 31; i >= 0; --i) {  
		// 撤销第二个异或操作(注意顺序是相反的)  
		decrypted_a1[i] ^= (uint8_t)((*(a2 + (47 - i) % 16)) ^ (unsigned __int8)i);  
		
		// 由于加密过程中的第一个异或操作是循环的,我们需要使用解密后的值来计算原始值  
		// 因此,我们需要先存储解密后的当前值,然后再使用它来撤销第一个异或操作  
		uint8_t temp = decrypted_a1[i];  
		decrypted_a1[i] ^= decrypted_a1[(v3 + i - 1) % v3]; // 撤销第一个异或操作  
	}  
	
	// 现在decrypted_a1数组包含了解密后的数据,可以将其复制回encrypted_a1(如果需要的话)  
	// 或者将其用于其他目的  
	memcpy(encrypted_a1, decrypted_a1, 32); // 可选:将解密后的数据复制回原始数组  
}  
// 假设 a1 是一个指向足够大内存区域的指针
uint64_t reverseSub_4019EB(uint64_t a1)
{
	char temp; // 临时变量用于交换
	int i; // 循环计数器
	
	// 遍历每个四字节块
	for (i = 0; i <= 7; ++i)
	{
		for (int j = 0; ; ++j )
		{
			if ( j >= i )
				break;
			for(int m=0;m<3;m++){
				temp = *(char *)(a1 + 4 * i);
				for (int k = 0; k <= 2; ++k )
					*(char *)(a1 + 4 * i + k) = *(char *)(4 * i + k + 1 + a1);
				*(char *)(a1 + 4 * i + 3) = temp;
			}
			
		}
		
	}
	
	return a1; // 返回修改后的数组指针
}

int main() {  
	// 示例加密后的a1数组和a2字符串  
	uint8_t encrypted_a1[] = {  
		23, 40, 7, 26, 29, 3, 69, 125, 111, 9, 125, 118, 99, 126, 74, 54,  
		112, 89, 28, 5, 25, 63, 9, 70, 111, 26, 43, 48, 58, 102, 60, 69  
	};  
	const char *a2 = "Geek___Challenge"; // 注意:这里我们假设a2已经正确填充到16个字节  
	
	// 解密  
	decrypt_401AAC(encrypted_a1, a2);  
	
	// 打印解密后的a1数组(以十六进制形式)  
	for (int i = 0; i < 32; ++i) {  
		printf("%c", encrypted_a1[i]);  
	}  
	reverseSub_4019EB((uint64_t)encrypted_a1);
	printf("\n");
	for (int i = 0; i < sizeof(encrypted_a1); ++i)
		printf("%c", encrypted_a1[i]);
	return 0;  
}

image-20241114095256359

//SYC{Wow!!_Y0u_4r3_9o0d_At_r3$!!}

也许你也听jay

解压后是一个txt文件

image-20241114095452008

经典o0O混淆

简单去混淆后的code如下

#include <stdio.h>
#include<string.h>
int main() {
	
	char URL[46];
	char str1[46];
	strcpy(str1, URL);
	unsigned char str2O[] = {0x96, 0xa1, 0xa0, 0x9b, 0x9b, 0x5f, 0x49, 0x46, 0x85, 0x82, 0x53, 0x95, 0x7d, 0x36, 0x8d, 0x74, 0x82, 0x88, 0x46, 0x7a, 0x81, 0x65, 0x80, 0x6c, 0x78, 0x2f, 0x6b, 0x6a, 0x27, 0x50, 0x61, 0x38, 0x3f, 0x37, 0x33, 0xf1, 0x27, 0x32, 0x34, 0x1f, 0x39, 0x23, 0xde, 0x1c, 0x17, 0xd4};
	int  arr1[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D};
	int  arr2[] = {0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58, 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
	int arr3[]={0x65, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58, 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x00, 0x31, 0x30, 0x2F};
	int len = strlen(URL);
	for(int i = 0; i < len; i++) {
		arr3[i] ^=  arr2[i+1];  
		
	}
	for(int i = 0; i < len; i++) {
		str1[i] ^=  arr1[i];  
		
	}
	for(int i = 0; i < len; i++) {
		arr3[i] -=  arr1[i];  
		
	}
	for(int i = 0; i < len; i++) {
		str1[i] -=  arr1[47 + i];  
		arr1[i]^=arr3[51];
		
	}
	for(int i = 0; i < len; i++) {
		str1[i] +=  arr2[i];  
	}
	for(int i=0;i<len;i++){
		if(str1[i] != str2O[i]){
			printf("Error");
		}
	}
	return 0;
}

ez的,理一理逻辑就行了,+改成-,-改成+,^不变啥的

exp

#include<stdio.h>
#include<string.h>
int main(){
	char URL[46];
	int len=45;
	unsigned char str1[] = {0x96, 0xa1, 0xa0, 0x9b, 0x9b, 0x5f, 0x49, 0x46, 0x85, 0x82, 0x53, 0x95, 0x7d, 0x36, 0x8d, 0x74, 0x82, 0x88, 0x46, 0x7a, 0x81, 0x65, 0x80, 0x6c, 0x78, 0x2f, 0x6b, 0x6a, 0x27, 0x50, 0x61, 0x38, 0x3f, 0x37, 0x33, 0xf1, 0x27, 0x32, 0x34, 0x1f, 0x39, 0x23, 0xde, 0x1c, 0x17, 0xd4};
	int  arr1[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D};
	int  arr2[] = {0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58, 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
	int arr3[]={0x65, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58, 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x00, 0x31, 0x30, 0x2F};
	for(int i = 0; i < len; i++) {
		arr3[i] ^=  arr2[i+1];  
		
	}
	for(int i = 0; i < len; i++) {
		arr3[i] -=  arr1[i];  
	}
	
	for(int i = 0; i < len; i++) {
		str1[i] -=  arr2[i];  
	}
	for(int i = 0; i < len; i++) {
		arr1[i]^=arr3[51];
		str1[i] +=  arr1[47 + i];  		
	}
	for(int i = 0; i < len; i++) {
		str1[i] ^=  arr1[i];  
		
	}
	printf("%s",str1);
	return 0;
}

解出来是个网址

image-20241114095837456

点进去,恍然大悟题目名字的意思

image-20241114100120001

RC4,key是lovebeforeBC,密文是Q7u+cyiOQtKHRMqZNzPpApgmTL4j+TE=,找个在线网站解了

image-20241114100242730

//SYC{ILIKELISTENJAYSONG}

week2

知识点:python编译原理,python字节码

好像是python?

解压出来是一个二进制文件

image-20241114233329274

放010看看,发现是python字节码

image-20241114233425732

转换成python源码如下

# 定义初始常量和提示
flag = 'SYC{MD5(input)}'
print("Please input0:")
input0 = ''  # 初始化输入为空字符串

# 定义辅助函数
def test2(s2):#传参s2,对s2的每一个字符进行加密并传给cipher
    key = "SYC"
    length = 18
    cipher = []
    for i in range(length):
        cipher.append(
            (ord(s2[i]) ^ i + ~ord(key[i % 3]) + 1)
        )
    return cipher

def test(s, R):#传入参数字符串s和密钥R,对s的每一个字符进行位移加密(类凯撒加密)
    result = []
    for i in s:
        if 'A' <= i <= 'Z':
            result.append(
                chr((ord(i) - ord('A') + R) % 26 + ord('A'))
            )
        elif 'a' <= i <= 'z':
            result.append(
                chr((ord(i) - ord('a') + R) % 26 + ord('a'))
            )
        elif '0' <= i <= '9':
            result.append(
                chr((ord(i) - ord('0') + R) % 10 + ord('0'))
            )
        else:
            result.append(i)
    return ''.join(result)

# 定义变量
a = 13
b = 14
c = (a + b) ^ a
d = b * 100
e = a ^ b
m = d - c * 4 + e - 1
r = m % 26

# 调用 test 和 test2 函数
cipher1 = test(input0, r)
cipher2 = test2(cipher1)

# 预定义的数字列表
num = [-1, -36, 26, -5, 14, 41, 6, -9, 60, 29, -28, 17, 21, 7, 35, 38, 26, 48]

# 校验 cipher2 和 num
for i in range(18):
    if cipher2[i] != num[i]:
        print("wrong!")
        break
else:
    print("Rrrright!")

exp:


def de_test2(s2):
    key = "SYC"
    length = 18
    for i in range(length):
        
        s2[i]=(s2[i]-(~ord(key[i % 3]) + 1))^i

    return s2

def de_test(s, R):#逆向test,正向是+R,逆向就-R,然后再%26保证结果在0~25之间,再加上对应的值转换成字符
    result = []
    for i in s:
        if 'A' <= chr(i) <= 'Z':
            result.append(
                chr((i - ord('A') - R) % 26 + ord('A'))
            )
        elif 'a' <= chr(i) <= 'z':
            result.append(
                chr((i - ord('a') - R) % 26 + ord('a'))
            )
        elif '0' <= chr(i) <= '9':
            result.append(
                chr((i - ord('0') - R) % 10 + ord('0'))
            )
        else:
            result.append(chr(i))
    return ''.join(result)

a = 13
b = 14
c = (a + b) ^ a
d = b * 100
e = a ^ b
m = d - c * 4 + e - 1
r = m % 26

num = [-1, -36, 26, -5, 14, 41, 6, -9, 60, 29, -28, 17, 21, 7, 35, 38, 26, 48]

num=de_test2(num)
flag=""
flag=de_test(num,r)
print("SYC{"+flag+"}")
#SYC{ed798fdd74e5c382b9c7fcca88500aca}

玩就行了

游戏题,没怎么了解过unity逆向,就硬肝到666分

image-20241115092520818

然后发现给了一个Data.txt文件

image-20241115092607972

看不懂,导入010看看

image-20241115092711731

MZ开头,保存并改后缀为exe,运行

image-20241115092753311

无壳,放ida分析

定位到main函数

image-20241115092831888

关注三个函数

sub_14000144B(Str, 20i64);
sub_140001596(Str, v4);
sub_14000161C(Str, &v4[5]);

1.sub_14000144B

image-20241115093007480

和上面那道一样的加密方式

2.sub_140001596

image-20241115093048255

循环异或,key是 "GEEK"

3.sub_14000161C

image-20241115093119123

就是一个简单的赋值操作

exp:

#include<stdio.h>
#include<string.h>
void decryptString(char *decrypted, const char *encrypted, int a2) {
	size_t length = strlen(encrypted);
	
	// 复制加密字符串到解密字符串
	strncpy(decrypted, encrypted, length + 1); // +1 to include null terminator
	
	for (size_t i = 0; i < length; ++i) {
		char currentChar = decrypted[i];
		
		if (currentChar >= '0' && currentChar <= '9') { // 数字字符 '0'-'9'
			// 对数字进行逆向操作
			decrypted[i] = ((currentChar - '0' - a2 + 10) % 10) + '0';
		} else if (currentChar >= 'A' && currentChar <= 'Z') { // 大写字母 'A'-'Z'
			// 对大写字母进行逆向操作
			decrypted[i] = ((currentChar - 'A' - a2 + 26) % 26) + 'A';
		} else if (currentChar >= 'a' && currentChar <= 'z') { // 小写字母 'a'-'z'
			// 对小写字母进行逆向操作
			decrypted[i] = ((currentChar - 'a' - a2 + 26) % 26) + 'a';
		}
		// 其他字符保持不变
	}
}
int main(){

	int str[]={10, 22, 18, 48, 48, 12, 45, 10, 43, 48, 61, 36, 40, 35, 48, 5, 36, 44, 45, 38, 24, 34, 6, 35, 62, 9, 127, 19, 58};
	char v4[]={"GEEK"};
	for(int i=0;i<29;i++){
		str[i]^=v4[i%4];
	}
	char enc[30]={'\0'};
	char flag[30]={'\0'};
	for(int i=0;i<=29;i++){
		enc[i]=(char)str[i];
	}
	decryptString(flag,enc,20);
	printf("%s",flag);
	return 0;
}
//SYC{cOnGraduulaTions_mIneR:D}

奇怪的RC4

知识点:RC4加密算法

解压后是一个python打包的exe

image-20241115094142150

使用pyinstxtractor解包

image-20241115094355969

找到里面的 easy_xor_and_rc4.pyc 文件

找个在线网站反编译

image-20241115094614379

也可以使用uncompyle6库

image-20241115101341466

拿到源码

# uncompyle6 version 3.9.2
# Python bytecode version base 3.8.0 (3413)
# Decompiled from: Python 3.12.3 | packaged by conda-forge | (main, Apr 15 2024, 18:20:11) [MSC v.1938 64 bit (AMD64)]
# Embedded file name: easy_xor_and_rc4.py
from Rc4 import *

def xor1(plaintext, xor_list):
    try:
        xor_list = [ord(i) for i in xor_list]
    except:
        pass
    else:
        try:
            plaintext = [ord(i) for i in plaintext]
        except:
            pass
        else:
            for i in range(len(plaintext)):
                plaintext[i] ^= xor_list[i]
            else:
                return plaintext


def xor2(plaintext):
    try:
        plaintext = [ord(i) for i in plaintext]
    except:
        pass
    else:
        for i in range(len(plaintext) - 1):
            plaintext[i + 1] = plaintext[i] ^ plaintext[i + 1]
        else:
            return plaintext


def enc(plaintext, key, xor_list):
    plaintext = rc4(plaintext, key)
    plaintext = xor1(plaintext, xor_list)
    plaintext = xor2(plaintext)
    return plaintext


plaintext = input("please give your input:")
key = "SYCFOREVER"
xor_list = list(range(len(plaintext)))
cipher = [158, 31, 205, 434, 354, 15, 383, 298, 304, 351, 465, 312, 261, 442, 
 397, 474, 310, 397, 31, 21, 78, 67, 47, 133, 168, 48, 153, 99, 103, 
 204, 137, 29, 22, 13, 228, 3, 136, 141, 248, 124, 26, 26, 65, 200, 
 7]
plaintext = enc(plaintext, key, xor_list)
for i in range(len(cipher)):
    if cipher[i] != plaintext[i]:
        print("Wrong")
        exit(1)
else:
    print("You know the flag!!")

发现它还导入了自定义的RC4库,再回去找找

image-20241115101801837

一样的处理,拿到源码:

def KSA(key):
    j = 0
    S = list(range(256))
    key_length = len(key)
    for i in range(256):
        j = (j + S[i] + key[i % key_length]) % 256
        S[i], S[j] = S[j], S[i]
    else:
        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[j], S[i]
        k = (S[i] + S[j]) % 256
        yield k


def rc4(plaintext, key):
    try:
        key = [ord(i) for i in key]
    except:
        pass
    else:
        try:
            plaintext = [ord(i) for i in plaintext]
        except:
            pass
        else:
            for i in range(len(plaintext)):
                plaintext[i] += i
            else:
                S = KSA(key)
                xor_value = PRGA(S)
                for i in range(len(plaintext)):
                    plaintext[i] ^= int(next(xor_value)) + 6
                else:
                    return plaintext

主函数逻辑就是将输入的字符串进行三次加密

def enc(plaintext, key, xor_list):
    plaintext = rc4(plaintext, key)
    plaintext = xor1(plaintext, xor_list)
    plaintext = xor2(plaintext)
    return plaintext

其中key和xor_list都是已知的,最后与cipher进行比较,我们要做的就是逆回去

  1. xor2
for i in range(len(plaintext) - 1):
    plaintext[i + 1] = plaintext[i] ^ plaintext[i + 1]

常规异或,如a[1]=a[0]^a[1] , a[2]=a[1]^a[1]

逆向就是a[i]=a[i+1]^a[i],从末尾开始

逆xor2

def xor2(plaintext):
    for i in range(len(plaintext) - 1, 0, -1):
        plaintext[i] ^= plaintext[i - 1]
    return plaintext
  1. xor1
xor_list = [ord(i) for i in xor_list]#xor_list已知
for i in range(len(plaintext)):
    plaintext[i] ^= xor_list[i]

逆向就是再异或一遍

逆xor1:

def xor1(plaintext, xor_list):
    for i in range(len(plaintext)):
        plaintext[i] ^= xor_list[i]
    return plaintext
  1. enc
def KSA(key):#KSA(Key Scheduling Algorithm)用于生成 RC4 算法中的状态向量 S,它是一个长度为 256 的数组,用来保存密钥流。
    j = 0
    S = list(range(256))
    key_length = len(key)
    for i in range(256):
        j = (j + S[i] + key[i % key_length]) % 256
        S[i], S[j] = S[j], S[i]
    else:
        return S#返回最终的 S 数组,它是经过密钥调度后的状态向量。

def PRGA(S):#PRGA(Pseudo-Random Generation Algorithm)用于生成密钥流,它基于由 KSA 生成的状态向量 S。这个生成器是一个无限循环的生成器(使用 yield 关键字)
    i = 0
    j = 0
    while True:
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i], S[j] = S[j], S[i]
        k = (S[i] + S[j]) % 256
        yield k


def rc4(plaintext, key):
    try:
        key = [ord(i) for i in key]
    except:
        pass
    else:
        try:
            plaintext = [ord(i) for i in plaintext]
        except:
            pass
        else:
            for i in range(len(plaintext)):
                plaintext[i] += i#每个字节先增加i(索引值)
            else:
                S = KSA(key)#生成状态向量S
                xor_value = PRGA(S)#生成伪随机字节流
                for i in range(len(plaintext)):
                    plaintext[i] ^= int(next(xor_value)) + 6#这里就是魔改的地方,正常的RC4没有+6
                else:
                    return plaintext

逆enc

def rc4_decrypt(ciphertext, key):
    key = [ord(i) for i in key]#初始化KSA和PRGA函数和加密一致
    S = KSA(key)
    xor_value = PRGA(S)

    # Step 1: Reverse `plaintext[i] ^= int(next(xor_value)) + 6`
    for i in range(len(ciphertext)):
        ciphertext[i] ^= int(next(xor_value)) + 6

    # Step 2: Reverse `plaintext[i] += i`
    for i in range(len(ciphertext) - 1, -1, -1):
        ciphertext[i] -= i

    return ciphertext

完整exp:

def PRGA(S):
    i = 0
    j = 0
    while True:
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i], S[j] = S[j], S[i]
        k = (S[i] + S[j]) % 256
        yield k

def KSA(key):
    j = 0
    S = list(range(256))
    key_length = len(key)
    for i in range(256):
        j = (j + S[i] + key[i % key_length]) % 256
        S[i], S[j] = S[j], S[i]
    else:
        return S

def dec(cipher, key, xor_list):
    # Step 1: Reverse the second XOR operation
    cipher = xor2(cipher)
    # Step 2: Reverse the first XOR operation
    cipher = xor1(cipher, xor_list)
    # Step 3: Apply RC4 decryption
    cipher = rc4_decrypt(cipher, key)
    return cipher

def xor1(plaintext, xor_list):
    for i in range(len(plaintext)):
        plaintext[i] ^= xor_list[i]
    return plaintext

def xor2(plaintext):
    for i in range(len(plaintext) - 1, 0, -1):
        plaintext[i] ^= plaintext[i - 1]
    return plaintext

def rc4_decrypt(ciphertext, key):
    key = [ord(i) for i in key]
    S = KSA(key)
    xor_value = PRGA(S)

    # Step 1: Reverse `plaintext[i] ^= int(next(xor_value)) + 6`
    for i in range(len(ciphertext)):
        ciphertext[i] ^= int(next(xor_value)) + 6

    # Step 2: Reverse `plaintext[i] += i`
    for i in range(len(ciphertext) - 1, -1, -1):
        ciphertext[i] -= i

    return ciphertext

# 已知的密文
cipher = [
    158, 31, 205, 434, 354, 15, 383, 298, 304, 351, 465, 312, 261, 442,
    397, 474, 310, 397, 31, 21, 78, 67, 47, 133, 168, 48, 153, 99, 103,
    204, 137, 29, 22, 13, 228, 3, 136, 141, 248, 124, 26, 26, 65, 200,
    7
]
# 密钥
key = "SYCFOREVER"
# 异或列表
xor_list = list(range(len(cipher)))
# 解密
flag = dec(cipher, key, xor_list)
# 输出解密后的内容
print("解密结果:")
for i in flag:
    print(chr(i), end='') # 转换为字符输出
#SYC{Bel1eve_thAt_you_a3e_Unique_@nd_tHe_beSt}

giraffe_eat_rainbow

查壳,发现OLLVM保护,没见过

image-20241115104347739

用ida分析,发现长这样

image-20241115105758887

image-20241115105811363

看不懂一脸懵

查资料

基于IDA Python的OLLVM反混淆(一) 手动去混淆 - 吾爱破解 - 52pojie.cn

[原创]控制流平坦化一篇就够了(上)-软件逆向-看雪-安全社区|安全招聘|kanxue.com

了解到OLLVM控制流平坦化

正常的程序执行流程图
图片描述

基本块1
基本块2
if(condition){
    基本块3
}else{
    基本块4
}
基本块5
基本块6

控制流平坦化之后的
图片描述

基本块1
switchVar = 2;
while(true){
    switch(switchVar){
        case 2:
            基本块2
            switchVar = condition ? 3 : 4;
        case 3:
            基本块3
            switchVar = 5
        case 4:
            基本块4
            switchVar = 5
        case 5:
            基本块5
            switchVar = 6
        case 6:
            基本块6
            goto end;
    }
}
end:

没管正向是怎么做的,只了解逆向有两种方法:

1.使用deflat.py去平坦化

具体参考去除控制流平坦化的工具deflat.py安装及使用 - 月如霜 - 博客园

试过了,报错(😩)

2.在ida中使用插件D-810

image-20241115110023372

选择ollvm.json,然后重新反编译

image-20241115110151935

就是对输入的字符串进行加密然后与目标字符串比较,重点关注encrypto

image-20241115110245261

看不懂,浇给GPT,并转换成c代码

#include <stdio.h>
#include <string.h>

void encrypt(char *a1, const char *a2, unsigned char *a3) {
    size_t len = strlen(a1);  // 获取输入字符串的长度
    unsigned char *key = a3;  // 密钥指针
    unsigned char result;
    
    // 假设 a2 是另一个参数,用于加密过程中可能的对照表或数据
    for (size_t i = 0; i < len; ++i) {
        // 简单的加密操作,使用异或(XOR)作为加密方式
        result = a1[i] ^ key[i % strlen((char*)key)];  // 通过密钥加密每个字符
        a1[i] = result;  // 将加密后的字符存回原字符串
    }
    
    // 假设函数的目的是修改输入字符串,结果直接写入 a1
}

int main() {
    char text[] = "Hello, world!";#明文
    const char *key = "secretkey";  // 密钥
    unsigned char a3[] = {0x12, 0x34, 0x56, 0x78};  // 另一个可能的密钥数据
    
    printf("Original text: %s\n", text);
    
    encrypt(text, key, a3);  // 执行加密操作
    
    printf("Encrypted text: %s\n", text);
    
    return 0;
}

加密逻辑就是循环异或密钥,和前面的一样的方式

exp:(key是动调拿到的

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main(){
	unsigned char s2[36]={
			0x1D, 0x36, 0x73, 0x16, 0x49, 0x2D, 0x1A, 0x1D, 0x29, 0x06, 
			0x42, 0x2C, 0x76, 0x07, 0x10, 0x0E, 0x7E, 0x39, 0x55, 0x32, 
			0x75, 0x03, 0x1B, 0x1D, 0x19, 0x5F, 0x52, 0x23, 0x01, 0x03, 
			0x1D, 0x3F, 0x00, 
	};
	char v7[]={"No0m0bOB"};//No0m0bOB//BOb0m0oN
	
	for(int i=0;i<32;i++){
		s2[i]=s2[i]^v7[i%8];
	}
	printf("%s",s2);
	return 0;
}
//SYC{yOU_girAFe_L0Ve_EaT_W0bN1aR}

DH爱喝茶

知识点:花指令,TEA家族系列算法
参考沃德:TEA家族算法 - Q7h2q9 - 博客园

ELF文件,无壳(看名字猜TEA算法和花指令)

image-20241119145237160

ida分析,发现红了

image-20241119145341935

发现这里有一些无意义的跳转

image-20241119145711775

nop一下就好了

image-20241119145623639

f5反编译

image-20241119145754796

重点关注enc函数

image-20241119145828402

确信是TEA算法,然后魔改了delta

整体逻辑就是将输入的字符串进行魔改TEA加密然后与目标字符串比对

exp:

#include <stdio.h>
#include <stdint.h>
#include <string.h>

// 正向加密函数
unsigned int __cdecl enc(unsigned int *a1, int *a2, int asd)
{
	unsigned int v3; // [esp+8h] [ebp-28h]
	unsigned int v4; // [esp+Ch] [ebp-24h]
	int v5;          // [esp+10h] [ebp-20h]
	unsigned int i;  // [esp+14h] [ebp-1Ch]
	int v7;          // [esp+1Ch] [ebp-14h]
	int v8;          // [esp+20h] [ebp-10h]
	
	v3 = *a1;
	v4 = a1[1];
	v5 = asd;
	v7 = *a2;
	v8 = a2[1];
	
	for (i = 0; i <= 0x1F; ++i)
	{
		v4 -= (v3 + v5) ^ (16 * v3 + a2[2]) ^ ((v3 >> 5) + a2[3]);
		v3 -= (v4 + v5) ^ (16 * v4 + v7) ^ ((v4 >> 5) + v8);
		v5 -= (unsigned __int8)(v8 ^ v7) - 0x6789ABCE;
	}
	
	*a1 = v3;
	a1[1] = v4;
	return v4;
}

int main()
{
	int v51[] = {0xecaa140, 0xeca8fc0, 0xeca8fc0, 0xeca8fc0};
	int v6[4]; 
	unsigned int v7[8]; 
	int v8; 
	int v9; 
	int v10; 
	int v11; 
	int v12; 
	int v13; 
	int v14; 
	int v15; 
	int v61[4] = {0x9e26af15, 0xe26af359, 0x26af379e, 0x6af37be2};
	v6[0] = 0x56789ABC;
	v6[1] = 0x6789ABCD;
	v6[2] = 0x789ABCDE;
	v6[3] = 0x89ABCDEF;
	v8 = 0x1F85A965;
	v9 = 0xEEC063EC;
	v10 = 0x5BF1D0B6;
	v11 = 0xF2FDE7B0;
	v12 = 0xAA38809A;
	v13 = 0x670772E9;
	v14 = 0x360D24B9;
	v15 = 0xE98C688C;
	
	v7[0] = v8;
	v7[1] = v9;
	v7[2] = v10;
	v7[3] = v11;
	v7[4] = v12;
	v7[5] = v13;
	v7[6] = v14;
	v7[7] = v15;
	
	// 对每个块进行加密
	for (int i = 3; i >= 0; --i)
	{
		// 正确的索引应该是 2 * i 和 2 * i + 1
		// 因为每个 4 字节的数据块由两个 int 组成
		enc((unsigned int *)&v7[2 * i], v61, v51[i]);
		v61[i] = v6[i];
	}
	
	// 输出结果
	for (int i = 0; i < 8; ++i) {
		printf("%c%c%c%c", (v7[i] & 0xFF), (v7[i] >> 8 & 0xFF), (v7[i] >> 16 & 0xFF), (v7[i] >> 24 & 0xFF));
	}
	
	return 0;
}
//SYC{DH_likes_flower_and_tea!!!!}

CPP_flower

知识点:!花指令!

exe,无壳(看名字猜花指令)

ida分析,发现报红

image-20241119150343148

经典E8混淆

无脑后发现下面还有混淆

image-20241119150650567

retn干扰了,继续nop

最后弄了好久,总算是勉强能看了(有些地方逻辑还是不太清楚)

image-20241119151431081

重点关注判断部分的代码

image-20241119151531054

unk_2D2C30是目标内容,Buf2是根据输入的字符串加密得来的

加密部分也看不懂

动调试试

image-20241119152643436

盲猜v4 == dword_536004这里在判断字符串长度,内存查看是50,也就是要求输入内容长度是50,随便输50个字符进去↑

image-20241119152659157

重点Buf2是怎么被赋值的

for ( i = 0; i < dword_536004; ++i )
{
      v6 = (_DWORD *)sub_52128A(v17, i);
      v13 = *v6 ^ *(char *)sub_521113(v16, i);
      Buf2[i] = v13;
}

每次循环将v6的值与v16[i]进行异或然后赋值给Buf2,那继续猜测v16里放的应该就是用户输入的字符串

在内存里找到v6的值,第一次是0x6D

image-20241119153336107

继续步过

image-20241119153748479

拿到v13的值0x5C

image-20241119153810895

而我输入的第一个字符是'1'

image-20241119153411109

异或一下看看是不是 0x6D^0x5C='1'

image-20241119153843518

没问题,那加密逻辑就清晰了

exp:

#include<stdio.h>
#include<stdlib.h>
unsigned char ida_chars[] =
{
	0x3E, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0xEB, 0x00, 
	0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 
	0x8E, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0xE5, 0x00, 
	0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 
	0x3F, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0xC8, 0x00, 
	0x00, 0x00, 0xDE, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 
	0x44, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0xCB, 0x00, 
	0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 
	0x3C, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xBE, 0x00, 
	0x00, 0x00, 0xCB, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 
	0x55, 0x00, 0x00, 0x00, 0x9E, 0x00, 0x00, 0x00, 0x6D, 0x00, 
	0x00, 0x00, 0xD9, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 
	0x97, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x52, 0x00, 
	0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 
	0xFE, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x1A, 0x00, 
	0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 
	0x3A, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x06, 0x00, 
	0x00, 0x00, 0x5E, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 
	0x5A, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x22, 0x00, 
	0x00, 0x00, 0xA1, 0x00, 0x00, 0x00, 0xC5, 0x00
};

unsigned char v6[] =
{
	0x6D, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0xA8, 0x00, 
	0x00, 0x00, 0x5D, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 
	0xBE, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0xBA, 0x00, 
	0x00, 0x00, 0xE5, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 
	0x51, 0x00, 0x00, 0x00, 0xC7, 0x00, 0x00, 0x00, 0xFB, 0x00, 
	0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
	0x2B, 0x00, 0x00, 0x00, 0xD9, 0x00, 0x00, 0x00, 0x94, 0x00, 
	0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 
	0x59, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x00, 0x00, 0xF8, 0x00, 
	0x00, 0x00, 0xA7, 0x00, 0x00, 0x00, 0xE7, 0x00, 0x00, 0x00, 
	0x22, 0x00, 0x00, 0x00, 0xAD, 0x00, 0x00, 0x00, 0x1F, 0x00, 
	0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x00, 0x00, 
	0xF9, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x26, 0x00, 
	0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 
	0x9B, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x7B, 0x00, 
	0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 
	0x65, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x00, 0x00, 0x68, 0x00, 
	0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 
	0x32, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x50, 0x00, 
	0x00, 0x00, 0xC4, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00
};
int main(){
	srand(0x7DE9u);
	for(int i=0;i<50;i++){
		printf("0x%02x ",rand()%256);
	}
	for(int i=0;i<50;i++){
		ida_chars[4*i]=ida_chars[4*i]^v6[4*i];
		printf("%c",ida_chars[4*i]);
	}
	
	return 0;
}
//SYC{Y0u_c@n_3nJoy_yhe_Flow3r_anytime_and_anywhere}

有一定的运气成分,还好加密方式不复杂,不然我铁定做不出来(😢)

week3

ez_hook

知识点:数据结构与算法(树、Z字形排列算法、逆向hook技术、动调if绕过)

解压后是一个exe,无壳,ida分析

直接定位到main

image-20241119214241333

关注sub_40167D

image-20241119214302045

image-20241119214327541

image-20241119214349875

老实说数据结构没学好,问了GPT才知道这是树,sub_401597是初始化,sub_401602是后序遍历也就是倒序输出

看后面,

有个Z_change和xor

image-20241119214548358

这个函数是对串入的字符串进行Z字形排列后再输出

image-20241119214606351

逻辑都很清楚

然后想到题目名字ez_hook,就去网上搜了一下

参考Hook原理--逆向开发 - 国孩 - 博客园简单了解了一下hook技术

image-20241119214955673

大概意思就是改变了代码的执行流程,再想到ida中的CheckRemoteDebuggerPresent,明白了静态分析的代码可能不对,要动调

if ( CheckRemoteDebuggerPresent(hProcess, &pbDebuggerPresent) && pbDebuggerPresent )处下断点

把ZF寄存器改为1即可绕过动调检测

image-20241119215347852

继续跟进,发现程序运行到xor时去了另一个地方

image-20241119215641047

image-20241119215657251

结束后正常返回

image-20241119215722377

确定hook的地方就是xor,跳转到另一个函数里,对字符串里的每个字符异或0x7

exp:

# 初始数据
flag = "zoXpih^lhX6soX7lr~DTHtGpX|"

# Step 1: 对 flag 中的每个字符进行异或运算
# 确保 v2 的长度不超过 flag 的长度
result = []
for i in range(len(flag)):
    xor_char = chr(ord(flag[i]) ^ 7)
    result.append(xor_char)
xor_result = ''.join(result)

print("XOR Result:", xor_result)

# Step 2: 实现 reverse_zigzag_cipher 函数
def reverse_zigzag_cipher(cipher_text, num_rows):
    length = len(cipher_text)
    rows = [''] * num_rows
    down = True
    row = 0

    # First, assign characters in zigzag order
    index_map = [[] for _ in range(num_rows)]
    for i in range(length):
        index_map[row].append(i)
        if down:
            row += 1
            if row == num_rows:
                row = num_rows - 2
                down = False
        else:
            row -= 1
            if row == -1:
                row = 1
                down = True

    # Reorder characters in original zigzag sequence
    position = 0
    for r in range(num_rows):
        for i in index_map[r]:
            rows[r] += cipher_text[position]
            position += 1

    # Reconstruct the original text
    result = []
    row, down = 0, True
    for _ in range(length):
        result.append(rows[row][0])
        rows[row] = rows[row][1:]
        if down:
            row += 1
            if row == num_rows:
                row = num_rows - 2
                down = False
        else:
            row -= 1
            if row == -1:
                row = 1
                down = True
    return ''.join(result)

# Example usage
cipher_text = xor_result
num_rows = 3  # 根据原函数传入的 a2 参数
original_text = reverse_zigzag_cipher(cipher_text, num_rows)
print("Original Text:", original_text)
flag=original_text[::-1]
print(flag)
#SYC{you_kn0w_wh@t_1s_hoOk}

blasting_master

知识点:md5爆破

无壳,ida分析,定位到main

image-20241119220348353

关注sub_55682F272464

直接上动调

image-20241119221043639

sub_55682F2723E2函数是生成a1字符串的md5值(32位)

image-20241119221111631

image-20241119221223462

调试了一会大概理清了整体逻辑:对输入的字符串从第一位开始,每四位将其md5值存储在s2中(如abcdef,第一次是abcd,第二次是bcde,第三次是cdef,以此类推),再对刚存储的内容进行加密,最后将s2与目标数组比较

那么逆向就很清晰了:先解密拿到每四位的md5值,然后爆破求解

exp1:求md5值

#include<stdio.h>
#include<stdint.h>
unsigned char b[] =
{
	0xB2, 0x50, 0xA0, 0xBC, 0x3A, 0x7F, 0x54, 0x6D, 0x96, 0x07, 
	0x0F, 0x71, 0x9A, 0x72, 0xEB, 0xA5, 0xA0, 0xB5, 0x71, 0xA4, 
	0x6A, 0xB8, 0xBA, 0xFA, 0xE4, 0x31, 0xC3, 0x71, 0x54, 0x29, 
	0xA7, 0x59, 0x20, 0x2B, 0x13, 0x21, 0xBD, 0x67, 0x5F, 0x8D, 
	0x65, 0x3A, 0x02, 0x27, 0x08, 0x4F, 0x92, 0x9C, 0xB5, 0x7C, 
	0xDF, 0x69, 0x34, 0xB8, 0x82, 0x2D, 0xF6, 0xCA, 0x7A, 0x65, 
	0x98, 0x63, 0xDC, 0x51, 0x2A, 0x34, 0x97, 0x4F, 0xF8, 0xBC, 
	0x23, 0x1F, 0x38, 0xA8, 0xA6, 0x2F, 0xA9, 0x0D, 0x64, 0x4C, 
	0xAC, 0x2F, 0xF9, 0xF5, 0x2D, 0xB1, 0x91, 0xA8, 0xD5, 0x76, 
	0xD9, 0x2D, 0xC6, 0xAC, 0x2E, 0x69, 0x32, 0xD5, 0x64, 0x1D, 
	0xC1, 0x3C, 0xEC, 0xF5, 0x2C, 0x90, 0xED, 0xF4, 0x17, 0x8B, 
	0x55, 0x4C, 0xE4, 0x6C, 0x3B, 0xB3, 0xDA, 0x29, 0xC0, 0x7B, 
	0x39, 0xDF, 0x92, 0x73, 0xFC, 0xC9, 0xC2, 0xA8, 0x68, 0x11, 
	0x22, 0x2B, 0x64, 0x3F, 0x12, 0x9B, 0x95, 0x73, 0x2A, 0x05, 
	0xD3, 0x3F, 0x2E, 0x33, 0xF1, 0x85, 0xED, 0x07, 0x7B, 0x86, 
	0x8F, 0x62, 0x2D, 0x79, 0x03, 0xAC, 0x80, 0xCE, 0xF5, 0xB2, 
	0xA0, 0x0C, 0xF7, 0xE1, 0xC5, 0x0E, 0x63, 0x27, 0xD1, 0x65, 
	0x23, 0xEA, 0x5A, 0x1C, 0x02, 0x0B, 0x32, 0xBA, 0x1F, 0xE5, 
	0xC7, 0x22, 0xA5, 0x66, 0x77, 0xEA, 0x5B, 0xE4, 0x64, 0xAB, 
	0x8B, 0x60, 0xB6, 0xDF, 0x00, 0xDC, 0xF7, 0x6D, 0x93, 0xEC, 
	0x2F, 0x2F, 0x68, 0x07, 0x50, 0xE0, 0xD1, 0x1A, 0x3F, 0xC6, 
	0x4E, 0x2E, 0xC6, 0xBB, 0xAE, 0x08, 0x40, 0xD8, 0x5B, 0x11, 
	0xB5, 0xDC, 0x15, 0x35, 0x7F, 0x63, 0x49, 0x3E, 0x5B, 0x9C, 
	0x0D, 0xFC, 0x0D, 0xB6, 0x80, 0xB7, 0x2B, 0x00, 0xEF, 0x3C, 
	0x0C, 0x2F, 0xEB, 0x86, 0x44, 0x57, 0x74, 0x9E, 0x5F, 0x1F, 
	0x8B, 0xA1, 0xC9, 0x01, 0xF1, 0xD8, 0xF4, 0x92, 0x82, 0x95, 
	0x6F, 0x85, 0xD2, 0x15, 0x22, 0x1F, 0xF0, 0x9F, 0xD1, 0xAB, 
	0x51, 0x39, 0x9A, 0xB6, 0xC4, 0xDA, 0xFB, 0x38, 0x8D, 0xE6, 
	0x8C, 0x57, 0x19, 0x5E, 0x94, 0xDA, 0x57, 0xCC, 0xF0, 0xB9, 
	0x0A, 0x4A, 0x17, 0x82, 0xFC, 0xC5, 0x4F, 0x4B, 0x5A, 0xA5, 
	0xF4, 0xE5, 0x3E, 0xFA, 0x3A, 0x0A, 0xF4, 0xB4, 0x8E, 0x7F, 
	0x25, 0x84, 0x75, 0x90, 0xCD, 0x35, 0x87, 0xEB, 0xC3, 0xCE, 
	0x81, 0x2B, 0x86, 0xC9, 0x16, 0x7E, 0x85, 0x68, 0x2D, 0xF1, 
	0xDB, 0x8E, 0x74, 0x15, 0xCF, 0x95, 0x51, 0x07, 0x88, 0x5E, 
	0x1B, 0xE9, 0x37, 0xC9, 0x5B, 0xBA, 0x61, 0xEB, 0x9F, 0x7B, 
	0xE4, 0x89, 0x10, 0xF0, 0x6E, 0xCD, 0x75, 0x71, 0xAD, 0x09, 
	0x74, 0x58, 0x49, 0xA3, 0xF5, 0x33, 0x83, 0x75, 0x22, 0x95, 
	0x1B, 0xE3, 0x3C, 0x48, 0x05, 0x5C, 0xAD, 0xA8, 0x6B, 0xFD, 
	0x41, 0xEB, 0xAF, 0xC6, 0x02, 0x28, 0xC6, 0x5E, 0xCF, 0x36, 
	0xAE, 0x50, 0xCE, 0x93, 0xF2, 0x70, 0x88, 0x9D, 0x3F, 0x4A, 
	0x9F, 0x86, 0xE7, 0x67, 0x64, 0xB0, 0x02, 0x96, 0x0C, 0xAB, 
	0x9F, 0xEB, 0x4B, 0x03, 0x44, 0x92, 0xDE, 0x6C, 0xF4, 0xCE, 
	0x32, 0x4F, 0x4F, 0x38, 0xE2, 0x52, 0x59, 0xCA, 0x95, 0x4A, 
	0x11, 0xD8, 0x30, 0xA2, 0x7B, 0xD5, 0x3A, 0xE6, 0x11, 0xDA, 
	0x3A, 0x4A, 0x33, 0x61, 0x39, 0x65, 0x26, 0xD2, 0x78, 0xBC, 
	0xED, 0xBD, 0xA5, 0x8B, 0x2B, 0x87, 0x4C, 0x95, 0x47, 0x25, 
	0x02, 0xBA, 0x83, 0x3D, 0xDC, 0xE4, 0x6A, 0xAD, 0x67, 0xDD, 
	0x22, 0xB1, 0xBD, 0x2B, 0x7C, 0x53, 0x11, 0x3C, 0xD9, 0x23, 
	0x06, 0x3D, 0x20, 0xBA, 0x28, 0xC8, 0x2D, 0x89, 0x51, 0x57, 
	0x63, 0x82, 0xA0, 0xC8, 0xA8, 0xDE, 0x29, 0x61, 0xC1, 0x53, 
	0x51, 0xB0, 0xBC, 0x37, 0x04, 0xEE, 0xC9, 0x35, 0x8A, 0xA8, 
	0xA2, 0x66, 0xBA, 0x6F, 0x24, 0xB6, 0x3F, 0x62, 0x41, 0x6D, 
	0x10, 0x46, 0xCB, 0x06, 0x12, 0x39, 0xD9, 0x0E, 0xF9, 0xDC, 
	0x19, 0xA7, 0x65, 0xB8, 0xC0, 0x40, 0xBE, 0xF6, 0x99, 0x9A, 
	0xAF, 0x02, 0x16, 0x37, 0x4D, 0xA5, 0x75, 0x4C, 0x42, 0x4B, 
	0x1A, 0xF0, 0x52, 0xDA, 0x38, 0xF3, 0x6B, 0xA9, 0x1A, 0xDC, 
	0xFA, 0x80, 0xB0, 0x60, 0xB1, 0xFD, 0x73, 0x7B, 0x78, 0xD9, 
	0x62, 0x83, 0x26, 0xBF, 0x16, 0x33, 0x71, 0x79, 0x6F, 0x11, 
	0x2F, 0xE9, 0xA7, 0xBB, 0x46, 0x46, 0xD6, 0x8F, 0xF6, 0x21, 
	0x7E, 0xFC, 0x68, 0x12, 0x86, 0x6B, 0xFC, 0x51, 0xC9, 0x70, 
	0x7A, 0x74, 0xBC, 0x8F, 0x6E, 0x0B, 0x86, 0x42, 0x6F, 0x5C, 
	0xFD, 0xF7, 0x4E, 0x27, 0x71, 0xFE, 0x37, 0xE6, 0xC8, 0x62, 
	0x47, 0xFC, 0xD5, 0x6C, 0xBA, 0x5C, 0xD9, 0x29, 0x5A, 0x73, 
	0xAE, 0xC3, 0x8F, 0xF0, 0x46, 0x95, 0x32, 0x42, 0x2D, 0xD0, 
	0x00, 0x00 ,0x00, 0x00,
};
int main(){
	unsigned char byte_4060[640];
	for(int num=0;num<40;num++){
		printf("'");
		for (int j = 0; j <= 15; ++j) {
			// 逆向计算公式
			int temp = b[16 * num + j] - 82 * (j % 15);
			while(temp%7!=0){
				temp+=256;
			} 
			byte_4060[j + 16 * num] = (temp / 7) ^ (j + 42);
		}
		for (int k = 0; k < 16; k++) {
			printf("%02x", byte_4060[k + 16 * num]);
		}
		printf("'");
		printf(",");
		printf("\n");
	}
	printf("\n");
}

image-20241119221715525

exp2:爆破求flag(感谢密码02432B74)

import hashlib
import string
list=['14b908a7d09c68a87840b9c8984f61ca','4aeea74f605d72553e4a0dc8927e85a6','ca3475908da4054871db7622664482bd','492d01189a5d0ae8d8eb3e5c768898de',
'2ca599b2fe6161e62ab94afa5172e06d','ded0ef649d5ec3f761ffc75414d90636','948e6ccc51e130e0b6510b973f60276d','d6bddd367016bcaafde8065e8a9e3221',
'72a23ece2adc1a4aa194eefc5b34064c','6d5e030a5b9bb58d09c2cd1f2e0b4707','4add79d075c321be4596ed49d8c9f2e4','9473c1f4e7170fa9138bd50722008199',
'30e0e84737fa51539b381802fe2dfbaf','23c7aa253cb89e57e2e9d568cd0967da','e30cdf55bb41a7e369bf603263cd0ddd','bed0eddd0a340891cba8057871869b51',
'46eb9e84cfd25a806ca850eac9007b86','3c57ccd1dbdd27291690875d52e7b5ed','ba8ac621d7f740b0bb3c1e1c329a968f','5ca31cff249c8f3b81516b2c2fc0f97b',
'1d34a2f86cd36f37098a558db2ca6dba','cd48d075fb56ad6c2f5b1f0677d060d6','5ad94a9c059ec72cce69378e8d58399a','64ce3d46424def4389b9652439c04db3',
'44d16275afab9eef60b4e673e6025ddf','8307c9ea2a958ad9969c49060328c067','98bd1c45684cf587ac2347a92dd7bb51','7a1b9d44d07b43b5b46b7db8611abe27',
'e2ed036c5568391e56c6a19c30c739a2','6e75a6fc07caaa04191c4cbe89e9433c','60d688310ecd47acc590ad11cec54c8b','65929756419580cedea7b72c082512d3',
'dc90ac6dbfd7f3a8b24fc5b5408e433b','d58d8faa955dbc5fd07f0779875f2e68','217e4b5798a8d20f9c7be8de23feca7d','9cc9b8eb21eab1aaeaa2d6eef4b42e4c',
'edca31600f569d6a284ffa5a44a6561d','726ba28e82fecb8f746d0c5a0ce01e17','730db39a64e4237153eff8716f29a70d','dc0dcf58f0309e227b31ea8c601fbf89',
]
l=string.printable
a="SYC{"
m=''
num=0
for i in range(0,len(list)-1):
    for j in l:
        m=a[(i+1):]+j
        if(hashlib.md5(m.encode()).hexdigest()==list[i+1]):
            a+=j
            break

print(a)
#SYC{W0w!y0u_@re_th3_BeSt_blasting_Exp3rt!!}

Aes!

知识点:AES

解压,exe,无壳,ida分析,定位到main,看标题就猜到是魔改AES

image-20241119222807464

知道了密钥,关注AES加密,一通分析后

__int64 __fastcall AES_encrypto(const void *key, unsigned int a2, _BYTE *a3, _BYTE *a4, unsigned int a5)
{
  __int64 v6; // [rsp+0h] [rbp-80h] BYREF
  __int64 v7[2]; // [rsp+20h] [rbp-60h] BYREF
  __int64 v8[4]; // [rsp+30h] [rbp-50h] BYREF
  int v9[90]; // [rsp+50h] [rbp-30h] BYREF
  int j; // [rsp+1B8h] [rbp+138h]
  unsigned int i; // [rsp+1BCh] [rbp+13Ch]
  int *v12; // [rsp+1C0h] [rbp+140h]
  _BYTE *v13; // [rsp+1C8h] [rbp+148h]
  _BYTE *v14; // [rsp+1F0h] [rbp+170h]
                                                // a1="SYCLOVERSYCLOVER"
                                                // 128位密钥
                                                // a2=16
  v14 = a3;
  v13 = a4;
  v12 = (int *)(&v6 + 10);
  memset(v8, 0, sizeof(v8));
  v7[0] = 0i64;
  v7[1] = 0i64;
  if ( key && a3 && a4 )
  {
    if ( a2 <= 16 )
    {
      if ( (a5 & 0xF) != 0 )                    // a5=16
      {
        printf("input is wrong!\n");
        return 0xFFFFFFFFi64;
      }
      else
      {
        memcpy(v8, key, a2);
        sub_7FF7F50B1408((__int64)v8, 16u, v9); // 密钥扩展(魔改)
        for ( i = 0; i < a5; i += 16 )
        {
          InitStateMatrix((__int64)v7, v14);    // 初始化状态矩阵
          AddRoundKey((__int64)v7, (__int64)v12);// 轮密钥加
          for ( j = 1; j <= 9; ++j )
          {
            v12 += 4;
            SubBytes((__int64)v7);              // 字节替换(一样)
            ShiftRows((__int64)v7);             // 魔改
            MixColumns((__int64)v7);
            AddRoundKey((__int64)v7, (__int64)v12);
          }
          SubBytes((__int64)v7);
          ShiftRows((__int64)v7);
          AddRoundKey((__int64)v7, (__int64)(v12 + 4));
          CopyStateMatrix((__int64)v7, v13);    // 将状态矩阵的内容逐字节复制到指定的输出缓冲区。这通常发生在 AES 加密过程的最后步骤,将最终的加密结果从状态矩阵导出到输出。
          v13 += 16;
          v14 += 16;
          v12 = v9;
        }
        return 0i64;
      }
    }
    else
    {
      printf("keylen is wrong!\n");
      return 0xFFFFFFFFi64;
    }
  }
  else
  {
    printf("input wrong!\n");
    return 0xFFFFFFFFi64;
  }
}

做题过程挺曲折的,直接给exp了,后面找个机会专门说AES

exp1.求逆S盒(魔改点1:S盒)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<stdint.h>
#define SBOX_SIZE 16

void generate_inverse_sbox(unsigned char sbox[SBOX_SIZE][SBOX_SIZE], unsigned char inv_sbox[SBOX_SIZE][SBOX_SIZE]) {
	// 初始化逆 S 盒
	for (int i = 0; i < SBOX_SIZE; i++) {
		for (int j = 0; j < SBOX_SIZE; j++) {
			unsigned char value = sbox[i][j];
			// 根据 S 盒的位置反推逆 S 盒
			inv_sbox[value / SBOX_SIZE][value % SBOX_SIZE] = (i * SBOX_SIZE) + j;
		}
	}
}

int main() {
	//魔改 S 盒
	unsigned char custom_sbox[SBOX_SIZE][SBOX_SIZE] = {
		0x7C, 0xCA, 0x7B, 0x77, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 
		0x67, 0x2B, 0xFE, 0xD7, 0x47, 0xAB, 0x76, 0x63, 0x82, 0xC9, 
		0x7D, 0xFA, 0x59, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 
		0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 
		0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 
		0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 
		0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 
		0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 
		0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 
		0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, 
		0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 
		0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 
		0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0x97, 0xCD, 
		0x0C, 0x13, 0xEC, 0x5F, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 
		0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 
		0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 
		0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 
		0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 
		0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 
		0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 
		0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 
		0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 
		0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 
		0x8E, 0x94, 0x9B, 0x1E, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 0x8C, 
		0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 
		0x0F, 0xB0, 0x54, 0xBB, 0x16, 0x87
	};
	
	unsigned char inv_sbox[SBOX_SIZE][SBOX_SIZE] = {0};
	
	// 生成逆 S 盒
	generate_inverse_sbox(custom_sbox, inv_sbox);
	
	// 打印结果
	printf("Inverse S-box:\n");
	for (int i = 0; i < SBOX_SIZE; i++) {
		for (int j = 0; j < SBOX_SIZE; j++) {
			printf("0x%02x, ", inv_sbox[i][j]);
		}
		printf("\n");
	}
	
	return 0;
}

exp2:还原


#include<stdint.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

// 定义 _byteswap_ulong 宏
#ifndef _byteswap_ulong
#define _byteswap_ulong(x) ((uint32_t)(((x) << 24) | (((x) & 0xff00) << 8) | (((x) >> 8) & 0xff00) | ((x) >> 24)))
#endif
// 其它头文件

static const int S[16][16] = { 0x7C, 0xCA, 0x7B, 0x77, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 
	0x67, 0x2B, 0xFE, 0xD7, 0x47, 0xAB, 0x76, 0x63, 0x82, 0xC9, 
	0x7D, 0xFA, 0x59, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 
	0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 
	0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 
	0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 
	0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 
	0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 
	0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 
	0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, 
	0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 
	0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 
	0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0x97, 0xCD, 
	0x0C, 0x13, 0xEC, 0x5F, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 
	0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 
	0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 
	0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 
	0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 
	0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 
	0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 
	0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 
	0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 
	0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 
	0x8E, 0x94, 0x9B, 0x1E, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 0x8C, 
	0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 
	0x0F, 0xB0, 0x54, 0xBB, 0x16, 0x87 };

/**
 * 逆S盒
 */
static const int S2[16][16] = { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x82, 0xf2, 0xd7, 0xfa,
	0x7c, 0xe3, 0x39, 0x83, 0x9b, 0x2f, 0xfe, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xed, 0x4c, 0x95, 0x0b, 0x42, 0xf9, 0xc3, 0x4e,
	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
	0x72, 0xf7, 0xf5, 0x64, 0x86, 0x68, 0x98, 0x0e, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
	0x6c, 0x70, 0x48, 0x50, 0xfc, 0xec, 0xb9, 0xda, 0x5e, 0x16, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x85,
	0x90, 0xd8, 0xab, 0x11, 0x8c, 0xbc, 0xd3, 0x0a, 0xf6, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x10, 0x03, 0xc1, 0xaf, 0xbd, 0x02, 0x00, 0x14, 0x8a, 0x6b,
	0x3a, 0x91, 0x12, 0x41, 0x4f, 0x67, 0xdc, 0xff, 0x97, 0xf1, 0xcf, 0xce, 0xef, 0xb4, 0xe6, 0x73,
	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x80, 0xe2, 0xf8, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
	0x47, 0xf0, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0f, 0xaa, 0x18, 0xbe, 0x1b,
	0xfb, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfd, 0x78, 0xcd, 0x5a, 0xf3,
	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x13, 0x01, 0x59, 0x27, 0x81, 0xeb, 0x5f,
	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xee,
	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf4, 0xb0, 0xc8, 0xea, 0xbb, 0x3c, 0x84, 0x53, 0x99, 0x61,
	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x15, 0x63, 0x55, 0x21, 0x0c, 0x7d, };

/**
 * 获取整形数据的低8位的左4个位
 */
static int getLeft4Bit(int num) {
	int left = num & 0x000000f0;
	return left >> 4;
}

/**
 * 获取整形数据的低8位的右4个位
 */
static int getRight4Bit(int num) {
	return num & 0x0000000f;
}
/**
 * 根据索引,从S盒中获得元素
 */
static int getNumFromSBox(int index) {
	int row = getLeft4Bit(index);
	int col = getRight4Bit(index);
	return S[row][col];
}

/**
 * 把一个字符转变成整型
 */
static int getIntFromChar(char c) {
	int result = (int) c;
	return result & 0x000000ff;
}

/**
 * 把16个字符转变成4X4的数组,
 * 该矩阵中字节的排列顺序为从上到下,
 * 从左到右依次排列。
 */
static void convertToIntArray(char *str, int pa[4][4]) {
	int k = 0;
	int i,j;
	for(i = 0; i < 4; i++)
		for(j = 0; j < 4; j++) {
		pa[j][i] = getIntFromChar(str[k]);
		k++;
	}
}
/**
 * 把一个4字节的数的第一、二、三、四个字节取出,
 * 入进一个4个元素的整型数组里面。
 */
static void splitIntToArray(int num, int array[4]) {
	int one, two, three;
	one = num >> 24;
	array[0] = one & 0x000000ff;
	two = num >> 16;
	array[1] = two & 0x000000ff;
	three = num >> 8;
	array[2] = three & 0x000000ff;
	array[3] = num & 0x000000ff;
}

/**
 * 将数组中的元素循环左移step位
 */
static void leftLoop4int(int array[4], int step) {
	int temp[4];
	int i;
	int index;
	for(i = 0; i < 4; i++)
		temp[i] = array[i];
	
	index = step % 4 == 0 ? 0 : step % 4;
	for(i = 0; i < 4; i++){
		array[i] = temp[index];
		index++;
		index = index % 4;
	}
}

/**
 * 把数组中的第一、二、三和四元素分别作为
 * 4字节整型的第一、二、三和四字节,合并成一个4字节整型
 */
static int mergeArrayToInt(int array[4]) {
	int one = array[0] << 24;
	int two = array[1] << 16;
	int three = array[2] << 8;
	int four = array[3];
	return one | two | three | four;
}

/**
 * 常量轮值表
 */
static const unsigned int Rcon[10] = { 0x01000000, 0x02000000,
	0x04000000, 0x08000000,
	0x10000000, 0x20000000,
	0x40000000, 0x80000000,
	0x1b000000, 0x36000000 };
/**
 * 密钥扩展中的T函数
 */
static int T(int num, int round) {
	int numArray[4];
	int i;
	int result;
	splitIntToArray(num, numArray);
	leftLoop4int(numArray, 1);//字循环
	
	//字节代换
	for(i = 0; i < 4; i++)
		numArray[i] = getNumFromSBox(numArray[i]);
	
	result = mergeArrayToInt(numArray);
	return result ^ Rcon[round];
}

//密钥对应的扩展数组
static unsigned int w[44]={0x5359434C, 0x4F564552, 0x5359434C, 0x4F564552,
	0xE33743C8, 0xAC61069A, 0xFF3845D6, 0xB06E0084,
	0x7E4BAF2F, 0xD22AA9B5, 0x2D12EC63, 0x9D7CECE7,
	0x6A1E3B71, 0xB83492C4, 0x95267EA7, 0x085A9240,
	0xDC513241, 0x6465A085, 0xF143DE22, 0xF9194C62,
	0x1878986C, 0x7C1D38E9, 0x8D5EE6CB, 0x7447AAA9,
	0x98D44BFE, 0xE4C97317, 0x699795DC, 0x1DD03F75,
	0xA8A1D65A, 0x4C68A54D, 0x25FF3091, 0x382F0FE4,
	0x3D0ABF5D, 0x71621A10, 0x549D2A81, 0x6CB22565,
	0x1135F20D, 0x6057E81D, 0x34CAC29C, 0x5878E7F9,
	0x9BA1DF67, 0xFBF6377A, 0xCF3CF5E6, 0x9744121F,};
/**
 * 打印W数组
 */
static void printW() {
	int i, j;
	for(i = 0, j = 1; i < 44; i++,j++){
		printf("w[%d] = 0x%x ", i, w[i]);
		if(j % 4 == 0)
			printf("\n");
	}
	printf("\n");
}


/**
 * 轮密钥加
 */
static void addRoundKey(int array[4][4], int round) {
	int warray[4];
	int i,j;
	for(i = 0; i < 4; i++) {
		
		splitIntToArray(w[ round * 4 + i], warray);
		
		for(j = 0; j < 4; j++) {
			array[j][i] = array[j][i] ^ warray[j];
		}
	}
}

static int GFMul2(int s) {
	int result = s << 1;
	int a7 = result & 0x00000100;
	
	if(a7 != 0) {
		result = result & 0x000000ff;
		result = result ^ 0x1b;
	}
	
	return result;
}

static int GFMul3(int s) {
	return GFMul2(s) ^ s;
}

static int GFMul4(int s) {
	return GFMul2(GFMul2(s));
}

static int GFMul8(int s) {
	return GFMul2(GFMul4(s));
}

static int GFMul9(int s) {
	return GFMul8(s) ^ s;
}

static int GFMul11(int s) {
	return GFMul9(s) ^ GFMul2(s);
}

static int GFMul12(int s) {
	return GFMul8(s) ^ GFMul4(s);
}

static int GFMul13(int s) {
	return GFMul12(s) ^ s;
}

static int GFMul14(int s) {
	return GFMul12(s) ^ GFMul2(s);
}

/**
 * GF上的二元运算
 */
static int GFMul(int n, int s) {
	int result;
	
	if(n == 1)
		result = s;
	else if(n == 2)
		result = GFMul2(s);
	else if(n == 3)
		result = GFMul3(s);
	else if(n == 0x9)
		result = GFMul9(s);
	else if(n == 0xb)//11
		result = GFMul11(s);
	else if(n == 0xd)//13
		result = GFMul13(s);
	else if(n == 0xe)//14
		result = GFMul14(s);
	
	return result;
}
/**
 * 把4X4数组转回字符串
 */
static void convertArrayToStr(int array[4][4], char *str) {
	int i,j;
	for(i = 0; i < 4; i++)
		for(j = 0; j < 4; j++)
			*str++ = (char)array[j][i];
}
/**
 * 检查密钥长度
 */
static int checkKeyLen(int len) {
	if(len == 16)
		return 1;
	else
		return 0;
}


/**
 * 参数 p: 明文的字符串数组。
 * 参数 plen: 明文的长度。
 * 参数 key: 密钥的字符串数组。
 *
 * 根据索引从逆S盒中获取值
 */
static int getNumFromS1Box(int index) {
	int row = getLeft4Bit(index);
	int col = getRight4Bit(index);
	return S2[row][col];
}
/**
 * 逆字节变换
 */
static void deSubBytes(int array[4][4]) {
	int i,j;
	for(i = 0; i < 4; i++)
		for(j = 0; j < 4; j++)
			array[i][j] = getNumFromS1Box(array[i][j]);
}
/**
 * 把4个元素的数组循环右移step位
 */
static void rightLoop4int(int array[4], int step) {
	int temp[4];
	int i;
	int index;
	for(i = 0; i < 4; i++)
		temp[i] = array[i];
	
	index = step % 4 == 0 ? 0 : step % 4;
	index = 3 - index;
	for(i = 3; i >= 0; i--) {
		array[i] = temp[index];
		index--;
		index = index == -1 ? 3 : index;
	}
}

/**
 * 逆行移位
 */
static void deShiftRows(int array[4][4]) {
	int rowTwo[4], rowThree[4], rowFour[4];
	int i;
	for(i = 0; i < 4; i++) {
		rowTwo[i] = array[1][i];
		rowThree[i] = array[2][i];
		rowFour[i] = array[3][i];
	}
	
	rightLoop4int(rowTwo, 1);
	rightLoop4int(rowThree, 2);
	rightLoop4int(rowFour, 3);
	
	for(i = 0; i < 4; i++) {
		array[1][i] = rowTwo[i];
		array[2][i] = rowThree[i];
		array[3][i] = rowFour[i];
	}
	
}
/**
 * 逆列混合用到的矩阵
 */
static const int deColM[4][4] = { 0xe, 0xb, 0xd, 0x9,
	0x9, 0xe, 0xb, 0xd,
	0xd, 0x9, 0xe, 0xb,
	0xb, 0xd, 0x9, 0xe };

/**
 * 逆列混合
 */
static void deMixColumns(int array[4][4]) {
	int tempArray[4][4];
	int i,j;
	for(i = 0; i < 4; i++)
		for(j = 0; j < 4; j++)
			tempArray[i][j] = array[i][j];
	
	for(i = 0; i < 4; i++)
		for(j = 0; j < 4; j++){
		array[i][j] = GFMul(deColM[i][0],tempArray[0][j]) ^ GFMul(deColM[i][1],tempArray[1][j])
		^ GFMul(deColM[i][2],tempArray[2][j]) ^ GFMul(deColM[i][3], tempArray[3][j]);
	}
}
/**
 * 把两个4X4数组进行异或
 */
static void addRoundTowArray(int aArray[4][4],int bArray[4][4]) {
	int i,j;
	for(i = 0; i < 4; i++)
		for(j = 0; j < 4; j++)
			aArray[i][j] = aArray[i][j] ^ bArray[i][j];
}
/**
 * 从4个32位的密钥字中获得4X4数组,
 * 用于进行逆列混合
 */
static void getArrayFrom4W(int i, int array[4][4]) {
	int index,j;
	int colOne[4], colTwo[4], colThree[4], colFour[4];
	index = i * 4;
	splitIntToArray(w[index], colOne);
	splitIntToArray(w[index + 1], colTwo);
	splitIntToArray(w[index + 2], colThree);
	splitIntToArray(w[index + 3], colFour);
	
	for(j = 0; j < 4; j++) {
		array[j][0] = colOne[j];
		array[j][1] = colTwo[j];
		array[j][2] = colThree[j];
		array[j][3] = colFour[j];
	}
	
}

/**
 * 参数 c: 密文的字符串数组。
 * 参数 clen: 密文的长度。
 * 参数 key: 密钥的字符串数组。
 */
void deAes(char *c, int clen, char *key) {
	
	int cArray[4][4];
	int keylen,k;
	keylen = strlen(key);
	if(clen == 0 || clen % 16 != 0) {
		printf("密文字符长度必须为16的倍数!现在的长度为%d\n",clen);
		exit(0);
	}
	
	if(!checkKeyLen(keylen)) {
		printf("密钥字符长度错误!长度必须为16、24和32。当前长度为%d\n",keylen);
		exit(0);
	}
	
	//extendKey(key);//扩展密钥
	/*
	  
	  1.修改密钥扩展
	  2.修改s盒
	  3.修改行位移
	  
	 */
	for(k = 0; k < clen; k += 16) {
		int i;
		int wArray[4][4];
		
		convertToIntArray(c + k, cArray);
		addRoundKey(cArray, 10);
		
		for(i = 9; i >= 1; i--) {
			deSubBytes(cArray);
			
			deShiftRows(cArray);
			
			deMixColumns(cArray);
			getArrayFrom4W(i, wArray);
			deMixColumns(wArray);
			
			addRoundTowArray(cArray, wArray);
		}
		
		deSubBytes(cArray);
		
		deShiftRows(cArray);
		
		addRoundKey(cArray, 0);
		
		convertArrayToStr(cArray, c + k);
		
	}
}
unsigned char ciphertext[] =
{
	0x99, 0xE8, 0xB8, 0x01, 0xC8, 0x82, 0x51, 0x93, 0x12, 0xEE, 
	0x89, 0x64, 0xE7, 0xEF, 0x63, 0x8D, 0x51, 0xDF, 0x5D, 0x78, 
	0x39, 0xAA, 0x39, 0x62, 0xA0, 0xB4, 0x50, 0x30, 0x47, 0x30, 
	0x21, 0x06
};
int main() {
	// 加密, 其中plain是明文字符数组, len是长度, key是密钥
//	aes(plain, len, key);
	//解密,其中ciphertext是密文字符数组, len是长度, key是密钥
	char key[]={"SYCLOVERSYCLOVER"};
	deAes((char *)ciphertext, 32, key);
	printf("%s",ciphertext);
}

//SYC{B3l1eue_Th@t_y0u__l3aRn_Aes}

致我的星星

html逆向

分析js代码,定位到关键验证代码

image-20241120155319406

整体看下来就是获取用户键值,并渲染对应画面以及播放音乐,并将键值拼接成一个字符串,当其md5值等于目标值时渲染最终画面以及播放音乐

再往下看以及结合刚进入页面弹出的输入框不难分析出这是一道迷宫题,正确的输入就是迷宫的走法

image-20241120155730347

再往下看到了方程组,结合控制台输出以及之后的代码,不难确定这是在给特点的坐标“赋值”,也就是确定起点和终点

image-20241120155759489

第一步就是求解方程组拿到起点和终点

exp1:

from z3 import *
#使用z3求解a1-a8
a1, a2, a3, a4, a5, a6, a7, a8 = Ints('a1 a2 a3 a4 a5 a6 a7 a8')
s = Solver()

s.add(43654*a1 - 57003*a2 -3158*a3 + 30120*a4 -58621*a5 -41947*a6 +122237*a7 +129534*a8 == 2594143,
-48022*a1 + 18308*a2 + 52478*a3 + 69397*a4  +49696*a5 + 12288*a6 -40437*a7 -23154*a8 ==  651137,
124109*a1  +58952*a2 + 16645*a3 -17531*a4 + 53139*a5  +49937*a6  + 3282*a7   +7656*a8 == 2071815,
108286*a1 + 118886*a2 +116876*a3   +2281*a4 -64590*a5  -3021*a6 + 13386*a7 -56070*a8 ==  703,
105983*a1 + 8794*a2 + 31851*a3 -35052*a4  -7880*a5  + 2183*a6 + 47575*a7 +107236*a8 == 2511919,
-38005*a1 -6833*a2 +107897*a3 +119771*a4 +124322*a5 + 13335*a6+ 121590*a7 -17434*a8 == 4816084,
60696*a1 +95253*a2 +101581*a3 + 93822*a4 +112989*a5  +65643*a6  +45639*a7 + 26705*a8 == 5330538,
49019*a1 +72343*a2 -21814*a3  +85020*a4 -62332*a5  +99828*a6  +  587*a7 -65119*a8 ==  505173)

print(s.check())
if s.check() == sat:
    model = s.model()
    print([(a, model[a]) for a in [a1, a2, a3, a4, a5, a6, a7, a8]])
else:
    print("No solution found")
#[(a1, 3), (a2, 4), (a3, 6), (a4, 8), (a5, 13), (a6, 13), (a7, 15), (a8, 15)]

确定了'S'和'Y'的位置

继续往下

image-20241120160119018

locate1()在构造初始地图,后面的left、right、down、up等就是相应的左、右、下、上

最后一部分

image-20241120160236972

走迷宫逻辑

S,T,A,R分别对应左右下上

**注意:这里的chance值会随循环由0变成1,结合前面的row=20,col=10以及地图构造和移动函数的内部逻辑:100*chance,推断出实际上有两个10x10的地图 **

那么第二步就是构造迷宫图

exp2:

#include<stdio.h>

char data[] = {
	'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#',
	'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#',
	'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#',
	'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#',
	'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#',
	'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#',
	'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#',
	'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#',
	'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#',
	'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'
	};
int coordinates[][2] = {
	{1, 11}, {1, 12}, {1, 13}, {1, 14},
	{2, 1}, {2, 4}, {2, 11}, {2, 12}, {2, 14},
	{3, 4}, {3, 14},
	{5, 7}, {5, 8}, {5, 12}, {5, 14}, {5, 15}, {5, 18},
	{6, 1}, {6, 2}, {6, 4}, {6, 5}, {6, 7}, {6, 8}, {6, 11}, {6, 15},
	{7, 1}, {7, 5}, {7, 11}, {7, 12}, {7, 13}, {7, 14}, {7, 15}, {7, 16},
	{8, 1}, {8, 12}, {8, 13}, {8, 15}, {8, 18},
	{9, 3}, {9, 4}, {9, 6}, {9, 7}, {9, 8}
};
int main(){
	int rows = 10, cols = 20;
	int row,col,index;
	int num_coordinates = sizeof(coordinates) / sizeof(coordinates[0]);
	// 修改 data 中对应坐标的元素
	for (int i = 0; i < num_coordinates; i++) {
		row = coordinates[i][0];
		col = coordinates[i][1];
		index = row * cols + col; // 将二维坐标转换为一维索引
		data[index] = '*';
	}
	
	
	int a1=3-1,a2=4-1,a3=6-1,a4=8-1,a5=13-1,a6=13-1,a7=15-1,a8=15-1;
	//S:(a1,a6) (a4,a5):(3,13),(8,13) 
	//Y:(a2,a8) (a3,a7):(4,15),(6,15)
	data[a1*20+a6]='S';
	data[a4*20+a5]='S';
	data[a2*20+a8]='Y';
	data[a3*20+a7]='Y';
	// 输出修改后的 data 数组(以矩阵形式打印)
	for (int i = 0; i < 10; i++) {
		for (int j = 0; j < 10; j++) {
			printf("%c ", data[i * 10 + j]);
		}
		printf("\n");
	}
	printf("----------------------------------------\n");
	for (int i = 0; i < 10; i++) {
		for (int j = 0; j < 10; j++) {
			printf("%c ", data[100+i * 10 + j]);
		}
		printf("\n");
	}
	return 0;
}

拿到地图

image-20241120160908103

路径1:STTAAARRRR

路径2:AAATTTTS

一起输入,最终画面(小震撼,出题人NB)

image-20241120161210327

SYC{STTAAARRRRAAATTTTS}

LinkedListModular

知识点:常规逆向,RSA

re crypto交叉题,ELF文件,ida分析

定位到main,

image-20241120161426805

输入一个长度为256位的字符串,然后check,核心就是check了,点进去分析

check()里面主要是利用c的gmp库进行大数运算,无脑读代码

image-20241120161527373

逻辑就是将明文m分为4组,每组64个字符进行了一系列加密

输出给了"p q e c"各自每一位十六进制异或key[i]的结果

exp0:还原每一组对应的p q e c

v7=[0x39,0x71,0x5e,0x17,0x16,0x3c,0x5e,0x10,0x75,0x5f,0x0a,0x50,0x73,0x43,0x1b,0x40,0x47,0x59,0x79,0x29,0x0a,0x56,0x14,0x38,0x5b,0x47,0x7f,0x0f,0x59,0x01,0x7a,0x41,0x4f,0x46,0x11,0x58,0x2a,0x7b,0x5f,0x0c,0x42,0x6f,0x0a,0x47,0x28,0x59,0x59,0x01,0x27,0x40,0x49,0x15,0x12,0x09,0x2a,0x7f,0x0d,0x5d,0x4e,0x69,0x0a,0x4d,0x2e,0x0b,0x0f,0x57,0x20,0x11,0x4c,0x43,0x16,0x0d,0x7b,0x2a,0x58,0x5a,0x15,0x6c,0x5d,0x43,0x7e,0x0c,0x59,0x50,0x77,0x46,0x48,0x48,0x10,0x58,0x79,0x7d,0x5d,0x5c,0x42,0x6e,0x5f,0x4d,0x29,0x0b,0x0f,0x52,0x72,0x41,0x1a,0x16,0x4d,0x09,0x28,0x28,0x5e,0x5b,0x11,0x3b,0x5e,0x47,0x7c,0x50,0x0f,0x53,0x75,0x44,0x18,0x14,0x17,0x59,0x2c,0x29,0x0c,0x59,0x11,0x3c,0x0a,0x4d,0x2f,0x50,0x5c,0x04,0x7b,0x16,0x1d,0x15,0x40,0x0c,0x7b,0x78,0x0a,0x5c,0x40,0x69,0x5b,0x44,0x75,0x51,0x0d,0x5c,0x72,0x4a,0x1d,0x15,0x40,0x59,0x2f,0x2e,0x58,0x56,0x16,0x69,0x0b,0x41,0x28,0x5e,0x53,0x52,0x7b,0x41,0x4d,0x41,0x17,0x5d,0x7c,0x7a,0x5f,0x57,0x12,0x6e,0x0b,0x44,0x2d,0x0a,0x58,0x53,0x7b,0x45,0x4c,0x43,0x17,0x0a,0x7d,0x7e,0x08,0x58,0x40,0x3b,0x59,0x41,0x79,0x51,0x5b,0x00,0x73,0x13,0x41,0x49,0x11,0x5c,0x79,0x7b,0x0f,0x0c,0x4f,0x3f,0x5e,0x17,0x29,0x5e,0x5e,0x01,0x70,0x13,0x49,0x40,0x45,0x0b,0x2f,0x79,0x58,0x0d,0x14,0x3f,0x0b,0x14,0x2a,0x51,0x59,0x04,0x77,0x45,0x40,0x15,0x45,0x5b,0x2f,0x7d,0x08,0x5d,0x42,0x3b,0x09,0x17,0x6c,0x18,0x51,0x55,0x3b,0x11,0x1f,0x13,0x47,0x5c,0x7e,0x2e,0x57,0x5d,0x46,0x6e,0x5a,0x41,0x79,0x0d,0x5b,0x54,0x21,0x13,0x1b,0x12,0x44,0x5f,0x2a,0x78,0x5d,0x5f,0x40,0x6d,0x58,0x14,0x29,0x0d,0x5f,0x00,0x75,0x16,0x40,0x49,0x10,0x09,0x7d,0x79,0x56,0x56,0x45,0x3b,0x09,0x13,0x2f,0x0c,0x58,0x5d,0x26,0x4b,0x1b,0x45,0x17,0x57,0x28,0x73,0x57,0x0b,0x47,0x6c,0x5d,0x4d,0x2d,0x5e,0x0f,0x04,0x22,0x11,0x41,0x14,0x44,0x5f,0x7e,0x7e,0x0a,0x58,0x45,0x61,0x5e,0x46,0x7a,0x5f,0x52,0x07,0x20,0x41,0x4a,0x42,0x42,0x57,0x71,0x28,0x57,0x09,0x41,0x3d,0x09,0x47,0x7b,0x50,0x58,0x07,0x70,0x4b,0x4a,0x45,0x4c,0x5f,0x28,0x28,0x59,0x5e,0x11,0x69,0x5a,0x11,0x2e,0x58,0x5e,0x5c,0x26,0x40,0x1d,0x15,0x11,0x5c,0x28,0x7d,0x08,0x0b,0x44,0x6d,0x0c,0x14,0x7e,0x0b,0x0a,0x50,0x20,0x11,0x18,0x15,0x4c,0x5b,0x7b,0x73,0x0b,0x09,0x12,0x3f,0x0b,0x43,0x29,0x0c,0x5e,0x51,0x76,0x46,0x1b,0x46,0x43,0x5a,0x78,0x28,0x0f,0x58,0x46,0x3a,0x5f,0x45,0x74,0x5d,0x5d,0x5d,0x71,0x45,0x41,0x14,0x43,0x09,0x2c,0x72,0x5f,0x5e,0x12,0x61,0x0c,0x47,0x75,0x5b,0x5a,0x52,0x71,0x14,0x18,0x47,0x43,0x5b,0x7f,0x73,0x0b,0x56,0x4e,0x6f,0x0b,0x4d,0x7c,0x0f,0x5f,0x53,0x75,0x43,0x1a,0x42,0x40,0x0c,0x2a,0x2f,0x0d,0x0c,0x40,0x6f,0x0c,0x43,0x79,0x5c,0x0a,0x5c,0x72,0x44,0x41,0x12,0x44,0x0a,0x2d,0x2e,0x0b,0x0b,0x46,0x6f,0x5a,0x17,0x7e,0x0d,0x0f,0x5d,0x7a,0x47,0x49,0x41,0x16,0x4f,0x2c,0x71,0x5e,0x17,0x13,0x6a,0x5d,0x47,0x6c,0x0a,0x51,0x55,0x3b,0x44,0x1f,0x42,0x47,0x0b,0x2a,0x7d,0x5d,0x5c,0x40,0x6d,0x59,0x10,0x2f,0x0d,0x5d,0x03,0x75,0x10,0x4f,0x13,0x43,0x5a,0x7a,0x7e,0x5b,0x59,0x16,0x60,0x59,0x4c,0x28,0x0c,0x0f,0x52,0x25,0x4b,0x49,0x43,0x47,0x0d,0x7e,0x7d,0x5f,0x58,0x13,0x6d,0x5b,0x4c,0x7b,0x0b,0x58,0x04,0x70,0x13,0x1a,0x46,0x4c,0x5a,0x2b,0x72,0x5c,0x5f,0x41,0x6a,0x0a,0x41,0x7e,0x0a,0x5e,0x53,0x76,0x45,0x18,0x40,0x45,0x59,0x79,0x7f,0x0b,0x0b,0x47,0x61,0x5b,0x45,0x7f,0x5c,0x5d,0x56,0x74,0x46,0x4d,0x40,0x4c,0x57,0x70,0x29,0x0a,0x59,0x4f,0x6f,0x5a,0x41,0x78,0x50,0x5b,0x57,0x72,0x13,0x48,0x45,0x10,0x09,0x28,0x78,0x5d,0x0a,0x13,0x6b,0x0b,0x4c,0x79,0x5a,0x5a,0x03,0x76,0x42,0x1a,0x44,0x45,0x0b,0x7d,0x7e,0x5c,0x0b,0x11,0x6e,0x5c,0x4c,0x75,0x5c,0x5e,0x51,0x22,0x41,0x4c,0x16,0x40,0x5c,0x7d,0x7b,0x57,0x56,0x44,0x3d,0x59,0x41,0x2f,0x50,0x0e,0x54,0x20,0x45,0x1b,0x45,0x40,0x57,0x70,0x7f,0x0a,0x5d,0x4e,0x68,0x0d,0x46,0x7f,0x08,0x08,0x5c,0x76,0x10,0x4a,0x49,0x43,0x5e,0x70,0x7b,0x57,0x5c,0x13,0x6e,0x57,0x4d,0x2d,0x58,0x0f,0x57,0x72,0x4a,0x1f,0x45,0x40,0x09,0x79,0x7b,0x5a,0x56,0x43,0x60,0x56,0x45,0x2a,0x51,0x0a,0x03,0x25,0x41,0x1d,0x40,0x4d,0x0a,0x7b,0x7a,0x0b,0x0b,0x16,0x3c,0x5d,0x44,0x7b,0x5b,0x08,0x01,0x7b,0x10,0x4d,0x42,0x15,0x0a,0x7f,0x2d,0x56,0x0e,0x15,0x3f,0x0b,0x17,0x7c,0x5c,0x0e,0x50,0x27,0x4b,0x18,0x46,0x12,0x09,0x7d,0x29,0x5b,0x5f,0x4e,0x6b,0x09,0x43,0x7c,0x0f,0x53,0x06,0x26,0x40,0x18,0x45,0x43,0x59,0x2c,0x7f,0x5c,0x56,0x16,0x61,0x5f,0x17,0x28,0x58,0x5e,0x03,0x20,0x45,0x49,0x47,0x47,0x0b,0x7e,0x7e,0x5a,0x5e,0x42,0x3a,0x57,0x47,0x78,0x0f,0x08,0x51,0x76,0x42,0x18,0x49,0x46,0x56,0x7c,0x7a,0x5c,0x57,0x12,0x6a,0x5f,0x4d,0x7c,0x5d,0x5c,0x53,0x73,0x43,0x4e,0x49,0x16,0x0c,0x7a,0x79,0x5f,0x5c,0x16,0x3d,0x0a,0x44,0x7d,0x5b,0x5a,0x01,0x75,0x43,0x4c,0x16,0x43,0x0a,0x2b,0x29,0x08,0x5e,0x4e,0x6b,0x09,0x4c,0x7f,0x0d,0x0f,0x57,0x76,0x42,0x4a,0x41,0x10,0x0a,0x78,0x79,0x0b,0x5e,0x45,0x3c,0x5e,0x40,0x2d,0x0c,0x5a,0x5d,0x7a,0x16,0x1b,0x45,0x46,0x5a,0x2d,0x2f,0x0c,0x0b,0x11,0x3b,0x5d,0x13,0x79,0x5d,0x0d,0x55,0x7a,0x4a,0x1a,0x40,0x15,0x5f,0x7b,0x7c,0x0c,0x59,0x15,0x68,0x5d,0x42,0x7b,0x0a,0x59,0x57,0x72,0x42,0x41,0x14,0x12,0x0b,0x7b,0x7d,0x57,0x56,0x11,0x6e,0x56,0x41,0x7a,0x0a,0x0e,0x50,0x72,0x14,0x48,0x13,0x43,0x5c,0x28,0x7c,0x56,0x58,0x45,0x68,0x57,0x4c,0x7a,0x0b,0x0f,0x5d,0x21,0x13,0x18,0x43,0x16,0x58,0x2f,0x2a,0x5a,0x0b,0x11,0x3a,0x5f,0x43,0x7f,0x08,0x09,0x57,0x72,0x40,0x1c,0x12,0x44,0x59,0x71,0x7f,0x5b,0x5c,0x46,0x3f,0x5c,0x42,0x7e,0x0f,0x59,0x00,0x27,0x11,0x4e,0x12,0x45,0x09,0x7e,0x29,0x0f,0x0e,0x44,0x6a,0x5a,0x46,0x2e,0x5c,0x5e,0x06,0x20,0x45,0x4c,0x40,0x16,0x56,0x7c,0x2d,0x08,]
v8=[0x39,0x71,0x5e,0x17,0x40,0x38,0x58,0x17,0x74,0x0c,0x0e,0x52,0x71,0x16,0x4d,0x46,0x43,0x0a,0x2c,0x2d,0x0b,0x5c,0x40,0x61,0x5a,0x45,0x7e,0x0a,0x0a,0x52,0x7b,0x42,0x4d,0x15,0x44,0x0d,0x7c,0x7e,0x0b,0x5f,0x15,0x6f,0x57,0x4c,0x74,0x5e,0x0f,0x01,0x74,0x17,0x41,0x13,0x44,0x5c,0x2f,0x7c,0x08,0x58,0x11,0x6e,0x5e,0x42,0x79,0x5c,0x5f,0x54,0x7b,0x41,0x1d,0x42,0x15,0x5f,0x2d,0x72,0x57,0x0c,0x40,0x3b,0x5c,0x46,0x29,0x51,0x0e,0x54,0x22,0x40,0x41,0x12,0x11,0x5e,0x7e,0x7a,0x0c,0x58,0x40,0x3f,0x57,0x4c,0x7b,0x5d,0x5d,0x54,0x75,0x13,0x1a,0x44,0x4d,0x59,0x7d,0x7e,0x0a,0x58,0x13,0x6c,0x0c,0x13,0x7a,0x0f,0x0e,0x50,0x25,0x46,0x1d,0x13,0x16,0x09,0x2d,0x7a,0x0a,0x5d,0x42,0x3a,0x5c,0x14,0x28,0x5e,0x5e,0x00,0x72,0x17,0x1b,0x43,0x11,0x5b,0x79,0x78,0x56,0x0b,0x42,0x6c,0x0e,0x47,0x75,0x0a,0x5c,0x54,0x72,0x46,0x1c,0x41,0x43,0x59,0x2f,0x2f,0x5d,0x5b,0x41,0x6b,0x59,0x16,0x7e,0x08,0x53,0x00,0x74,0x44,0x49,0x42,0x45,0x0b,0x79,0x7c,0x57,0x0c,0x13,0x3b,0x57,0x40,0x2f,0x0a,0x53,0x55,0x72,0x44,0x18,0x13,0x15,0x0d,0x79,0x7b,0x5e,0x5b,0x40,0x60,0x5e,0x45,0x28,0x0f,0x0a,0x50,0x20,0x16,0x49,0x44,0x47,0x56,0x28,0x78,0x0d,0x0c,0x46,0x6a,0x5a,0x47,0x7b,0x5c,0x5e,0x52,0x26,0x13,0x41,0x47,0x4d,0x0c,0x78,0x73,0x5a,0x5b,0x42,0x6d,0x0e,0x41,0x78,0x5a,0x5c,0x54,0x72,0x42,0x41,0x43,0x15,0x5b,0x2f,0x72,0x0a,0x5e,0x13,0x6d,0x59,0x17,0x6c,0x18,0x51,0x55,0x3b,0x11,0x48,0x47,0x17,0x58,0x28,0x7c,0x08,0x0d,0x14,0x6c,0x5b,0x43,0x75,0x08,0x0d,0x51,0x72,0x41,0x1f,0x47,0x4d,0x0c,0x79,0x7c,0x0d,0x0c,0x42,0x3b,0x57,0x4c,0x7e,0x0a,0x0d,0x07,0x21,0x13,0x18,0x40,0x44,0x56,0x7c,0x7b,0x0c,0x5e,0x46,0x6c,0x0a,0x47,0x7a,0x5e,0x0e,0x5d,0x70,0x17,0x4b,0x46,0x42,0x56,0x2f,0x78,0x08,0x59,0x40,0x6e,0x56,0x16,0x7b,0x5a,0x5b,0x57,0x26,0x11,0x1f,0x13,0x4d,0x09,0x71,0x7e,0x5e,0x0a,0x47,0x3c,0x5b,0x44,0x74,0x5c,0x53,0x5c,0x71,0x17,0x40,0x46,0x10,0x5c,0x7c,0x7d,0x0a,0x59,0x42,0x3b,0x5e,0x11,0x7f,0x5e,0x59,0x51,0x70,0x40,0x1a,0x45,0x15,0x5c,0x2f,0x79,0x57,0x58,0x14,0x3f,0x0d,0x4d,0x7f,0x5e,0x58,0x03,0x26,0x4b,0x18,0x40,0x4d,0x5f,0x28,0x78,0x08,0x57,0x13,0x38,0x0b,0x13,0x7a,0x0c,0x0d,0x53,0x25,0x40,0x1a,0x11,0x41,0x0d,0x7c,0x7a,0x5e,0x58,0x43,0x6c,0x5b,0x10,0x29,0x5f,0x09,0x54,0x70,0x4a,0x4c,0x14,0x45,0x59,0x7c,0x29,0x0c,0x5b,0x15,0x3b,0x58,0x42,0x7b,0x5f,0x08,0x07,0x21,0x11,0x1a,0x12,0x4c,0x0b,0x2c,0x7a,0x57,0x56,0x44,0x38,0x5a,0x10,0x2e,0x0b,0x58,0x51,0x26,0x17,0x4a,0x46,0x41,0x09,0x2f,0x78,0x57,0x0d,0x4e,0x3c,0x0c,0x4c,0x7a,0x58,0x58,0x54,0x71,0x43,0x1b,0x11,0x4d,0x56,0x2d,0x7c,0x5a,0x58,0x42,0x60,0x0a,0x45,0x2e,0x0f,0x53,0x55,0x74,0x40,0x4f,0x48,0x44,0x5a,0x2a,0x2e,0x5e,0x5c,0x12,0x3d,0x58,0x13,0x7d,0x0c,0x5f,0x5c,0x70,0x45,0x4c,0x16,0x45,0x4f,0x2c,0x71,0x5e,0x17,0x46,0x69,0x0e,0x10,0x6c,0x0a,0x51,0x55,0x3b,0x47,0x1b,0x15,0x44,0x0b,0x2f,0x78,0x0c,0x0d,0x45,0x6d,0x5f,0x13,0x2a,0x0d,0x5e,0x56,0x25,0x40,0x1d,0x49,0x45,0x5b,0x2c,0x29,0x59,0x56,0x4f,0x6e,0x57,0x47,0x7f,0x58,0x53,0x57,0x72,0x13,0x48,0x14,0x16,0x0e,0x7c,0x28,0x0d,0x5b,0x4e,0x68,0x0e,0x4d,0x74,0x51,0x08,0x5d,0x25,0x16,0x4c,0x45,0x47,0x0e,0x70,0x7b,0x5b,0x0e,0x40,0x3f,0x5e,0x16,0x29,0x08,0x59,0x52,0x76,0x42,0x1a,0x43,0x4d,0x0a,0x28,0x7f,0x56,0x0e,0x15,0x6d,0x5e,0x42,0x79,0x58,0x5a,0x50,0x76,0x4b,0x48,0x43,0x45,0x5f,0x2a,0x7b,0x08,0x56,0x13,0x6f,0x5c,0x10,0x7d,0x08,0x0e,0x00,0x7a,0x16,0x4b,0x44,0x4c,0x5f,0x7e,0x73,0x5e,0x09,0x44,0x3a,0x0a,0x41,0x2a,0x50,0x53,0x06,0x76,0x45,0x48,0x41,0x40,0x0c,0x2d,0x79,0x57,0x5f,0x46,0x3c,0x0e,0x43,0x2a,0x5c,0x5d,0x55,0x26,0x42,0x4d,0x11,0x44,0x0e,0x70,0x28,0x0b,0x0c,0x46,0x6c,0x58,0x11,0x2d,0x0a,0x58,0x01,0x26,0x14,0x4e,0x43,0x40,0x09,0x28,0x7a,0x5e,0x0e,0x15,0x6c,0x5b,0x16,0x7e,0x5e,0x09,0x03,0x71,0x42,0x4b,0x41,0x45,0x0c,0x2f,0x7a,0x08,0x5e,0x11,0x6f,0x09,0x43,0x2d,0x0f,0x0e,0x50,0x25,0x11,0x40,0x15,0x12,0x5a,0x2a,0x72,0x0f,0x09,0x4f,0x6f,0x5b,0x13,0x7c,0x5c,0x5f,0x04,0x76,0x17,0x4f,0x41,0x17,0x5b,0x71,0x28,0x58,0x0a,0x41,0x3d,0x0c,0x45,0x74,0x5e,0x08,0x06,0x70,0x47,0x49,0x40,0x44,0x57,0x2d,0x7f,0x5c,0x5c,0x45,0x3d,0x5f,0x4d,0x2e,0x59,0x09,0x50,0x73,0x43,0x48,0x49,0x46,0x5c,0x2f,0x7a,0x5e,0x58,0x40,0x3c,0x0e,0x11,0x7b,0x5c,0x0f,0x50,0x77,0x13,0x4e,0x49,0x46,0x0e,0x28,0x73,0x0f,0x5a,0x46,0x38,0x5f,0x17,0x7f,0x5e,0x09,0x03,0x22,0x41,0x1f,0x11,0x11,0x09,0x79,0x29,0x57,0x5c,0x4f,0x69,0x0c,0x13,0x2a,0x5b,0x5b,0x5c,0x20,0x45,0x1b,0x16,0x47,0x0e,0x7b,0x7b,0x08,0x0d,0x15,0x3b,0x5f,0x4d,0x7b,0x0a,0x0a,0x03,0x72,0x45,0x4e,0x12,0x4c,0x5c,0x2a,0x72,0x0c,0x09,0x47,0x6a,0x0a,0x4c,0x7a,0x5c,0x09,0x01,0x74,0x41,0x4d,0x47,0x10,0x0b,0x78,0x73,0x5a,0x5e,0x4f,0x3f,0x5c,0x10,0x79,0x59,0x0a,0x00,0x25,0x40,0x40,0x13,0x17,0x57,0x70,0x2d,0x0f,0x5a,0x4e,0x6d,0x0c,0x16,0x28,0x5a,0x5a,0x07,0x75,0x14,0x4f,0x43,0x12,0x5c,0x70,0x7c,0x0b,0x0a,0x15,0x38,0x58,0x44,0x7a,0x5b,0x52,0x03,0x26,0x11,0x4b,0x13,0x4c,0x59,0x70,0x72,0x5f,0x5b,0x4f,0x3d,0x09,0x11,0x7a,0x0b,0x0e,0x56,0x71,0x16,0x1c,0x12,0x4d,0x59,0x7c,0x7c,0x59,0x59,0x4e,0x69,0x57,0x44,0x78,0x0b,0x09,0x51,0x25,0x17,0x4f,0x14,0x16,0x0a,0x2f,0x2e,0x5c,0x5c,0x40,0x60,0x5b,0x43,0x74,0x0c,0x5b,0x00,0x70,0x43,0x4e,0x11,0x4c,0x58,0x79,0x7c,0x57,0x5a,0x15,0x38,0x5f,0x41,0x2d,0x0b,0x59,0x00,0x70,0x42,0x4f,0x16,0x11,0x5a,0x7a,0x7f,0x5e,0x58,0x47,0x69,0x0c,0x41,0x7d,0x5c,0x5b,0x51,0x7b,0x17,0x1f,0x16,0x41,0x56,0x79,0x72,0x0f,0x5d,0x43,0x6c,0x5c,0x42,0x79,0x5b,0x53,0x51,0x76,0x47,0x4e,0x42,0x15,0x5f,0x70,0x78,0x5f,]
v9=[0x39,0x71,0x5e,0x17,0x16,0x6b,0x5a,0x43,0x7e,0x0b,0x5e,0x56,0x21,0x43,0x1f,0x16,0x4c,0x0d,0x70,0x7d,0x5d,0x5a,0x46,0x6b,0x5d,0x16,0x75,0x5b,0x5d,0x54,0x71,0x16,0x41,0x12,0x42,0x0a,0x28,0x7f,0x5d,0x0e,0x14,0x69,0x0a,0x41,0x7c,0x58,0x5a,0x50,0x20,0x42,0x4a,0x12,0x11,0x09,0x2a,0x7b,0x08,0x0d,0x46,0x3b,0x0b,0x10,0x2a,0x0a,0x0f,0x04,0x70,0x47,0x18,0x47,0x43,0x09,0x78,0x28,0x08,0x5d,0x44,0x3c,0x5a,0x13,0x28,0x0f,0x0a,0x50,0x72,0x17,0x1c,0x48,0x42,0x5b,0x2d,0x2a,0x0d,0x58,0x47,0x6e,0x5a,0x47,0x78,0x5c,0x53,0x51,0x20,0x14,0x4d,0x42,0x40,0x5c,0x2a,0x2a,0x0a,0x0a,0x44,0x6f,0x0a,0x14,0x7c,0x0b,0x59,0x06,0x26,0x43,0x4d,0x14,0x4d,0x5c,0x7a,0x7c,0x0a,0x58,0x4e,0x6f,0x09,0x4d,0x79,0x0b,0x5c,0x56,0x73,0x46,0x41,0x43,0x11,0x58,0x2b,0x7d,0x0b,0x5c,0x43,0x6b,0x0b,0x41,0x78,0x08,0x58,0x53,0x22,0x43,0x1b,0x13,0x40,0x5f,0x7c,0x79,0x5f,0x5d,0x42,0x3b,0x5b,0x10,0x2d,0x0c,0x0d,0x56,0x74,0x40,0x4d,0x11,0x12,0x56,0x2a,0x2d,0x0c,0x57,0x14,0x38,0x0d,0x42,0x7d,0x50,0x0f,0x5c,0x26,0x14,0x1a,0x45,0x40,0x0b,0x2f,0x73,0x5b,0x5e,0x47,0x6d,0x5d,0x41,0x7c,0x51,0x08,0x57,0x25,0x44,0x40,0x13,0x45,0x0a,0x7c,0x2d,0x5a,0x59,0x11,0x69,0x5f,0x13,0x7c,0x5f,0x5c,0x03,0x74,0x14,0x18,0x45,0x17,0x09,0x7e,0x2a,0x5d,0x0c,0x15,0x6b,0x5d,0x42,0x74,0x5e,0x52,0x06,0x21,0x16,0x1c,0x16,0x15,0x0c,0x7e,0x2e,0x0f,0x0d,0x41,0x3a,0x0b,0x46,0x6c,0x18,0x51,0x55,0x3b,0x14,0x1c,0x15,0x17,0x5e,0x7b,0x2f,0x5a,0x59,0x47,0x6b,0x0a,0x41,0x74,0x50,0x5e,0x03,0x76,0x41,0x4e,0x41,0x41,0x0b,0x7e,0x2e,0x5b,0x0e,0x40,0x6c,0x57,0x46,0x29,0x0c,0x52,0x56,0x20,0x46,0x40,0x40,0x43,0x56,0x7d,0x73,0x5e,0x0e,0x16,0x3d,0x0e,0x10,0x7d,0x5a,0x08,0x52,0x20,0x4b,0x1d,0x47,0x46,0x5f,0x28,0x7e,0x08,0x0b,0x4e,0x6e,0x59,0x17,0x7a,0x0b,0x52,0x04,0x20,0x47,0x1c,0x16,0x42,0x5a,0x7c,0x7c,0x5e,0x09,0x4e,0x3c,0x56,0x11,0x75,0x0b,0x5d,0x01,0x73,0x10,0x49,0x12,0x47,0x56,0x2f,0x7a,0x5d,0x58,0x45,0x3c,0x0e,0x4d,0x7d,0x50,0x09,0x06,0x72,0x46,0x1a,0x13,0x45,0x5f,0x28,0x7b,0x0f,0x5d,0x44,0x38,0x58,0x13,0x7e,0x5b,0x0d,0x53,0x73,0x11,0x48,0x11,0x40,0x09,0x2a,0x7e,0x5d,0x59,0x12,0x3b,0x0c,0x41,0x75,0x50,0x5c,0x07,0x21,0x4a,0x4e,0x43,0x10,0x0d,0x70,0x2f,0x56,0x0c,0x15,0x6a,0x5b,0x13,0x79,0x51,0x0d,0x00,0x20,0x40,0x18,0x40,0x41,0x0b,0x2a,0x7c,0x58,0x59,0x14,0x3b,0x57,0x43,0x79,0x0c,0x5b,0x5c,0x22,0x13,0x4f,0x13,0x45,0x0e,0x79,0x7e,0x57,0x58,0x46,0x6a,0x0c,0x16,0x2e,0x58,0x09,0x56,0x72,0x13,0x40,0x13,0x4d,0x57,0x7f,0x2e,0x0d,0x0b,0x43,0x3f,0x5b,0x40,0x28,0x0a,0x5e,0x56,0x20,0x4b,0x4c,0x15,0x47,0x5d,0x28,0x2e,0x58,0x0b,0x44,0x6e,0x5f,0x10,0x29,0x5a,0x5e,0x53,0x75,0x16,0x18,0x11,0x4c,0x0d,0x7c,0x2d,0x5b,0x0d,0x11,0x6f,0x09,0x10,0x79,0x0f,0x0a,0x57,0x73,0x11,0x1d,0x40,0x12,0x4f,0x2c,0x71,0x5e,0x17,0x14,0x69,0x5a,0x44,0x6c,0x0a,0x51,0x55,0x3b,0x13,0x4e,0x49,0x4c,0x0c,0x2b,0x7b,0x58,0x58,0x15,0x6e,0x5e,0x43,0x2d,0x0c,0x5a,0x56,0x7b,0x40,0x1d,0x42,0x44,0x58,0x79,0x2e,0x08,0x0d,0x4f,0x3b,0x0b,0x17,0x7b,0x58,0x5b,0x50,0x73,0x10,0x41,0x48,0x10,0x56,0x7c,0x7b,0x5d,0x0e,0x41,0x61,0x09,0x10,0x79,0x0c,0x53,0x50,0x72,0x4b,0x40,0x49,0x44,0x58,0x78,0x2e,0x5a,0x0a,0x12,0x60,0x09,0x42,0x7e,0x0a,0x53,0x5d,0x21,0x41,0x40,0x47,0x41,0x0b,0x2c,0x7b,0x57,0x0a,0x4f,0x3f,0x5b,0x46,0x7a,0x5c,0x5d,0x53,0x27,0x45,0x4c,0x16,0x4d,0x5f,0x2c,0x7d,0x5d,0x57,0x4f,0x3f,0x0b,0x11,0x2e,0x5a,0x5f,0x5c,0x74,0x10,0x48,0x15,0x4c,0x09,0x71,0x2d,0x58,0x0d,0x11,0x61,0x0e,0x11,0x7d,0x5a,0x08,0x01,0x70,0x47,0x49,0x44,0x44,0x0b,0x7f,0x29,0x5b,0x0d,0x44,0x3f,0x5d,0x10,0x7f,0x0b,0x0a,0x56,0x21,0x43,0x1d,0x14,0x10,0x09,0x78,0x7f,0x56,0x5f,0x47,0x61,0x5b,0x45,0x2e,0x59,0x09,0x03,0x21,0x42,0x41,0x16,0x46,0x5a,0x2b,0x7e,0x5b,0x5b,0x41,0x3a,0x0b,0x40,0x2d,0x5a,0x5f,0x55,0x71,0x47,0x1c,0x48,0x11,0x0e,0x28,0x2d,0x5c,0x57,0x4e,0x6d,0x58,0x4d,0x2f,0x5c,0x0d,0x54,0x21,0x4b,0x48,0x42,0x46,0x56,0x28,0x78,0x5f,0x0c,0x4e,0x61,0x5f,0x13,0x7b,0x5e,0x58,0x01,0x26,0x10,0x40,0x40,0x17,0x0c,0x79,0x7c,0x5b,0x5d,0x13,0x38,0x57,0x47,0x2d,0x08,0x5a,0x52,0x76,0x4a,0x4c,0x12,0x16,0x59,0x78,0x7d,0x08,0x0c,0x47,0x3b,0x5b,0x13,0x7c,0x5e,0x5f,0x5c,0x73,0x42,0x4a,0x11,0x47,0x59,0x2f,0x7a,0x5f,0x0e,0x14,0x3b,0x0b,0x11,0x78,0x0c,0x53,0x50,0x25,0x45,0x1b,0x40,0x4d,0x5d,0x2c,0x2e,0x5d,0x57,0x41,0x6d,0x57,0x46,0x79,0x0a,0x5a,0x55,0x75,0x41,0x18,0x16,0x17,0x0c,0x2d,0x29,0x08,0x5c,0x15,0x6c,0x57,0x40,0x74,0x5c,0x5e,0x04,0x73,0x41,0x1c,0x49,0x44,0x5b,0x2a,0x29,0x0d,0x56,0x14,0x6e,0x09,0x10,0x75,0x0d,0x53,0x53,0x73,0x43,0x48,0x11,0x45,0x5d,0x7a,0x7c,0x0b,0x5c,0x4e,0x6f,0x0a,0x41,0x29,0x5b,0x08,0x52,0x71,0x16,0x1c,0x15,0x17,0x58,0x7f,0x73,0x5c,0x56,0x13,0x3c,0x58,0x10,0x7a,0x5e,0x59,0x5d,0x71,0x11,0x1d,0x11,0x4c,0x59,0x28,0x29,0x0a,0x5c,0x43,0x61,0x0d,0x17,0x75,0x51,0x0a,0x04,0x20,0x47,0x1c,0x11,0x4c,0x5c,0x2f,0x78,0x59,0x5c,0x42,0x3a,0x58,0x45,0x2d,0x5b,0x52,0x03,0x77,0x47,0x1a,0x16,0x12,0x59,0x2b,0x7f,0x0c,0x58,0x41,0x3b,0x5f,0x46,0x2a,0x58,0x59,0x06,0x77,0x17,0x18,0x49,0x47,0x59,0x7a,0x7d,0x56,0x0b,0x46,0x6a,0x0d,0x14,0x7d,0x5c,0x0a,0x5d,0x74,0x16,0x18,0x44,0x45,0x59,0x28,0x72,0x5f,0x0d,0x12,0x69,0x5a,0x10,0x2e,0x08,0x0a,0x55,0x26,0x44,0x4e,0x15,0x45,0x5f,0x7e,0x7b,0x0b,0x5a,0x13,0x6e,0x0e,0x44,0x79,0x0f,0x5a,0x52,0x7b,0x11,0x4d,0x42,0x12,0x09,0x79,0x7e,0x0c,0x0e,0x15,0x69,0x0a,0x46,0x28,0x0c,0x5b,0x55,0x7a,0x14,0x49,0x40,0x16,0x57,0x2c,0x7f,0x0d,0x0a,0x14,0x3f,0x56,0x40,0x7c,0x0f,0x5c,0x57,0x76,0x42,0x4d,0x42,0x43,0x0a,0x78,0x79,]
v10=[0x39,0x71,0x5e,0x17,0x15,0x69,0x59,0x16,0x7a,0x0a,0x59,0x04,0x20,0x41,0x4b,0x40,0x17,0x5a,0x7c,0x7e,0x0d,0x0c,0x43,0x3b,0x0c,0x40,0x2e,0x0a,0x53,0x5c,0x7a,0x45,0x4f,0x44,0x47,0x59,0x7c,0x73,0x5c,0x0b,0x12,0x6a,0x5c,0x11,0x7b,0x5e,0x5c,0x5d,0x7b,0x17,0x1d,0x40,0x11,0x0d,0x78,0x2e,0x5b,0x0d,0x40,0x6b,0x59,0x10,0x7e,0x5d,0x59,0x06,0x71,0x4a,0x40,0x40,0x11,0x0b,0x2c,0x7e,0x5e,0x0b,0x4e,0x68,0x57,0x11,0x7f,0x0b,0x5c,0x06,0x22,0x10,0x4e,0x44,0x45,0x5b,0x78,0x7e,0x5f,0x56,0x12,0x6d,0x5c,0x42,0x7a,0x58,0x0d,0x50,0x72,0x47,0x4c,0x49,0x44,0x5d,0x7e,0x72,0x08,0x0d,0x43,0x3f,0x0e,0x4d,0x7a,0x5e,0x5f,0x04,0x7a,0x46,0x1d,0x40,0x4d,0x57,0x7c,0x2a,0x0b,0x0b,0x11,0x38,0x5b,0x17,0x79,0x5d,0x5e,0x5d,0x73,0x41,0x49,0x47,0x40,0x5e,0x7f,0x2a,0x0f,0x5e,0x4f,0x61,0x57,0x45,0x7d,0x5c,0x0e,0x54,0x71,0x17,0x4b,0x45,0x47,0x59,0x7a,0x7e,0x5e,0x09,0x11,0x38,0x5b,0x44,0x74,0x5b,0x5b,0x56,0x72,0x44,0x48,0x12,0x41,0x09,0x2b,0x79,0x5a,0x5c,0x4f,0x69,0x5c,0x40,0x7d,0x5f,0x5b,0x56,0x71,0x45,0x1c,0x42,0x45,0x09,0x7d,0x7b,0x5f,0x5a,0x13,0x6d,0x0d,0x42,0x7f,0x50,0x58,0x01,0x7a,0x42,0x1f,0x16,0x12,0x5a,0x79,0x2d,0x56,0x0b,0x42,0x3b,0x0a,0x46,0x28,0x08,0x5b,0x5d,0x22,0x10,0x1c,0x16,0x15,0x0c,0x7b,0x78,0x56,0x56,0x4f,0x38,0x5a,0x40,0x28,0x0a,0x5d,0x55,0x22,0x40,0x4d,0x44,0x43,0x5f,0x2a,0x73,0x08,0x0a,0x40,0x6f,0x0a,0x17,0x6c,0x18,0x51,0x55,0x3b,0x13,0x1d,0x11,0x16,0x0c,0x7f,0x7a,0x5b,0x5e,0x4e,0x3c,0x56,0x43,0x78,0x5b,0x5e,0x54,0x74,0x17,0x1b,0x45,0x17,0x5d,0x28,0x7f,0x0f,0x5b,0x46,0x6f,0x09,0x46,0x78,0x0a,0x5d,0x57,0x22,0x40,0x1a,0x41,0x11,0x0e,0x7f,0x2e,0x0d,0x5b,0x14,0x68,0x0b,0x45,0x28,0x5d,0x5d,0x5d,0x75,0x13,0x40,0x45,0x17,0x5c,0x78,0x2f,0x0d,0x0e,0x15,0x3b,0x0e,0x47,0x2f,0x58,0x58,0x03,0x22,0x4a,0x4b,0x41,0x43,0x0a,0x78,0x7f,0x08,0x0c,0x42,0x6d,0x5e,0x4d,0x79,0x5e,0x09,0x5d,0x77,0x44,0x1d,0x48,0x4c,0x5f,0x7b,0x7c,0x0f,0x5e,0x11,0x6e,0x0c,0x13,0x29,0x0c,0x52,0x04,0x21,0x13,0x49,0x47,0x41,0x58,0x2a,0x78,0x0f,0x56,0x45,0x38,0x0d,0x40,0x7b,0x50,0x5b,0x5d,0x75,0x47,0x41,0x46,0x17,0x5f,0x2c,0x7e,0x5c,0x0d,0x4f,0x68,0x57,0x41,0x28,0x0c,0x5b,0x06,0x75,0x4b,0x18,0x15,0x42,0x58,0x7d,0x29,0x5e,0x5c,0x43,0x6a,0x5b,0x47,0x2e,0x59,0x0f,0x07,0x77,0x42,0x40,0x45,0x41,0x09,0x2b,0x2d,0x08,0x0b,0x14,0x61,0x5b,0x10,0x29,0x51,0x5c,0x50,0x21,0x4b,0x1b,0x48,0x40,0x09,0x7e,0x2f,0x5c,0x0d,0x11,0x6a,0x5d,0x4d,0x7f,0x5f,0x0d,0x55,0x70,0x11,0x4a,0x40,0x40,0x0d,0x7a,0x7f,0x08,0x0a,0x16,0x6b,0x0a,0x14,0x7c,0x5a,0x5c,0x56,0x72,0x13,0x1f,0x49,0x41,0x0b,0x70,0x7a,0x5b,0x59,0x15,0x60,0x5e,0x14,0x7d,0x5f,0x0d,0x03,0x7a,0x41,0x4a,0x48,0x12,0x0a,0x71,0x2a,0x57,0x09,0x14,0x3c,0x5d,0x41,0x79,0x5b,0x5e,0x07,0x75,0x47,0x4c,0x40,0x4d,0x4f,0x2c,0x71,0x5e,0x17,0x13,0x6b,0x0c,0x47,0x6c,0x0a,0x51,0x55,0x3b,0x43,0x48,0x48,0x42,0x5e,0x7e,0x7e,0x5c,0x0e,0x4f,0x3a,0x0e,0x40,0x74,0x0b,0x5c,0x52,0x74,0x41,0x49,0x40,0x11,0x09,0x2b,0x28,0x56,0x0a,0x13,0x69,0x5a,0x10,0x2d,0x5c,0x5f,0x01,0x73,0x11,0x4a,0x42,0x42,0x0c,0x2b,0x2d,0x0c,0x5a,0x40,0x6a,0x0e,0x45,0x2e,0x0d,0x59,0x54,0x25,0x17,0x4c,0x11,0x46,0x5f,0x78,0x72,0x5f,0x0d,0x47,0x6a,0x09,0x45,0x7b,0x0b,0x0e,0x52,0x22,0x17,0x18,0x49,0x15,0x0c,0x78,0x72,0x5c,0x0e,0x13,0x3b,0x0a,0x41,0x74,0x5e,0x59,0x53,0x22,0x42,0x18,0x40,0x47,0x0c,0x2a,0x28,0x56,0x5c,0x4f,0x6a,0x58,0x40,0x28,0x5e,0x08,0x51,0x25,0x11,0x1d,0x40,0x16,0x57,0x71,0x7a,0x5a,0x5a,0x40,0x61,0x09,0x14,0x28,0x5d,0x5c,0x00,0x22,0x42,0x4d,0x40,0x43,0x5d,0x71,0x7a,0x0c,0x0d,0x15,0x6b,0x5f,0x40,0x75,0x5f,0x5b,0x06,0x75,0x46,0x4c,0x43,0x12,0x09,0x2f,0x73,0x5f,0x5a,0x4f,0x6d,0x0c,0x10,0x7f,0x5a,0x5f,0x04,0x71,0x41,0x40,0x46,0x44,0x0c,0x7f,0x78,0x5c,0x5e,0x14,0x6e,0x5d,0x45,0x28,0x08,0x5c,0x07,0x72,0x4b,0x49,0x42,0x4c,0x5e,0x2a,0x7d,0x0a,0x5b,0x41,0x3b,0x5a,0x40,0x29,0x5a,0x09,0x04,0x21,0x42,0x4d,0x49,0x47,0x0b,0x71,0x2d,0x08,0x59,0x14,0x3f,0x5c,0x4d,0x79,0x5c,0x0a,0x57,0x22,0x44,0x49,0x43,0x4d,0x0c,0x7b,0x7e,0x57,0x09,0x4e,0x6c,0x5a,0x10,0x7e,0x0a,0x09,0x01,0x25,0x10,0x40,0x14,0x17,0x0e,0x2b,0x28,0x56,0x5e,0x44,0x38,0x0b,0x4d,0x7e,0x0a,0x5e,0x56,0x70,0x41,0x1d,0x45,0x47,0x5a,0x70,0x7e,0x5e,0x0a,0x45,0x61,0x0c,0x13,0x2e,0x5b,0x0a,0x04,0x76,0x47,0x4f,0x13,0x47,0x5d,0x7e,0x7b,0x5e,0x09,0x41,0x6d,0x0c,0x47,0x2e,0x5f,0x58,0x55,0x76,0x4a,0x1a,0x16,0x47,0x5c,0x2f,0x2e,0x58,0x0c,0x43,0x69,0x59,0x42,0x7b,0x08,0x52,0x56,0x27,0x4a,0x1a,0x48,0x44,0x0e,0x79,0x2d,0x57,0x0b,0x15,0x6f,0x5f,0x11,0x2d,0x58,0x08,0x00,0x7a,0x42,0x48,0x48,0x46,0x0a,0x2d,0x7b,0x0f,0x0e,0x41,0x3c,0x0b,0x46,0x7f,0x08,0x59,0x04,0x7a,0x40,0x41,0x48,0x10,0x0c,0x70,0x2d,0x08,0x5e,0x4e,0x3c,0x0b,0x4c,0x2e,0x0f,0x0d,0x07,0x76,0x4b,0x40,0x49,0x45,0x0d,0x2d,0x2f,0x08,0x5d,0x4f,0x6b,0x0d,0x46,0x74,0x08,0x5e,0x5c,0x27,0x17,0x1d,0x42,0x43,0x09,0x7e,0x7a,0x0d,0x5b,0x12,0x6c,0x0a,0x45,0x7d,0x50,0x5b,0x00,0x76,0x40,0x4d,0x44,0x10,0x56,0x78,0x7d,0x5b,0x5a,0x41,0x3a,0x5f,0x46,0x7f,0x0b,0x09,0x57,0x22,0x43,0x41,0x44,0x17,0x57,0x7e,0x28,0x08,0x5e,0x4e,0x6b,0x5c,0x13,0x2e,0x51,0x5c,0x5c,0x73,0x40,0x1f,0x11,0x4d,0x0b,0x2b,0x29,0x5b,0x0e,0x13,0x6c,0x09,0x4c,0x7e,0x5e,0x59,0x51,0x7a,0x10,0x1c,0x14,0x12,0x0e,0x7d,0x29,0x5a,0x58,0x12,0x6c,0x0e,0x46,0x7b,0x50,0x59,0x5c,0x74,0x4b,0x4b,0x46,0x11,0x5c,0x7b,0x7a,0x58,0x0e,0x4f,0x69,0x57,0x17,0x75,0x5a,0x0e,0x04,0x71,0x11,0x4e,0x12,0x12,0x5f,0x78,0x7f,0x0d,0x5f,0x15,0x6e,0x0e,0x10,0x7e,0x50,0x0e,0x04,0x20,0x14,0x4c,0x49,0x41,0x0e,0x7d,0x78,0x0b,]

key="IKnowYouLikeCrypto"
for i in range(len(v7)):
    v7[i]=chr(v7[i]^ord(key[i%len(key)]))
    print(v7[i],end="")
print()
print("----------------------------------------------")
for i in range(len(v8)):
    v8[i]=chr(v8[i]^ord(key[i%len(key)]))
    print(v8[i],end="")
print()
print("----------------------------------------------")
for i in range(len(v9)):
    v9[i]=chr(v9[i]^ord(key[i%len(key)]))
    print(v9[i],end="")
print()
print("----------------------------------------------")
for i in range(len(v10)):
    v10[i]=chr(v10[i]^ord(key[i%len(key)]))
    print(v10[i],end="")

分别拿到了p q e c后,再分别分析,基本上都是e和phi不互质的问题

exp1:第一组


import gmpy2
import libnum
p=0xae1e96a501b0360bd9ca423f2d9366e7c01c56e2d02dd20effc4c290e8bbd2cc53bb2a65b5262e254418d706335708ebd713cf9fac04fb1209d666adc6ebb6fee8c97a8dde4c23d3704198f918de46fe69a0d4d7878341c25118e7d1ac368753ce45f77b64580e0a89e300ac8f1be75d3a001df26bcfdaf82a479e14f6f25bfb
q=0xcfc337e9217545d01babb00c330747aed4e6d99df42892bffce38e9b5c8a89d0528a7daac8d0075d72813669bc332688c9f6df2793b393580ac71f05db159e2dee3a6fd34ca2ba5ccae8428efefd6ee5454b6751ca71c008468278d7fe911e8c292172fa77468e996d80f4661c24ccdcc76c655a9168b0edeed165b2dd89501b
e=0xd322
c=0x6f23dc633746ecd6f6b6c753556a969ded7f9033b7617d4497b3a3ac685b92063e42c5657a01604ed084035637440889bd6865449021a15dfa33ed2d9531f50c41d452df7399554a35f4340993d64c9e1c7b54894d291b33ac95b39719093d788a1d218f54f00494990f8aff3d09e21edae2172cd8b42ae6f8abfdb05e5d9a6ff4b5092f60f8ce2a576e429a80bd15fc7073d75415c824fc450a9295128e30804760179bc3213ade1121d615f7ebbf192f93dd25031de12e12e15ae189db525ddbdfb2f54f098c0a027b6b1277c22108dfd2699f7946ce51f1c73a78721896bd8baa3b7fa4dfc063ab212eb0684531f372f2edc7b1f7baa3353b55cc750b95ff
n = p*q
phi = (p-1)*(q-1)
_gcd = gmpy2.gcd(e, phi)
d = gmpy2.invert(e//_gcd, phi)
m_gcd1 = gmpy2.powmod(c, d, n)
m = gmpy2.iroot(m_gcd1, _gcd)    
flag = libnum.n2s(int(m[0]))
print(flag)
#把m[0]转化成hex字符串
hex_str = hex(m[0])
print(hex_str)
#688682bc45a043f2e139153780fdd54af8517dd885464bdfa3dbcf776169255c

exp2:第二组

import gmpy2
import libnum
p=0x7a7b8ee72d467eefe378502ca7804e0b55e0b68987dd7e8c03f7f7f717554183d2a0d99c7b33e8e1a28be171b77f8974616ac49645d7d5cf6fe5f4dcbfd1d25c3ad75e1eb3e4038d55a29c7114e176fd34626c2a8e76021d079cdb85cc8016acab00047910dfa5cd0439a3cc13527557ea879c184454a443711083a4f9d1d46b
q=0xc17c7a7fbc5469af413f79c07cc5b892cfbbaa00950b115e267e83e2669f3f6779c7302ecfc9f850e0e4185892e96d356d65b1d372432c5a3f297cfb8373fe9a090a3f8dadf6ef6f2ca5b5107454ee6b1385d165bb4bb7776cbbccb8de1993a5ebb34ee365ff39b9ec9613121ba99d74759e0bf80726805ce03ed7f1e49375f1
e=0x10ae
c=0x5be0df3bb240ffd53f2d914eb79878231821a1dba5cc491a888c8fd553a905a7f1cea2750c39ea48ab4175115591310c0f9d63e1aee9d2480780f3ce4f98c57114cd2901ea6f560e04a0a9cec157dac3def734fa10ab54c27bf20211cf1f1f6f6afe5fc9ef5c9af864f054a5e61c48c6e6dc087cc350008d4232d08b0b5011923f1077ead75d54a792aa8a51a0b37bfa3faef0b9380cff209c7bf3a20fbbb087caf177b83c9bf03e965bd7347dd18418f3e50aef29cc89fa594ccd31b6f63f397eeba71629fec2c8699148dfd6be32deb96577690814bb4fe6dbefe2379468e0e317a870795ba04ab2e306fe5340700c415048eff5909a2453752845572a0931

n = p*q
phi = (p-1)*(q-1)
_gcd = gmpy2.gcd(e, phi)
d = gmpy2.invert(e//_gcd, phi)
m_gcd1 = gmpy2.powmod(c, d, n)
m = gmpy2.iroot(m_gcd1, _gcd)    
flag = libnum.n2s(int(m[0]))
print(flag)
#把m[0]转化成hex字符串
hex_str = hex(m[0])
print(hex_str)
#9304306d542508c59abf30f99b98fefcd2951df2effc81fca8e5aa26414819cb

exp3:第三组

import gmpy2
import libnum
p=0xa2562b53b1ff8b9635122c92612d8b6ea43ac0e40115c03befc0fb1bdefcda35a77f1cf23e5fdfa51ee864dac707524584cf4243cade36ea0b2ce14d9337d796f85b730483e7b6e342d44a36a1bc4052125b4eaef3724af9cfb8cab719d9efc54df851042408c2f69c1e5f46f00f067f7fa5cf7a3cb227879cbdefac7eab6cd3
q=0xfeec12d4602e4895f53715d7e5a7583ee93c49079480aadae13c7c9d720a5fd976b6b9ac5ef65570f9e9d9b6d0b0b39f1372ea819bc14cc10a0a23a7f22f60c1a4fc536ebc4997bb873db9d8cb34f58fec2a05dc766cb865e09aa6c1a059713ccb1b31a9c986ecd4f45dc53c95e32ae6d370ee3566daa8b5f5bf6fe5fa20cd0f
e=0xc051
c=0xa798cb067b716ae1382d2070efb8bdb71050b88d9503a68fe5e851999071e4ee9f72c88b3975de09e8f436566d75f90e6388fddb3497b1e8f8f6bf8ad13cd35040d6b5b3f2e3ba3b1dddf14800840b0bfb08f25b5546cd5a34025e8eaaf289478c5f1b91229a31c980f773deb90cc0752da82aa17585bb616fc0b4f0749003a36f11acbdd4e85f7b092ee3864835c1063afccdbf3b585855a03e904cbc9c7fe9d86011a1237e396e4e2c72deec76829de7e67282cda86abd348bb98aac5ea83f3735c70a29f45cff6b4b76b03f12c4ea936368d13ba15a87da416a91be05ebaa0e67e1070e5d7a15f178c42ff05bab0e3de009f00b8e4cecf950f7250427e12
n = p*q
phi = (p-1)*(q-1)
_gcd = gmpy2.gcd(e, phi)
d = gmpy2.invert(e//_gcd, phi)
m_gcd1 = gmpy2.powmod(c, d, n)
m = gmpy2.iroot(m_gcd1, _gcd)    
flag = libnum.n2s(int(m[0]))
print(flag)
#把m[0]转化成hex字符串
hex_str = hex(m[0])
print(hex_str)
#144576b4302a8c5262d7d4d9b2ebb3468835c709cc88fc0b8b38b52a6f31d3ab

exp4:第四组

import gmpy2
import libnum
from Crypto.Util.number import *
p=0xb06c6c2ac320c555cc4bc5bc89976436582de33d77788ed0eb1e5b726e242c2890ede50d918d3b7cab74141519e43761f515590279fb4fa8674a94d0985aedfa4b54580307416aa1888015e12e2536350ffa418203161b5fb2438035160327e21f4015d4b7393d90fff50f8d5be3da08abefac23898a55dc60a24470c8fe76eb
q=0xadabc61519e9642517eb5c2a4a416f34c62a2c1ea6ec4c1d0d4686a95c31dcabba2c13fa8217e14fc541857b846d88027a1f7cfee9aba0757c3a92ab579086586c0e52b8184de0c69ae674b034342b0db40955fbffdc84ee875b9b84f7d2bf32836f03c304b34fea2ea03731af95d9156b91a16ff9338fe8a9fce24525b65509
e=0xd2c2
c=0x11861752a8ca58b777300efbc8ed05ea54d0c326cbfb573a0bd21fe5a20191b03f07be7aea9ac192adbe48726a0a03ccc838375d7c4fcd0b8814578fad47ea0407281bbb205960c6453fff81584ce334a23960c6321c720da7b190281c6d46b55e3bab0493d8ff6cf3855a2a6039c259f955e2cbdfb9dcabc813ad82c5333d535950e28cfb2aa556c32700f64c2b63058cf33fe6c40677a93d8c80a0f9db60da1ce90182ed0aa6ed33a2a9288dc9ff19ed9bffb59991bddf282b38a59ded27f71c4e5e0190e5244d916556c033bb2a184c87cf1923fb87902fa9dbb5ad5f927249bedfa4b47e5a379297926e3216a808b93ea2c7bf014c0b7ae29eacf595a43e
n = p*q
phi = (p-1)*(q-1)
_gcd = gmpy2.gcd(e, phi)
d = gmpy2.invert(e//_gcd, phi)
m_gcd1 = gmpy2.powmod(c, d, n)
m = gmpy2.iroot(m_gcd1, _gcd)    
flag = libnum.n2s(int(m[0]))
print(m[0])
#把m[0]转化成hex字符串
hex_str = hex(m[0])
print(hex_str)
#6b25edeccfcf74f0dfc77abc90d757a49c1d0fb1c90e67db7918c61be80ad59c
#688682bc45a043f2e139153780fdd54af8517dd885464bdfa3dbcf776169255c9304306d542508c59abf30f99b98fefcd2951df2effc81fca8e5aa26414819cb144576b4302a8c5262d7d4d9b2ebb3468835c709cc88fc0b8b38b52a6f31d3ab6b25edeccfcf74f0dfc77abc90d757a49c1d0fb1c90e67db7918c61be80ad59c

根据题目要求,对还原得到的明文进行md5加密

#flag{d3f06717efc6c0daf454ffeac9764687}

week4

Math-attachment

知识点:

re crypto交叉题

无壳,ida分析,定位到main

image-20241120164925257

又是一堆神奇的加密,简单分析一下换成python形式浇给crypto手

from Crypto.Util.number import *
import time
def main():
    print("Reverse And Crypto Are Best, Isn't It?")
    print("Please input your flag(hex format):")
    print("The hex format python code is:")
    print("======================================")
    # off_5010可能是某种常量或注释,此处省略
    print("======================================")
    print("Give it to me:")

    s = input().strip()
    
    if len(s) == 68:
        # 替换掉基于时间的随机数生成,使用固定随机数或简单的生成方法
        random_state = int(time.time())  # 这里我们仅使用时间戳作为随机数种子

        m = int(s, 16)  # 将输入的hex字符串转换为整数
        
        # Step 1: Generate primes p, q and calculate n
        p = next_prime(random_state)#512
        q = next_prime(random_state + 1)  # 确保不同的随机种子来生成不同的素数  512
        n = p * q

        v28 = next_prime(random_state + 2)#32位
        v30 = pow(m, v28, n)
        c_output = hex(v30)
        print(f"c_output='{c_output}'")

        print("#========================================================================")

        # Step 2: Generate second set of primes p1, q1 and calculate n1, phi1
        p1 = getPrime(512)
        q1 = getPrime(512)
        n1 = p1 * q1
        e1 = 39847
        
        phi1 = (p1 - 1) * (q1 - 1)
        v40 = gcd(e1, phi1)#保证互素
        if v40 != 1:
            exit(-1)
        
        v35 = pow(p, e1, n1)
        n1_output = hex(n1)
        print(f"n1_output='{n1_output}'")

        print("#========================================================================")

        c1_output = hex(v35)
        print(f"c1_output='{c1_output}'")

        print("#========================================================================")

        # Step 3: Hint1 calculation
        v41 = 2023
        v42 = v41 * p1
        v43 = 2024
        v44 = v42 + v43
        v36 = pow(v44, q1, n1)
        hint1_output = hex(v36)
        print(f"hint1_output='{hint1_output}'")

        print("#========================================================================")

        # Step 4: Generate third set of primes p2, q2 and calculate n2, phi2
        p2 = next_prime(random_state + 5)
        q2 = next_prime(random_state + 6)
        n2 = p2 * q2
        e2 = 44021

        phi2 = (p2 - 1) * (q2 - 1)
        v40 = gcd(e2, phi2)
        if v40 != 1:
            exit(-1)

        v49 = pow(q, e2, n2)
        v53 = 2023 * p2
        v54 = 2024 * q2
        v55 = v53 + v54
        v56 = 2323
        v50 = pow(v55, 2323, n2)
        
        v57 = 2024 * p2
        v58 = 2023 * q2
        v59 = v57 + v58
        v60 = 2424
        v51 = pow(v59, 2424, n2)
        
        n2_output = hex(n2)
        print(f"n2_output='{n2_output}'")

        print("#========================================================================")

        c2_output = hex(v49)
        print(f"c2_output='{c2_output}'")

        print("#========================================================================")

        hint2_output = hex(v50)
        print(f"hint2_output='{hint2_output}'")

        print("#========================================================================")

        hint3_output = hex(v51)
        print(f"hint3_output='{hint3_output}'")

        print("#========================================================================")

        # Step 5: Final calculations
        v61 = v28
        v62 = int("9c5ab7c1cc9a4f60b1d53afafd7016d00e811e5a1c6fb258c75a246a0630a75644100828e21757de1d9a5ff99ebd05257aa9d895c1de40a2eb"
                  "619fa52f32b38acb52669841d528351df863137b0a14f4aff6506cf0c7cdf1801c2bd3d7fb4e583811f4f771f7e5c0e5f42a85839affed38df"
                  "8b913fa6a4e782adc028e5e86162f", 16)
        v63 = int("488d156b0cbef000f1bf6c47006a3595", 16)
        v64 = pow(v63, v61, v62)
        a_output = hex(v64)
        print(f"a_output='{a_output}'")

        print("#========================================================================")

    else:
        print("Invalid input.")

main()

下面是密码手的操作

dlp解e,两个rsa变种解就行

sage_dlp
n = int("9c5ab7c1cc9a4f60b1d53afafd7016d00e811e5a1c6fb258c75a246a0630a75644100828e21757de1d9a5ff99ebd05257aa9d895c1de40a2eb"
                  "619fa52f32b38acb52669841d528351df863137b0a14f4aff6506cf0c7cdf1801c2bd3d7fb4e583811f4f771f7e5c0e5f42a85839affed38df"
                  "8b913fa6a4e782adc028e5e86162f", 16)
m = int("488d156b0cbef000f1bf6c47006a3595", 16)
c=0xc028af32e59098f182059e09d4463c34a71b5db98d0d538305102ce68cda72f6897606fd8d933b51633e63c63be59cc3454e8d04d287eda3535f21a8c9496f9e5b62edc81eb971d55b9ecc20b4d6671709e73af110d1bef9413e9786032d268fd7d243d01ccbdbeb0757e5a5affbc976e83f85bde685618d592fe23d754919a2
tmp_list = [10529,65777,344417,503777,549247,730447,859927,860113]


def r(h, g, N, p, qi):
    """
    N : p-1
    qi: N中的素因子
    """

    Zp = Zmod(p)
    h = pow(h, N//qi, p)
    g = pow(g, N//qi, p)
    ri = discrete_log(Zp(h), Zp(g))
    return int(ri)

r_list = []
for qi in tmp_list:
    tmp = r(c,m,n-1,n,qi)
    print(tmp)
    r_list.append(tmp)
    
x = crt(r_list, tmp_list)

module = 1
for i in tmp_list:
    module *= i  
while True:
    if int(x).bit_length()>128:
        print('fail')
        break
    if int(pow(m, x, n))==c:
        print('x =', x)
        
        
        break
    x += module
#3035716141

rsa变种看注释

from gmpy2 import *
import libnum
from Crypto.Util.number import *

c_output=0x639cd472630afb1aa9f5490b4f3de3b4701eef5c61aad06345f9e001021340cf989fc082693f745716bd39d015793e62be08913dcb82b2b6c8ed56d15a4cc230a60ea185d593a858b47276c403c79b6da23b561b200295a8addba7a48660d17a9eef322e430b939aecc4ca0c0f4fcc003524cdca68b7be935962f4b4ad8cafd5
n1_output=0x11df715605906c9cfc906faf4d02a380b9489fe890952cfbc7713af87031b61a4a3a0e2c46ba89ef462a3a77def7d5de0a0a10b3d1303afc06ed7bc9f07e01e9883b06ce17c290fe550844cf9028f50642e4190ccb13cdf0bb0493e437c54ee17643202cc1b35741208957eb6c1843299b4480e6d32a311de6fd6f4b9d9e8fab
c1_output=0x5a768e8e3e4efe51f566d77dd9a1312f5398bc9e1fa4e828be6a3b6aa6109de02c4eec524e23bf0836b7b25f534a429744e980bdc3acd77a8133c543ea1cf4f4665fbd46bc21d38edd60a687007e079980cac97e1099610aeceee3bff13483396a4cfb061df7d5bce9c7fba6ae14fbead5f56aa990f23ee9cbe8a8fc066d5fa
hint1_output=0xc3fd84beeb2363d414848fda5898976625bcbb9637982f83853a6c96e64c8ec94645409b7036e3b187ecf930e294fc448c4ac6bfa9945078300b1619bc98d13275770f562874c7fd389ba9ef4e05019633566e65ba95e5a30e29a45b79774c6aaed89aa43105508e868941c81861120f50fe182e33b80701e1714205759f380
n2_output=0x3cc006e0dea07f834418109ac8c1a447258c7da01223107fd255303613ce9ffc3faa74823a28ea1e211a34c349f20b49bb00447777e4d7f5139219e62fb993562f7e705e0919ccbc414956e8a6cc3e01812ca6eb10558060fe0f7c06da63e5d6169ea5790e86f3e2e804d399d1429529d3031738f134e619a0decce12bde4cd
c2_output=0x2de5d5191bf279ba3ea338bd4390a18d0233da9e050b3aa2644a9427eff787b4d74aa3c7dc348f214247997ae32fb86428935e61234f9ef63e9b562c40b6b07c9133cad4672c9aa7f515d3f7d067b6187d30e4346c4afeceae031c3116ccf97acaddb2af42d459c61ce0df7b56ce1e0ba15cf28aed5415615aa9398fb494e5b
hint2_output=0x2dd30b086f1c8fa7860ed5cde1e02a062e8722ae9823579f764d5da86ec250b2dfee6934463a06b133d791c3cfbe5f88a43bfae7f25cfb3efb61c10aa710aa76e2229241986fb16f1ae34a867cb7ba641d5637b70a92027479e9c18d1372059a4e04a7298c5b279fa6d84abc1b466b29bba8a1a2ea9e8ad568c14af17c4f50e
hint3_output=0x35751402de3cb0f6481451a7b3665b3ddd15c9f0ad07398c4ee35c01ff926dd2545dc41d591fca58b485e3cd114d7c0a67196f95fcebc9391f10c89ded2b1ef3e5014ab8fe5ea33e2afb1cd9af7d84fca17e56e759b136578c29f679a64f0e2060492eee268af2304f7c689ece60a941ba8100dd0d2af1a45499afd10cf9eaa
a_output=0xc028af32e59098f182059e09d4463c34a71b5db98d0d538305102ce68cda72f6897606fd8d933b51633e63c63be59cc3454e8d04d287eda3535f21a8c9496f9e5b62edc81eb971d55b9ecc20b4d6671709e73af110d1bef9413e9786032d268fd7d243d01ccbdbeb0757e5a5affbc976e83f85bde685618d592fe23d754919a2



v62 = int("9c5ab7c1cc9a4f60b1d53afafd7016d00e811e5a1c6fb258c75a246a0630a75644100828e21757de1d9a5ff99ebd05257aa9d895c1de40a2eb"
                  "619fa52f32b38acb52669841d528351df863137b0a14f4aff6506cf0c7cdf1801c2bd3d7fb4e583811f4f771f7e5c0e5f42a85839affed38df"
                  "8b913fa6a4e782adc028e5e86162f", 16)
v63 = int("488d156b0cbef000f1bf6c47006a3595", 16)
e=3035716141
p=8322702520093461725345474921382490371590722812300898286855429480858040940795864872670979194950858395679015786254600561557473646577470249336319696443951447
q=9750519000978689681670874765366589789654954203826327625769191967176869975210484907633262302897836811114538388307606532973182712892530056725474630222521371

phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
m=pow(c_output,d,p*q)
print(hex(m))
print(long_to_bytes(m))
# h_2=hint2_output*pow(gmpy2.invert(2024,n2_output),2323,n2_output)%n2_output
# h_3=hint3_output*pow(gmpy2.invert(2023,n2_output),2424,n2_output)%n2_output
# h_2=pow(h_2,2424,n2_output)
# h_3=pow(h_3,2323,n2_output)
# p2=GCD(h_2-h_3,n2_output)
# p2=7024309655100234018073671712534739855626883854576434542940212496492494783884199126997988874234684185584503609884115154177390543529852705061640224390715907
# print(p2)
# q2=n2_output//p2
# print(q2*p2==n2_output)
# phi=(p2-1)*(q2-1)
# e2=44021
# d=gmpy2.invert(e2,phi)

# q=pow(c2_output,d,n2_output)
# print(q)



# q1=8819414114132955494127870936116438844832338680741658526804268799372075565540014095418599047929296332721948036347789064724493985936439034191846511473814813
# e1 = 39847
# p1=n1_output//q1
# phy=(p1-1)*(q1-1)
# d=gmpy2.invert(e1,phy)
# m=pow(c1_output,d,q1*p1)
# print(m)



# h_1=pow(2024,n1_output,n1_output)
# h_1=(hint1_output-h_1)%n1_output
# print(h_1)
# print(f"q:{GCD(h_1,n1_output)}")



# print(a_output==pow(v63,x,v62))
# print(v62)

flag{IKnowYouLikeReverseAndCrypto}

ez_re

知识点:AES、TLS

exe,无壳,ida分析

打开发现2处报红,

image-20241120163723957

image-20241120163828027

还是E8,统统nop

进入main

image-20241120163956033

image-20241120164033645

逻辑差不多就是将用户的输入进行CBC模式的AES加密,前面设置了一些加密用的向量,v8是加密后要与之验证的数组。

加密用到了windows下的一个库"bcrypt.h"

调试拿到pbSecret、pbIV的内容(说实话感觉没受到TLS反调试的影响)

直接上exp:

#include <Windows.h>
#include <bcrypt.h>
#include <stdio.h>
#pragma comment(lib, "bcrypt.lib")
unsigned char pbSecret[] = {
    0xAD, 0xDD, 0xDB, 0x08, 0x2D, 0xD9, 0x4D, 0xCA, 0xBA, 0xD5,
    0xD7, 0x56, 0x39, 0xEA, 0xC9, 0xDA,
};

unsigned char pbIV[] = {
    0x63, 0x3B, 0xBD, 0xFB, 0x3A, 0x2C, 0xC6, 0xFF, 0x5C, 0x08,
  0x62, 0xA2, 0xCD, 0xA2, 0xEA, 0xB4
};

unsigned char v8[] = {
    0xDD, 0xE0, 0x4C, 0x75, 0x97, 0x33, 0x14, 0xB8,
    0x17, 0xB6, 0x19, 0x11, 0x61, 0x8A, 0x60, 0x23,
    0x46, 0x16, 0xE2, 0x1A, 0x65, 0xC3, 0x5B, 0x26,
    0x68, 0xF5, 0xAD, 0x30, 0xB1, 0xEE, 0x4B, 0xC6,
    0xAB, 0xB5, 0x9E, 0xBB, 0x73, 0x95, 0x4A, 0xC2,
    0x78, 0xEF, 0xCB, 0xA9, 0xBE, 0x71, 0xE1, 0xA0
};
int main() {
    BCRYPT_ALG_HANDLE phAlgorithm = NULL;
    BCRYPT_KEY_HANDLE phKey = NULL;
    ULONG pcbResult = 0;
    unsigned char decrypted[48] = { 0 }; // Size should match decrypted data size
    // 1. Open AES algorithm provider
    if (BCryptOpenAlgorithmProvider(&phAlgorithm, L"AES", 0, 0) != 0) {
        printf("Error opening algorithm provider\n");
        return -1;
    }

    // 2. Set the chaining mode to CBC
    if (BCryptSetProperty(phAlgorithm, L"ChainingMode", (PUCHAR)L"ChainingModeCBC", 0x20u, 0) != 0) {
        printf("Error setting chaining mode\n");
        BCryptCloseAlgorithmProvider(phAlgorithm, 0);
        return -1;
    }

    // 3. Generate the symmetric key
    if (BCryptGenerateSymmetricKey(phAlgorithm, &phKey, 0, 0, pbSecret, 0x10u, 0) != 0) {
        printf("Error generating symmetric key\n");
        BCryptCloseAlgorithmProvider(phAlgorithm, 0);
        return -1;
    }
    // 4. Decrypt the data
    if (BCryptDecrypt(phKey, (PUCHAR)v8, sizeof(v8), NULL, pbIV, sizeof(pbIV), decrypted, sizeof(decrypted), &pcbResult, 0) != 0) {
        printf("Error decrypting data\n");
    }
    else {
        printf("Decrypted data:\n");
        for (ULONG i = 0; i < pcbResult; i++) {
            printf("%c", decrypted[i]);
        }
        printf("\n");
    }
    // Clean up
    BCryptDestroyKey(phKey);
    BCryptCloseAlgorithmProvider(phAlgorithm, 0);

    return 0;
}
//SYC{W0w_Y0U_fOUNdDD_TLS_AND_AeS}

Misc

签到

image-20241120170246790

Truth of Word

word隐写

1.文字与背景颜色一样

image-20241120170351103

2.解压后media文件

image-20241120170424137

  1. 宏(查了好久,才知道有这东西)

image-20241120170456470

编辑宏

image-20241120170532618

#SYC{W0rd_H@5@_Ama1n9_StrUCtu3e!}

ez_pcap_1

追踪TCP(SMB)流

image-20241120171454455

#SYC{smb_pcapng_1s_g00d!}

cimbar

题目如下

theTruth0fCimbar

参考用摄像头传输文件 —— Cimbar - 哔哩哔哩

image-20241120171717456

对着表手搓

01010011 01011001 01000011 01111011 01000001 01101110 00110000 01110100 
01101000 00110011 01110010 01011111 01000001 01101101 01000000 01111010
00110001 01101110 00111001 01011111 01010001 01010010 01011111 01000011
01101111 00110100 01100101 01111101

image-20241120172858377

#SYC{An0th3r_Am@z1n9_QR_Co4e}

累死了,以后还是少些脚手架吧

多总结。逆向的路还很长很长~~

posted @ 2024-11-24 14:34  Q7h2q9  阅读(70)  评论(0编辑  收藏  举报