ISITDTUCTF

# PREFACE:最近确实作业很多,题只能慢慢写吧,9-17:小做了四个比较 ez 的

# re01

核心加密部分:

image-20231017081840615

翻译为循环:

# ISITDTU{11111111aaaaaaaa}
prime = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,
103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,
211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,
331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,
449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,
587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,
709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,
853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,
991,997,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,
1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,
1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,1319,1321,1327]
print(len(prime))
v14 = [0 for _ in range(25)]
for k in range(5):
    for m in range(5):
        v14[5 * k + m] = prime[k * 5 + m]
print(v14)
map = {}
a = [0x4CFC,0x52A8,0x5AA2,0x651C,0x4881,0x5203,0x57DF,0x6043,0x6B51,0x49C6,0x538F,0x5975,0x6231,0x6D6B,0x42DC,0x4C10,0x51AC,0x59B8,0x6448,0x1F63,0x2475,0x27C9,0x2C8D,0x333F]
def enc(a):
    global map, prime
    output = [0 for _ in range(25)]
    for i in range(5):
        for j in range(5):
            for k in range(5):
                output[5 * i + j] += prime[5 * k + j] * a[5 * i + k]

z3 求解即可

from z3 import *
input = [Int(f'input_{i}') for i in range(25)]
count_5 = 5
count_5_1 = 5
count_5_2 = 5
a6 = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,
103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,
211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,
331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,
449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,
587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,
709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,
853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,
991,997,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,
1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,
1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,1319,1321,1327]
output = [0x43AD, 0x4CFC,0x52A8,0x5AA2,0x651C,0x4881,0x5203,0x57DF,0x6043,0x6B51,0x49C6,0x538F,0x5975,0x6231,0x6D6B,0x42DC,0x4C10,0x51AC,0x59B8,0x6448,0x1F63,0x2475,0x27C9,0x2C8D,0x333F,0x7F78]
s = Solver()
for i in range(count_5):
    for j in range(count_5_2):
        sum_expr = Sum([a6[5 * k + j] * input[5 * i + k] for k in range(count_5_1)])
        s.add(output[5 * i + j] == sum_expr)
if s.check() == sat:
    m = s.model()
    solution = [m[input[i]].as_long() for i in range(25)]
    print("Solution for input array:", solution)
else:
    print("No solution found")
x = [103, 111, 111, 100, 95, 106, 111, 98, 95, 121, 111, 117, 95, 115, 111, 108, 118, 101, 100, 95, 114, 101, 48, 49, 33]
for i in x:
    print(chr(i),end='')
    
# good_job_you_solved_re01!

# dot

检测 osname ,然后进行魔改的 morse 编码,与密文对照

golang 写的,反编译几乎没法看,看汇编即可

魔改的 morse 编码可以不用逆,看出来是一一映射的加密即可,动态 patch 检测的 osname (注意第二个返回值是 osname 的长度,也需要 patch)写入表,在加密过程后获得表,与密文对照即可获得 flag

(这里前面有将所有字符变为大写,最后直接交全大写即可)

map = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890{}-'
a = '-... -.-. ..... --. -- --.- .--. .--- -.... .-.. ..- _ --- - ....- .. ...- .---- .-- ----- --.. -..- -.-- ...-- ..--- .-. -... -.-. ..... --. -- --.- .--. .--- -.... .-.. ..- _ --- - ....- .. ...- .---- .-- ----- --.. -..- -.-- ...-- ..--- .-. . -.. --... ----. -.- ---.. .- ..-. .... ... '
a = a.split(' ')
b = '..... ... --- .. --.. ----- --... .---- --. ----- --.. -.-- --... _ ..... ... --- --...'
b = b.split()
flag = ''
for i in b:
    for j in range(len(a)):
        if (i == a[j]):
            # print(map[j],end='')
            flag += map[j]
            break
flag = flag.upper()
print(flag)
# C0MPUT3RDTUW3LC0M3

# sanity_check

go 的反编译完全的就是…

硬看汇编即可,对着栈看(这里被 nop 掉的即为判断并跳出循环的)

image-20231017142409397

前面一直没注意到 main_calc

__int64 __fastcall main_calc()
{
  __int64 result; // rax
  __int64 v1; // r14
  __int64 v2; // [rsp+0h] [rbp-10h]
  void *retaddr; // [rsp+10h] [rbp+0h] BYREF
  if ( (unsigned __int64)&retaddr <= *(_QWORD *)(v1 + 16) )
    runtime_morestack_noctxt_abi0();
  if ( result > 1 )
  {
    v2 = main_calc();
    return v2 + main_calc();
  }
  return result;
}

这里是一个斐波那契数列,然后结合汇编发现,和 flag 进行异或即可

实际上,这里也可以断在合适的位置,直接在栈中找到 flag

image-20231017142853962

解密 exp:

a = [0x54,0x69,0x68,0x71,0x5C,0x4C,0x7B,0x52,0x42,0x4A,0x52,0x2B,0x0F5,0x0B6,0x120,0x20D,0x3AE,0x64F,0x0A47,0x1007,0x1A28,0x2A9D,0x4565,0x6F9E,0x0B555,0x12563,0x1DA5F,0x2FF27,0x4D90A,0x7D8EA,0x0CB26A,0x148AB8,0x213D62,0x35C78B,0x570489]
b = [0,1]
for i in range(len(a)):
    if (i+1 == len(b)):
        b.append(b[i] + b[i-1])
    print(chr(a[i] ^ b[i]),end='')
# ISITDTU{This_Is_Where_Your_RE_Journey_Begin}

# simple_encrypt

golang,反编译同样有巨大的问题

换表的 base64,然后有个异或 0x2a 比较明显,但是解密不对,可以猜测,发现数字不会有操作,而字母猜测前几个为 Th1s

a = 'Guf'
b = 'Ths'
for i in range(3):
    print(ord(a[i]) - ord(b[i]))

image-20231017164530423

差 13,猜测得到最后 exp…

a = [0x6d,0x5f,0x1b,0x4c,0x75,0x1b,0x4c,0x75,0x4c,0x1b,0x50,0x49,0x53,0x19,0x75,0x19,0x4b,0x5a,0x4f,0x46,0x49,0x4d,0x75,0x40,0x1b,0x4d,0x5f,0x75,0x7e,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x0b]
print('ISITDTU{',end='')
flag = ''
for i in a:
    if chr(i ^ 0x2a) in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
        flag += chr((((i ^ 0x2a) - ord('A') + 13) % 26) + ord('A'))
    elif chr(i ^ 0x2a) in 'abcdefghijklmnopqrstuvwxyz':
        flag += chr((((i ^ 0x2a) - ord('a') + 13) % 26) + ord('a'))
    else:
        flag += chr(i ^ 0x2a)
    # flag += chr(i ^ 0x2a)
print(flag,end='')
print('}')
# ISITDTU{Th1s_1s_s1mpl3_3ncrypt_w1th_G000000!}