2025 ?CTF week3 re wp

questionCTF week3 wp – b0t

re1 BrokenData

根据提示input[10]要么是y要么是Y,都试一下

以Y举例

dump下

key1:

0xA0,0x6A,0x8E,0x86,0x42,0x3C,0x9E,0x27,0x23,0x52,0x7B,0xDA,0x51,0x8D,0x97,0x27

key2:

0x4D,0x71,0x79,0x67,0x80,0xA1,0xF1,0x24,0x27,0x8C,0x8B,0x7C,0x2B,0xB1,0x7D,0x84

Buf1[208] = {

0x81,0x6D,0xF2,0xDA,0x3B,0x09,0xCF,0x85,0xBC,0x3F,0xDC,0x25,0xED,0x45,0x52,0xAF,

0x3A,0xDD,0x51,0x69,0x6B,0x5E,0x97,0x2E,0xF6,0xF4,0x2B,0x3F,0xC9,0x01,0xBC,0xFB,

0xD1,0xA5,0x58,0x8E,0x1F,0xE6,0xB8,0x36,0xA7,0x1E,0xA1,0x9D,0x3E,0x42,0x52,0x6C,

0x91,0xFD,0xDE,0xDC,0x1B,0xD2,0x88,0x3C,0x89,0x48,0x19,0x57,0x2F,0x30,0x03,0x3D,

0x02,0x32,0x8E,0xFC,0x3C,0x5B,0x8A,0x47,0xCA,0xB4,0x3E,0xD3,0x8E,0x05,0x5D,0xCD,

0x8D,0xE7,0xFC,0x29,0xCA,0xBA,0xDE,0x9E,0x6C,0x3B,0x96,0x92,0x0B,0x54,0x7F,0xC6,

0x71,0x4D,0x2A,0x82,0x8F,0x42,0x0C,0x54,0x2C,0x84,0xF8,0x67,0x34,0x7E,0xC8,0x77,

0xE1,0x1B,0x7F,0xDB,0x8B,0x87,0x97,0x01,0x01,0x63,0x14,0x05,0x4D,0xBF,0xCC,0x10,

0x52,0x49,0x87,0xBC,0x5E,0x16,0xEA,0x0F,0x7D,0xF5,0x75,0x8D,0x05,0xB0,0x43,0xF2,

0x57,0xFD,0x7E,0x40,0xFE,0xB4,0x5C,0xA8,0xC0,0x63,0x8B,0x08,0x80,0xE6,0x2B,0x4D,

0x41,0x77,0x71,0x07,0xFC,0x71,0xFE,0x21,0x77,0x07,0x8B,0xE2,0x7D,0x9E,0xB6,0x04,

0x64,0x0D,0xBD,0xE1,0x59,0x10,0x5F,0xA7,0x80,0x08,0xAB,0x96,0x3C,0x34,0xC6,0xBB,

0x81,0x0D,0xE4,0xFA,0x53,0x99,0x22,0xC1,0xC9,0xA7,0xE9,0x39,0x75,0x10,0xDA,0xA4

};

再分析enc函数,跟进enc

void __fastcall enc(char *input, char *key, char *output)
{
  char v3; // al
  int j; // [rsp+30h] [rbp-48h]
  int i; // [rsp+34h] [rbp-44h]
  int v6; // [rsp+38h] [rbp-40h]
  int j_1; // [rsp+3Ch] [rbp-3Ch]
  __int64 bufa[2]; // [rsp+40h] [rbp-38h] BYREF

  v6 = 0;
  for ( i = 0; i < 13; ++i )
  {
    j_1 = dword_7FF6CCFD6180[i];
    memset(bufa, 0, sizeof(bufa));
    for ( j = 0; j < 16; ++j )
    {
      if ( j >= j_1 )
        v3 = input[5];
      else
        v3 = input[j + v6];
      *((_BYTE *)bufa + j) = v3;
    }
    if ( i % 2 )
      sub_7FF6CCFD1AA0(key, 0x10u, (__int64)bufa, (__int64)bufa, 0x10u);
    else
      sub_7FF6CCFD1AA0(key + 16, 0x10u, (__int64)bufa, (__int64)bufa, 0x10u);
    qmemcpy(&output[16 * i], bufa, 0x10uLL);
    v6 += j_1;
  }
}

首先for循环这一段是对56字节加密数据进行填充,挺奇特的填充方式

每一块是16字节,根据dword_7FF6CCFD6180块索引得出的值是原始数据的字节数,每一块赋值dword_7FF6CCFD6180[i]个字节后用input[5]填充

填充完的原文有13x16 = 208字节,跟密文一样

后面这个if判断的逻辑是奇数块用key2加密,偶数块用key1加密

跟进 sub_7FF6CCFD1AA0

__int64 __fastcall sub_7FF6CCFD1AA0(const void *buf_4, unsigned int n16, __int64 buf, __int64 a4, unsigned int i)
{
  unsigned int j; // [rsp+20h] [rbp-1E8h]
  int k; // [rsp+24h] [rbp-1E4h]
  _BYTE *v8; // [rsp+28h] [rbp-1E0h]
  _BYTE buf_1[16]; // [rsp+38h] [rbp-1D0h] BYREF
  _BYTE v11[368]; // [rsp+50h] [rbp-1B8h] BYREF
  _BYTE buf_3[16]; // [rsp+1C0h] [rbp-48h] BYREF
  _BYTE buf_2[16]; // [rsp+1D0h] [rbp-38h] BYREF

  v8 = v11;
  memset(buf_1, 0, sizeof(buf_1));
  memset(buf_2, 0, sizeof(buf_2));
  memset(buf_3, 0, sizeof(buf_3));
  qmemcpy(buf_2, buf_4, n16);
  sub_7FF6CCFD1100(buf_2, 16LL, v11);
  for ( j = 0; j < i; j += 16 )
  {
    sub_7FF6CCFD1000((__int64)buf_3, (_BYTE *)buf);
    sub_7FF6CCFD1490(buf_3, v11);
    for ( k = 1; k < 10; ++k )
    {
      v8 += 16;
      sub_7FF6CCFD1560(buf_3);
      sub_7FF6CCFD15E0(buf_3);
      sub_7FF6CCFD1860(buf_3);
      sub_7FF6CCFD1490(buf_3, v8);
    }
    sub_7FF6CCFD1560(buf_3);
    sub_7FF6CCFD15E0(buf_3);
    sub_7FF6CCFD1490(buf_3, v8 + 16);
    sub_7FF6CCFD1080(buf_3, a4);
    a4 += 16LL;
    buf += 16LL;
    v8 = v11;
  }
  return 0LL;
}

跟进sub_7FF6CCFD1100

__int64 __fastcall sub_7FF6CCFD1100(__int64 a1, int n16, _DWORD *a3)
{
  int i; // [rsp+0h] [rbp-28h]
  int m; // [rsp+4h] [rbp-24h]
  int j; // [rsp+8h] [rbp-20h]
  int k; // [rsp+Ch] [rbp-1Ch]
  _DWORD *v8; // [rsp+10h] [rbp-18h]
  _DWORD *v9; // [rsp+10h] [rbp-18h]
  _DWORD *v10; // [rsp+18h] [rbp-10h]

  if ( !a1 || !a3 )
    return 0xFFFFFFFFLL;
  if ( n16 != 16 )
    return 0xFFFFFFFFLL;
  v8 = a3;
  v10 = a3 + 44;
  for ( i = 0; i < 4; ++i )
    a3[i] = _byteswap_ulong(*(_DWORD *)(4 * i + a1));
  for ( j = 0; j < 10; ++j )
  {
    v8[4] = dword_7FF6CCFD4280[j] ^ byte_7FF6CCFD6080[HIBYTE(v8[3])] ^ (unsigned __int16)(byte_7FF6CCFD6080[(unsigned __int8)v8[3]] << 8) ^ (byte_7FF6CCFD6080[BYTE1(v8[3])] << 16) & 0xFF0000 ^ (byte_7FF6CCFD6080[(unsigned __int8)BYTE2(v8[3])] << 24) ^ *v8;
    v8[5] = v8[4] ^ v8[1];
    v8[6] = v8[5] ^ v8[2];
    v8[7] = v8[6] ^ v8[3];
    v8 += 4;
  }
  v9 = a3 + 40;
  for ( k = 0; k < 11; ++k )
  {
    for ( m = 0; m < 4; ++m )
      v10[m] = v9[m];
    v9 -= 4;
    v10 += 4;
  }
  return 0LL;
}__int64 __fastcall sub_7FF6CCFD1100(__int64 a1, int n16, _DWORD *a3)
{
  int i; // [rsp+0h] [rbp-28h]
  int m; // [rsp+4h] [rbp-24h]
  int j; // [rsp+8h] [rbp-20h]
  int k; // [rsp+Ch] [rbp-1Ch]
  _DWORD *v8; // [rsp+10h] [rbp-18h]
  _DWORD *v9; // [rsp+10h] [rbp-18h]
  _DWORD *v10; // [rsp+18h] [rbp-10h]

  if ( !a1 || !a3 )
    return 0xFFFFFFFFLL;
  if ( n16 != 16 )
    return 0xFFFFFFFFLL;
  v8 = a3;
  v10 = a3 + 44;
  for ( i = 0; i < 4; ++i )
    a3[i] = _byteswap_ulong(*(_DWORD *)(4 * i + a1));
  for ( j = 0; j < 10; ++j )
  {
    v8[4] = dword_7FF6CCFD4280[j] ^ c[HIBYTE(v8[3])] ^ (unsigned __int16)(byte_7FF6CCFD6080[(unsigned __int8)v8[3]] << 8) ^ (byte_7FF6CCFD6080[BYTE1(v8[3])] << 16) & 0xFF0000 ^ (byte_7FF6CCFD6080[(unsigned __int8)BYTE2(v8[3])] << 24) ^ *v8;
    v8[5] = v8[4] ^ v8[1];
    v8[6] = v8[5] ^ v8[2];
    v8[7] = v8[6] ^ v8[3];
    v8 += 4;
  }
  v9 = a3 + 40;
  for ( k = 0; k < 11; ++k )
  {
    for ( m = 0; m < 4; ++m )
      v10[m] = v9[m];
    v9 -= 4;
    v10 += 4;
  }
  return 0LL;
}

查看byte_7FF6CCFD6080

在这里插入图片描述

很标准的AES的S盒

再跟进dword_7FF6CCFD4280也是标准的rcon

猜测是AES加密,奇偶块用的密钥不同

可以直接用赛博厨子梭出来,手动去除填充

在这里插入图片描述

也可以直接写脚本解密



#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <openssl/md5.h>
#include <openssl/aes.h>
#include <stdlib.h>

static const uint8_t Buf1[208] = {
  0x81,0x6D,0xF2,0xDA,0x3B,0x09,0xCF,0x85,0xBC,0x3F,0xDC,0x25,0xED,0x45,0x52,0xAF,
  0x3A,0xDD,0x51,0x69,0x6B,0x5E,0x97,0x2E,0xF6,0xF4,0x2B,0x3F,0xC9,0x01,0xBC,0xFB,
  0xD1,0xA5,0x58,0x8E,0x1F,0xE6,0xB8,0x36,0xA7,0x1E,0xA1,0x9D,0x3E,0x42,0x52,0x6C,
  0x91,0xFD,0xDE,0xDC,0x1B,0xD2,0x88,0x3C,0x89,0x48,0x19,0x57,0x2F,0x30,0x03,0x3D,
  0x02,0x32,0x8E,0xFC,0x3C,0x5B,0x8A,0x47,0xCA,0xB4,0x3E,0xD3,0x8E,0x05,0x5D,0xCD,
  0x8D,0xE7,0xFC,0x29,0xCA,0xBA,0xDE,0x9E,0x6C,0x3B,0x96,0x92,0x0B,0x54,0x7F,0xC6,
  0x71,0x4D,0x2A,0x82,0x8F,0x42,0x0C,0x54,0x2C,0x84,0xF8,0x67,0x34,0x7E,0xC8,0x77,
  0xE1,0x1B,0x7F,0xDB,0x8B,0x87,0x97,0x01,0x01,0x63,0x14,0x05,0x4D,0xBF,0xCC,0x10,
  0x52,0x49,0x87,0xBC,0x5E,0x16,0xEA,0x0F,0x7D,0xF5,0x75,0x8D,0x05,0xB0,0x43,0xF2,
  0x57,0xFD,0x7E,0x40,0xFE,0xB4,0x5C,0xA8,0xC0,0x63,0x8B,0x08,0x80,0xE6,0x2B,0x4D,
  0x41,0x77,0x71,0x07,0xFC,0x71,0xFE,0x21,0x77,0x07,0x8B,0xE2,0x7D,0x9E,0xB6,0x04,
  0x64,0x0D,0xBD,0xE1,0x59,0x10,0x5F,0xA7,0x80,0x08,0xAB,0x96,0x3C,0x34,0xC6,0xBB,
  0x81,0x0D,0xE4,0xFA,0x53,0x99,0x22,0xC1,0xC9,0xA7,0xE9,0x39,0x75,0x10,0xDA,0xA4
};

const int lengths[13] = {1,4,6,9,11,6,3,2,3,1,7,1,2}; // first 13 entries from dword_... (sum == 56)
const char *basekey = "%es_&ou_fou**_ke%"; // 17 bytes

// decrypt one 16-byte block AES-128
void aes_decrypt_block(const uint8_t in[16], uint8_t out[16], const uint8_t key16[16]) {
    AES_KEY dec_key;
    AES_set_decrypt_key(key16, 128, &dec_key);
    AES_decrypt(in, out, &dec_key);
}

// encrypt one 16-byte block AES-128
void aes_encrypt_block(const uint8_t in[16], uint8_t out[16], const uint8_t key16[16]) {
    AES_KEY enc_key;
    AES_set_encrypt_key(key16, 128, &enc_key);
    AES_encrypt(in, out, &enc_key);
}

int try_candidate(char candidate_char) {
    uint8_t key1[16], key2[16];
    uint8_t md[16];
    // key1 = MD5(basekey, 17)
    MD5((const unsigned char*)basekey, 17, md);
    memcpy(key1, md, 16);
    // key2: modified basekey with positions 0,4,16 set to candidate_char, then MD5(...,17)
    char keymod[24];
    memcpy(keymod, basekey, 17);
    keymod[0] = candidate_char;
    keymod[4] = candidate_char;
    keymod[16] = candidate_char;
    MD5((const unsigned char*)keymod, 17, md);
    memcpy(key2, md, 16);

    // reconstruct input (56 bytes)
    unsigned char input[56];
    memset(input, 0, sizeof(input));
    int v6 = 0;
    int seen_input5 = 0;
    unsigned char input5 = 0;

    // For each block i=0..12
    for (int i = 0; i < 13; ++i) {
        const uint8_t *cipher_block = Buf1 + 16*i;
        uint8_t decblk[16];
        // key selection: in original code, if (i % 2) use buf (key1), else use buf+16 (key2)
        const uint8_t *use_key = (i % 2) ? key1 : key2;
        aes_decrypt_block(cipher_block, decblk, use_key);

        int j1 = lengths[i];
        // fill input bytes for j < j1, validate filler for j >= j1
        for (int j = 0; j < 16; ++j) {
            unsigned char v3 = decblk[j];
            if (j < j1) {
                // should map to input[v6 + j]
                int idx = v6 + j;
                if (idx >= 0 && idx < 56) {
                    input[idx] = v3;
                } else {
                    // out of range - fail
                    return 0;
                }
            } else {
                // should equal input[5]
                if (!seen_input5) {
                    input5 = v3;
                    seen_input5 = 1;
                } else {
                    if (input5 != v3) {
                        // inconsistency -> candidate fails
                        return 0;
                    }
                }
            }
        }
        v6 += j1;
    }

    if (!seen_input5) {
        // no filler observed? unlikely, but fail
        return 0;
    }
    // set input[5]
    input[5] = input5;

    // At this point we have a filled 56-byte input. Verify by re-encrypting to produce Buf2 and compare with Buf1.
    // Reproduce enc() exactly and check Buf2 == Buf1
    unsigned char Buf2[208];
    memset(Buf2, 0, sizeof(Buf2));
    v6 = 0;
    for (int i = 0; i < 13; ++i) {
        uint8_t bufa[16];
        int j1 = lengths[i];
        for (int j = 0; j < 16; ++j) {
            if (j >= j1) bufa[j] = input[5];
            else bufa[j] = input[v6 + j];
        }
        // encrypt bufa -> outblk
        uint8_t outblk[16];
        const uint8_t *use_key = (i % 2) ? key1 : key2;
        aes_encrypt_block(bufa, outblk, use_key);
        // copy to Buf2
        memcpy(Buf2 + 16*i, outblk, 16);
        v6 += j1;
    }

    if (memcmp(Buf1, Buf2, sizeof(Buf1)) == 0) {
        // success: print recovered input
        printf("SUCCESS candidate input[10] = '%c'\n", candidate_char);
        printf("Recovered input (56 bytes):\n");
        for (int i = 0; i < 56; ++i) {
            unsigned char c = input[i];
            // print printable or hex escape
            if (c >= 0x20 && c < 0x7f) putchar(c);
            else printf("\\x%02X", c);
        }
        putchar('\n');
        // also print hex
        printf("Hex: ");
        for (int i = 0; i < 56; ++i) printf("%02X ", input[i]);
        printf("\n");
        return 1;
    } else {
        // mismatch
        return 0;
    }
}

int main(void) {
    char candidates[2] = {'y','Y'};
    int found = 0;
    for (int k = 0; k < 2; ++k) {
        if (try_candidate(candidates[k])) {
            found = 1;
            break;
        } else {
            printf("candidate '%c' failed.\n", candidates[k]);
        }
    }
    if (!found) {
        printf("No candidate succeeded. You can try other possible input[10] bytes by modifying the code.\n");
    }
    return 0;
}



编译:gcc -std=c11 -O2 decScript.c -o decScript -lcrypto

运行:./decScript

flag{Wow!_You_restored_the_data_and_this_is_your_reward}

re2 Fisher

根据题目可知有钩子

主函数

int __fastcall main(int argc, const char **argv, const char **envp)
{
  unsigned int v3; // eax
  __int64 argv_1; // rdx
  __int64 envp_1; // r8
  char *Str1; // [rsp+20h] [rbp-98h]
  char input[112]; // [rsp+30h] [rbp-88h] BYREF

  sub_140001970("Give your bait:", argv, envp);
  memset(input, 0, 0x64uLL);
  sub_1400019F0("%s", input);
  v3 = strlen(input);
  Str1 = (char *)sub_1400014B0(input, v3);
  if ( !strcmp(Str1, "tAZ5tAZ5tAZ5vg7F2RZF2RZQ0gv5yCfAxSZKzq==") )
    sub_140001970("The fisherman like your bait.\n", argv_1, envp_1);
  else
    sub_140001970("The fisherman doesn't like your bait.\n", argv_1, envp_1);
  free(Str1);
  system("pause");
  return 0;
}

查找字符串有个strcmp
在这里插入图片描述

交叉引用

char sub_140001020()
{
  HMODULE hModule; // [rsp+20h] [rbp-18h]

  hModule = GetModuleHandleA("ucrtbase.dll");
  strcmp_0 = (int (__cdecl *)(const char *, const char *))GetProcAddress(hModule, "strcmp");
  sub_140001070(strcmp_0, (__int64)a2);
  return 1;
}

勾取了strcmp,跟进a2

__int64 __fastcall a2(_BYTE *i_1)
{
  char v2; // [rsp+20h] [rbp-C8h]
  int k; // [rsp+24h] [rbp-C4h]
  int j; // [rsp+28h] [rbp-C0h]
  _BYTE v5[64]; // [rsp+30h] [rbp-B8h]
  int n64; // [rsp+70h] [rbp-78h]
  _BYTE *i; // [rsp+78h] [rbp-70h]
  _BYTE v9[16]; // [rsp+80h] [rbp-68h] BYREF
  _BYTE buf[64]; // [rsp+90h] [rbp-58h] BYREF

  sub_140001430();
  memset(buf, 0, sizeof(buf));
  n64 = 0;
  for ( i = i_1; *i; ++i )
    ++n64;
  if ( n64 != 64 )
    return 0xFFFFFFFFLL;
  memcpy(buf, i_1, sizeof(buf));
  v9[0] = 17;
  v9[1] = 34;
  v9[2] = 51;
  v9[3] = 68;
  v9[4] = 85;
  v9[5] = 102;
  v9[6] = 119;
  v9[7] = -120;
  for ( j = 0; j < 8; ++j )
    teaenc(&buf[8 * j], v9);
  v5[0] = 8;
  v5[1] = -18;
  v5[2] = 89;
  v5[3] = 77;
  v5[4] = 13;
  v5[5] = -32;
  v5[6] = -64;
  v5[7] = -119;
  v5[8] = -95;
  v5[9] = -104;
  v5[10] = -78;
  v5[11] = -69;
  v5[12] = -49;
  v5[13] = 112;
  v5[14] = 127;
  v5[15] = -27;
  v5[16] = -24;
  v5[17] = 47;
  v5[18] = -102;
  v5[19] = -118;
  v5[20] = 32;
  v5[21] = -53;
  v5[22] = 116;
  v5[23] = 18;
  v5[24] = -14;
  v5[25] = 48;
  v5[26] = 120;
  v5[27] = 31;
  v5[28] = 14;
  v5[29] = -21;
  v5[30] = 31;
  v5[31] = -120;
  v5[32] = -56;
  v5[33] = -68;
  v5[34] = 78;
  v5[35] = -8;
  v5[36] = 82;
  v5[37] = 19;
  v5[38] = 83;
  v5[39] = -117;
  v5[40] = -99;
  v5[41] = -65;
  v5[42] = 102;
  v5[43] = 11;
  v5[44] = 106;
  v5[45] = -84;
  v5[46] = 33;
  v5[47] = 79;
  v5[48] = -23;
  v5[49] = 31;
  v5[50] = 70;
  v5[51] = 70;
  v5[52] = -98;
  v5[53] = -53;
  v5[54] = -6;
  v5[55] = 99;
  v5[56] = -93;
  v5[57] = -123;
  v5[58] = 20;
  v5[59] = -55;
  v5[60] = 46;
  v5[61] = -9;
  v5[62] = 16;
  v5[63] = -59;
  v2 = 1;
  for ( k = 0; k < 64; ++k )
  {
    if ( buf[k] != v5[k] )
    {
      v2 = 0;
      break;
    }
  }
  if ( v2 )
    return 0;
  else
    return (unsigned int)-1;
}

是个tea加密

写出解密脚本


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

#define DELTA 0x6D6DD6D7u

void tea_decrypt_block(uint8_t *c8, uint8_t *out8, uint32_t a2[4]) {
    // load little-endian u32 words
    uint32_t v3 = (uint32_t)c8[0] | ((uint32_t)c8[1] << 8) | ((uint32_t)c8[2] << 16) | ((uint32_t)c8[3] << 24);
    uint32_t v4 = (uint32_t)c8[4] | ((uint32_t)c8[5] << 8) | ((uint32_t)c8[6] << 16) | ((uint32_t)c8[7] << 24);

    uint32_t sum = (uint32_t)(0u - (32u * DELTA));

    for (int i = 0; i < 32; ++i) {
        uint32_t tmp_v4 = ( (a2[3] + (v3 >> 5))
                         ^ ( (sum + v3) )
                         ^ ( (a2[2] + (v3 << 4)) ) );
        v4 -= tmp_v4;
        uint32_t tmp_v3 = ( (a2[1] + (v4 >> 5))
                         ^ ( (sum + v4) )
                         ^ ( (a2[0] + (v4 << 4)) ) );
        v3 -= tmp_v3;
        sum += DELTA;
    }

    out8[0] = (uint8_t)(v3 & 0xFF);
    out8[1] = (uint8_t)((v3 >> 8) & 0xFF);
    out8[2] = (uint8_t)((v3 >> 16) & 0xFF);
    out8[3] = (uint8_t)((v3 >> 24) & 0xFF);
    out8[4] = (uint8_t)(v4 & 0xFF);
    out8[5] = (uint8_t)((v4 >> 8) & 0xFF);
    out8[6] = (uint8_t)((v4 >> 16) & 0xFF);
    out8[7] = (uint8_t)((v4 >> 24) & 0xFF);
}

int main(void) {
    int8_t v5_signed[64] = {
         8, -18,  89,  77,  13, -32, -64, -119,
        -95, -104, -78, -69, -49, 112, 127, -27,
        -24,  47, -102, -118,  32, -53, 116,  18,
        -14,  48, 120,  31,  14, -21,  31, -120,
        -56, -68,  78,  -8,  82,  19,  83, -117,
        -99, -65, 102,  11, 106, -84,  33,  79,
        -23,  31,  70,  70, -98, -53,  -6,  99,
        -93, -123,  20, -55,  46,  -9,  16, -59
    };

    uint8_t ctext[64];
    for (int i = 0; i < 64; ++i) {
        ctext[i] = (uint8_t)v5_signed[i];
    }

    uint8_t v9_bytes[16] = { 17,34,51,68, 85,102,119,(uint8_t) (-120), 0,0,0,0, 0,0,0,0 };
    uint32_t a2[4];
    memcpy(a2, v9_bytes, 16);

    uint8_t plain[64];
    for (int b = 0; b < 8; ++b) {
        tea_decrypt_block(ctext + b*8, plain + b*8, a2);
    }

    printf("Decrypted (ASCII):\n");
    char outstr[65];
    memcpy(outstr, plain, 64);
    outstr[64] = '\0';
    printf("%s\n", outstr);

    printf("\nDecrypted (hex):\n");
    for (int i = 0; i < 64; ++i) {
        printf("%02x", plain[i]);
    }
    printf("\n");

    return 0;
}

再base64
在这里插入图片描述

flag{Fisherman_is_very_satisfied_with_your_bait}

re3 trap

ida打开,给main函数美化一下
在这里插入图片描述

在左边的函数框中发现这个函数

int64 __fastcall sub_7FF6E9D01200(__int64 a1)
{
  int i; // [rsp+20h] [rbp-38h]
  int j; // [rsp+24h] [rbp-34h]
  _BYTE _1i4W[16]; // [rsp+28h] [rbp-30h] BYREF

  qmemcpy(_1i4W, "1i4W", 4);
  _1i4W[4] = -103;
  _1i4W[5] = 53;
  _1i4W[6] = 119;
  _1i4W[7] = 17;
  qmemcpy(&_1i4W[8], "6Rv", 3);
  if ( IsDebuggerPresent() )
  {
    for ( i = 0; i < 32; ++i )
      Buf2[i] ^= i;
    for ( j = 0; j < 11; ++j )
      _1i4W[j] ^= (_BYTE)j + 1;
  }
  qmemcpy(1i4W, _1i4W, 0xBuLL);
  return a1;
}

调试就改变数据

查看pdata段,这个函数在main函数之前就初始化了
在这里插入图片描述

汇编这里jz改成jnz
在这里插入图片描述

再调试,异或表和密文就没有改过

写出脚本:

table = [0x31, 0x69, 0x34, 0x57, 0x99, 0x35, 0x77, 0x11, 0x36, 0x52, 0x76]
buf2 = [
    0x57,0x51,0x04,0x3B,0xD9,0xB6,0xF1,0x96,0xFF,0xC4,0xF2,0x96,0xCC,0xA6,0xB4,0x1B,
    0x4D,0x01,0x60,0x32,0x04,0x2C,0x5B,0x43,0x47,0x72,0xB4,0xB5,0xB0,0x96,0xD0,0xFE
]

length = 0x20
E = buf2[:length]

orig = [0] * length
for i in range(length):
    b = E[i]
    if i > 0:
        b ^= E[i-1]
    if (i % 2) == 1:
        b ^= (table[i % 11] + 1) & 0xFF
    else:
        b ^= table[i % 11]
    orig[i] = b & 0xFF

orig_bytes = bytes(orig)
print(orig_bytes)

flag{Y0u_h@V3_E5c4ped_Fr0m_7r4p}

PS:之前有些反调试好像被我nop掉了

re4 babyre

本来是一个去混淆的题,不知道为什么ida9自动去了混淆。。

// The function seems has been flattened
__int64 __fastcall main(int a1, char **a2, char **a3)
{
  char input[112]; // [rsp+10h] [rbp-E0h] BYREF
  char dest[108]; // [rsp+80h] [rbp-70h] BYREF
  int v6; // [rsp+ECh] [rbp-4h]

  v6 = 0;
  memcpy(dest, &src_, 0x64uLL);
  memset(input, 0, 0x64uLL);
  __isoc99_scanf(&unk_4020E4, input);
  enc(input);
  if ( !strcmp(input, dest) )
    printf("Success!\n");
  else
    printf("Fail!\n");
  return 0LL;
}
// The function seems has been flattened
__int64 __fastcall enc(char *s)
{
  size_t i_2; // rsi
  size_t i_4; // rsi
  __int64 result; // rax
  _QWORD v4[2]; // [rsp+0h] [rbp-60h] BYREF
  int v5; // [rsp+14h] [rbp-4Ch]
  int v6; // [rsp+18h] [rbp-48h]
  int i; // [rsp+1Ch] [rbp-44h]
  char *sa; // [rsp+20h] [rbp-40h]
  _DWORD *v9; // [rsp+28h] [rbp-38h]
  _DWORD *v10; // [rsp+30h] [rbp-30h]
  size_t i_1; // [rsp+38h] [rbp-28h]
  __int64 v12; // [rsp+40h] [rbp-20h]
  int v13; // [rsp+4Ch] [rbp-14h]
  size_t i_3; // [rsp+50h] [rbp-10h]
  int v15; // [rsp+58h] [rbp-8h]
  int v16; // [rsp+5Ch] [rbp-4h]

  v4[1] = s;
  v9 = &v4[-2];
  v10 = &v4[-2];
  sa = s;
  sub_401180();
  v5 = 0;
  v6 = 0;
  for ( i = 0; ; ++i )
  {
    i_1 = i;
    i_2 = strlen(sa);
    if ( i_1 >= i_2 )
      break;
    v6 = (v6 + 1) % 256;
    v5 = ((unsigned __int8)byte_404070[v6] + v5) % 256;
    *v10 = (unsigned __int8)byte_404070[v6];
    v12 = v5;
    byte_404070[v6] = byte_404070[v5];
    byte_404070[v5] = *v10;
    *v9 = (unsigned __int8)byte_404070[((unsigned __int8)byte_404070[v5] + (unsigned __int8)byte_404070[v6]) % 256];
    sa[i] ^= *v9;
    v13 = i + 1;
  }
  for ( i = 0; ; ++i )
  {
    i_3 = i;
    i_4 = strlen(sa);
    LODWORD(result) = 746392057;
    if ( i_3 >= i_4 )
      break;
    v15 = (unsigned __int8)(8 * sa[i]);
    sa[i] = ((int)(unsigned __int8)sa[i] >> 5) | v15;
    v16 = i + 1;
  }
  return result;
}
// The function seems has been flattened
__int64 sub_401180()
{
  __int64 result; // rax
  size_t v1; // rsi
  size_t v2; // [rsp+0h] [rbp-50h] BYREF
  unsigned int v3; // [rsp+14h] [rbp-3Ch]
  int v4; // [rsp+18h] [rbp-38h]
  unsigned int i; // [rsp+1Ch] [rbp-34h]
  size_t *v6; // [rsp+20h] [rbp-30h]
  void *dest; // [rsp+28h] [rbp-28h]
  unsigned int i_1; // [rsp+30h] [rbp-20h]
  char i_2; // [rsp+37h] [rbp-19h]
  unsigned int i_3; // [rsp+38h] [rbp-18h]
  unsigned int v11; // [rsp+3Ch] [rbp-14h]
  unsigned int i_4; // [rsp+40h] [rbp-10h]
  int v13; // [rsp+44h] [rbp-Ch]
  char v14; // [rsp+4Bh] [rbp-5h]
  unsigned int v15; // [rsp+4Ch] [rbp-4h]

  v6 = &v2 - 2;
  dest = &v2 - 14;
  memcpy(&v2 - 14, &src__0, 0x64uLL);
  for ( i = 0; ; ++i )
  {
    i_1 = i;
    if ( i >= 256 )
      break;
    i_2 = i;
    i_3 = i;
    byte_404070[i] = i;
    v11 = i + 1;
  }
  v3 = 0;
  v4 = 0;
  for ( i = 0; ; ++i )
  {
    i_4 = i;
    LODWORD(result) = 0x6C3830AE;
    if ( i >= 256 )
      break;
    *(_DWORD *)v6 = (unsigned __int8)byte_404070[i];
    v13 = *(_DWORD *)v6 + v4;
    v14 = *((_BYTE *)dest + v3);
    v4 = (unsigned __int8)(v14 + v13);
    byte_404070[i] = byte_404070[(unsigned __int8)(v14 + v13)];
    byte_404070[v4] = *(_DWORD *)v6;
    v2 = ++v3;
    v1 = strlen((const char *)dest);
    if ( v2 >= v1 )
      v3 = 0;
    v15 = i + 1;
  }
  return result;
}

一个rc4再循环左移3

写出脚本

src0 = [0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF]  
dest = [0xC6, 0xAC, 0xEE, 0x8B, 0x57, 0x04, 0x64, 0x3A,
        0xA7, 0x3B, 0x84, 0x67, 0xAC, 0xD7, 0x8E, 0xD8,
        0x1D, 0x03, 0x85, 0x55, 0xF6, 0x51, 0x90]
def rc4_init(key):
    S = list(range(256))
    j = 0
    for i in range(256):
        j = (j + S[i] + key[i % len(key)]) & 0xFF
        S[i], S[j] = S[j], S[i]
    return S
def rc4_crypt(data, S):
    i = j = 0
    out = []
    for byte in data:
        i = (i + 1) & 0xFF
        j = (j + S[i]) & 0xFF
        S[i], S[j] = S[j], S[i]
        K = S[(S[i] + S[j]) & 0xFF]
        out.append(byte ^ K)
    return out
def ror3(x):
    return ((x >> 3) | ((x << 5) & 0xFF)) & 0xFF

rot_reversed = [ror3(x) for x in dest]

S = rc4_init(src0)
plain_bytes = rc4_crypt(rot_reversed, S)

flag = bytes(plain_bytes).decode()
print(flag)

re5 ezmath

用Z3求解

import z3
s = z3.Solver()
flag = [z3.BitVec('%d' % i,8) for i in range(80)]
v = {}
for n in range(4,83):
    v[n] = flag[83 - n]
s0 = flag[0]
s.add(93 * v[55] == 131)
s.add(-92 * v[55] + 91 * v[20] == 98)
s.add(79 * v[48] - 117 * v[55] - 55 * v[20] == 88)
s.add(121 * v[59] + 58 * v[55] -124 * v[20] + 104 * v[48] == 221)
s.add(2 * v[59] - 85 * v[55] + 44 * v[20] - 100 * v[48] - 47 * v[4] == 156)
s.add(-67 * v[48] - 110 * v[55] -10 * v[59] + 57 * v[58] + 11 * v[4] + 27 * v[20] == 146)
s.add(110 * v[55] + 53 * v[58] + 47 * v[62] - 22 * v[59] -72 * v[20] - 18 * v[48] - 110 * v[4] == 249)
s.add(120 * v[55] + 115 * v[58] + 34 * v[62] + 90 * v[59] + 86 * v[20] + 126 * v[48] -63 * v[4] - 75 * v[15] == 19)
s.add(46 * v[55] - 84 * v[58] -18 * v[59] - 96 * v[62] + 17 * v[29] -119 * v[48] -9 * v[15] + 81 * v[20] + 18 * v[4] == 225)
s.add(-86 * v[62] + 104 * v[59] + 26 * v[55] + 124 * v[58] -117 * v[20] + 48 * v[29] + 107 * v[6] - 83 * v[15] - 101 * v[4] == 64)
s.add(28 * v[6] + 100 * v[15] + 90 * v[20] + 117 * v[29] + 79 * v[77] - 30 * v[62] -41 * v[55] - 14 * v[58] - 24 * v[4] == 206)
s.add(40 * v[48] + 59 * v[51] + 50 * v[58] + 123 * v[59] -115 * v[62] + 80 * v[77] + 74 * v[20] - 80 * v[29] - 103 * v[4] == 50)
s.add(36 * v[58] + 89 * v[59] + 31 * v[62] + 85 * v[73] -77 * v[51] + 95 * v[55] + 8 * v[20] + 39 * v[48] + 9 * v[6] == 167)
s.add(-33 * v[48] + 92 * v[55] + 6 * v[59] - 59 * v[62] + 68 * v[77] + 57 * v[69] + 7 * v[15] + 20 * v[20] - 100 * v[4] == 121)
s.add(122 * v[77] - 46 * v[59] -54 * v[51] + 40 * v[58] -45 * v[38] + 91 * v[48] + 30 * v[6] + 96 * v[20] - 105 * v[4] == 200)
s.add(-106 * v[55] - 111 * v[58] + 72 * v[59] + 28 * v[73] -53 * v[77] + 39 * v[75] + 58 * v[38] + 90 * v[51] + 68 * v[6] == 98)
s.add(-65 * v[6] + 66 * v[29] -91 * v[38] + 51 * v[41] -14 * v[51] - 72 * v[55] -68 * v[69] + 103 * v[59] + 11 * v[4] == 90)
s.add(-117 * v[29] + 56 * v[38] + 10 * v[41] + 81 * v[48] + 41 * v[51] - 13 * v[53] -27 * v[77] - 97 * v[62] - 48 * v[6] == 51)
s.add(-120 * v[38] - 39 * v[41] + 120 * v[53] - 99 * v[59] + 127 * v[62] - 16 * v[73] -71 * v[20] - 97 * v[37] + 42 * v[6] == 136)
s.add(111 * v[31] - 18 * v[37] -115 * v[73] + 30 * v[55] -39 * v[48] + 25 * v[53] -123 * v[15] + 92 * v[20] - 72 * v[6] == 45)
s.add(34 * v[77] + 90 * v[75] + 113 * v[54] + 14 * v[59] -68 * v[48] + 19 * v[51] + 78 * v[38] - 25 * v[41] - 59 * v[15] == 150)
s.add(-60 * v[37] + 38 * v[38] + 79 * v[47] -121 * v[51] + 119 * v[73] - 53 * v[53] + 93 * v[20] - 69 * v[29] - 95 * v[4] == 117)
s.add(97 * v[41] + 76 * v[48] + 27 * v[54] + 23 * v[55] + 45 * v[77] - 76 * v[59] -107 * v[29] + 124 * v[31] + 47 * v[5] == 155)
s.add(-119 * v[37] - 22 * v[38] + 43 * v[47] + 124 * v[58] -45 * v[77] + 38 * v[59] + 127 * v[31] -119 * v[35] + 46 * v[15] == 117)
s.add(-2 * v[35] + 10 * v[37] -75 * v[41] + 4 * v[51] + 77 * v[62] - 72 * v[55] + 69 * v[22] + 82 * v[31] + 112 * v[20] == 16)
s.add(-65 * v[81] - 58 * v[59] + 22 * v[37] - 58 * v[54] + 69 * v[22] + 33 * v[35] -124 * v[6] + 60 * v[20] + 74 * v[4] == 23)
s.add(-72 * v[20] + 71 * v[22] -80 * v[29] - 98 * v[31] + 7 * v[34] + 65 * v[38] -93 * v[69] + 16 * v[62] + 7 * v[6] == 124)
s.add(-38 * v[29] + 117 * v[31] + 67 * v[59] + 5 * v[58] -59 * v[38] - 14 * v[41] + 34 * v[6] - 11 * v[12] + 34 * v[5] == 210)
s.add(15 * v[31] + 84 * v[34] -127 * v[58] - 5 * v[37] -94 * v[81] - 91 * v[59] -104 * v[12] + 61 * v[23] - 73 * v[4] == 217)
s.add(-73 * v[34] - 117 * v[35] -68 * v[38] + 119 * v[69] + 17 * v[74] -119 * v[81] + 31 * v[23] + 30 * v[31] -123 * v[5] == 59)
s.add(61 * v[72] - 60 * v[74] -2 * v[41] - 17 * v[55] + 89 * v[35] + 9 * v[37] -29 * v[6] - 67 * v[31] + 44 * v[5] == 134)
s.add(-102 * v[77] + 43 * v[81] + 2 * v[59] - 93 * v[62] + 25 * v[41] + 40 * v[48] + 29 * v[23] + 41 * v[35] + 95 * v[16] == 139)
s.add(-36 * v[16] + 123 * v[23] -107 * v[77] - 63 * v[57] + 94 * v[47] - 69 * v[52] + 97 * v[29] - 30 * v[34] -82 * v[4] + 29 * v[12] == 139)
s.add(-62 * v[29] - 89 * v[31] + 68 * v[38] - 95 * v[62] + 110 * v[81] - 65 * v[77] + 73 * v[18] - 22 * v[23] - 59 * v[4] == 30)
s.add(-20 * v[12] + 60 * v[37] + 104 * v[81] + 43 * v[74] -8 * v[69] - 5 * v[73] + 32 * v[59] - 47 * v[60] + 12 * v[4] == 63)
s.add(-25 * v[19] - 114 * v[35] + 104 * v[69] - 22 * v[60] -61 * v[51] - 59 * v[58] -7 * v[47] - 58 * v[49] -97 * v[5] - 65 * v[6] == 230)
s.add(-39 * v[31] + 111 * v[32] -30 * v[48] - 92 * v[54] + 5 * v[55] - 28 * v[57] -6 * v[18] + 22 * v[19] + 61 * v[4] == 224)
s.add(89 * v[20] - 107 * v[37] -120 * v[41] + 29 * v[48] + 117 * v[64] + 110 * v[59] -77 * v[53] + 12 * v[55] + 80 * v[12] == 6)
s.add(76 * v[41] + 71 * v[58] + 19 * v[61] - 45 * v[69] -61 * v[73] + 36 * v[74] -74 * v[20] + 45 * v[34] - 20 * v[16] == 81)
s.add(-48 * v[19] + 17 * v[32] + 115 * v[38] - 18 * v[53] -14 * v[62] + 43 * v[79] -25 * v[5] - 58 * v[15] + 117 * v[4] == 76)
s.add(58 * v[22] - 82 * v[29] -77 * v[31] + 69 * v[44] -64 * v[51] - 75 * v[55] -12 * v[60] + 47 * v[66] + 95 * v[4] + 62 * v[19] == 78)
s.add(38 * v[58] - 44 * v[61] + 109 * s0 -107 * v[75] + 20 * v[29] - 74 * v[53] -39 * v[6] + 80 * v[18] + 101 * v[4] == 115)
s.add(-122 * v[18] - 49 * v[29] + 3 * v[51] + 34 * v[57] -17 * v[66] + 109 * v[61] + 91 * v[7] - 10 * v[16] + 76 * v[5] == 19)
s.add(72 * v[32] + 57 * v[35] + 19 * v[42] - 92 * v[57] + 17 * v[58] + 16 * v[62] + 68 * v[73] + 84 * v[64] + 127 * v[15] == 27)
s.add(-15 * v[47] + 80 * v[53] -73 * v[81] + 72 * v[77] + 16 * v[55] + 38 * v[57] -33 * v[32] -121 * v[40] + 123 * v[22] == 29)
s.add(-5 * v[68] - 8 * v[79] + 74 * v[58] + 70 * v[66] + 88 * v[32] + 40 * v[53] + 17 * v[7] + 90 * v[29] -102 * v[5] == 172)
s.add(-8 * v[29] + 122 * v[58] + 91 * v[60] + 71 * v[62] + 10 * v[66] -118 * v[72] -114 * v[20] - 72 * v[22] - 25 * v[8] == 158)
s.add(-68 * v[73] - 33 * v[72] -27 * v[63] + 104 * v[69] -114 * v[40] + 41 * v[62] -114 * v[8] + 28 * v[29] - 78 * v[7] == 94)
s.add(67 * v[20] - 106 * v[42] -36 * v[53] + 71 * v[64] + 109 * v[78] - 98 * v[66] -29 * v[6] - 88 * v[7] -117 * v[4] == 176)
s.add(-23 * v[81] - 57 * v[80] + 77 * v[68] - 68 * v[75] -94 * v[64] + 15 * v[66] + 66 * v[35] - 80 * v[42] + 59 * v[19] == 254)
s.add(97 * v[76] - 126 * v[66] -90 * v[54] - 60 * v[63] + 34 * v[48] + 45 * v[51] + 53 * v[18] + 7 * v[37] -105 * v[15] == 46)
s.add(-59 * v[20] + 66 * v[33] -47 * v[61] + 2 * v[62] + 44 * v[74] + 51 * v[79] + 83 * v[82] + 98 * v[80] + 20 * v[8] -81 * v[19] == 45)
s.add(29 * v[38] - 107 * v[46] -105 * v[58] - 90 * v[66] -58 * v[76] - 41 * v[72] -67 * v[5] + 98 * v[6] -125 * v[4] == 199)
s.add(-102 * v[41] - 73 * v[45] -10 * v[76] - 75 * v[64] + 127 * v[59] + 1 * v[46] -123 * v[32] - 92 * v[40] -102 * v[12] == 164)
s.add(82 * v[12] - 27 * v[28] + 111 * v[73] + 97 * v[62] -1 * v[80] + 79 * v[29] + 22 * v[41] + 86 * v[4] - 87 * v[5] == 248)
s.add(-21 * v[80] - 102 * v[79] -107 * v[68] + 58 * v[72] -93 * v[56] - 14 * v[57] + 37 * v[23] + 68 * v[40] + 84 * v[16] == 116)
s.add(62 * v[29] - 20 * v[35] + 107 * v[41] + 30 * v[60] -37 * v[80] - 2 * v[76] + 40 * v[20] + 13 * v[28] -107 * v[14] == 118)
s.add(113 * v[55] + 107 * v[70] -13 * v[72] - 28 * v[78] + 41 * v[38] + 122 * v[53] -95 * v[27] + 40 * v[31] -99 * v[4] - 79 * v[6] == 119)
s.add(-85 * v[31] + 21 * v[44] + 50 * v[70] + 55 * v[61] -115 * v[51] - 40 * v[59] + 110 * v[6] + 11 * v[16] + 15 * v[5] == 0)
s.add(39 * v[71] - 95 * v[68] + 48 * v[57] + 105 * v[62] + 32 * v[48] - 78 * v[51] + 56 * v[37] - 89 * v[41] + 99 * v[34] == 164)
s.add(17 * v[48] - 94 * v[51] -12 * v[54] - 19 * v[59] -28 * v[62] + 17 * v[65] + 45 * v[81] - 27 * v[66] -126 * v[24] - 45 * v[35] == 214)
s.add(-121 * v[41] + 120 * v[64] + 72 * v[76] -116 * v[79] + 110 * v[32] + 55 * v[38] -41 * v[19] - 4 * v[23] + 59 * v[9] == 231)
s.add(-73 * v[76] - 118 * v[69] + 69 * v[55] + 14 * v[68] -3 * v[36] - 111 * v[40] + 125 * v[14] - 72 * v[16] - 18 * v[4] == 138)
s.add(-80 * v[58] + 97 * v[61] -92 * v[68] - 99 * v[69] + 108 * v[82] - 20 * v[75] -73 * v[46] + 90 * v[51] - 69 * v[11] == 85)
s.add(71 * v[50] + 88 * v[53] -97 * v[78] + 34 * v[80] -31 * v[56] - 53 * v[60] -76 * v[14] - 47 * v[42] - 89 * v[5] == 72)
s.add(-57 * v[55] + 114 * v[62] -69 * v[65] + 59 * v[79] -100 * s0 + 118 * v[81] -14 * v[18] + 111 * v[25] + 60 * v[16] == 66)
s.add(51 * v[43] - 15 * v[45] + 9 * v[46] - 85 * v[47] -53 * v[74] + 75 * v[61] -62 * v[35] - 37 * v[40] + 4 * v[15] == 250)
s.add(23 * v[29] + 59 * v[30] -109 * v[37] + 90 * v[54] -66 * v[58] - 86 * v[68] + 27 * v[81] -65 * s0 -69 * v[5] + 91 * v[17] == 126)
s.add(94 * v[48] - 7 * v[56] -49 * v[72] - 65 * v[73] + 27 * v[76] + 74 * v[82] -48 * v[23] - 87 * v[35] - 39 * v[21] == 250)
s.add(19 * v[33] + 122 * v[51] + 66 * v[60] + 64 * v[74] -85 * v[80] - 89 * v[78] + 95 * v[19] + 42 * v[22] -127 * v[16] == 147)
s.add(3 * v[54] - 93 * v[66] -93 * v[67] + 29 * v[68] + 50 * v[82] -123 * v[78] -80 * v[23] -114 * v[47] - 71 * v[6] == 243)
s.add(117 * v[82] + 15 * v[64] -97 * v[53] + 25 * v[55] -51 * v[28] + 29 * v[31] -86 * v[15] + 25 * v[25] + 109 * v[10] == 109)
s.add(-81 * v[37] - 99 * v[38] -87 * v[79] + 13 * v[75] + 69 * v[47] + 13 * v[62] -70 * v[7] - 81 * v[13] -123 * v[4] == 136)
s.add(-61 * v[29] - 33 * v[30] -69 * v[49] - 66 * v[55] + 40 * v[56] - 56 * v[71] + 52 * v[80] - 65 * v[78] -75 * v[11] + 16 * v[25] == 125)
s.add(-42 * v[10] + 59 * v[13] -20 * v[22] - 71 * v[39] -89 * v[46] + 121 * v[50] -38 * v[67] + 71 * v[79] + 1 * v[60] - 24 * v[6] == 97)
s.add(55 * v[26] - 49 * v[29] -99 * v[38] + 102 * v[68] -112 * v[69] + 86 * v[76] -61 * v[14] + 58 * v[21] - 41 * v[7] == 206)
s.add(44 * v[35] - 74 * v[37] -84 * v[42] -119 * v[54] + 96 * v[78] + 24 * v[80] + 90 * v[26] - 89 * v[27] -109 * v[6] == 69)
s.add(49 * v[24] + 85 * v[29] -78 * v[34] + 123 * v[38] -127 * v[58] - 9 * v[54] + 125 * v[70] + 128 * s0 + 81 * v[4] == 253)
s.add(-64 * v[39] - 57 * v[43] + 39 * s0 - 18 * v[65] + 40 * v[36] -124 * v[37] + 9 * v[30] - 5 * v[17] + 74 * v[12] == 168)
s.add(8 * v[18] + 109 * v[28] + 79 * v[54] - 26 * v[68] -92 * v[75] + 26 * v[72] + 108 * v[30] + 117 * v[52] + 101 * v[9] == 132)
if s.check() == z3.sat:
    m = s.model()
    f = ''.join(chr(m[flag[i]].as_long()) for i in range(80))
    print(f)
else:
    print('unsat')

flag{we1COME_7#_THe_zE_Wor1d_HOpe_You_3NjOY_it_bjjf2xmDY2hEWJDarycY4RMpKlB?dSkt}

re6 strangeEnc

ida打开,8字节一块的加密,而且用#填充

int __fastcall main(int argc, const char **argv, const char **envp)
{
  size_t v3; // rax
  size_t v4; // rax
  char *input; // rbx
  char *input_2; // rbp
  unsigned __int64 *input_1; // rcx
  __int64 i; // rax

  _main(argc, argv, envp);
  printf("input your flag:\n");
  scanf("%s", input);
  v3 = strlen(input);
  if ( (v3 & 7) != 0 )
  {
    strncat(input, "#######", 8 - (v3 & 7));
    v3 = strlen(input);
  }
  v4 = v3 >> 3;
  if ( (_DWORD)v4 )
  {
    input = input;
    input_2 = &input[8 * (unsigned int)(v4 - 1) + 8];
    do
    {
      input_1 = (unsigned __int64 *)input;
      input += 8;
      sub_7FF6B20E1CC0(input_1, "Koishi__");
    }
    while ( input != input_2 );
  }
  for ( i = 0LL; i != 40; ++i )
  {
    if ( input[i] != ans[i] )
    {
      printf("wrong \n");
      return 0;
    }
  }
  printf("right \n");
  return 0;
}

跟进加密函数sub_7FF6B20E1CC0

unsigned __int64 *__fastcall sub_7FF6B20E1CC0(unsigned __int64 *input, _QWORD *Koishi__)
{
  __int64 v2; // rsi
  __int64 v3; // rax
  unsigned __int64 v4; // rbx
  __int64 *v5; // rdx
  char v6; // cl
  __int64 v7; // rax
  int *v8; // rdi
  __int64 v9; // r10
  unsigned __int64 v10; // r8
  __int64 *v11; // rdx
  char v12; // cl
  unsigned int v13; // eax
  unsigned int v14; // eax
  unsigned int v15; // r8d
  unsigned __int64 v16; // r10
  __int64 *v17; // rdx
  char v18; // cl
  __int64 v19; // rax
  int v20; // eax
  __int64 v21; // r8
  __int64 *v22; // r11
  unsigned __int64 v23; // rsi
  unsigned __int64 v24; // r8
  char v25; // cl
  __int64 v26; // rax
  unsigned __int64 *input_1; // rax
  int v28; // [rsp+2Ch] [rbp-8Ch]
  __int64 v29; // [rsp+30h] [rbp-88h] BYREF
  __int64 v30; // [rsp+38h] [rbp-80h]
  __int64 v31; // [rsp+40h] [rbp-78h]
  __int64 v32; // [rsp+48h] [rbp-70h]
  __int64 v33; // [rsp+50h] [rbp-68h] BYREF
  __int64 v34; // [rsp+58h] [rbp-60h]
  __int64 v35; // [rsp+60h] [rbp-58h] BYREF
  __int64 v36; // [rsp+68h] [rbp-50h]
  _BYTE v37[72]; // [rsp+70h] [rbp-48h] BYREF

  v2 = 0LL;
  v3 = sub_7FF6B20E1360(*Koishi__);
  sub_7FF6B20E1550(v3);
  v4 = *input;
  v30 = 0x40C141C242C343CLL;
  v29 = 0x20A121A222A323ALL;
  v31 = 0x60E161E262E363ELL;
  v33 = 0x109111921293139LL;
  v32 = 0x810182028303840LL;
  v35 = 0x50D151D252D353DLL;
  v34 = 0x30B131B232B333BLL;
  v36 = 0x70F171F272F373FLL;
  v5 = &v29;
  do
  {
    v6 = (unsigned __int8)&v29 + 63 - (_BYTE)v5;
    v7 = (v4 >> (64 - *(_BYTE *)v5)) & 1;
    v5 = (__int64 *)((char *)v5 + 1);
    v2 |= v7 << v6;
  }
  while ( v37 != (_BYTE *)v5 );
  v8 = (int *)&Keys;
  v28 = HIDWORD(v2);
  while ( 1 )
  {
    v9 = *(_QWORD *)v8;
    v10 = 0LL;
    v29 = 0x504050403020120LL;
    v31 = 0x11100F0E0D0C0D0CLL;
    v30 = 0xB0A090809080706LL;
    v33 = 0x1B1A191819181716LL;
    v32 = 0x1514151413121110LL;
    v34 = 0x1201F1E1D1C1D1CLL;
    v11 = &v29;
    do
    {
      v12 = (unsigned __int8)&v29 + 47 - (_BYTE)v11;
      v13 = ((unsigned int)v2 >> (32 - *(_BYTE *)v11)) & 1;
      v11 = (__int64 *)((char *)v11 + 1);
      v10 |= v13 << v12;
    }
    while ( &v35 != v11 );
    v14 = sub_7FF6B20E19B0(v10 ^ v9);
    v15 = 0;
    v16 = v14;
    v30 = 0xA1F12051A170F01LL;
    v29 = 0x111C0C1D15140710LL;
    v31 = 0x9031B200E180802LL;
    v32 = 0x19040B16061E0D13LL;
    v17 = &v29;
    do
    {
      v18 = (unsigned __int8)&v29 + 31 - (_BYTE)v17;
      v19 = (v16 >> (32 - *(_BYTE *)v17)) & 1;
      v17 = (__int64 *)((char *)v17 + 1);
      v15 |= v19 << v18;
    }
    while ( &v33 != v17 );
    v20 = v28;
    v8 += 2;
    v28 = v2;
    v21 = v20 ^ v15;
    if ( &initialized == v8 )
      break;
    LODWORD(v2) = v21;
  }
  v22 = &v29;
  v23 = (v21 << 32) | (unsigned int)v2;
  v24 = 0LL;
  v29 = 0x2040183810300828LL;
  v30 = 0x1F3F17370F2F0727LL;
  v31 = 0x1E3E16360E2E0626LL;
  v32 = 0x1D3D15350D2D0525LL;
  v33 = 0x1C3C14340C2C0424LL;
  v34 = 0x1B3B13330B2B0323LL;
  v35 = 0x1A3A12320A2A0222LL;
  v36 = 0x1939113109290121LL;
  do
  {
    v25 = (unsigned __int8)&v29 + 63 - (_BYTE)v22;
    v26 = (v23 >> (64 - *(_BYTE *)v22)) & 1;
    v22 = (__int64 *)((char *)v22 + 1);
    v24 |= v26 << v25;
  }
  while ( v37 != (_BYTE *)v22 );
  input_1 = input;
  *input = v24;
  return input_1;
}

des的盒一个个对照过来,是魔改的一个des加密,而且伪代码里很贴心地标明了key,这就好办了

根据 DES Feistel 结构的对称性,L xor F(R,key)后R和L互换,key在加密时用的是1-16,还原时依旧是用 F(R,key) 来xor L还原出L再互换,所以用key从16-1就行

input patch成密文,每轮换下key,得到flag
在这里插入图片描述

flag{Fun_Fact_its_littleEndian_DES}

re7 wtf

进去一个输入flag的网站
在这里插入图片描述

f12开发者工具
在这里插入图片描述

搜下源码就可以搜到两个js文件

看html的话两个js文件放在这里
在这里插入图片描述

看一下src.js

var _a;
var ___Key = 'Komeji Satori';
var ans = [
  94, 49, 141, 165, 142, 18, 244, 41, 100, 131, 44, 13, 99, 120, 148, 85, 226, 180, 172, 152, 204, 85, 244, 48
];
(_a = document.querySelector('#submit')) === null || _a === void 0 ? void 0 : _a.addEventListener('click', function () {
    var flag = document.querySelector('#input');
    var input = flag.value;
    var bytes = new TextEncoder().encode(input);
    bytes[0] ^= 0x12;
    bytes[1] ^= 0x34;
    bytes[2] ^= 0x56;
    bytes[3] ^= 0x78;
    console.log(___Key);
    bytes = encode(bytes, ___Key);
    for (var i = 0; i < bytes.length; i++) {
        bytes[i] ^= ___Key[i % ___Key.length].charCodeAt(0);
    }
    for (var i = 0; i < ans.length; i++) {
        if (bytes[i] !== ans[i]) {
            document.querySelector('#input').value = 'Wrong flag!';
            return;
        }
    }
    document.querySelector('#input').value = 'Correct flag! you find Koishi!';
    document.body.style.backgroundImage = 'url(\'koishi.webp\')';
    document.body.style.backgroundPosition = 'center';
});
function encode(input, key) {
    var _a;
    var keyBytes = new Uint8Array(16);
    var keyData = new TextEncoder().encode(key);
    for (var i = 0; i < 16; i++) {
        keyBytes[i] = keyData[i % keyData.length];
    }
    var k = new Uint32Array(4);
    for (var i = 0; i < 4; i++) {
        k[i] = (keyBytes[i * 4] << 24) | (keyBytes[i * 4 + 1] << 16) |
            (keyBytes[i * 4 + 2] << 8) | keyBytes[i * 4 + 3];
    }
    var DELTA = 0x9e3779b9;
    function teaEncrypt(v0, v1) {
        var sum = 0;
        for (var i = 0; i < 32; i++) {
            sum = (sum + DELTA) >>> 0;
            v0 = (v0 + (((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >>> 5) + k[1]))) >>> 0;
            v1 = (v1 + (((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >>> 5) + k[3]))) >>> 0;
        }
        return [v0, v1];
    }
    var paddedLength = Math.ceil(input.length / 8) * 8;
    var padded = new Uint8Array(paddedLength);
    padded.set(input);
    for (var i = 0; i < paddedLength; i += 8) {
        var v0 = (padded[i] << 24) | (padded[i + 1] << 16) | (padded[i + 2] << 8) |
            padded[i + 3];
        var v1 = (padded[i + 4] << 24) | (padded[i + 5] << 16) |
            (padded[i + 6] << 8) | padded[i + 7];
        _a = teaEncrypt(v0, v1), v0 = _a[0], v1 = _a[1];
        padded[i] = (v0 >>> 24) & 0xFF;
        padded[i + 1] = (v0 >>> 16) & 0xFF;
        padded[i + 2] = (v0 >>> 8) & 0xFF;
        padded[i + 3] = v0 & 0xFF;
        padded[i + 4] = (v1 >>> 24) & 0xFF;
        padded[i + 5] = (v1 >>> 16) & 0xFF;
        padded[i + 6] = (v1 >>> 8) & 0xFF;
        padded[i + 7] = v1 & 0xFF;
    }
    if (input.length < paddedLength) {
        var newInput = new Uint8Array(paddedLength);
        newInput.set(input);
        input = newInput;
    }
    for (var i = 0; i < paddedLength; i++) {
        input[i] = padded[i];
    }
    return input;
}

异或+tea

div.js粘进控制台运行
在这里插入图片描述

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;___Key = 'K0meji_K0ishi';
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;___Key.toString = function() {
    return 'Komeji Satori';
}
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;var Ori = console.log;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;console.log = function(...args) {
    for (var i = 0; i < args.length; i++) {
        if (args[i] == ___Key) {
            args[i] = 'Komeji Satori';
        }
    }
    Ori(...args);
}
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;___Key = 'K0meji_K0ishi';
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;___Key.toString = function() {
    return 'Komeji Satori';
}
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;var Ori = console.log;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;console.log = function(...args) {
    for (var i = 0; i < args.length; i++) {
        if (args[i] == ___Key) {
            args[i] = 'Komeji Satori';
        }
    }
    Ori(...args);
}
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

key被换成了K0meji_K0ishi

写脚本解密

def tea_decrypt(v0, v1, k):
    DELTA = 0x9e3779b9
    sum_ = DELTA * 32 
    for _ in range(32):
        v1 = (v1 - (((v0 << 4) + k[2]) ^ (v0 + sum_) ^ ((v0 >> 5) + k[3]))) & 0xFFFFFFFF
        v0 = (v0 - (((v1 << 4) + k[0]) ^ (v1 + sum_) ^ ((v1 >> 5) + k[1]))) & 0xFFFFFFFF
        sum_ = (sum_ - DELTA) & 0xFFFFFFFF
    return v0, v1


ans = [94, 49, 141, 165, 142, 18, 244, 41, 100, 131, 44, 13, 99, 120, 148, 85, 226, 180, 172, 152, 204, 85, 244, 48]
key = 'K0meji_K0ishi'
key_bytes = [ord(c) for c in key]

step1 = [ans[i] ^ key_bytes[i % len(key_bytes)] for i in range(len(ans))]

key_16 = [key_bytes[i % len(key_bytes)] for i in range(16)]
k = [
    (key_16[0] << 24) | (key_16[1] << 16) | (key_16[2] << 8) | key_16[3],
    (key_16[4] << 24) | (key_16[5] << 16) | (key_16[6] << 8) | key_16[7],
    (key_16[8] << 24) | (key_16[9] << 16) | (key_16[10] << 8) | key_16[11],
    (key_16[12] << 24) | (key_16[13] << 16) | (key_16[14] << 8) | key_16[15]
]

step2 = []
for i in range(0, len(step1), 8):
    v0 = (step1[i] << 24) | (step1[i + 1] << 16) | (step1[i + 2] << 8) | step1[i + 3]
    v1 = (step1[i + 4] << 24) | (step1[i + 5] << 16) | (step1[i + 6] << 8) | step1[i + 7]

    decrypted_v0, decrypted_v1 = tea_decrypt(v0, v1, k)

    step2.extend([
        (decrypted_v0 >> 24) & 0xFF,
        (decrypted_v0 >> 16) & 0xFF,
        (decrypted_v0 >> 8) & 0xFF,
        decrypted_v0 & 0xFF,
        (decrypted_v1 >> 24) & 0xFF,
        (decrypted_v1 >> 16) & 0xFF,
        (decrypted_v1 >> 8) & 0xFF,
        decrypted_v1 & 0xFF
    ])

step3 = step2.copy()
if len(step3) >= 4:
    step3[0] ^= 0x12
    step3[1] ^= 0x34
    step3[2] ^= 0x56
    step3[3] ^= 0x78

flag_bytes = bytes(step3)
print("flag:", flag_bytes)

flag: b’flag{JS_1s_V3rY_dyN4M1C}’

标题基于SpringBoot的校园创客空间管理系统设计与实现AI更换标题第1章引言介绍校园创客空间管理系统的研究背景、意义、国内外研究现状、论文方法与创新点。1.1研究背景与意义阐述校园创客空间的发展现状及其对管理系统的需求。1.2国内外研究现状分析国内外校园创客空间管理系统的研究进展。1.3研究方法及创新点概述本文采用的研究方法及系统设计的创新点。第2章相关理论总结SpringBoot框架及相关技术,确立系统设计的理论基础。2.1SpringBoot框架概述介绍SpringBoot框架的特点、优势及在Web开发中的应用。2.2相关技术总结概述数据库技术、前端技术及系统安全技术等。2.3理论基础确立基于上述理论,确立校园创客空间管理系统的设计基础。第3章系统需求分析详细分析校园创客空间管理系统的功能需求、性能需求及用户需求。3.1功能需求分析列举系统应具备的核心功能,如用户管理、项目管理等。3.2性能需求分析分析系统对响应时间、并发处理能力等性能指标的要求。3.3用户需求分析从用户角度出发,分析用户对系统的期望和需求。第4章系统设计详细介绍系统的架构设计、数据库设计及界面设计。4.1系统架构设计给出系统的整体架构,包括前后端分离、微服务架构等。4.2数据库设计设计系统的数据库结构,包括表结构、索引及关系等。4.3界面设计展示系统的用户界面设计,包括页面布局、交互设计等。第5章系统实现与测试阐述系统的实现过程,包括编码实现、系统集成及测试验证。5.1编码实现介绍系统各模块的编码实现过程及关键技术点。5.2系统集成系统各模块之间的集成方式及集成测试过程。5.3测试验证通过单元测试、集成测试等方法验证系统的功能和性能。第6章结论与展望总结系统设计与实现的主要成果,提出未来研究方向。6.1研究结论概括系统设计与实现的主要成果,包括功能实现、性能优化等。6.2展望指出系统存在的不足及
内容概要:本文系统研究了基于分布式模型预测控制(DMPC)的多个固定翼无人机一致性控制问题,提出并实现了相应的Matlab仿真方案。通过建立固定翼无人机精确的动力学模型,结合分布式控制架构,采用模型预测控制策略,使多个无人机在无中央协调的情况下实现状态一致性,如位置、速度和航向的协同收敛。文中详尽阐述了系统建模、控制算法设计、一致性协议构建及Matlab代码实现过程,重点解决了通信延迟、局部信息交互受限以及动态环境适应性等关键技术难点,并通过大量仿真实验验证了该方法的有效性、鲁棒性与可扩展性。; 适合人群:具备一定现代控制理论基础和Matlab编程能力,从事自动化、航空航天、机器人学、集群智能或智能系统等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于多无人机协同飞行、编队控制、集群作业与自主导航等实际场景;②服务于高校科研项目、课程设计、学位论文研究及工程原型开发,旨在深入掌握分布式控制与模型预测控制的融合机制与工程实现;③帮助读者复现已有算法成果,并为进一步研究复杂通信拓扑、障碍规避与任务分配等高级功能提供坚实基础。; 阅读建议:建议读者结合Matlab代码与文中的理论推导同步学习,动手搭建仿真模型,重点关注状态一致性收敛过程、代价函数设计与控制参数调优策略,同时可尝试拓展至不同初始条件、通信拓扑结构及外部干扰场景下的性能测试与分析。
内容概要:本文围绕基于蜣螂优化算法(DBO)的无线传感器网络(WSN)覆盖优化问题展开研究,旨在通过智能优化算法提升网络覆盖率与资源利用效率。研究采用Matlab进行算法实现,通过对传感器节点的部署位置进行全局寻优,最大化监测区域的覆盖范围并减少覆盖盲区。文中系统阐述了蜣螂优化算法的原理、WSN覆盖模型的构建、适应度函数的设计及仿真流程,并通过对比实验验证了DBO算法在收敛速度、优化精度和稳定性方面相较于传统优化方法的优越性。研究不仅提供了完整的代码实现,还探讨了算法在物联网、环境监测等实际场景中的应用潜力,突出了智能优化技术在解决复杂工程问题中的价值。; 适合人群:具备一定编程基础,熟悉Matlab编程环境,从事无线传感器网络、智能优化算法、物联网应用或相关领域研究的科研人员、工程技术人员及研究生。; 使用场景及目标:①解决无线传感器网络中节点部署导致的覆盖不均与资源浪费问题;②提升复杂环境下WSN的监测覆盖率与系统稳定性;③为智能优化算法在通信网络布局、环境监控、智慧农业等领域的工程应用提供可复现的技术范例; 阅读建议:建议结合提供的Matlab代码进行仿真实验,深入理解蜣螂优化算法的参数设置、迭代机制与收敛特性,同时可尝试将其迁移应用于其他组合优化问题如路径规划、任务调度或多目标优化中,以拓展算法的应用边界。
源码下载地址: https://pan.quark.cn/s/7385d689617d AIS解码算法达成6位码的数据获取 AIS(Automatic Identification System,自动识别系统)是一种用于船舶自动识别和追踪的系统,它运用6位码对信息进行编码和传输。在实际操作中,我们需要将AIS传输的信息解密并提取出有用的内容。下面我们将阐述AIS解码算法的实现过程。 一、将ASCII码转换为6位二进制数值 在AIS系统中,信息是采用6位码进行编码的,因此我们需要将ASCII码转换为6位二进制数值。这个过程可以通过bool EightByteToSix(BYTE inEight, BYTE &outSix)函数完成。该函数将ASCII码转换为6位二进制数值,并将结果存储在outSix中。 函数的实现可以分为三个阶段: 1. 验证输入的ASCII码是否合法。 2. 将ASCII码转换为6位二进制数值。 3. 如果SUM大于10000000,则加上101000,否则加上101000。 二、将ASCII码字符串转换为6位二进制数值数组 在实际操作中,我们需要将ASCII码字符串转换为6位二进制数值数组。这可以通过bool EightStrToSix(CString inEight, LPBYTE outSix)函数实现。该函数将ASCII码字符串转换为6位二进制数值数组,并将结果存储在outSix中。 函数的实现可以分为五个步骤: 1. 将ASCII码字符串转换为6位二进制数值。 2. 将6位二进制数值保存到字节中。 3. 将字节保存到输出数组中。 4. 处理每个ASCII码的转换过程。 5. 将结果保存到输出数组中。 三、AIS解码算法的实现过程 AI...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值