WEEK1

ezasm

简单分析是一个xor 后的 sub

1
2
3
4
5
6
7
8
9
code = "nhuo[M`7mc7uhc$7midgbTf`7`$7%#ubf7 ci5Y"
flag = ""
for i in str(code):
temp = ord(i)
temp += 0xA
temp ^= 0x1E
flag += chr(temp)
print(flag)
#flag{It_is_als0_impor@nt_t0_13arn_4sm!}

easy_re

打开是一个简单的高四位和第四位的转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def swap_high_low_nibble(num):
# 通过位运算分离高4位和低4位
high_nibble = (num >> 4) & 0x0F
low_nibble = num & 0x0F

# 交换高4位和低4位
swapped_num = (low_nibble << 4) | high_nibble

return swapped_num


# 测试示例
input_list = [102, 198, 22, 118, 183, 69, 39, 151, 245, 71, 3, 245, 55, 3, 198, 103, 51, 245, 71, 134, 86, 245,
38, 150, 230, 22, 39, 151, 245, 7, 39, 3, 38, 198, 51, 214, 215]
result_list = [swap_high_low_nibble(num) for num in input_list]

print("原始列表:", input_list)
print("交换高4位和低4位后的列表:", result_list)
flag = ""
for i in result_list:
flag += chr(i)

print(flag)
#flag{Try_t0_s0lv3_the_binary_pr0bl3m}

Seed

首先动态调试出来10个随机数【v5】的值:[0x26,0x45,0x49,0x8e,0x0b9,0x43,0x0cd,0x9b,0x0fa,0x0c]。

然后经过简单的xor得到flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
lalal = [0x26,0x45,0x49,0x8e,0x0b9,0x43,0x0cd,0x9b,0x0fa,0x0c]

code = [64, 41, 40, 233, 194, 4, 164, 237, 159, 83, 95, 117, 60, 209, 205, 43, 168, 196, 137, 105, 21, 33,
22, 239, 215, 39, 146, 223, 202, 83, 95, 42, 60, 209, 206, 3, 163, 239, 165, 120, 22, 26, 45, 225,
196]

flag = ""

print(len(code))
for i in range(45):
temp = code[i] ^ lalal[i % 10]
flag += chr(temp)
print(flag)
#flag{Give_y0u_the_se3d_and_D0_you_w@nt_t0_do}

easy_math

通过z3求解器解开后转成16进制再转车字符即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from z3 import *

l = [Int('l%d' % i) for i in range(6)]
solver = Solver()
solver.add((593*l[0] + 997*l[1] + 811*l[2] + 258*l[3] + 829*l[4] + 532*l[5])== 0x5b8e0aef71d34ff43)
solver.add((605*l[0] + 686*l[1] + 328*l[2] + 602*l[3] + 695*l[4] + 576*l[5])== 0x551a262360964ef7f)
solver.add((373*l[0] + 512*l[1] + 449*l[2] + 756*l[3] + 448*l[4] + 580*l[5])== 0x49d158a5657d6931c)
solver.add((560*l[0] + 635*l[1] + 422*l[2] + 971*l[3] + 855*l[4] + 597*l[5])== 0x625568d5abbabf4f3)
solver.add((717*l[0] + 507*l[1] + 388*l[2] + 925*l[3] + 324*l[4] + 524*l[5])== 0x50ee0c025e70e3c23)
solver.add((312*l[0] + 368*l[1] + 884*l[2] + 518*l[3] + 495*l[4] + 414*l[5])== 0x40e735f8aa2815f65)


if solver.check() == sat:
print("结果:", solver.model())

code = [0x66, 0x6C,0x61,0x67,0x7B,0x4E,0x30,0x5f,0x4f,0x6e,0x65,0x5f,0x6b,0x6e,0x30,0x77,
0x73,0x5f,0x6d,0x40,0x74,0x68,0x5f,0x42,0x33,0x74,0x74,0x65,0x72,0x5f,0x54,0x68,0x40,0x6e,0x5f
,0x6d,0x65,0x21,0x21,0x21,0x21,0x7d]
flag = ""
for i in code:
flag += chr(i)
print(flag)
#flag{N0_One_kn0ws_m@th_B3tter_Th@n_me!!!!}

ea_apk

这个题对我来说真的是坎坷。走了好多好多的弯路。。不过最后解出来的时候发现好简单…

这个题可不能用jadx,它编译出来有问题,要用gda

用dga打开后看到主函数是一个经过编码后对比。

看到加密过程是一个base58换表的操作。

这里看到表:

image-20231004005326912

然后用工具就解开了

image-20231004005413457

#flag{Jue_1_ju3_Y0ung_and_G0at_1s_go0d_for_yOuR_body}

WEEK2

pycode

1
2
3
4
5
6
7
for i in range(len(flag)):
temp = chr(ord(flag[i]) ^ 8)
value += temp

for i in range(len(value)):
temp = chr(ord(value[i]) + 3)
output += temp

先是base64,然后倒叙,然后字符串替换。

==AeAF3M-tzO-giQ-AUQosDQ9tGK7MDPuhC47tDNB5Tb8Yn4sdW4

【这个题,好像有时候在线网站解出来就是有点问题】

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import base64

key = '==AeAF3M-tzO-giQ-AUQosDQ9tGK7MDPuhC47tDNB5Tb8Yn4sdW4'
flag = ''
key = key.replace('-', '+')
key = key.replace('4', 'c')
key = key.replace('t', '0')
key = key[::-1]
print(key)
key = base64.b64decode(key.encode()).decode()

print(key)
for i in key:
flag += chr((ord(i) - 3) ^ 8)
print(flag)
#flag{1b36920e-c180-b250-6537-30238f5}

签到题?

not gcc

我将文件名字改成了1.bc

clang 1.bc -o 1

得到了1这个ELF文件。发现是数独

image-20231107174339175

image-20231107174036119

image-20231107174216219

得到:

497513268 538426917 612987354 759164823 261839475 843275196 986351742 125748639 374692581

image-20231107174926061

如果map[]里面是数据!=0时候,v2就需要==0。v2 就是输入的数据。

1
2
3
4
5
6
7
8
9
10
key = '497513268538426917612987354759164823261839475843275196986351742125748639374692581'
num = '407003208500020900012980004709104800061000470003270006086300040020740630304002000'
flag = ''
for i in range(len(key)):
if(key[i] == num[i]):
flag += '0'
else:
flag += key[i]
print(flag)
#090510060038406017600007350050060023200839005840005190900051702105008009070690581

然后再md5

flag{afb5d3a138821e30d6e1e6ccce4e5554}

WEEK3

EaseRE

image-20231107220642042

>python pyinstxtractor.py easyre.exe

uncompyle6 main.pyc

image-20231107221040467

然后我们看懂它的代码:就是有一个key,然后将data中的数据和它xor后,满足条件后就将它base64解码后转成二进制来执行。

就可以去执行了。

image-20231107222404323

然后我们就把它给弄出来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# uncompyle6 version 3.9.0
# Python bytecode version base 3.8.0 (3413)
# Decompiled from: Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: main.py
import base64
import marshal
import sympy as sp
encoded_data = b'#`VVVVVVVVVVVVVVVVVVVVVSVVVVFVVVV_YZVVVVMVU|VNFV@pU|V{xUMVYvVzBSMVDSVFRVMFDSV\\VQMV@\x7fVAxPMFU{V@BPp`]vU%B_MF]eVy]VMFY|UxZUVFUbTPBSMVrSVFRVMV\x7fCVT|]N`^VVVVVVVVVVVVVVVpVVVVPVVVVF`VVV_GFVVVVsVU\'V@FUp`PSVO\'TMV].V$FUMVPSVBFVOC".U_`SqV]/UU|VQ`U/V_`RsV]/V^ZUQpVMVUtVMVR@V_\'SqV]/Vo|VqV]/UU|VVpU/Vy`RGVU/Vy`SGVUoPPFTUVU.U_\'SsVXSV_\'QqVQRVQ&pqFM/UPFSQ`U|VENVqFE/V$`TqVFMVUtVMVR@V_\'SqV]/Vo|VqV]/UU|VVpU/Vy`RGVU/Vy`SGVU/Vy`TqVFMV_`TqVZMVUtVMVR@VU|VqFs/UvVRqVM/U\'RVxFRUV_QfqVACVT|RCb|VVFVV!FVVVVSgVFVVVT|Q%pEdvOY\'%pAnN@"yMsxSuPAb%p{~rOE{NO]nNOyvUzQ`tPAbMT|^%pYeMO{vTOUdN@{bsPA#sYxUB.xUvcxUvAx\\N%{`vPAnsPA#sYxRN%\x7f\x7ftcxUv!|Vtp/VVVS!UzM&u~"`rsx[tzZ\'O%AbN$]"t_FUVVVVto`VVVVVVF`UUV^ZVDVU_V^^VFNTTVRZVEVUPpRNVEVTt\x7fRVVVUmT`VVVPA#N@&`uPAqv%A"tnxVVVSN{U!ez%M\'!&&VP ez!UZmA.\'X"g^\'/NUcvXd.TPRTTD!&UB\\`dT.R}Q{!QQUdr~UguyU&sTU"u$An^PMdN@t!rpA&sPNcXQxSr@Am@p]bu\'#gT_^EVVVVtp|VVVUvU@YxM@Ye%pA`tz{bsYxQv@"`sOCvUzAbN%.|MsxRMzo\x7fM&x]M@"}ty{`sPA|tp/VVVUnS`VVV_^GVVVVt\x7fVVVVSvTSocu%E&uPB<VFVVV_ZFVVVVTUFRVFFTTVRZVpxTTVR\\Vp**'
for xor_key in range(101):
x = sp.symbols('x')
f = x ** 2 + x + 1
integral_value = sp.integrate(f, (x, 1, xor_key))
check_value = 13024
if integral_value * 3 == check_value:
xor_decoded_data = bytes([byte ^ xor_key for byte in encoded_data])
decoded_data = base64.b64decode(xor_decoded_data)
open("new.pyc","wb").write(decoded_data)
exit()

因为这个代码是可以直接执行的,所以是new.pyc而不是new.py

补头然后再次反编译就可以了。。。

因为不会010,所以:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 以十六进制字符串的方式定义要写入的内容
hex_content = "550D0D0A000000000000000000000000"

# 打开a.py文件并写入十六进制内容
with open('a.pyc', 'wb') as file:
file.write(bytes.fromhex(hex_content))

# 打开new.pyc文件并将其内容追加到a.py文件
with open('new.pyc', 'rb') as source_file:
with open('a.pyc', 'ab') as destination_file:
destination_file.write(source_file.read())

print("内容已写入a.pyc文件")

uncompyle6 a.pyc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# uncompyle6 version 3.9.0
# Python bytecode version base 3.8.0 (3413)
# Decompiled from: Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: fun.py


def rc4_encrypt(key, plaintext):
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i]
else:
i = j = 0
ciphertext = bytearray()
for char in plaintext:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
k = S[(S[i] + S[j]) % 256]
ciphertext.append(char ^ k)
else:
return ciphertext


key = b'example_key'
check = b'\xd8\x94\x1e\xab\x9bft\xeb]@\x1b\xba\xe6\xe8\x133W\xdd\x0e\xe6\x924\xf1\x80mh\xeb=\x08a\x02\t.\xb5\x05B\xb0\xb0/D\x8cY'
print('Plz input your flag:')
flag = input().encode('utf-8')
encrypted = rc4_encrypt(key, flag)
if encrypted == check:
print('yes')
else:
print('no')

ok 发现是rc4

解密就好了

ststst

这个是首先是一个SMC

image-20231108171221836

进来首先是看到mprotect

image-20231108171330158

看到地址是40696这个位置。我们动态调试运行这个函数后,找到这个地址的首地址。“u”后“c”后“p”

然后这个地址就被解密出来了,是一个tea加密

image-20231108171455454

加密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
__int64 __fastcall main(int a1, char **a2, char **a3)
{
int i; // [rsp+4h] [rbp-3Ch]
_QWORD input[6]; // [rsp+10h] [rbp-30h] BYREF

input[5] = __readfsqword(0x28u);
puts("plz input u fl4g:");
__isoc99_scanf("%32s", input);//输入
sub_400763();
for ( i = 0; i <= 3; ++i )//实现加密
sub_400696(&input[i], &dword_601080);//dword_601080这个里面是key
if ( !memcmp(input, &dword_6010A0, 0x20uLL) )//dword_6010A0这个里面就是加密后的数据
puts("yeh~");
else
puts("oh,no");
return 0LL;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
__int64 __fastcall sub_400696(unsigned int *a1, _DWORD *k)
{
__int64 result; // rax
unsigned int v3; // [rsp+10h] [rbp-10h]
unsigned int v4; // [rsp+14h] [rbp-Ch]
int v5; // [rsp+18h] [rbp-8h]
unsigned int i; // [rsp+1Ch] [rbp-4h]

v3 = *a1; // a1[0]
v4 = a1[1];
v5 = 0;
for ( i = 0; i <= 0x1F; ++i )
{
v5 -= 1640531527;
v3 += (v4 + v5) ^ (16 * v4 + *k) ^ ((v4 >> 5) + k[1]);
v4 += (v3 + v5) ^ (16 * v3 + k[2]) ^ ((v3 >> 5) + k[3]);
}
*a1 = v3;
result = v4;
a1[1] = v4;
return result;
}

解密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <cstdio>
#include <stdint.h>
#include <stdlib.h>
void decrypt(unsigned int* v, const unsigned int* k)
{
//必须得使用 uint32_t 不能用int
uint32_t v3 = v[0];
uint32_t v4 = v[1];
//因为原式子中最开始是0每次都 -1640531527 了这么多【32次】
//所以在逆向的时候首先先定义 (-1640531527) * 32 然后每次 + 1640531527
uint32_t v5 = ((-1640531527) * 32 ) & 0xFFFFFFFF;//这里报错了,所以就 &0xffffffff

for (int i = 0; i <= 31; ++i)
{
//这里就是加密原理
v4 -= (v3 + v5) ^ (16 * v3 + k[2]) ^ ((v3 >> 5) + k[3]);
v3 -= (v4 + v5) ^ (16 * v4 + k[0]) ^ ((v4 >> 5) + k[1]);
v5 += 1640531527;
}

v[0] = v3;
v[1] = v4;
}
int main()
{
unsigned int v[8] = {
0x0DB8F2569,0x40CD83E3,0xA033E680,0xFFF7A644,
0x690C3A17,0x0B621B866,0x34E7E2A7,0xAD10A692
};//这里是加密数据,每次的加密数据不一样。可以有更多
unsigned int k[4] = { 0x01234567, 0x89ABCDEF, 0xFEDCBA98, 0x76543210 };//这里是密钥。每次都是k[4]

for (int i = 0; i < 8; i += 2)//这个8是因为加密后的数据有8个。在加密的时候必须得是+=2
{
decrypt(v + i, k);
}
for (int i = 0; i < 8; i++)//这里是将解密后的数据打印出来
{
printf("%xh\n", v[i]);//这里打印出来后,可能大小端绪的问题就需要用后面的代码
}

//下面是将8个32位的数据转化成32个8位的数据。并且用小端序存放
//将给定的十六进制数据按小端序存放,并将其转化为8位数据存储在名为flag的32个元素的数组中:
unsigned char flag[32];
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 4; j++) {
flag[i * 4 + j] = (v[i] >> (j * 8)) & 0xFF;
}
}

// Print the result
printf("flag[32] = {");
for (int i = 0; i < 32; i++) {
printf("0x%02X", flag[i]);
if (i < 31) {
printf(", ");
}
}
printf("}\n");

//最后转化出来的数据打出来
for (int i = 0; i < 32; i++)
{
printf("%c", flag[i]);
}

}
#5ef846656801c9b9714388d2ccd98cdd

image-20231108203640822

得到:5ef846656801c9b9714388d2ccd98cdd