crackme

Crack 什么 Crack 啊,直接运行就行了。

babyRe

这题为什么不放在 Crypto,咱甚至没去看那个可执行文件。

1
2
3
4
5
6
p+q=
292884018782106151080211087047278002613718113661882871562870811030932129300110050822187903340426820507419488984883216665816506575312384940488196435920320779296487709207011656728480651848786849994095965852212548311864730225380390740637527033103610408592664948012814290769567441038868614508362013860087396409860
(p+1)*(q+1)=
21292789073160227295768319780997976991300923684414991432030077313041762314144710093780468352616448047534339208324518089727210764843655182515955359309813600286949887218916518346391288151954579692912105787780604137276300957046899460796651855983154616583709095921532639371311099659697834887064510351319531902433355833604752638757132129136704458119767279776712516825379722837005380965686817229771252693736534397063201880826010273930761767650438638395019411119979149337260776965247144705915951674697425506236801595477159432369862377378306461809669885764689526096087635635247658396780671976617716801660025870405374520076160
c=
5203005542361323780340103662023144468501161788183930759975924790394097999367062944602228590598053194005601497154183700604614648980958953643596732510635460233363517206803267054976506058495592964781868943617992245808463957957161100800155936109928340808755112091651619258385206684038063600864669934451439637410568700470057362554045334836098013308228518175901113235436257998397401389511926288739759268080251377782356779624616546966237213737535252748926042086203600860251557074440685879354169866206490962331203234019516485700964227924668452181975961352914304357731769081382406940750260817547299552705287482926593175925396

众所周知:

1
2
(p+1)\*(q+1) = p\*q + (p+q) +1
phi = (p-1)\*(q-1) = p\*q - (p+q) + 1

所以直接算 d 解:

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.Util.number import long_to_bytes, inverse
a = 292884018782106151080211087047278002613718113661882871562870811030932129300110050822187903340426820507419488984883216665816506575312384940488196435920320779296487709207011656728480651848786849994095965852212548311864730225380390740637527033103610408592664948012814290769567441038868614508362013860087396409860
b = 21292789073160227295768319780997976991300923684414991432030077313041762314144710093780468352616448047534339208324518089727210764843655182515955359309813600286949887218916518346391288151954579692912105787780604137276300957046899460796651855983154616583709095921532639371311099659697834887064510351319531902433355833604752638757132129136704458119767279776712516825379722837005380965686817229771252693736534397063201880826010273930761767650438638395019411119979149337260776965247144705915951674697425506236801595477159432369862377378306461809669885764689526096087635635247658396780671976617716801660025870405374520076160
c = 5203005542361323780340103662023144468501161788183930759975924790394097999367062944602228590598053194005601497154183700604614648980958953643596732510635460233363517206803267054976506058495592964781868943617992245808463957957161100800155936109928340808755112091651619258385206684038063600864669934451439637410568700470057362554045334836098013308228518175901113235436257998397401389511926288739759268080251377782356779624616546966237213737535252748926042086203600860251557074440685879354169866206490962331203234019516485700964227924668452181975961352914304357731769081382406940750260817547299552705287482926593175925396

n = b - a - 1
phi = n-a+1
e = 65537

d = inverse(e, phi)
flag = long_to_bytes(pow(c, d, n))

print(flag)

EasyRe

直接 IDA 启动,其逻辑并不复杂,就是看着哪里怪怪的:

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[24]; // [rsp+20h] [rbp-60h] BYREF
char v5[72]; // [rsp+38h] [rbp-48h] BYREF
__int16 v6; // [rsp+80h] [rbp+0h]
char v7; // [rsp+82h] [rbp+2h]
char v8[112]; // [rsp+90h] [rbp+10h]
char Str[104]; // [rsp+100h] [rbp+80h] BYREF
int v10; // [rsp+168h] [rbp+E8h]
int i; // [rsp+16Ch] [rbp+ECh]

_main();
strcpy(v4, "]P_ISRF^PCY[I_YWERYC");
memset(v5, 0, sizeof(v5));
v6 = 0;
v7 = 0;
puts("please input your strings:");
gets(Str);
v10 = strlen(Str);
while ( Str[i] )
{
for ( i = 0; i < v10; ++i )
v8[i] = Str[i] ^ 0x11;
}
for ( i = 0; i < v10; ++i )
{
if ( v8[i] == 66 || v8[i] == 88 )
v8[i] = -101 - v8[i];
}
for ( i = v10 - 1; i >= 0; --i )
v8[v10 - i - 1] = v8[i];
i = 0;
if ( v10 > 0 )
{
if ( v8[i] == v4[i] )
printf("yes!!!");
else
printf("no!!!");
}
return 0;
}

单纯的异或,只不过对 BX 有特殊处理。逆着算一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cipher = "]P_ISRF^PCY[I_YWERYC"
cipher = [ord(i) for i in cipher]

# Step 1: Reverse
cipher = cipher[::-1]

# Step 2: Restore B and X
for i in range(len(cipher)):
if cipher[i] == (-101-66) % 256:
cipher[i] = 66
if cipher[i] == (-101-88) % 256:
cipher[i] = 88

# Step 3: XOR
for i in range(len(cipher)):
cipher[i] ^= 0x11

print("".join([chr(i) for i in cipher]))

eazy_z3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
print("Please input flag:")
flag = input()
if len(flag)!=42:
print("Check your length!")
exit()

l=[]
for i in range(6):
s=""
for j in flag[i*7:i*7+7]:
s+=hex(ord(j))[2:]
l.append(int(s,16))
if (
(593*l[5] + 997*l[0] + 811*l[1] + 258*l[2] + 829*l[3] + 532*l[4])== 0x54eb02012bed42c08 and \
(605*l[4] + 686*l[5] + 328*l[0] + 602*l[1] + 695*l[2] + 576*l[3])== 0x4f039a9f601affc3a and \
(373*l[3] + 512*l[4] + 449*l[5] + 756*l[0] + 448*l[1] + 580*l[2])== 0x442b62c4ad653e7d9 and \
(560*l[2] + 635*l[3] + 422*l[4] + 971*l[5] + 855*l[0] + 597*l[1])== 0x588aabb6a4cb26838 and \
(717*l[1] + 507*l[2] + 388*l[3] + 925*l[4] + 324*l[5] + 524*l[0])== 0x48f8e42ac70c9af91 and \
(312*l[0] + 368*l[1] + 884*l[2] + 518*l[3] + 495*l[4] + 414*l[5])== 0x4656c19578a6b1170):
print("Good job!")
else:
print("Wrong\nTry again!!!")
exit()

别慌,直接用 sympy 求解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from Crypto.Util.number import long_to_bytes
from sympy import symbols, Eq, solve

l = symbols('l0 l1 l2 l3 l4 l5')

equations = \
[Eq(593*l[5] + 997*l[0] + 811*l[1] + 258*l[2] + 829*l[3] + 532*l[4], 0x54eb02012bed42c08),
Eq(605*l[4] + 686*l[5] + 328*l[0] + 602*l[1] + 695*l[2] + 576*l[3], 0x4f039a9f601affc3a),
Eq(373*l[3] + 512*l[4] + 449*l[5] + 756*l[0] + 448*l[1] + 580*l[2], 0x442b62c4ad653e7d9),
Eq(560*l[2] + 635*l[3] + 422*l[4] + 971*l[5] + 855*l[0] + 597*l[1], 0x588aabb6a4cb26838),
Eq(717*l[1] + 507*l[2] + 388*l[3] + 925*l[4] + 324*l[5] + 524*l[0], 0x48f8e42ac70c9af91),
Eq(312*l[0] + 368*l[1] + 884*l[2] + 518*l[3] + 495*l[4] + 414*l[5], 0x4656c19578a6b1170)]

solutions = solve(equations, l)

for key in solutions:
value = solutions[key]
print(long_to_bytes(value).decode('ascii'), end="")

mfx_re

upx: 6

其实就是 UPX 壳,但是出题人把其中 UPX 的标识符改为了 MFX。将其修改回来就可以用 UPX 脱壳了。然后丢进 IDA 直奔主题:

1
2
3
4
5
6
7
8
9
10
11
12
scanf("%s", s);
strcpy(s2, "HRBSEza63aa28d,bb62,3c40,7708,e`31c0d8acd7|");
v17 = 0;
for ( i = 0; ; ++i )
{
v3 = i;
if ( v3 >= strlen(s) )
break;
--s[i];
}
strcmp(s, s2);
puts("Now you know your flag!");

不难解:

1
2
3
4
5
6
7
cipher = 'HRBSEza63aa28d,bb62,3c40,7708,e`31c0d8acd7|'
plain = ''

for i in cipher:
plain += chr(ord(i) + 1)

print(plain)

z3_revenge

上难度了。

Screenshot-202311292137.webp

不过这又有什么问题呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import re

inputs = open('input.txt', 'r').read().split('\n')
inputs = [line.lstrip(' && ') for line in inputs]

for line in inputs:
# find all SBYTE*(v*) replace to v**
# example: SBYTE1(v5) -> v51
regex = r"SBYTE(\d+)\(v(\d+)\)"
line = re.sub(regex, r"v\2\1", line)
# find all SHIBYTE(v*) replace to v*7
# example: SHIBYTE(v8) -> v87
regex = r"SHIBYTE\(v(\d+)\)"
line = re.sub(regex, r"v\1\\7", line)
# find all (char)v* replace to v*0
# example: (char)v9 -> v90
regex = r"\(char\)v(\d+)"
line = re.sub(regex, r"v\1\\0", line)
print("Eq(",line.replace('\\', '').replace(' == ', ', '),"),")

这个脚本可以把 IDA 反编译出来的伪代码转换为 sympy 需要的等式:

Screenshot-202311292141.webp

然后上 sympy!

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
from sympy import symbols, Eq, solve

v40, v41, v42, v43 = symbols('v40 v41 v42 v43')
v44, v45, v46, v47 = symbols('v44 v45 v46 v47')
v50, v51, v52, v53 = symbols('v50 v51 v52 v53')
v54, v55, v56, v57 = symbols('v54 v55 v56 v57')
v60, v61, v62, v63 = symbols('v60 v61 v62 v63')
v64, v65, v66, v67 = symbols('v64 v65 v66 v67')
v70, v71, v72, v73 = symbols('v70 v71 v72 v73')
v74, v75, v76, v77 = symbols('v74 v75 v76 v77')
v80, v81, v82, v83 = symbols('v80 v81 v82 v83')
v84, v85, v86, v87 = symbols('v84 v85 v86 v87')
v90, v91, v92, v93 = symbols('v90 v91 v92 v93')

equations = [
...
]

solutions = solve(equations, [v40, v41, v42, v43, v44, v45, v46, v47,
v50, v51, v52, v53, v54, v55, v56, v57,
v60, v61, v62, v63, v64, v65, v66, v67,
v70, v71, v72, v73, v74, v75, v76, v77,
v80, v81, v82, v83, v84, v85, v86, v87,
v90, v91, v92])

for key in solutions:
value = solutions[key]
print(chr(value), end="")
print()