第十五届极客大挑战部分WP(主Re)
极客2024 部分题WP
队伍名:不只是来看看题
分数:10023
高斯有言:“当一幢建筑物完成时,应该把脚手架拆除干净。”
从建筑物的角度出发,移除脚手架无疑是有益的,因为它使得建筑本身更加美观,呈现出设计者所追求的艺术效果;对于未来的设计师与建造师而言,这却是不利的。因为脚手架不仅是施工过程中的辅助工具,更是建筑创意与技术实现之间的重要桥梁,它承载了建筑设计的原始思路与实现路径。这些理念和方法是构建过程中不可或缺的组成部分,对后续的设计与施工有着重要的参考价值。
所以WP写得有些过于详细(
Reverse
week1
先来一道签到题
知识点:汇编语言
打开压缩包,是一个.s文件,不懂,双击看看
打开发现是汇编语言,分析转.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;
}
#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;
}
#SYC{H3lI0_@_new_R3vers3_Ctf3r!!}
ezzzzz
知识点:安卓逆向,Tea算法
解压后是一个apk文件,安卓逆向,放jadx里分析
定位到MainActivity
大概是将输入的字符串用Enc.encrypt进行加密后与R.string.target进行比较
先找目标字符串R.string.target
找了一圈没找到,搜字符串"target",找到可疑点
复制下来
/*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;
}
#SYC{g0od_j0b_wweLCoMeToooSSSyC_zz_1_et3start_yoUr_j0urney!!}
让我康康你的调试
知识点:RC4加解密
ELF文件,无壳
定位到主函数
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;
}
#SYC{we1come_t0_Geek's_3asy_rc4!}
我勒个z3
知识点:z3求解,算法逆向
无壳,ida分析
定位到main
逻辑大概就是
[1] 验证输入的key:将输入的字符串逐个赋值给v4[i++],调用sub_401B7B((const char *)v4)验证key
[2] 验证flag:将输入的字符串逐个赋值给v6[i++],然后调用sub_401AAC(v6, v4)对v6进行加密,最终通过sub_40179A(v6)进行验证
验证key:
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
其中a2是刚刚解出来的key
再看sub_4019EB
其中
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
经典解方程,去请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;
}
//SYC{Wow!!_Y0u_4r3_9o0d_At_r3$!!}
也许你也听jay
解压后是一个txt文件
经典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;
}
解出来是个网址
点进去,恍然大悟题目名字的意思
RC4,key是lovebeforeBC,密文是Q7u+cyiOQtKHRMqZNzPpApgmTL4j+TE=,找个在线网站解了
//SYC{ILIKELISTENJAYSONG}
week2
知识点:python编译原理,python字节码
好像是python?
解压出来是一个二进制文件
放010看看,发现是python字节码
转换成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分
然后发现给了一个Data.txt文件
看不懂,导入010看看
MZ开头,保存并改后缀为exe,运行
无壳,放ida分析
定位到main函数
关注三个函数
sub_14000144B(Str, 20i64);
sub_140001596(Str, v4);
sub_14000161C(Str, &v4[5]);
1.sub_14000144B
和上面那道一样的加密方式
2.sub_140001596
循环异或,key是 "GEEK"
3.sub_14000161C
就是一个简单的赋值操作
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
使用pyinstxtractor解包
找到里面的 easy_xor_and_rc4.pyc 文件
找个在线网站反编译
也可以使用uncompyle6库
拿到源码
# 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库,再回去找找
一样的处理,拿到源码:
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进行比较,我们要做的就是逆回去
- 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
- 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
- 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保护,没见过
用ida分析,发现长这样
看不懂一脸懵
查资料
基于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
选择ollvm.json,然后重新反编译
就是对输入的字符串进行加密然后与目标字符串比较,重点关注encrypto
看不懂,浇给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算法和花指令)
ida分析,发现红了
发现这里有一些无意义的跳转
nop一下就好了
f5反编译
重点关注enc函数
确信是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分析,发现报红
经典E8混淆
无脑后发现下面还有混淆
retn干扰了,继续nop
最后弄了好久,总算是勉强能看了(有些地方逻辑还是不太清楚)
重点关注判断部分的代码
unk_2D2C30是目标内容,Buf2是根据输入的字符串加密得来的
加密部分也看不懂
动调试试
盲猜v4 == dword_536004这里在判断字符串长度,内存查看是50,也就是要求输入内容长度是50,随便输50个字符进去↑
重点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
继续步过
拿到v13的值0x5C
而我输入的第一个字符是'1'
异或一下看看是不是 0x6D^0x5C='1'
没问题,那加密逻辑就清晰了
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
关注sub_40167D
老实说数据结构没学好,问了GPT才知道这是树,sub_401597是初始化,sub_401602是后序遍历也就是倒序输出
看后面,
有个Z_change和xor
这个函数是对串入的字符串进行Z字形排列后再输出
逻辑都很清楚
然后想到题目名字ez_hook,就去网上搜了一下
参考Hook原理--逆向开发 - 国孩 - 博客园简单了解了一下hook技术
大概意思就是改变了代码的执行流程,再想到ida中的CheckRemoteDebuggerPresent,明白了静态分析的代码可能不对,要动调
在if ( CheckRemoteDebuggerPresent(hProcess, &pbDebuggerPresent) && pbDebuggerPresent )处下断点
把ZF寄存器改为1即可绕过动调检测
继续跟进,发现程序运行到xor时去了另一个地方
结束后正常返回
确定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
关注sub_55682F272464
直接上动调
sub_55682F2723E2函数是生成a1字符串的md5值(32位)
调试了一会大概理清了整体逻辑:对输入的字符串从第一位开始,每四位将其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");
}
exp2:爆破求flag(感谢密码)
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
知道了密钥,关注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代码,定位到关键验证代码
整体看下来就是获取用户键值,并渲染对应画面以及播放音乐,并将键值拼接成一个字符串,当其md5值等于目标值时渲染最终画面以及播放音乐
再往下看以及结合刚进入页面弹出的输入框不难分析出这是一道迷宫题,正确的输入就是迷宫的走法
再往下看到了方程组,结合控制台输出以及之后的代码,不难确定这是在给特点的坐标“赋值”,也就是确定起点和终点
第一步就是求解方程组拿到起点和终点
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'的位置
继续往下
locate1()在构造初始地图,后面的left、right、down、up等就是相应的左、右、下、上
最后一部分
走迷宫逻辑
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;
}
拿到地图
路径1:STTAAARRRR
路径2:AAATTTTS
一起输入,最终画面(小震撼,出题人NB)
SYC{STTAAARRRRAAATTTTS}
LinkedListModular
知识点:常规逆向,RSA
re crypto交叉题,ELF文件,ida分析
定位到main,
输入一个长度为256位的字符串,然后check,核心就是check了,点进去分析
check()里面主要是利用c的gmp库进行大数运算,无脑读代码
逻辑就是将明文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
又是一堆神奇的加密,简单分析一下换成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处报红,
还是E8,统统nop
进入main
逻辑差不多就是将用户的输入进行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
签到
Truth of Word
word隐写
1.文字与背景颜色一样
2.解压后media文件
- 宏(查了好久,才知道有这东西)
编辑宏
#SYC{W0rd_H@5@_Ama1n9_StrUCtu3e!}
ez_pcap_1
追踪TCP(SMB)流
#SYC{smb_pcapng_1s_g00d!}
cimbar
题目如下
对着表手搓
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
#SYC{An0th3r_Am@z1n9_QR_Co4e}
累死了,以后还是少些脚手架吧
多总结。逆向的路还很长很长~~