DASCTF 2025
ezmac + login writeup
DASCTF 2025
ezmac
参考:
- https://blog.imipy.com/post/macos-shellcode-cheat-sheet.html
- https://github.com/radareorg/radare2/blob/master/libr/include/sflib/darwin-arm-64/ios-syscalls.txt
- https://stackoverflow.com/questions/56985859/ios-arm64-syscalls
去掉一个花指令:
__text:00000001000003A8 00 00 80 D2 MOV X0, #0
__text:00000001000003AC 00 00 00 CB SUB X0, X0, X0
[ ... ]
__text:00000001000003C4 E4 03 00 AA MOV X4, X0
__text:00000001000003C8 9F 00 00 F1 CMP X4, #0
[ ... begin]
__text:00000001000003CC 40 01 00 54 B.EQ loc_1000003F4
__text:00000001000003D0 25 00 00 90 A5 EC ADRL X5, input
__text:00000001000003D0 00 91
__text:00000001000003D8 86 04 00 D1 SUB X6, X4, #1
__text:00000001000003DC A5 00 06 8B ADD X5, X5, X6 ; byte_10000403A
__text:00000001000003E0 A7 00 40 39 LDRB W7, [X5]
__text:00000001000003E4 FF 28 00 71 CMP W7, #0xA
__text:00000001000003E8 61 00 00 54 B.NE loc_1000003F4
__text:00000001000003EC 07 00 80 52 MOV W7, #0
__text:00000001000003F0 A7 00 00 39 STRB W7, [X5]
[ ... end]
__text:00000001000003F4 loc_1000003F4
1
2
3
4
5
6
7
8
9
10
key = 0x39
cipher = [0x7d, 0x7b, 0x68, 0x7f, 0x69, 0x78, 0x44, 0x78, 0x72, 0x21, 0x74, 0x76, 0x75, 0x22, 0x26, 0x7b, 0x7c, 0x7e, 0x78, 0x7a, 0x2e, 0x2d, 0x7f, 0x2d]
key_list = []
for i in range(len(cipher)):
key_list.append(key)
key += 1
for c, k in zip(cipher, key_list):
print(chr(c ^ k), end='')
DASCTF{83c720da35436cc0}
login
如果缺少OpenSSL 1.1可以下一个:
1
2
wget https://mirror.cs.uchicago.edu/ubuntu/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.24_amd64.deb
sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2.24_amd64.deb
client有一个读config:
1
2
3
4
5
6
7
8
9
10
11
if (mode == 0) {
memcpy(out, buf + 4, 16); // bytes [4:19] -> key
} else if (mode == 1) {
memcpy(out, buf + 23, 16); // bytes [23:38] -> iv
} else if (mode == 2) {
memcpy(out, buf + 46, 42); // bytes [46:87] -> passwd
} else {
free(buf);
fclose(f);
return 0;
}
传明文时除了”req login …“都用RC4,传Key IV时用RSA。 server的state有0123分别对应:接收”req login …“明文,接收rsa(IV),接收rsa(Key),接收aes-cbc(passwd)。每个state都有一个简单的for循环校验,不通过输出backdoor。
nepqd已知,先构建出PEM:
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
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
N_HEX = "9a49428cadd84b7a81cb80f916e645a6a9dd23c2fe679f93af6a77eff0f0bb1309b77fb7861275f07ab41e98ae5c2ecf933f27d47b9ce0a55a3e06569cacbb4c9183f8ee9a47f2cfbb3a5965c9326f45d2d608cfeabea1a1879eae95b70224d2e7736b9bc4109756f55a3f70f11a9b9c6564fb6456d329c336fbb59859db5fde1f2338294e863c4f05b4a89e6c3b761d52a2081a0af0a320fde831daa741fad77aa7ef2dd30b3e33d1a6e7b44ed44ef40de4557a4fd65b63db63d105386bbd81071739ec3d0fe44b6a0952a2b065bededfecea6e22229fea32adfc9a6e2ccfdf5da437a56ad41d7ef08c2c4635d3a0218aab2a5ed6e9dd42d684bc918efe24d3" # off_C2D0
E_HEX = "10001"
P_HEX = "b782eca6a75067d398dd8ef00e9d024cc554f292d7820a72848d3c619dafaf61ab8f7d719d4cd8ac44351281afd64f8cf23bc8aa5ec48bbd9eb301af50b96f528a108e6643223130a84addd5b9e1ad108c44d706adc5fb097a17ab990f395f3781296e356ac60d64b9a2a641c3e2f593bbe98d38df528a1c67e583ef623b667f" # off_C2E0
Q_HEX = "d73b03a9b0c4b7e9236d56938d6264e6c8ecaab709effcf02f4e5ec26310273b81089e1cb3d4c050e852721d3daf1d5b7a2be2df02bafcffb77e17d1a8e6428bf87579c859cbe778d3b9ea93aff0d934a0e7b83a1d7a39d0a1779ea18db5fffd99b118c4c2361a22308f54f7ae568e7bf2de6d1b6eb0be1d77eca8edd94f9fad" # off_C2E8
D_HEX = "28c7df24a5798679db2a44979275f5f3179db180d91335702942fb1b70e985de825da90f2eb65d20ddf8be1d9d4e15bc1d84e95795ff8c0c28ce3c33fde054f6e82a4f4cc22597b350c9c62ccc0188bd4152a701a3601558f22aa9fae8b9fdac6c2bc09b1637f71e0511805e04b203c4fdb2b36ad232fe819b06ed4e57c74f39fd9b72623c16ff2100f148f622bf12876260c4859672360dc0da3da6b45c5c8c6215ccda072765840c213fba11a91d6bf598a8a8065797566c8950a34ea0a072a9ed0c38bdc58662f186ec578ca55d5098443fd566cc722ace9c4e89afc4e302c8a4870e11a003b935f4a102695bfd64bb0fa74dcc372682e2b24ff45a1a69" # off_C2F0
n = int(N_HEX, 16)
e = int(E_HEX, 16)
p = int(P_HEX, 16)
q = int(Q_HEX, 16)
d = int(D_HEX, 16)
# 计算 CRT 参数
dp = d % (p - 1)
dq = d % (q - 1)
qi = pow(q, -1, p)
priv_numbers = rsa.RSAPrivateNumbers(
p=p, q=q, d=d,
dmp1=dp, dmq1=dq, iqmp=qi,
public_numbers=rsa.RSAPublicNumbers(e=e, n=n),
)
key = priv_numbers.private_key()
pem = key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL, # BEGIN RSA PRIVATE KEY
encryption_algorithm=serialization.NoEncryption(),
)
print(pem.decode())
再用厨子,RSA-OAEP解密出key和IV:
IV
aassddffgghhjjllKey
qqwweerrttyyuuiiPasswd 是个aes-cbc
DASCTF{dqmaxfwkm921kr21m;df1m1dqmlk1d12d1}
This post is licensed under CC BY 4.0 by the author.