BaseCTF-Reverse

1.upx

下载附件,提示附件是关于upx的,查壳,发现有upx壳

进行脱壳,防止冲突,将其程序改为111.exe

发现这个程序的upx特征头被魔改了,拖到010进行修改,假upx头为75 70 78 真UPX头为55 50 58

改完就可以脱壳了

查壳一下,发现无壳了

拖进ida64里,先字符串看一下

出现了base64表,猜测与base64有关,进入主函数

表面输入的字符串base64编码得到就行,点击b64函数也证明了那个确实与base64有关,且是换表

void *__fastcall b64(char *a1)
{
  int v1; // eax
  int v2; // edx
  int v3; // eax
  char v4; // al
  char v5; // al
  char v7[68]; // [rsp+20h] [rbp-70h] BYREF
  int v8; // [rsp+64h] [rbp-2Ch]
  void *v9; // [rsp+68h] [rbp-28h]
  int v10; // [rsp+74h] [rbp-1Ch]
  int v11; // [rsp+78h] [rbp-18h]
  int v12; // [rsp+7Ch] [rbp-14h]
  char *Str; // [rsp+80h] [rbp-10h]
  int v14; // [rsp+88h] [rbp-8h]
  int v15; // [rsp+8Ch] [rbp-4h]

  Str = a1;
  _map((unsigned __int8 *)v7);
  v12 = strlen(Str);
  v11 = (3 - v12 % 3) % 3;
  v10 = 4 * ((v12 + v11) / 3);
  v9 = malloc(v10 + 1);
  memset(v9, 0, v10 + 1);
  v15 = 0;
  v14 = 0;
  while ( v15 < v12 )
  {
    if ( v12 <= v15 + 1 )
      v1 = 0;
    else
      v1 = (unsigned __int8)Str[v15 + 1] << 8;
    v2 = v1 + ((unsigned __int8)Str[v15] << 16);
    if ( v12 <= v15 + 2 )
      v3 = 0;
    else
      v3 = (unsigned __int8)Str[v15 + 2];
    v8 = v2 + v3;
    *((_BYTE *)v9 + v14) = v7[((v2 + v3) >> 18) & 0x3F];
    *((_BYTE *)v9 + v14 + 1) = v7[(v8 >> 12) & 0x3F];
    if ( v12 <= v15 + 1 )
      v4 = 61;
    else
      v4 = v7[(v8 >> 6) & 0x3F];
    *((_BYTE *)v9 + v14 + 2) = v4;
    if ( v12 <= v15 + 2 )
      v5 = 61;
    else
      v5 = v7[v8 & 0x3F];
    *((_BYTE *)v9 + v14 + 3) = v5;
    v15 += 3;
    v14 += 4;
  }
  return v9;
}

找到新表,旧表和加密的字符串

加密的字符串

$rg7_dhd~Alidg+zeyhz`vnz_d,7sy0=

写个解密脚本

import base64
new = 'A,.1fgvw#`/2ehux$~"3dity%_;4cjsz^+{5bkrA&=}6alqB*-[70mpC()]89noX'  
old = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
flag = ''
mapper = str.maketrans(new,old)
enc = "$rg7_dhd~Alidg+zeyhz`vnz_d,7sy0="
decoded = enc.translate(mapper)
flag = base64.b64decode(decoded)
print(flag)

输出

BaseCTF{UPX_1s_$o_e@sy}

2.You are good at IDA

也是吴海洋师傅出的题,必须来做一些啦

查壳,脱壳,发现无壳且64位

拖入ida64中,进入主函数

直接跳出了一个字符,又有下划线,看起来很像flag的内容

又有提示出来了这是第一个部分,然后说你可以通过查找字符串的方式看看

然后查看了一下

点进第二个部分

进入伪函数

按住r然后看是否会改变

发现数字已经变成字符串了,然后查看最后一个部分是在Interesting函数里

进行转换

开始进行拼接

Y0u_4Re_900d_47_id4

查看提示是否为19个字符

包上BaseCTF{}

提交一波,发现flag正确

BaseCTF{Y0u_4Re_900d_47_id4}

查壳,发现有壳,且64位

进行脱壳

查壳,发现无壳

拖入ida64中,进入主函数

发现含有base64编码,先解码一波看看

竟然直接解出来了,好吧,考察的就是upx脱壳,甚至都没有换表

BaseCTF{Hav3_@_g0od_t1m3!!!}

 

4.ez_xor

也是继续做吴师傅的题目哈哈

查壳,发现无壳,且64位

拖进ida64位中,进入主函数

主函数代码如下

int __fastcall main(int argc, const char **argv, const char **envp)
{
  int v4; // [rsp+2Ch] [rbp-74h] BYREF
  char v5[8]; // [rsp+30h] [rbp-70h] BYREF
  __int64 v6; // [rsp+38h] [rbp-68h]
  __int64 v7; // [rsp+40h] [rbp-60h]
  int v8; // [rsp+48h] [rbp-58h]
  char v9; // [rsp+4Ch] [rbp-54h]
  char Str[8]; // [rsp+50h] [rbp-50h] BYREF
  __int64 v11; // [rsp+58h] [rbp-48h]
  __int64 v12; // [rsp+60h] [rbp-40h]
  char v13[8]; // [rsp+68h] [rbp-38h] BYREF
  __int64 v14[3]; // [rsp+70h] [rbp-30h] BYREF
  int v15; // [rsp+88h] [rbp-18h]
  char v16; // [rsp+8Ch] [rbp-14h]
  unsigned int v17; // [rsp+98h] [rbp-8h]
  unsigned int v18; // [rsp+9Ch] [rbp-4h]

  _main(argc, argv, envp);
  memset(v14, 0, sizeof(v14));
  v15 = 0;
  v16 = 0;
  *(_QWORD *)Str = '\x1D\v-&%\x05\t\x01';
  v11 = 0x673D491E20317A24i64;
  v12 = 0x34056E2E2508504Di64;
  strcpy(v13, "\"@;%");
  *(_QWORD *)v5 = 0i64;
  v6 = 0i64;
  v7 = 0i64;
  v8 = 0;
  v9 = 0;
  v4 = 7499608;
  v18 = strlen(Str);
  printf("Please input Your answer:");
  scanf("%s", v5);
  v17 = strlen(v5);
  if ( v17 == 28 )
  {
    KeyStream(&v4, v14, 28i64);
    encrypt(v14, v5, v17);
    if ( (unsigned int)CheckFlag(v5, Str, v18) )
      printf("You are good!");
    else
      printf("It's not flag!");
    return 1;
  }
  else
  {
    printf(aLengthWasWrong);
    return 0;
  }
}

分析一波

大部分情况下你能见到的计算机使用的都是“小端序”,对于一个字节放不下的整数,会按顺序存放最低字节、次低字节、……

但编程时写的(IDA伪代码看到的)是我们实际使用的数据。

例如,0xDEADBEEF 在内存中是(小地址)EF BE AD DE(大地址)。

这一段讨论的是整数,字符串和其他有结构的数据类型不在讨论范围。

v4 = 7499608 = 0x726F58 在内存中是这样的:

毕竟C语言是很“自由”的,所有数据以字节形式放在内存里,你可以认为内存中的 58 6F 72 00 是一个整数 7499608,也可以认为是一个字符串 "Xor"。关键看代码中对它进行了什么操作。

双击 Str 和 v11 和 v12 和 v13,可以看到它们在内存(栈)上的起始地址偏移。赋值后,它们在内存中是这样的:

下面 strlen(Str) 时,从 Str 开头开始直到找到一个 0x00 为止,所以上图 28 个字节都可以算进 Str 的范围。

注意 v13 的\"表示一个"字符。毕竟字符串以"起止,不用转义字符的话会解析错误的。

双击KeyStream进入这个函数

如果感觉不直观的话,可以右键单击函数名,在 Set item type 中改为正确的数据类型__int64 __fastcall KeyStream(char* a1, char* a2, int a3)

这个函数会修改 a2 也就对应于 main 中的实参 v14。

再看看encrypt函数(这里除了设置数据类型,还修改了变量名):

异或解密就是再和异或的数异或一次就能还原

例如(这里的ABC并不是指字符ABC,可以理解为公式)

A ^ B = C

C ^ B = A

写个脚本

def key_stream(key):
    key_box = []
    for i in range(28):
        key_box.append(key[i%3] ^ i)
    return key_box

def decrypt(enc, key):
    flag = ""
    key = key[::-1]
    for i in range(len(enc)):
        flag += chr(enc[i] ^ key[i])
    return flag

enc1 = bytes.fromhex("1D0B2D2625050901")[::-1]
enc2 = bytes.fromhex("673D491E20317A24")[::-1]
enc3 = bytes.fromhex("34056E2E2508504D")[::-1]
enc4 = b"\"@;%"
enc = enc1 + enc2 + enc3 + enc4
print(enc)

key = (7499608).to_bytes(4, 'little')
key_box = key_stream(key)
print(key_box)

flag = decrypt(enc,key_box)
print(flag)

输出一下

BaseCTF{X0R_I5_345Y_F0r_y0U}

5.baseplus

查壳,脱壳,发现是64位

拖入ida64位中,查看主函数

分析可知题目将输入的字符串经过Encode函数后与预定的密文

lvfzBiZiOw7<lhF8dDOfEbmI]i@bdcZfEc^z>aD! 进行比较,重点在观察Encode函数的伪代码

然后我们进入到encode那里

附上源码

__int64 __fastcall Encode(const char *a1, __int64 a2)
{
  int v3; // r10d
  char *v4; // r9
  __int64 v5; // r8
  __int64 v6; // rdi
  int v7; // ebp
  __int64 v8; // rax
  __int64 result; // rax
  __int64 v10; // rax
  __int64 v11; // rcx
  bool v12; // r13
  bool v13; // r12
  char v14; // [rsp+8h] [rbp-40h]
  __int16 v15; // [rsp+9h] [rbp-3Fh]
  unsigned __int8 v16; // [rsp+Bh] [rbp-3Dh]
  char v17[60]; // [rsp+Ch] [rbp-3Ch] BYREF

  v3 = strlen(a1);
  if ( v3 <= 0 )
  {
    LODWORD(result) = 0;
  }
  else
  {
    v4 = v17;
    v5 = 4i64;
    v6 = 0i64;
    v7 = 0;
    do
    {
      v15 = 0;
      v16 = 0;
      if ( v3 > v7 )
      {
        v10 = v7 + 1;
        v11 = 1i64;
        do
        {
          v7 = v10;
          *(&v14 + v11) = a1[v10 - 1];
          v12 = (int)v11 <= 2;
          v13 = v3 > (int)v10++;
          ++v11;
        }
        while ( v13 && v12 );
      }
      v17[0] = Secret[(unsigned __int8)v15 >> 2];
      v17[1] = Secret[(HIBYTE(v15) >> 4) | (16 * (_BYTE)v15) & 0x30];
      v17[2] = Secret[(v16 >> 6) | (4 * HIBYTE(v15)) & 0x3C];
      v17[3] = Secret[v16 & 0x3F];
      v8 = v6;
      do
      {
        *(_BYTE *)(a2 + v8) = v4[v8] ^ 0xE;
        ++v8;
      }
      while ( v8 != v5 );
      LODWORD(result) = v5;
      v6 += 4i64;
      v4 -= 4;
      v5 += 4i64;
    }
    while ( v3 > v7 );
  }
  result = (int)result;
  *(_BYTE *)(a2 + (int)result) = 0;
  return result;
}

可以看到这里与上面的基本没什么大的变化,但是但是唯一有变化的就是

多了个异或

 do
      {
        *(_BYTE *)(a2 + v8) = v4[v8] ^ 0xE;
        ++v8;
      }

而且这个也是换了表了的,所以他是先换表,再异或

所以我们要先异或再换表

可以写代码,也可以直接赛博厨子,

先赛博厨子

可以看到已经解出来了

然后脚本,注意换表当中必须为64位,所以要删去最后一个C,不然显示报错

附上脚本

import base64

# 定义自定义的Base64字符集(删除了多余的字符)
custom_base64_chars = "/128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdE"
standard_base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
assert len(custom_base64_chars) == 64, "Custom Base64 character set must be 64 characters long."

# 创建映射表
encode_map = str.maketrans(standard_base64_chars, custom_base64_chars)
decode_map = str.maketrans(custom_base64_chars, standard_base64_chars)

def xor_with_0xE(text):
    return ''.join(chr(ord(c) ^ 0xE) for c in text)

def decode_custom_base64(encoded_text):
    # 使用自定义Base64表替换标准Base64表中的字符
    standard_encoded = encoded_text.translate(decode_map)
    # 使用标准库解码
    decoded_bytes = base64.b64decode(standard_encoded)
    return decoded_bytes.decode('utf-8')

# 密文
encrypted_text = "lvfzBiZiOw7<lhF8dDOfEbmI]i@bdcZfEc^z>aD!"

# 异或0xE
xored_text = xor_with_0xE(encrypted_text)

# 解码
decoded_text = decode_custom_base64(xored_text)

print("Decoded Text:", decoded_text)

最后解密出来的答案,又是魔改的一题啊

BaseCTF{BA5e_DEcoD1N6_sEcr3t}

6.ez_maze

打开附件,查壳,发现无壳且64位

拖入ida64中,打开主函数

查看不出什么信息,查看一下字符串看看

ok,结合一下题目,我们发现了迷宫的路径,还有提交结果用迷宫的走法md5

回到主函数进行分析,发现这应该是一个15*15的迷宫

对着字符串按 Shift+E 可以提取数据

手动整理一下,

这就是迷宫,要求以最短路径从x走到y,

手动走一下也行,就是最短路径了,sssssssddddwwwddsssssssdddsssddddd,然后再找个计算哈希值的工具(例如 CyberChef),得到32位的小写md5,就是flag了,这里也附上脚本,直接再ai上

maze = [
    8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1,
    0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1,
    0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1,
    0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1,
    0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1,
    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1,
    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 9
]

visited = [0] * (15 * 15)  # 记录访问过的点


def BFS(maze, x, y):
    queue = [(x, y, '')]  # 设置队列,bfs用队列,dfs用栈
    while queue:
        x, y, path = queue.pop(0)
        if x < 15 and y < 15 and x >= 0 and y >= 0 and visited[x * 15 + y] != 1 and maze[x * 15 + y] != 1:
            visited[x * 15 + y] = 1  # 证明已经访问过了
            queue.append((x + 1, y, path + 's'))  # 只能字符串相加
            queue.append((x, y - 1, path + 'a'))
            queue.append((x, y + 1, path + 'd'))
            queue.append((x - 1, y, path + 'w'))
        else:
            continue
        if maze[x * 15 + y] == 9:
            return path


flag = BFS(maze, 0, 0)
print(flag)

输出一下

注意wasd分别代表上左下右

然后md5加密一下

BaseCTF{131b7d6e60e8a34cb01801ae8de07efe}

7.lk

打开附件,先进行常规答题

我们进行随便输入A(万一凑巧搞出来了)

发现程序直接退出,我们直接查壳进入分析

查壳,发现无壳且64位,拖入ida64中,进入主函数

int __fastcall main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rax
  __int64 v4; // rax
  __int64 v5; // r8
  __int64 v6; // rax
  __int64 v7; // r8
  __int64 v8; // rax
  __int64 v9; // r8
  __int64 v10; // rax
  __int64 v11; // r8
  __int64 v12; // rax
  __int64 v13; // r8
  __int64 v14; // rax
  __int64 v15; // r8
  __int64 v16; // rax
  __int64 v17; // r8
  __int64 v18; // rax
  __int64 v19; // r8
  __int64 v20; // rax
  __int64 v21; // r8
  __int64 v22; // rax
  __int64 v23; // r8
  __int64 v24; // rax
  __int64 v25; // r8
  __int64 v26; // rax
  __int64 v27; // r8
  __int64 v28; // rax
  __int64 v29; // r8
  __int64 v30; // rax
  __int64 v31; // r8
  __int64 v32; // rax
  __int64 v33; // r8
  __int64 v34; // rax
  __int64 v35; // r8
  __int64 v36; // rax
  __int64 v37; // r8
  __int64 v38; // rax
  __int64 v39; // r8
  __int64 v40; // rax
  __int64 v41; // r8
  __int64 v42; // rax
  __int64 v43; // r8
  __int64 v44; // rax
  __int64 v45; // r8
  __int64 v46; // rax
  __int64 v47; // r8
  __int64 v48; // rax
  __int64 v49; // r8
  __int64 v50; // rax
  __int64 v51; // r8
  __int64 v52; // rax
  __int64 v53; // r8
  __int64 v54; // rax
  __int64 v55; // r8
  __int64 v56; // rax
  __int64 v57; // r8
  __int64 v58; // rax
  __int64 v59; // r8
  __int64 v60; // rax
  __int64 v61; // r8
  __int64 v62; // rax
  __int64 v63; // r8
  __int64 v64; // rax
  __int64 v65; // r8
  __int64 v66; // rax
  __int64 v67; // r8
  __int64 v68; // rax
  __int64 v69; // r8
  __int64 v70; // rax
  __int64 v71; // r8
  __int64 v72; // rax
  __int64 v73; // r8
  __int64 v74; // rax
  __int64 v75; // r8
  __int64 v76; // rax
  __int64 v77; // r8
  __int64 v78; // rax
  __int64 v79; // r8
  __int64 v80; // rax
  __int64 v81; // r8
  __int64 v82; // rax
  __int64 v83; // r8
  __int64 v84; // rax
  __int64 v85; // r8
  __int64 v86; // rax
  __int64 v87; // r8
  __int64 v88; // rax
  __int64 v89; // r8
  __int64 v90; // rax
  __int64 v91; // r8
  __int64 v92; // rax
  __int64 v93; // r8
  __int64 v94; // rax
  __int64 v95; // r8
  __int64 v96; // rax
  __int64 v97; // r8
  __int64 v98; // rax
  __int64 v99; // r8
  __int64 v100; // rax
  __int64 v101; // r8
  __int64 v102; // rax
  __int64 v103; // r8
  __int64 v104; // rax
  __int64 v105; // r8
  __int64 v106; // rax
  __int64 v107; // r8
  __int64 v108; // rax
  __int64 v109; // r8
  __int64 v110; // rax
  __int64 v111; // r8
  __int64 v112; // rax
  __int64 v113; // r8
  __int64 v114; // rax
  __int64 v115; // r8
  __int64 v116; // rax
  __int64 v117; // r8
  __int64 v118; // rax
  __int64 v119; // r8
  __int64 v120; // rax
  __int64 v121; // r8
  __int64 v122; // rax
  __int64 v123; // r8
  __int64 v124; // rax
  __int64 v125; // r8
  __int64 v126; // rax
  __int64 v127; // r8
  __int64 v128; // rax
  __int64 v129; // r8
  __int64 v130; // rax
  __int64 v131; // r8
  __int64 v132; // rax
  __int64 v133; // r8
  __int64 v134; // rax
  __int64 v135; // r8
  __int64 v136; // rax
  __int64 v137; // r8
  __int64 v138; // rax
  __int64 v139; // r8
  __int64 v140; // rax
  __int64 v141; // r8
  __int64 v142; // rax
  __int64 v143; // r8
  __int64 v144; // rax
  __int64 v145; // r8
  __int64 v146; // rax
  __int64 v147; // r8
  __int64 v148; // rax
  __int64 v149; // r8
  __int64 v150; // rax
  __int64 v151; // r8
  __int64 v152; // rax
  __int64 v153; // r8
  __int64 v154; // rax
  __int64 v155; // r8
  __int64 v156; // rax
  __int64 v157; // r8
  __int64 v158; // rax
  __int64 v159; // r8
  __int64 v160; // rax
  __int64 v161; // r8
  __int64 v162; // rax
  __int64 v163; // r8
  __int64 v164; // rax
  __int64 v165; // r8
  __int64 v166; // rax
  __int64 v167; // r8
  __int64 v168; // rax
  __int64 v169; // r8
  __int64 v170; // rax
  __int64 v171; // r8
  __int64 v172; // rax
  __int64 v173; // r8
  __int64 v174; // rax
  __int64 v175; // r8
  __int64 v176; // rax
  __int64 v177; // r8
  __int64 v178; // rax
  __int64 v179; // r8
  __int64 v180; // rax
  __int64 v181; // r8
  __int64 v182; // rax
  __int64 v183; // r8
  __int64 v184; // rax
  __int64 v185; // r8
  __int64 v186; // rax
  __int64 v187; // r8
  __int64 v188; // rax
  __int64 v189; // r8
  __int64 v190; // rax
  __int64 v191; // r8
  __int64 v192; // rax
  __int64 v193; // r8
  __int64 v194; // rax
  __int64 v195; // r8
  __int64 v196; // rax
  __int64 v197; // r8
  __int64 v198; // rax
  __int64 v199; // r8
  __int64 v200; // rax
  __int64 v201; // r8
  __int64 v202; // rax
  __int64 v203; // r8
  __int64 v204; // rax
  __int64 v205; // r8
  __int64 v206; // r8
  __int64 v208; // rax
  int i; // [rsp+20h] [rbp-18h]

  v3 = sub_140004DC0(std::cout, &unk_140007300, envp);
  v4 = std::ostream::operator<<(v3, sub_140005140);
  std::ostream::operator<<(v4, sub_140005140);
  v6 = sub_140004DC0(std::cout, "1. 以下哪部作品的主角不是伪娘", v5);
  std::ostream::operator<<(v6, sub_140005140);
  v8 = sub_140004DC0(std::cout, "A 少女*领域", v7);
  std::ostream::operator<<(v8, sub_140005140);
  v10 = sub_140004DC0(std::cout, "B 恋爱少女与守护之盾", v9);
  std::ostream::operator<<(v10, sub_140005140);
  v12 = sub_140004DC0(std::cout, "C 女装山脉", v11);
  std::ostream::operator<<(v12, sub_140005140);
  v14 = sub_140004DC0(std::cout, "D 处女爱上姐姐", v13);
  std::ostream::operator<<(v14, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[1]);
  v16 = sub_140004DC0(std::cout, "2. 以下哪个游戏作品不是纯愛游戏?", v15);
  std::ostream::operator<<(v16, sub_140005140);
  v18 = sub_140004DC0(std::cout, &unk_1400073B8, v17);
  std::ostream::operator<<(v18, sub_140005140);
  v20 = sub_140004DC0(std::cout, &unk_1400073D0, v19);
  std::ostream::operator<<(v20, sub_140005140);
  v22 = sub_140004DC0(std::cout, &unk_1400073F0, v21);
  std::ostream::operator<<(v22, sub_140005140);
  v24 = sub_140004DC0(std::cout, &unk_140007400, v23);
  std::ostream::operator<<(v24, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[2]);
  v26 = sub_140004DC0(std::cout, &unk_140007410, v25);
  std::ostream::operator<<(v26, sub_140005140);
  v28 = sub_140004DC0(std::cout, "A A级", v27);
  std::ostream::operator<<(v28, sub_140005140);
  v30 = sub_140004DC0(std::cout, "B S级", v29);
  std::ostream::operator<<(v30, sub_140005140);
  v32 = sub_140004DC0(std::cout, "C B级", v31);
  std::ostream::operator<<(v32, sub_140005140);
  v34 = sub_140004DC0(std::cout, "D C级", v33);
  std::ostream::operator<<(v34, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[3]);
  v36 = sub_140004DC0(std::cout, &unk_140007478, v35);
  std::ostream::operator<<(v36, sub_140005140);
  v38 = sub_140004DC0(std::cout, &unk_1400074B0, v37);
  std::ostream::operator<<(v38, sub_140005140);
  v40 = sub_140004DC0(std::cout, &unk_1400074C0, v39);
  std::ostream::operator<<(v40, sub_140005140);
  v42 = sub_140004DC0(std::cout, &unk_1400074D0, v41);
  std::ostream::operator<<(v42, sub_140005140);
  v44 = sub_140004DC0(std::cout, &unk_1400074E0, v43);
  std::ostream::operator<<(v44, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[4]);
  v46 = sub_140004DC0(std::cout, &unk_1400074F0, v45);
  std::ostream::operator<<(v46, sub_140005140);
  v48 = sub_140004DC0(std::cout, "A 里见莲太郎", v47);
  std::ostream::operator<<(v48, sub_140005140);
  v50 = sub_140004DC0(std::cout, "B 虛渊玄", v49);
  std::ostream::operator<<(v50, sub_140005140);
  v52 = sub_140004DC0(std::cout, "C 奈虚蘑菇", v51);
  std::ostream::operator<<(v52, sub_140005140);
  v54 = sub_140004DC0(std::cout, "D 冈本伦", v53);
  std::ostream::operator<<(v54, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[5]);
  v56 = sub_140004DC0(std::cout, &unk_140007558, v55);
  std::ostream::operator<<(v56, sub_140005140);
  v58 = sub_140004DC0(std::cout, "A 冰", v57);
  std::ostream::operator<<(v58, sub_140005140);
  v60 = sub_140004DC0(std::cout, "B 水", v59);
  std::ostream::operator<<(v60, sub_140005140);
  v62 = sub_140004DC0(std::cout, "C 火", v61);
  std::ostream::operator<<(v62, sub_140005140);
  v64 = sub_140004DC0(std::cout, "D 风", v63);
  std::ostream::operator<<(v64, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[6]);
  v66 = sub_140004DC0(std::cout, &unk_1400075C0, v65);
  std::ostream::operator<<(v66, sub_140005140);
  v68 = sub_140004DC0(std::cout, "A 材木座义辉", v67);
  std::ostream::operator<<(v68, sub_140005140);
  v70 = sub_140004DC0(std::cout, "B 叶山隼人", v69);
  std::ostream::operator<<(v70, sub_140005140);
  v72 = sub_140004DC0(std::cout, "C 平塚静", v71);
  std::ostream::operator<<(v72, sub_140005140);
  v74 = sub_140004DC0(std::cout, "D 折本香织", v73);
  std::ostream::operator<<(v74, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[7]);
  v76 = sub_140004DC0(std::cout, &unk_140007658, v75);
  std::ostream::operator<<(v76, sub_140005140);
  v78 = sub_140004DC0(std::cout, &unk_140007684, v77);
  std::ostream::operator<<(v78, sub_140005140);
  v80 = sub_140004DC0(std::cout, &unk_140007688, v79);
  std::ostream::operator<<(v80, sub_140005140);
  v82 = sub_140004DC0(std::cout, &unk_14000768C, v81);
  std::ostream::operator<<(v82, sub_140005140);
  v84 = sub_140004DC0(std::cout, &unk_140007690, v83);
  std::ostream::operator<<(v84, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[8]);
  v86 = sub_140004DC0(std::cout, &unk_140007698, v85);
  std::ostream::operator<<(v86, sub_140005140);
  v88 = sub_140004DC0(std::cout, &unk_1400076B8, v87);
  std::ostream::operator<<(v88, sub_140005140);
  v90 = sub_140004DC0(std::cout, &unk_1400076D0, v89);
  std::ostream::operator<<(v90, sub_140005140);
  v92 = sub_140004DC0(std::cout, "C 高坂京介", v91);
  std::ostream::operator<<(v92, sub_140005140);
  v94 = sub_140004DC0(std::cout, "D 司波达也", v93);
  std::ostream::operator<<(v94, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[9]);
  v96 = sub_140004DC0(std::cout, &unk_140007708, v95);
  std::ostream::operator<<(v96, sub_140005140);
  v98 = sub_140004DC0(std::cout, "A 丸井双叶", v97);
  std::ostream::operator<<(v98, sub_140005140);
  v100 = sub_140004DC0(std::cout, "B 佐藤信野", v99);
  std::ostream::operator<<(v100, sub_140005140);
  v102 = sub_140004DC0(std::cout, "C 松岗咲子", v101);
  std::ostream::operator<<(v102, sub_140005140);
  v104 = sub_140004DC0(std::cout, "D 吉冈有希", v103);
  std::ostream::operator<<(v104, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[10]);
  v106 = sub_140004DC0(std::cout, &unk_140007790, v105);
  std::ostream::operator<<(v106, sub_140005140);
  v108 = sub_140004DC0(std::cout, "A 99", v107);
  std::ostream::operator<<(v108, sub_140005140);
  v110 = sub_140004DC0(std::cout, "B 214", v109);
  std::ostream::operator<<(v110, sub_140005140);
  v112 = sub_140004DC0(std::cout, "C 520", v111);
  std::ostream::operator<<(v112, sub_140005140);
  v114 = sub_140004DC0(std::cout, "D 1314", v113);
  std::ostream::operator<<(v114, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[11]);
  v116 = sub_140004DC0(std::cout, &unk_140007800, v115);
  std::ostream::operator<<(v116, sub_140005140);
  v118 = sub_140004DC0(std::cout, "A 第七学区", v117);
  std::ostream::operator<<(v118, sub_140005140);
  v120 = sub_140004DC0(std::cout, "B 第十一学区", v119);
  std::ostream::operator<<(v120, sub_140005140);
  v122 = sub_140004DC0(std::cout, "C 第十七学区", v121);
  std::ostream::operator<<(v122, sub_140005140);
  v124 = sub_140004DC0(std::cout, "D 第二十一学区", v123);
  std::ostream::operator<<(v124, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[12]);
  v126 = sub_140004DC0(std::cout, "13. 琪露诺出塌了以下哪部作品 ?", v125);
  std::ostream::operator<<(v126, sub_140005140);
  v128 = sub_140004DC0(std::cout, "A 东方永夜抄", v127);
  std::ostream::operator<<(v128, sub_140005140);
  v130 = sub_140004DC0(std::cout, "B 东方心绮楼", v129);
  std::ostream::operator<<(v130, sub_140005140);
  v132 = sub_140004DC0(std::cout, "C 东方甜珠傅", v131);
  std::ostream::operator<<(v132, sub_140005140);
  v134 = sub_140004DC0(std::cout, "D 东方风神绿", v133);
  std::ostream::operator<<(v134, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[13]);
  v136 = sub_140004DC0(std::cout, &unk_1400078F0, v135);
  std::ostream::operator<<(v136, sub_140005140);
  v138 = sub_140004DC0(std::cout, "A 死宅", v137);
  std::ostream::operator<<(v138, sub_140005140);
  v140 = sub_140004DC0(std::cout, "B 本命", v139);
  std::ostream::operator<<(v140, sub_140005140);
  v142 = sub_140004DC0(std::cout, "C 现充", v141);
  std::ostream::operator<<(v142, sub_140005140);
  v144 = sub_140004DC0(std::cout, "D 萌", v143);
  std::ostream::operator<<(v144, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[14]);
  v146 = sub_140004DC0(std::cout, &unk_140007970, v145);
  std::ostream::operator<<(v146, sub_140005140);
  v148 = sub_140004DC0(std::cout, "A 181", v147);
  std::ostream::operator<<(v148, sub_140005140);
  v150 = sub_140004DC0(std::cout, "B 182", v149);
  std::ostream::operator<<(v150, sub_140005140);
  v152 = sub_140004DC0(std::cout, "C 183", v151);
  std::ostream::operator<<(v152, sub_140005140);
  v154 = sub_140004DC0(std::cout, "D 180", v153);
  std::ostream::operator<<(v154, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[15]);
  v156 = sub_140004DC0(std::cout, &unk_1400079D0, v155);
  std::ostream::operator<<(v156, sub_140005140);
  v158 = sub_140004DC0(std::cout, "A 五千二百日元", v157);
  std::ostream::operator<<(v158, sub_140005140);
  v160 = sub_140004DC0(std::cout, "B 两千五百日元", v159);
  std::ostream::operator<<(v160, sub_140005140);
  v162 = sub_140004DC0(std::cout, "C —千日元", v161);
  std::ostream::operator<<(v162, sub_140005140);
  v164 = sub_140004DC0(std::cout, "D 二百日元", v163);
  std::ostream::operator<<(v164, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[16]);
  v166 = sub_140004DC0(std::cout, &unk_140007A60, v165);
  std::ostream::operator<<(v166, sub_140005140);
  v168 = sub_140004DC0(std::cout, "A 4%", v167);
  std::ostream::operator<<(v168, sub_140005140);
  v170 = sub_140004DC0(std::cout, "B 5%", v169);
  std::ostream::operator<<(v170, sub_140005140);
  v172 = sub_140004DC0(std::cout, "C 6%", v171);
  std::ostream::operator<<(v172, sub_140005140);
  v174 = sub_140004DC0(std::cout, "D 9%", v173);
  std::ostream::operator<<(v174, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[17]);
  v176 = sub_140004DC0(std::cout, &unk_140007AF0, v175);
  std::ostream::operator<<(v176, sub_140005140);
  v178 = sub_140004DC0(std::cout, "A 神乐舞", v177);
  std::ostream::operator<<(v178, sub_140005140);
  v180 = sub_140004DC0(std::cout, "B 浅草舞", v179);
  std::ostream::operator<<(v180, sub_140005140);
  v182 = sub_140004DC0(std::cout, "C 夜來舞", v181);
  std::ostream::operator<<(v182, sub_140005140);
  v184 = sub_140004DC0(std::cout, "D 踢踏舞", v183);
  std::ostream::operator<<(v184, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[18]);
  v186 = sub_140004DC0(std::cout, &unk_140007B60, v185);
  std::ostream::operator<<(v186, sub_140005140);
  v188 = sub_140004DC0(std::cout, "A 吸血鬼女王", v187);
  std::ostream::operator<<(v188, sub_140005140);
  v190 = sub_140004DC0(std::cout, "B 大巫妖", v189);
  std::ostream::operator<<(v190, sub_140005140);
  v192 = sub_140004DC0(std::cout, "C 黑骑士", v191);
  std::ostream::operator<<(v192, sub_140005140);
  v194 = sub_140004DC0(std::cout, "D 叛逆的女神", v193);
  std::ostream::operator<<(v194, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[19]);
  v196 = sub_140004DC0(std::cout, &unk_140007BF8, v195);
  std::ostream::operator<<(v196, sub_140005140);
  v198 = sub_140004DC0(std::cout, "A 城和泉正", v197);
  std::ostream::operator<<(v198, sub_140005140);
  v200 = sub_140004DC0(std::cout, "B 干代金丸", v199);
  std::ostream::operator<<(v200, sub_140005140);
  v202 = sub_140004DC0(std::cout, "C 数珠丸恒次", v201);
  std::ostream::operator<<(v202, sub_140005140);
  v204 = sub_140004DC0(std::cout, "D 小鸟丸", v203);
  std::ostream::operator<<(v204, sub_140005140);
  sub_140005190(std::cin, &byte_14000A668[20]);
  if ( 948 * byte_14000A668[20]
     + 887 * byte_14000A668[19]
     + 410 * byte_14000A668[18]
     + 978 * byte_14000A668[17]
     + 417 * byte_14000A668[16]
     + 908 * byte_14000A668[15]
     + 965 * byte_14000A668[14]
     + 987 * byte_14000A668[13]
     + 141 * byte_14000A668[12]
     + 257 * byte_14000A668[11]
     + 323 * byte_14000A668[10]
     + 931 * byte_14000A668[9]
     + 773 * byte_14000A668[8]
     + 851 * byte_14000A668[7]
     + 758 * byte_14000A668[6]
     + 891 * byte_14000A668[5]
     + 575 * byte_14000A668[4]
     + 616 * byte_14000A668[3]
     + 860 * byte_14000A668[2]
     + 283 * byte_14000A668[1] == 913686
    && 938 * byte_14000A668[20]
     + 490 * byte_14000A668[19]
     + 920 * byte_14000A668[18]
     + 50 * byte_14000A668[17]
     + 568 * byte_14000A668[16]
     + 68 * byte_14000A668[15]
     + 35 * byte_14000A668[14]
     + 708 * byte_14000A668[13]
     + 938 * byte_14000A668[12]
     + 718 * byte_14000A668[11]
     + 589 * byte_14000A668[10]
     + 954 * byte_14000A668[9]
     + 974 * byte_14000A668[8]
     + 62 * byte_14000A668[7]
     + 580 * byte_14000A668[6]
     + 80 * byte_14000A668[5]
     + 111 * byte_14000A668[4]
     + 151 * byte_14000A668[3]
     + 421 * byte_14000A668[2]
     + 148 * byte_14000A668[1] == 630335
    && 908 * byte_14000A668[20]
     + 590 * byte_14000A668[19]
     + 668 * byte_14000A668[18]
     + 222 * byte_14000A668[17]
     + 489 * byte_14000A668[16]
     + 335 * byte_14000A668[15]
     + 778 * byte_14000A668[14]
     + 622 * byte_14000A668[13]
     + 95 * byte_14000A668[12]
     + 920 * byte_14000A668[11]
     + 932 * byte_14000A668[10]
     + 892 * byte_14000A668[9]
     + 409 * byte_14000A668[8]
     + 392 * byte_14000A668[7]
     + 11 * byte_14000A668[6]
     + 113 * byte_14000A668[5]
     + 948 * byte_14000A668[4]
     + 674 * byte_14000A668[3]
     + 506 * byte_14000A668[2]
     + 182 * byte_14000A668[1] == 707525
    && 479 * byte_14000A668[20]
     + 859 * byte_14000A668[19]
     + 410 * byte_14000A668[18]
     + 399 * byte_14000A668[17]
     + 891 * byte_14000A668[16]
     + 266 * byte_14000A668[15]
     + 773 * byte_14000A668[14]
     + 624 * byte_14000A668[13]
     + 34 * byte_14000A668[12]
     + 479 * byte_14000A668[11]
     + 465 * byte_14000A668[10]
     + 728 * byte_14000A668[9]
     + 447 * byte_14000A668[8]
     + 427 * byte_14000A668[7]
     + 890 * byte_14000A668[6]
     + 570 * byte_14000A668[5]
     + 716 * byte_14000A668[4]
     + 180 * byte_14000A668[3]
     + 571 * byte_14000A668[2]
     + 707 * byte_14000A668[1] == 724203
    && 556 * byte_14000A668[20]
     + 798 * byte_14000A668[19]
     + 380 * byte_14000A668[18]
     + 716 * byte_14000A668[17]
     + 71 * byte_14000A668[16]
     + 901 * byte_14000A668[15]
     + 949 * byte_14000A668[14]
     + 304 * byte_14000A668[13]
     + 142 * byte_14000A668[12]
     + 679 * byte_14000A668[11]
     + 459 * byte_14000A668[10]
     + 814 * byte_14000A668[9]
     + 282 * byte_14000A668[8]
     + 49 * byte_14000A668[7]
     + 873 * byte_14000A668[6]
     + 169 * byte_14000A668[5]
     + 437 * byte_14000A668[4]
     + 199 * byte_14000A668[3]
     + 771 * byte_14000A668[2]
     + 807 * byte_14000A668[1] == 688899
    && 465 * byte_14000A668[20]
     + 898 * byte_14000A668[19]
     + 979 * byte_14000A668[18]
     + 198 * byte_14000A668[17]
     + 156 * byte_14000A668[16]
     + 831 * byte_14000A668[15]
     + 856 * byte_14000A668[14]
     + 322 * byte_14000A668[13]
     + 25 * byte_14000A668[12]
     + 35 * byte_14000A668[11]
     + 369 * byte_14000A668[10]
     + 917 * byte_14000A668[9]
     + 522 * byte_14000A668[8]
     + 654 * byte_14000A668[7]
     + 235 * byte_14000A668[6]
     + 385 * byte_14000A668[5]
     + 469 * byte_14000A668[4]
     + 231 * byte_14000A668[3]
     + 496 * byte_14000A668[2]
     + 83 * byte_14000A668[1] == 604784
    && 305 * byte_14000A668[20]
     + 928 * byte_14000A668[19]
     + 260 * byte_14000A668[18]
     + 793 * byte_14000A668[17]
     + 787 * byte_14000A668[16]
     + 708 * byte_14000A668[15]
     + 758 * byte_14000A668[14]
     + 236 * byte_14000A668[13]
     + 688 * byte_14000A668[12]
     + 747 * byte_14000A668[11]
     + 711 * byte_14000A668[10]
     + 195 * byte_14000A668[9]
     + 50 * byte_14000A668[8]
     + 648 * byte_14000A668[7]
     + 787 * byte_14000A668[6]
     + 376 * byte_14000A668[5]
     + 220 * byte_14000A668[4]
     + 33 * byte_14000A668[3]
     + 194 * byte_14000A668[2]
     + 585 * byte_14000A668[1] == 665485
    && 767 * byte_14000A668[20]
     + 573 * byte_14000A668[19]
     + 22 * byte_14000A668[18]
     + 909 * byte_14000A668[17]
     + 598 * byte_14000A668[16]
     + 588 * byte_14000A668[15]
     + 136 * byte_14000A668[14]
     + 848 * byte_14000A668[12]
     + 964 * byte_14000A668[11]
     + 311 * byte_14000A668[10]
     + 701 * byte_14000A668[9]
     + 653 * byte_14000A668[8]
     + 541 * byte_14000A668[7]
     + 443 * byte_14000A668[6]
     + 7 * byte_14000A668[5]
     + 976 * byte_14000A668[4]
     + 803 * byte_14000A668[3]
     + 273 * byte_14000A668[2]
     + 859 * byte_14000A668[1] == 727664
    && 776 * byte_14000A668[20]
     + 59 * byte_14000A668[19]
     + 507 * byte_14000A668[18]
     + 164 * byte_14000A668[17]
     + 397 * byte_14000A668[16]
     + 744 * byte_14000A668[15]
     + 377 * byte_14000A668[14]
     + 768 * byte_14000A668[13]
     + 456 * byte_14000A668[12]
     + 799 * byte_14000A668[11]
     + 9 * byte_14000A668[10]
     + 215 * byte_14000A668[9]
     + 365 * byte_14000A668[8]
     + 181 * byte_14000A668[7]
     + 634 * byte_14000A668[6]
     + 818 * byte_14000A668[5]
     + 81 * byte_14000A668[4]
     + 236 * byte_14000A668[3]
     + 883 * byte_14000A668[2]
     + 95 * byte_14000A668[1] == 572015
    && 873 * byte_14000A668[20]
     + 234 * byte_14000A668[19]
     + 381 * byte_14000A668[18]
     + 423 * byte_14000A668[17]
     + 960 * byte_14000A668[16]
     + 689 * byte_14000A668[15]
     + 617 * byte_14000A668[14]
     + 240 * byte_14000A668[13]
     + 933 * byte_14000A668[12]
     + 300 * byte_14000A668[11]
     + 998 * byte_14000A668[10]
     + 773 * byte_14000A668[9]
     + 484 * byte_14000A668[8]
     + 905 * byte_14000A668[7]
     + 806 * byte_14000A668[6]
     + 792 * byte_14000A668[5]
     + 606 * byte_14000A668[4]
     + 942 * byte_14000A668[3]
     + 422 * byte_14000A668[2]
     + 789 * byte_14000A668[1] == 875498
    && 766 * byte_14000A668[20]
     + 7 * byte_14000A668[19]
     + 283 * byte_14000A668[18]
     + 900 * byte_14000A668[17]
     + 211 * byte_14000A668[16]
     + 305 * byte_14000A668[15]
     + 343 * byte_14000A668[14]
     + 696 * byte_14000A668[13]
     + 590 * byte_14000A668[12]
     + 736 * byte_14000A668[11]
     + 817 * byte_14000A668[10]
     + 603 * byte_14000A668[9]
     + 414 * byte_14000A668[8]
     + 828 * byte_14000A668[7]
     + 114 * byte_14000A668[6]
     + 845 * byte_14000A668[5]
     + 175 * byte_14000A668[4]
     + 212 * byte_14000A668[3]
     + 898 * byte_14000A668[2]
     + 988 * byte_14000A668[1] == 714759
    && 220 * byte_14000A668[20]
     + 30 * byte_14000A668[19]
     + 788 * byte_14000A668[18]
     + 106 * byte_14000A668[17]
     + 574 * byte_14000A668[16]
     + 501 * byte_14000A668[15]
     + 366 * byte_14000A668[14]
     + 952 * byte_14000A668[13]
     + 121 * byte_14000A668[12]
     + 996 * byte_14000A668[11]
     + 735 * byte_14000A668[10]
     + 689 * byte_14000A668[9]
     + 998 * byte_14000A668[8]
     + 689 * byte_14000A668[7]
     + 729 * byte_14000A668[6]
     + 886 * byte_14000A668[5]
     + 860 * byte_14000A668[4]
     + 70 * byte_14000A668[3]
     + 466 * byte_14000A668[2]
     + 961 * byte_14000A668[1] == 778853
    && 313 * byte_14000A668[20]
     + 748 * byte_14000A668[19]
     + 522 * byte_14000A668[18]
     + 864 * byte_14000A668[17]
     + 156 * byte_14000A668[16]
     + 362 * byte_14000A668[15]
     + 283 * byte_14000A668[14]
     + 49 * byte_14000A668[13]
     + 316 * byte_14000A668[12]
     + 79 * byte_14000A668[11]
     + 136 * byte_14000A668[10]
     + 299 * byte_14000A668[9]
     + 271 * byte_14000A668[8]
     + 604 * byte_14000A668[7]
     + 907 * byte_14000A668[6]
     + 540 * byte_14000A668[5]
     + 141 * byte_14000A668[4]
     + 620 * byte_14000A668[3]
     + 701 * byte_14000A668[2]
     + 866 * byte_14000A668[1] == 584591
    && 922 * byte_14000A668[20]
     + 399 * byte_14000A668[19]
     + 425 * byte_14000A668[18]
     + 26 * byte_14000A668[17]
     + 159 * byte_14000A668[16]
     + 224 * byte_14000A668[15]
     + 438 * byte_14000A668[14]
     + 770 * byte_14000A668[13]
     + 144 * byte_14000A668[12]
     + 406 * byte_14000A668[11]
     + 110 * byte_14000A668[10]
     + 991 * byte_14000A668[9]
     + 749 * byte_14000A668[8]
     + 701 * byte_14000A668[7]
     + 646 * byte_14000A668[6]
     + 147 * byte_14000A668[5]
     + 979 * byte_14000A668[4]
     + 674 * byte_14000A668[3]
     + 999 * byte_14000A668[2]
     + 913 * byte_14000A668[1] == 717586
    && 13 * byte_14000A668[20]
     + 537 * byte_14000A668[19]
     + 225 * byte_14000A668[18]
     + 421 * byte_14000A668[17]
     + 153 * byte_14000A668[16]
     + 484 * byte_14000A668[15]
     + 654 * byte_14000A668[14]
     + 743 * byte_14000A668[13]
     + 779 * byte_14000A668[12]
     + 74 * byte_14000A668[11]
     + 325 * byte_14000A668[10]
     + 439 * byte_14000A668[9]
     + 797 * byte_14000A668[8]
     + 41 * byte_14000A668[7]
     + 784 * byte_14000A668[6]
     + 269 * byte_14000A668[5]
     + 454 * byte_14000A668[4]
     + 725 * byte_14000A668[2]
     + 164 * byte_14000A668[1] == 537823
    && 591 * byte_14000A668[20]
     + 210 * byte_14000A668[19]
     + 874 * byte_14000A668[18]
     + 204 * byte_14000A668[17]
     + 485 * byte_14000A668[16]
     + 42 * byte_14000A668[15]
     + 433 * byte_14000A668[14]
     + 176 * byte_14000A668[13]
     + 436 * byte_14000A668[12]
     + 634 * byte_14000A668[11]
     + 82 * byte_14000A668[10]
     + 978 * byte_14000A668[9]
     + 818 * byte_14000A668[8]
     + 683 * byte_14000A668[7]
     + 404 * byte_14000A668[6]
     + 562 * byte_14000A668[5]
     + 41 * byte_14000A668[4]
     + 789 * byte_14000A668[3]
     + 200 * byte_14000A668[2]
     + 220 * byte_14000A668[1] == 587367
    && 584 * byte_14000A668[20]
     + 597 * byte_14000A668[19]
     + 928 * byte_14000A668[18]
     + 532 * byte_14000A668[17]
     + 902 * byte_14000A668[16]
     + 858 * byte_14000A668[15]
     + 820 * byte_14000A668[14]
     + 240 * byte_14000A668[13]
     + 124 * byte_14000A668[12]
     + 899 * byte_14000A668[11]
     + 848 * byte_14000A668[10]
     + 822 * byte_14000A668[9]
     + 409 * byte_14000A668[8]
     + 491 * byte_14000A668[7]
     + 587 * byte_14000A668[6]
     + 715 * byte_14000A668[5]
     + 410 * byte_14000A668[4]
     + 268 * byte_14000A668[3]
     + 721 * byte_14000A668[2]
     + 915 * byte_14000A668[1] == 842245
    && 421 * byte_14000A668[20]
     + 302 * byte_14000A668[19]
     + 327 * byte_14000A668[18]
     + 180 * byte_14000A668[17]
     + (byte_14000A668[16] << 9)
     + 160 * byte_14000A668[15]
     + 623 * byte_14000A668[14]
     + 28 * byte_14000A668[13]
     + 411 * byte_14000A668[12]
     + 53 * byte_14000A668[11]
     + 633 * byte_14000A668[10]
     + 560 * byte_14000A668[9]
     + 623 * byte_14000A668[8]
     + 477 * byte_14000A668[7]
     + 901 * byte_14000A668[6]
     + 287 * byte_14000A668[5]
     + 149 * byte_14000A668[4]
     + 726 * byte_14000A668[3]
     + 934 * byte_14000A668[2]
     + 875 * byte_14000A668[1] == 610801
    && 838 * byte_14000A668[20]
     + 434 * byte_14000A668[19]
     + 792 * byte_14000A668[18]
     + 649 * byte_14000A668[17]
     + 462 * byte_14000A668[16]
     + 170 * byte_14000A668[15]
     + 980 * byte_14000A668[14]
     + 15 * byte_14000A668[13]
     + 295 * byte_14000A668[12]
     + 495 * byte_14000A668[11]
     + 666 * byte_14000A668[10]
     + 934 * byte_14000A668[9]
     + 17 * byte_14000A668[8]
     + 69 * byte_14000A668[7]
     + 367 * byte_14000A668[6]
     + 780 * byte_14000A668[5]
     + 291 * byte_14000A668[4]
     + 834 * byte_14000A668[3]
     + 587 * byte_14000A668[2]
     + 133 * byte_14000A668[1] == 653127
    && 41 * byte_14000A668[20]
     + 422 * byte_14000A668[19]
     + 420 * byte_14000A668[18]
     + 224 * byte_14000A668[17]
     + 475 * byte_14000A668[16]
     + 854 * byte_14000A668[15]
     + 233 * byte_14000A668[14]
     + 179 * byte_14000A668[13]
     + 620 * byte_14000A668[12]
     + 69 * byte_14000A668[11]
     + 42 * byte_14000A668[10]
     + 684 * byte_14000A668[9]
     + 300 * byte_14000A668[8]
     + 745 * byte_14000A668[7]
     + 894 * byte_14000A668[6]
     + 554 * byte_14000A668[5]
     + 495 * byte_14000A668[4]
     + 66 * byte_14000A668[3]
     + 316 * byte_14000A668[2]
     + 391 * byte_14000A668[1] == 533470 )
  {
    sub_140004DC0(std::cout, &unk_140007C70, v205);
    for ( i = 0; i < 21; ++i )
      sub_1400051C0(std::cout, byte_14000A668[i]);
    sub_140004DC0(std::cout, "}", v206);
    return 0;
  }
  else
  {
    v208 = sub_140004DC0(std::cout, "戳啦 ", v205);
    std::ostream::operator<<(v208, sub_140005140);
    return 0;
  }
}

分析可知,对于这种超复杂的线性方程,我们可以用python的z3solver库解决

对于z3的解释

Z3 简介

Z3 是一个微软出品的开源约束求解器,能够解决很多种情况下的给定部分约束条件寻求一组满足条件的解的问题(可以简单理解为解方程的感觉,虽然这么比喻其实还差距甚远,请勿吐槽),功能强大且易于使用,本文以近期的 CTF 题为实例,向尚未接触过约束求解器的小伙伴们介绍 Z3 在 CTF 解题中的应用。

Z3 约束求解器是针对 Satisfiability modulo theories Problem 的一种通用求解器。所谓 SMT 问题,在 Z3 环境下是指关于算术、位运算、数组等背景理论的一阶逻辑组合决定性问题。虽然 Z3 功能强大,但是从理论上来说,大部分 SMT 问题的时间复杂度都过高,根本不可能在有限时间内解决。所以千万不要把 Z3 想象得过于万能。

Z3 在工业应用中实际上常见于软件验证、程序分析等。然而由于功能实在强大,也被用于很多其他领域。CTF 领域来说,能够用约束求解器搞定的问题常见于密码题、二进制逆向、符号执行、Fuzzing 模糊测试等。此外,著名的二进制分析框架 angr 也内置了一个修改版的 Z3。

Z3 本身提供一个类似于 Lisp 的内置语言,但是实际使用中,一般使用 Python Binding 操作会比较方便。

z3的安装

然后开始对超复杂的线性方程写脚本

from z3 import *

a = [Int('a[%d]' % i) for i in range(21)]
s = Solver()
s.add(948 * a[20]
     + 887 * a[19]
     + 410 * a[18]
     + 978 * a[17]
     + 417 * a[16]
     + 908 * a[15]
     + 965 * a[14]
     + 987 * a[13]
     + 141 * a[12]
     + 257 * a[11]
     + 323 * a[10]
     + 931 * a[9]
     + 773 * a[8]
     + 851 * a[7]
     + 758 * a[6]
     + 891 * a[5]
     + 575 * a[4]
     + 616 * a[3]
     + 860 * a[2]
     + 283 * a[1] == 913686)
s.add( 938 * a[20]
     + 490 * a[19]
     + 920 * a[18]
     + 50 * a[17]
     + 568 * a[16]
     + 68 * a[15]
     + 35 * a[14]
     + 708 * a[13]
     + 938 * a[12]
     + 718 * a[11]
     + 589 * a[10]
     + 954 * a[9]
     + 974 * a[8]
     + 62 * a[7]
     + 580 * a[6]
     + 80 * a[5]
     + 111 * a[4]
     + 151 * a[3]
     + 421 * a[2]
     + 148 * a[1] == 630335)
s.add( 908 * a[20]
     + 590 * a[19]
     + 668 * a[18]
     + 222 * a[17]
     + 489 * a[16]
     + 335 * a[15]
     + 778 * a[14]
     + 622 * a[13]
     + 95 * a[12]
     + 920 * a[11]
     + 932 * a[10]
     + 892 * a[9]
     + 409 * a[8]
     + 392 * a[7]
     + 11 * a[6]
     + 113 * a[5]
     + 948 * a[4]
     + 674 * a[3]
     + 506 * a[2]
     + 182 * a[1] == 707525)
s.add( 479 * a[20]
     + 859 * a[19]
     + 410 * a[18]
     + 399 * a[17]
     + 891 * a[16]
     + 266 * a[15]
     + 773 * a[14]
     + 624 * a[13]
     + 34 * a[12]
     + 479 * a[11]
     + 465 * a[10]
     + 728 * a[9]
     + 447 * a[8]
     + 427 * a[7]
     + 890 * a[6]
     + 570 * a[5]
     + 716 * a[4]
     + 180 * a[3]
     + 571 * a[2]
     + 707 * a[1] == 724203)
s.add( 556 * a[20]
     + 798 * a[19]
     + 380 * a[18]
     + 716 * a[17]
     + 71 * a[16]
     + 901 * a[15]
     + 949 * a[14]
     + 304 * a[13]
     + 142 * a[12]
     + 679 * a[11]
     + 459 * a[10]
     + 814 * a[9]
     + 282 * a[8]
     + 49 * a[7]
     + 873 * a[6]
     + 169 * a[5]
     + 437 * a[4]
     + 199 * a[3]
     + 771 * a[2]
     + 807 * a[1] == 688899)
s.add( 465 * a[20]
     + 898 * a[19]
     + 979 * a[18]
     + 198 * a[17]
     + 156 * a[16]
     + 831 * a[15]
     + 856 * a[14]
     + 322 * a[13]
     + 25 * a[12]
     + 35 * a[11]
     + 369 * a[10]
     + 917 * a[9]
     + 522 * a[8]
     + 654 * a[7]
     + 235 * a[6]
     + 385 * a[5]
     + 469 * a[4]
     + 231 * a[3]
     + 496 * a[2]
     + 83 * a[1] == 604784)
s.add( 305 * a[20]
     + 928 * a[19]
     + 260 * a[18]
     + 793 * a[17]
     + 787 * a[16]
     + 708 * a[15]
     + 758 * a[14]
     + 236 * a[13]
     + 688 * a[12]
     + 747 * a[11]
     + 711 * a[10]
     + 195 * a[9]
     + 50 * a[8]
     + 648 * a[7]
     + 787 * a[6]
     + 376 * a[5]
     + 220 * a[4]
     + 33 * a[3]
     + 194 * a[2]
     + 585 * a[1] == 665485)
s.add( 767 * a[20]
     + 573 * a[19]
     + 22 * a[18]
     + 909 * a[17]
     + 598 * a[16]
     + 588 * a[15]
     + 136 * a[14]
     + 848 * a[12]
     + 964 * a[11]
     + 311 * a[10]
     + 701 * a[9]
     + 653 * a[8]
     + 541 * a[7]
     + 443 * a[6]
     + 7 * a[5]
     + 976 * a[4]
     + 803 * a[3]
     + 273 * a[2]
     + 859 * a[1] == 727664)
s.add( 776 * a[20]
     + 59 * a[19]
     + 507 * a[18]
     + 164 * a[17]
     + 397 * a[16]
     + 744 * a[15]
     + 377 * a[14]
     + 768 * a[13]
     + 456 * a[12]
     + 799 * a[11]
     + 9 * a[10]
     + 215 * a[9]
     + 365 * a[8]
     + 181 * a[7]
     + 634 * a[6]
     + 818 * a[5]
     + 81 * a[4]
     + 236 * a[3]
     + 883 * a[2]
     + 95 * a[1] == 572015)
s.add( 873 * a[20]
     + 234 * a[19]
     + 381 * a[18]
     + 423 * a[17]
     + 960 * a[16]
     + 689 * a[15]
     + 617 * a[14]
     + 240 * a[13]
     + 933 * a[12]
     + 300 * a[11]
     + 998 * a[10]
     + 773 * a[9]
     + 484 * a[8]
     + 905 * a[7]
     + 806 * a[6]
     + 792 * a[5]
     + 606 * a[4]
     + 942 * a[3]
     + 422 * a[2]
     + 789 * a[1] == 875498)
s.add( 766 * a[20]
     + 7 * a[19]
     + 283 * a[18]
     + 900 * a[17]
     + 211 * a[16]
     + 305 * a[15]
     + 343 * a[14]
     + 696 * a[13]
     + 590 * a[12]
     + 736 * a[11]
     + 817 * a[10]
     + 603 * a[9]
     + 414 * a[8]
     + 828 * a[7]
     + 114 * a[6]
     + 845 * a[5]
     + 175 * a[4]
     + 212 * a[3]
     + 898 * a[2]
     + 988 * a[1] == 714759)
s.add( 220 * a[20]
     + 30 * a[19]
     + 788 * a[18]
     + 106 * a[17]
     + 574 * a[16]
     + 501 * a[15]
     + 366 * a[14]
     + 952 * a[13]
     + 121 * a[12]
     + 996 * a[11]
     + 735 * a[10]
     + 689 * a[9]
     + 998 * a[8]
     + 689 * a[7]
     + 729 * a[6]
     + 886 * a[5]
     + 860 * a[4]
     + 70 * a[3]
     + 466 * a[2]
     + 961 * a[1] == 778853)
s.add( 313 * a[20]
     + 748 * a[19]
     + 522 * a[18]
     + 864 * a[17]
     + 156 * a[16]
     + 362 * a[15]
     + 283 * a[14]
     + 49 * a[13]
     + 316 * a[12]
     + 79 * a[11]
     + 136 * a[10]
     + 299 * a[9]
     + 271 * a[8]
     + 604 * a[7]
     + 907 * a[6]
     + 540 * a[5]
     + 141 * a[4]
     + 620 * a[3]
     + 701 * a[2]
     + 866 * a[1] == 584591)
s.add( 922 * a[20]
     + 399 * a[19]
     + 425 * a[18]
     + 26 * a[17]
     + 159 * a[16]
     + 224 * a[15]
     + 438 * a[14]
     + 770 * a[13]
     + 144 * a[12]
     + 406 * a[11]
     + 110 * a[10]
     + 991 * a[9]
     + 749 * a[8]
     + 701 * a[7]
     + 646 * a[6]
     + 147 * a[5]
     + 979 * a[4]
     + 674 * a[3]
     + 999 * a[2]
     + 913 * a[1] == 717586)
s.add( 13 * a[20]
     + 537 * a[19]
     + 225 * a[18]
     + 421 * a[17]
     + 153 * a[16]
     + 484 * a[15]
     + 654 * a[14]
     + 743 * a[13]
     + 779 * a[12]
     + 74 * a[11]
     + 325 * a[10]
     + 439 * a[9]
     + 797 * a[8]
     + 41 * a[7]
     + 784 * a[6]
     + 269 * a[5]
     + 454 * a[4]
     + 725 * a[2]
     + 164 * a[1] == 537823)
s.add( 591 * a[20]
     + 210 * a[19]
     + 874 * a[18]
     + 204 * a[17]
     + 485 * a[16]
     + 42 * a[15]
     + 433 * a[14]
     + 176 * a[13]
     + 436 * a[12]
     + 634 * a[11]
     + 82 * a[10]
     + 978 * a[9]
     + 818 * a[8]
     + 683 * a[7]
     + 404 * a[6]
     + 562 * a[5]
     + 41 * a[4]
     + 789 * a[3]
     + 200 * a[2]
     + 220 * a[1] == 587367)
s.add( 584 * a[20]
     + 597 * a[19]
     + 928 * a[18]
     + 532 * a[17]
     + 902 * a[16]
     + 858 * a[15]
     + 820 * a[14]
     + 240 * a[13]
     + 124 * a[12]
     + 899 * a[11]
     + 848 * a[10]
     + 822 * a[9]
     + 409 * a[8]
     + 491 * a[7]
     + 587 * a[6]
     + 715 * a[5]
     + 410 * a[4]
     + 268 * a[3]
     + 721 * a[2]
     + 915 * a[1] == 842245)
s.add( 421 * a[20]
     + 302 * a[19]
     + 327 * a[18]
     + 180 * a[17]
     + a[16] * 512
     + 160 * a[15]
     + 623 * a[14]
     + 28 * a[13]
     + 411 * a[12]
     + 53 * a[11]
     + 633 * a[10]
     + 560 * a[9]
     + 623 * a[8]
     + 477 * a[7]
     + 901 * a[6]
     + 287 * a[5]
     + 149 * a[4]
     + 726 * a[3]
     + 934 * a[2]
     + 875 * a[1] == 610801)
s.add( 838 * a[20]
     + 434 * a[19]
     + 792 * a[18]
     + 649 * a[17]
     + 462 * a[16]
     + 170 * a[15]
     + 980 * a[14]
     + 15 * a[13]
     + 295 * a[12]
     + 495 * a[11]
     + 666 * a[10]
     + 934 * a[9]
     + 17 * a[8]
     + 69 * a[7]
     + 367 * a[6]
     + 780 * a[5]
     + 291 * a[4]
     + 834 * a[3]
     + 587 * a[2]
     + 133 * a[1] == 653127)
s.add( 41 * a[20]
     + 422 * a[19]
     + 420 * a[18]
     + 224 * a[17]
     + 475 * a[16]
     + 854 * a[15]
     + 233 * a[14]
     + 179 * a[13]
     + 620 * a[12]
     + 69 * a[11]
     + 42 * a[10]
     + 684 * a[9]
     + 300 * a[8]
     + 745 * a[7]
     + 894 * a[6]
     + 554 * a[5]
     + 495 * a[4]
     + 66 * a[3]
     + 316 * a[2]
     + 391 * a[1] == 533470 )
if s.check() == sat:
    ans = s.model()
    for i in range(1,21):
        print(chr(ans[a[i]].as_long()), end="")

    

进行输出

答案出现了

CDBBDCAAABBDBCCBCCAC

再回过头来验证一下

这里一定要把附件丢到文件下,否则程序会直接跳出

BaseCTF{ CDBBDCAAABBDBCCBCCAC}

然后这一题考察的就是超复杂线性方程的解法

8.喝杯下午茶

又是继续做吴师傅的题了,这次看看是怎么个事

依旧是常规的小操作来一波

无壳,丢进ida64里,查看字符串

然后开始f5进入到伪代码 sub_140016100()函数里

结合题目tea,可以知道这是一道经典的tea加密算法题

密码学中,微型加密算法(Tiny Encryption Algorithm,TEA)是一种易于描述和执行的块密码,通常只需要很少的代码就可实现。

代码的特点:

  • 加密使用的数据为2个32位无符号整数,密钥为4个32位无符号整数即密钥长度为128位(当加密解密的对象是一串数组的时候,需要将这个32位无符号整数的数组每两个32位无符号整数划分为一组,对每一组数据单独加密解密得到结果)
  • 该算法使用了一个常数 δ 作为倍数,它来源于黄金比率,以保证每一轮加密都不相同。但 δ 的精确值似乎并不重要,这里 TEA 把它定义为 δ=「(√5 - 1)231」(也就是程序中的 0×9E3779B9)作为魔数(了解即可)
加密过程

拥有一个叫做Feistel 结构的密码学结构。这种密码学结构通俗的来讲就是会将加密的plaintext分成L、R两部分,并且满足 L_{i+1} = R_i, R_{i+1} = F(K_i,R_i) \oplus L_i 这种交换式的加密方式的一种结构。

先将他们的值按H转成16进制,不然有负数

很明显v5是key v6是密文

然后分析加密

进入到sub_140015FB0()函数里

分析可知确实是一个标准的tea,不过delta变了而已

接下来用c语言搞出一个脚本

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define DELTA 0x114514

void DTea(uint32_t* flag, const uint32_t* Key) {
    uint32_t sum = DELTA * 32;
    int i;
    uint32_t v1 = flag[0];
    uint32_t v2 = flag[1];
    for (i = 0; i < 32; i++) {


        v2 -= ((v1 << 4) + Key[2]) ^ (v1 + sum) ^ ((v1 >> 5) + Key[3]);
        v1 -= ((v2 << 4) + Key[0]) ^ (v2 + sum) ^ ((v2 >> 5) + Key[1]);
        sum -= DELTA;
    }
    flag[0] = v1;
    flag[1] = v2;
}
int Check(uint32_t* enc, uint32_t* Input) {
    int i = 0;
    for (i; i < 10; i++) {
        if (enc[i] != Input[i]) {
            return 0;
        }
    }
    return 1;
}
int main() {
    uint32_t Key[4] = { 0x11223344, 0x55667788, 0x99AABBCC, 0xDDEEFF11 };
    uint32_t enc[11] = { 0x94B1F1E7 ,0x21D5D352 ,0x5247793D ,0x040D1C97 ,0xF36E7F74 ,0x9C53F70F ,0x6AEACFD8 ,0x6F9F06F4 ,0xEAFD9E2E ,0x32B655F7 ,0 };

    for (int i = 0; i < 5; i++) {
        DTea(&enc[i * 2], Key);
    }
    puts((char *)enc);

    return 0;
}

在线输出一下

BaseCTF{h3r3_4_cuP_0f_734_f0R_y0U!!!!!!}

9.ea_py

继续做师傅的题,查壳一看看,

卧槽,久违的py解包,进入到py解包工具,解包一下

放到在线网站

Key.pyc会在这个pyz文件夹里

由于Rc4这种加密既是加密也是解密所以我们只需要对源码进行修改复原在把密文传进去就会有flag

需要注意的是Key得和主程序是同一目录并且文件名不能有问题

代码

import Key
import sys

def init_Sbox(seed):
    k_b = [ord(seed[i % len(seed)]) for i in range(256)]
    s = list(range(256))
    j = 0
    for i in range(256):
        j = (j + s[i] + k_b[i]) % 256
        s[i], s[j] = s[j], s[i]
    return s

def KeyStream(text, Sbox):
    s = Sbox.copy()
    i, j = 0, 0
    k = [0] * len(text)
    for r in range(len(text)):
        i = (i + 1) % 256
        j = (j + s[i]) % 256
        s[i], s[j] = s[j], s[i]
        t = (s[i] + s[j]) % 256
        k[r] = s[t] ^ Key.keykey[r % len(Key.keykey)]
    return k

def Encrypt(text, seed):
    Sbox = init_Sbox(seed)
    key = KeyStream(text, Sbox)
    enc = [text[i] ^ key[i] for i in range(len(text))]
    return bytes(enc)

# Encrypted flag (this should be provided or replaced with actual data)
enc = b'\xe6\xaeC~F\xf2\xe3\xbb\xac\x9a-\x02U\x85p\xeb\x19\xd1\xe4\xc93sG\xb0\xeb1\xb5\x05\x05\xc3\xd7\x00\x18+D\xbc\x0cO\x9em\xf1\xbd'

# Input handling
flag = enc
#flag = [ord(i) for i in flag]
flag = Encrypt(flag, Key.key)
print(flag)
BaseCTF{Y0u_kn0W_d3c0Mp114710N_PY_4ND_rC4}

10.世界上最简单的编码

继续师傅的题目好吧

一套经典的小连招,查壳,无壳且64位

发现了base64编码表以及密文

进入f5伪代码

换表+对索引取值进行了魔改

表直接动调提取

其实这里分明显,传入了一个key的参数,进去之后直接看它在哪里发挥了作用就行了

编码索引值+了那我们就减回去就行了

table = "CDABGHEFKLIJOPMNSTQRWXUVabYZefcdijghmnklqropuvstyzwx23016745+/89"
enc = "TqK1YUSaQryEMHaLMnWhYU+Fe0WPenqhRXahfkV6WE2fa3iRW197Za62eEaD"
index = []
number = [1,2,3,4]
for i in range(len(enc)):
    tmp = table.index(enc[i]) - number[i % 4]
    if tmp >= 0:
        index.append(tmp)
    else:
        index.append(tmp + 64)
print(index)
for i in range(0,len(index),4):
    a = index[i]
    b = index[i + 1]
    c = index[i + 2]
    d = index[i + 3]
    sum = a << 18 | b << 12 | c << 6 | d
    for j in range(3):
        print(chr((sum >> ((2 - j) * 8)) & 0xff),end="")

输出

虽然讲拿下了,但是这道题环境出问题了,动调有点小失误

(建议拷打一下出题(bushi

BaseCTF{B45E64_eNCoDIn9_I5_rE4LLY_7OO_5implE}

11.RivestCipher

emmmmm

不知道这是什么编程语言不要慌,直接丢尽看看啥玩意

然后发现居然是go语言,有点意思了哈

进入主函数main_main

// main.main
void __fastcall main_main()
{
  __int64 v0; // rax
  int v1; // esi
  __int64 v2; // r14
  __int128 v3; // xmm15
  __int64 *v4; // rdi
  __int64 v5; // rbp
  int v6; // r8d
  int v7; // r9d
  int v8; // r10d
  __int64 v9; // r11
  __int64 v10; // rax
  __int64 v11; // rcx
  int v12; // r8d
  int v13; // r9d
  int v14; // r10d
  int v15; // r11d
  __int64 String; // rax
  __int64 v17; // rcx
  int v18; // r8d
  int v19; // r9d
  int v20; // r10d
  int v21; // r11d
  __int128 v22; // rdi
  __int64 v23; // rax
  int v24; // r8d
  int v25; // r9d
  int v26; // r10d
  __int64 v27; // r11
  __int64 v28; // rax
  int v29; // r8d
  int v30; // r9d
  const char *v31; // r10
  int v32; // r11d
  __int64 v33; // rcx
  unsigned __int64 v34; // rdx
  __int64 v35; // rsi
  __int64 v36; // rbx
  unsigned __int64 v37; // rdi
  unsigned __int8 v38; // r9
  __int64 v39; // rbx
  __int64 v40; // rax
  __int64 v41; // rdx
  int v42; // r8d
  int v43; // r9d
  int v44; // r10d
  int v45; // r11d
  __int64 v46; // rax
  __int64 *v47; // [rsp+0h] [rbp-1B0h]
  __int64 v48; // [rsp+10h] [rbp-1A0h] BYREF
  __int64 v49; // [rsp+18h] [rbp-198h]
  __int64 v50; // [rsp+20h] [rbp-190h]
  __int64 v51; // [rsp+28h] [rbp-188h]
  __int64 v52; // [rsp+30h] [rbp-180h]
  __int64 v53; // [rsp+38h] [rbp-178h]
  char v54; // [rsp+40h] [rbp-170h] BYREF
  __int64 v55; // [rsp+60h] [rbp-150h]
  __int64 v56; // [rsp+68h] [rbp-148h]
  unsigned __int64 v57; // [rsp+70h] [rbp-140h]
  __int64 v58; // [rsp+78h] [rbp-138h]
  __int64 v59; // [rsp+80h] [rbp-130h]
  RTYPE *v60; // [rsp+88h] [rbp-128h] BYREF
  char **v61; // [rsp+90h] [rbp-120h] BYREF
  _QWORD v62[2]; // [rsp+98h] [rbp-118h] BYREF
  _QWORD v63[2]; // [rsp+A8h] [rbp-108h] BYREF
  __int128 v64; // [rsp+B8h] [rbp-F8h]
  _QWORD v65[2]; // [rsp+C8h] [rbp-E8h] BYREF
  __int128 v66; // [rsp+D8h] [rbp-D8h]
  _QWORD v67[2]; // [rsp+E8h] [rbp-C8h] BYREF
  __int128 v68; // [rsp+F8h] [rbp-B8h] BYREF
  __int64 v69; // [rsp+108h] [rbp-A8h]
  RTYPE **v70; // [rsp+110h] [rbp-A0h]
  __int64 v71; // [rsp+118h] [rbp-98h]
  __int64 v72; // [rsp+140h] [rbp-70h]
  __int64 v73; // [rsp+148h] [rbp-68h]
  __int128 v74[5]; // [rsp+150h] [rbp-60h] BYREF
  __int64 v75; // [rsp+1A8h] [rbp-8h]
  __int64 vars0; // [rsp+1B0h] [rbp+0h] BYREF

  while ( (unsigned __int64)&v61 <= *(_QWORD *)(v2 + 16) )
    v0 = runtime_morestack_noctxt(v0);
  v75 = runtime_bss;
  v74[0] = v3;
  v4 = &v48 + 35;
  v47 = &vars0;
  ((void (__fastcall *)(__int64 *))loc_462C70)(v4);
  v5 = (__int64)v47;
  v10 = runtime_makeslice((unsigned int)&RTYPE_uint8, 4096, 4096, (_DWORD)v4, v1, v6, v7, v8, v9, v48, v49);
  v68 = v3;
  v47 = (__int64 *)v5;
  *(_QWORD *)&v68 = ((__int64 (__golang *)(__int64, __int64, __int64, __int64 *))loc_462C70)(
                      v10,
                      4096LL,
                      v11,
                      &v48 + 24);
  *((_QWORD *)&v68 + 1) = 4096LL;
  v69 = 4096LL;
  v70 = go_itab__os_File_io_Reader;
  v71 = v75;
  v72 = -1LL;
  v73 = -1LL;
  *(_QWORD *)&v74[0] = v68;
  ((void (__fastcall *)(char *, char *))loc_462FDA)((char *)v74 + 8, (char *)&v68 + 8);
  v67[0] = &RTYPE_string;
  v67[1] = &off_4CB2B8;
  fmt_Fprint(
    (unsigned int)go_itab__os_File_io_Writer,
    os_Stdout,
    (unsigned int)v67,
    1,
    1,
    v12,
    v13,
    v14,
    v15,
    v48,
    v49,
    v50,
    v51,
    v52);
  String = bufio__ptr_Reader_ReadString(v74, 10LL);
  if ( v17 )
  {
    v66 = v3;
    v65[0] = &RTYPE_string;
    v65[1] = &off_4CB2C8;
    *(_QWORD *)&v66 = *(_QWORD *)(v17 + 8);
    *((_QWORD *)&v66 + 1) = 1LL;
    fmt_Fprintln(
      (unsigned int)go_itab__os_File_io_Writer,
      os_Stdout,
      (unsigned int)v65,
      2,
      2,
      v18,
      v19,
      v20,
      v21,
      v48,
      v49,
      v50,
      v51,
      v52);
  }
  else
  {
    *(_QWORD *)&v22 = &runtime_noptrbss;
    if ( String )
      *(_QWORD *)&v22 = String;
    *((_QWORD *)&v22 + 1) = 10LL;
    v23 = main_rc4Encrypt(
            (unsigned int)"BaseCTFfloat32float64console19531259765625invaliduintptrChanDir Value>forcegcallocmWcpuprofallocmRunknowngctraceIO waitrunningsyscallwaitingUNKNOWN, goid= s=nil\n (scan  MB in pacer: % CPU ( zombie, j0 = head = panic:  nmsys= locks= dying= allocsGODEBUG m->g0= pad1=  pad2=  text= minpc= \tvalue= (scan)\ttypes : type CopySidWSARecvWSASendconnectavx512fGoString48828125nil PoolscavengepollDesctraceBufdeadlockraceFinipanicnilcgocheckrunnable procid rax     rbx     rcx     rdx     rdi     rsi     rbp     rsp     r8      r9      r10     r11     r12     r13     r14     r15     rip     rflags  cs      fs      gs       is not  pointer packed=BAD RANK status unknown(trigger= npages= nalloc= nfreed=[signal  newval= mcount= bytes,  stack=[ minLC=  maxpc= \tstack=[ minutes etypes no anodeCancelIoReadFileAcceptExWSAIoctlshutdownwsaioctlavx512bwavx512vlInherited244140625complex64interfaceinvalid nfuncargs(bad indirreflect: Interfacepsapi.dllprofBlockstackpoolhchanLeafwbufSpansmSpanDeadscavtraceinittracepanicwaitchan sendpreemptedcoroutinecopystack -> node= ms cpu,  (forced) wbuf1.n= wbuf2.n= s.limit= s.state= B work ( B exp.)  marked   unmarked in use)\n, size = bad prune, tail = recover:  not in [ctxt != 0, oldval=, newval= threads=: status= blocked= lockedg=atomicor8 runtime= m->curg=(unknown)traceback} stack=[ lockedm=FindCloseLocalFreeMoveFileWWriteFileWSASendTontdll.dllpclmulqdq/dev/stdin12207031256103515625complex128t.Kind == LockFileExWSASocketWws2_32.dllnotifyListprofInsertstackLargemSpanInUseGOMAXPROCSstop tracedisablethpinvalidptrschedtracesemacquiredebug call flushGen  MB goal, s.state =  s.base()= heapGoal=GOMEMLIMIT KiB now,  pages at  sweepgen= sweepgen , bound = , limit = tracefree(tracegc()\nexitThreadBad varintGC forced\n runqueue= stopwait= runqsize= gfreecnt= throwing= spinning=atomicand8float64nanfloat32nanException  ptrSize=  targetpc= until pc=unknown pcruntime: ggoroutine owner diedDnsQuery_WGetIfEntryCancelIoExCreatePipeGetVersionWSACleanupWSAStartupgetsockoptsetsockoptdnsapi.dll/dev/stdout/dev/stderrCloseHandleOpenProcessGetFileTypeshort write30517578125bad argSizemethodargs(ProcessPrngMoveFileExWNetShareAddNetShareDeluserenv.dllassistQueuenetpollInitreflectOffsglobalAllocmSpanManualstart traceclobberfreegccheckmarkscheddetailcgocall nilunreachable s.nelems=   of size  runtime: p  ms clock,  nBSSRoots=runtime: P  exp.) for minTrigger=GOMEMLIMIT=bad m value, elemsize= freeindex= span.list=, npages = tracealloc( p->status= in status  idleprocs= gcwaiting= schedtick= timerslen= mallocing=bad timedivfloat64nan1float64nan2float64nan3float32nan2GOTRACEBACK) at entry+ (targetpc= , plugin: runtime: g : frame.sp=created by broken pipebad messagefile existsbad addressRegCloseKeyCreateFileWDeleteFileWExitProcessFreeLibrarySetFileTimeVirtualLockWSARecvFromclosesocketgetpeernamegetsocknamecrypt32.dllmswsock.dllsecur32.dllshell32.dlli/o timeoutInput flag: 152587890625762939453125OpenServiceWRevertToSelfCreateEventWGetConsoleCPUnlockFileExVirtualQueryadvapi32.dlliphlpapi.dllkernel32.dllnetapi32.dllsweepWaiterstraceStringsspanSetSpinemspanSpecialgcBitsArenasmheapSpecialgcpacertracemadvdontneedharddecommitdumping heapchan receivelfstack.push span.limit= span.state=bad flushGen MB stacks, worker mode  nDataRoots= nSpanRoots= wbuf1=<nil> wbuf2=<nil> gcscandone runtime: gp= found at *( s.elemsize= B (鈭唃oal , cons/mark  maxTrigger= pages/byte\n s.sweepgen= allocCount end tracegc\nProcessPrng",
            7,
            7,
            v22,
            10,
            10,
            v19,
            v20,
            v21,
            v48,
            v49,
            v50,
            v51,
            v52,
            v53);
    if ( (_QWORD)v22 )
    {
      v64 = v3;
      v63[0] = &RTYPE_string;
      v63[1] = &off_4CB2D8;
      *(_QWORD *)&v22 = *(_QWORD *)(v22 + 8);
      v64 = v22;
      fmt_Fprintln(
        (unsigned int)go_itab__os_File_io_Writer,
        os_Stdout,
        (unsigned int)v63,
        2,
        2,
        v24,
        v25,
        v26,
        v27,
        v48,
        v49,
        v50,
        v51,
        v52);
    }
    else
    {
      v56 = 7LL;
      v59 = v23;
      v57 = 14LL;
      v28 = runtime_makeslice((unsigned int)&RTYPE_uint8, 14, 14, 0, 10, v24, v25, v26, v27, v48, v49);
      v33 = v56;
      v34 = v57;
      v35 = v59;
      v36 = 0LL;
      v37 = 0LL;
      while ( v33 > v36 )
      {
        v38 = *(_BYTE *)(v35 + v36);
        v31 = "0123456789abcdefTerminateProcess2384185791015625";
        if ( v37 >= v34 )
          runtime_panicIndex(v37, v36, v34);
        *(_BYTE *)(v28 + v37) = a0123456789abcd[v38 >> 4];
        v29 = v37 + 1;
        v30 = (unsigned __int8)a0123456789abcd[v38 & 0xF];
        if ( v34 <= v37 + 1 )
          runtime_panicIndex(v37 + 1, v36, v34);
        *(_BYTE *)(v37 + v28 + 1) = v30;
        ++v36;
        v37 += 2LL;
      }
      v39 = v28;
      v40 = runtime_slicebytetostring((unsigned int)&v54, v28, v34, v37, v35, v29, v30, (_DWORD)v31, v32, v48, v49, v50);
      if ( v39 == 64
        && (v55 = 64LL,
            v58 = v40,
            (unsigned __int8)runtime_memequal(
                               v40,
                               "0ebb0c573dd548f3d2b2525f02895cd5275b6f6e5776538982ea41246dae8517",
                               64LL)) )
      {
        v46 = 0LL;
      }
      else if ( runtime_cmpstring(64LL, v35, v41, "0ebb0c573dd548f3d2b2525f02895cd5275b6f6e5776538982ea41246dae8517") >= 0 )
      {
        v46 = 1LL;
      }
      else
      {
        v46 = -1LL;
      }
      if ( v46 )
      {
        v60 = &RTYPE_string;
        v61 = &off_4CB2F8;
        fmt_Fprintln(
          (unsigned int)go_itab__os_File_io_Writer,
          os_Stdout,
          (unsigned int)&v60,
          1,
          1,
          v42,
          v43,
          v44,
          v45,
          v48,
          v49,
          v50,
          v51,
          v52);
      }
      else
      {
        v62[0] = &RTYPE_string;
        v62[1] = &off_4CB2E8;
        fmt_Fprintln(
          (unsigned int)go_itab__os_File_io_Writer,
          os_Stdout,
          (unsigned int)v62,
          1,
          1,
          v42,
          v43,
          v44,
          v45,
          v48,
          v49,
          v50,
          v51,
          v52);
      }
    }
  }
}

发现了一串代码

交叉进行跟进

可以发现是标准的rc4加密过程

/ main.rc4Encrypt
__int64 __golang main_rc4Encrypt(
        __int64 a1,
        __int64 a2,
        __int64 a3,
        int a4,
        int a5,
        __int64 a6,
        int a7,
        int a8,
        int a9)
{
  __int64 v9; // r14
  int v10; // eax
  int v11; // r8d
  int v12; // r9d
  int v13; // r10d
  __int64 v14; // r11
  int v16; // r10d
  int v17; // r11d
  __int64 v18; // [rsp-38h] [rbp-48h]
  __int64 v19; // [rsp-38h] [rbp-48h]
  __int64 v20; // [rsp-30h] [rbp-40h]
  __int64 v21; // [rsp-30h] [rbp-40h]
  __int64 v22; // [rsp-28h] [rbp-38h]
  int v23; // [rsp+0h] [rbp-10h]
  __int64 v24; // [rsp+8h] [rbp-8h]
  void *retaddr; // [rsp+18h] [rbp+8h] BYREF
  __int64 v27; // [rsp+20h] [rbp+10h]
  __int64 v30; // [rsp+30h] [rbp+20h]
  int v34; // [rsp+48h] [rbp+38h]
  __int64 v35; // [rsp+48h] [rbp+38h]

  while ( (unsigned __int64)&retaddr <= *(_QWORD *)(v9 + 16) )
  {
    v27 = a1;
    v30 = a3;
    v35 = a6;
    runtime_morestack_noctxt(a1);
    a1 = v27;
    a3 = v30;
    a6 = v35;
  }
  v34 = a6;
  v10 = crypto_rc4_NewCipher(a1, a2, a3, a4, a5, a6, a7, a8, a9);
  if ( a2 )
    return 0LL;
  v23 = v10;
  v24 = runtime_makeslice((unsigned int)&RTYPE_uint8, a5, a5, a4, a5, v11, v12, v13, v14, v18, v20);
  crypto_rc4__ptr_Cipher_XORKeyStream(v23, v24, a5, a5, a4, a5, v34, v16, v17, v19, v21, v22);
  return v24;
}

然后取出其密钥就行

在一个页面特征处找到,猜测密钥是BaseCTF

丢进赛博厨子

BaseCTF{go1@ng_!S_RuNNin9_RC4}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值