0%

2023-SICTF-#Round2-wp-misc

Crypto兼职misc手,浅做点misc娱乐娱乐

Rank:2

image-20230911152802298



[签到]Welcome

题目描述:

1
关注微信公众号并发送"SICTF2023"就可以获得flag辣!

签到题,照着做即可。

flag:

SICTF{Welcome_to_SICTF2023_#Round2}



Pixel_art

题目描述:

1
这张颜色很奇怪的图片到底是干什么的呢?

下载题目附件,是一个zip压缩包,解密提示需要密码,但是也并没有别的密码提示,所以第一反应就是伪加密。十六进制打开文件:

image-20230908171507928

将这里的1改为0即可解密压缩包,得到图片:

Pixel_art

并没有发现如题目描述中所说的奇怪的像素点,在stegsolve中打开,切换各种查看方式也没有什么发现。于是想到LSB隐写,可以发现:

image-20230908171812016

果然藏了东西,保存为png文件后查看:

pixel

这图也太小了,查看其详细信息,果然发现:

image-20230908171941968

大小仅有20*20,不难想到flag被加密进了像素点里。写一个脚本提取像素点:

1
2
3
4
5
6
7
8
9
10
11
12
from PIL import Image

image = Image.open('temp.png') # 替换为你的图片文件路径
width, height = image.size
pixel_data = []

for y in range(height):
for x in range(width):
pixel = image.getpixel((x, y))
pixel_data.append(pixel)

print(pixel_data)

打印出来的像素点列表是这样的:

1
[(46, 46, 46), (46, 46, 46), (46, 46, 46), (46, 46, 46), (46, 46, 46), (46, 46, 46), (33, 63, 33), (33, 46, 63), (46, 46, 46), (46, 46, 46), (46, 46, 46), (46, 46, 46), (46, 46, 46), (46, 46, 46), (63, 46, 63), (33, 46, 63), (46, 46, 46), (46, 33, 46), (63, 46, 46), (46, 46, 46), (46, 46, 33), (63, 33, 33), (46, 63, 33), (33, 33, 33), (33, 33, 63), (46, 63, 33), (46, 63, 33), ......, (46, 46, 33), (46, 63, 46), (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0)]

那么这三个数字显然有特殊含义,当作ASCII码打印出对应字符发现:分别是:

1
2
3
46-. 
33-!
63-?

这三个字符不难对应到Ook加密上,写个完整脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from PIL import Image

image = Image.open('temp.png') # 替换为你的图片文件路径
width, height = image.size
pixel_data = []

for y in range(height):
for x in range(width):
pixel = image.getpixel((x, y))
pixel_data.append(pixel)

count = 0
for i in range(len(pixel_data)):
if(pixel_data[i] == (0,0,0)):
break
for j in pixel_data[i]:
print("Ook"+chr(j),end = "")

拿生成的字符串去在线网址解密:

image-20230908172734509

flag:

SICTF{0141ac35-ec19-4cee-a906-22805fdbed77}



baby_zip

题目描述:

1
攻破这个压缩包!

题目给了一个压缩包,首先检查出是真加密,然后尝试ziprello爆破无果,binwalk也没有发现额外文件,那么就只能是深入明文攻击了。

深入明文攻击参考:

zip压缩包取证笔记 | 独奏の小屋 (hasegawaazusa.github.io)

由参考博客知,进行深入明文攻击需要至少12个已知字节。而由于已知压缩包内为png文件,也就知道文件头:

1
89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52

所以,我们至少知道了16个准确的字节,超过了12个字节,已经满足深入明文攻击的条件了,(多的已知字节可以加快速度),接下来就使用工具即可。

image-20230909112256733

两步操作分别是:把已知十六进制的字节写入文件key.txt,再进行深入明文攻击即可。跑了接近二十分钟后,出了zip的三段内部密码(上图中最后一行),直接进行解密即可:

image-20230909112437253

得到图片:

flag1

十六进制打开末尾即得flag:

image-20230909112540496

flag:

SICTF{3a4998b8-345e-4943-a689-d01e8b08defb}



一起上号不

题目描述:

1
2
你为什么还不上号啊?宝!
Hint:你知道CobaltStrike吗?

题目给了一个流量包,导出http流对象,可以发现一个key.zip:

image-20230909142543063

导出该压缩包并解压,得到一个key文件,那现在要做的就是提取出key中的信息,去解密流量中的数据。但是怎么找都没找到这种key文件怎么使用,思路也就暂时停滞了。

直到hint出现,那就直接搜索CobaltStrike,发现一道类似流量分析题,照着一步步做就有了(其中CS_Decrypt中有一个脚本用到M2Crypto库,但是pip不下来,搜索资料发现这个库停止更新很久了,可能python版本对不上,平替为pycryptodome即可):

2021年“绿城杯”网络安全大赛-Misc-流量分析_夜白君的博客-CSDN博客

得到flag:

image-20230909142844158

flag:

SICTF{88a39373-e204-43b6-b321-33ac8972fde9}



QR_QR_QR

题目描述:

1
我就扫码而已啦!为什么要用pwntools?

题目给了一个端口,先用xshell手动交互一下:

image-20230910150031807

可以依稀看出是二维码的定位符,那么思路就是把这些0、1转化为二维码并扫码得到数据,但是粘出来数据想写脚本的时候发现:

image-20230910150225007

笑死,vscode右侧的预览直接显示出了二维码的效果,那直接扫码得到数据:

image-20230910150358330

但是上传这串数据的时候发现:

image-20230910150429700

超时了,彳亍,那确实得写脚本自动交互,交互一次后发现靶机端还会发送二维码数据,那应该是要循环一定次数后才会给flag了。

之后就是枯燥的debug时间。

exp.py:

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
from Crypto.Util.number import *
from pwn import *
import cv2
from PIL import Image
from pyzbar.pyzbar import decode

r=remote("210.44.151.51",10468)
count = 0
while(1):
count += 1
print(count)
data = list(r.recvuntil(b"P")[:-1])

# 定义图像的宽度和高度(根据数据长度调整)
width = 116
height = 116

# 创建一个空白图像
image = Image.new("1", (width, height), color=1) # 1表示单色(黑白)

# 获取图像的像素访问对象
pixels = image.load()

# 将01数据填充到图像中
for y in range(height):
for x in range(width):
index = y * width + x
if index < len(data) and data[index] == 48:
pixels[x, y] = 0 # 将0写为黑色像素点
else:
pixels[x, y] = 1 # 将0写为黑色像素点

# 保存图像为文件
image.save("1.png")
decocdeQR = decode(Image.open("1.png"))[0].data
r.sendline(decocdeQR)
temp = r.recvline()
print(temp)
temp = r.recvline()
print(temp)

循环1000次后,靶机端发送flag:

SICTF{d7d23552-d917-4ad4-962c-e415dd5b5b6e}



fast_morse

题目描述:

1
你好快啊!(flag需要包含SICTF{})

题目给了一个音频,Audacity打开:

image-20230910150829891

经典的音频隐写摩斯电码,但是敲完摩斯密码,最后得到的uuid少了一位,私聊出题人拿flag即可



Easy_Shark

题目描述:

1
鲨鱼!嗷呜!

题目给了一个流量文件,追踪tcp流能发现一段php代码:

image-20230910151203093

可以看出,在openssl扩展有效时,这段代码对数据的解密方式为AES_128后base64,并且给了key的值(之后了解到这是很明显的冰蝎的特征)。那么就可以使用cyberchef,对之后的每个tcp流里的base64数据进行恢复:

image-20230910151658797

再把解密出来的密文内部的base64段提取出来,再进行解密,就可以在最底下发现:

image-20230910151851063

可以看出,实际上这段程序就是在执行最下方的cmd命令,然后对回复的数据也进行如上解密,就可以得到命令执行后的对应内容。如此一来,可以得到两个有用的信息:

GronKey.txt:

1
1,50,61,8,9,20,63,41

flag.txt:

1
TGLBOMSJNSRAJAZDEZXGHSJNZWHG

flag的内容直接提交上去是不对的,因此肯定还需要进行解密,而如何解密就需要用到GronKey.txt,并且按正常思路,GronKey这个名字肯定是个提示。最终搜索到了Gronsfeld密码,解密即可:

exp.py:

1
2
3
4
5
6
from  Crypto.Util.number import *
from pycipher import Gronsfeld

t = [1,50,61,8,9,20,63,41]
temp = "TGLBOMSJNSRAJAZDEZXGHSJNZWHG"
print (Gronsfeld(t).decipher(temp))

这里有个比较坑的点:因为我是知道Gronsfeld这个密码的,但是我记得他的密钥只能是0-9的数字,加密原理就是字母加上密钥对应数字(类似于维吉尼亚密码),所以开始就排除了这个加密方式。之后一直没有搜到其他的Gron开头的加密,卡了很久。后来我搜到了一个Gronsfeld在线加密:

Vigenere / Gronsfeld - 许愿星 (wishingstarmoye.com)

可以发现,他确实用了超过10的数字当作密钥,那这到底是怎么加密的呢?我思考了一下,发现他的加密方式应该是:加密时,每个字母右移密钥列表中对应数字的位数;而解密时,每个字母左移密钥列表中对应数字的位数。

举个例子,T左移1位得到S,这很好理解;而G左移50位,其实就是右移2位(因为模26的缘故),因此得到I。

这样就可以顺利解密了。

flag:

SICTF{SHUMUISAGOODBOYYYYYYYYY}



还不上号

题目描述:

1
2
3
一起上号不?来!我教你怎么写payload!
Hint1:四位爆破,多注意一下细节,除了CS还有一部分
Hint2:压缩包密码为we1l

其实这道题就是Easy_shark和一起上号不的结合,这两个都做出来的话,这题其实难度不大了。

题目给了两个流量包,由名字可以知道一个包对应一半flag。其中,包1形式对应Ez_shark,包2形式对应一起上号不。

从包1入手,可以发现对比起Ez_shark,唯一的区别就是他没有给出AES的key值,因此必须要想办法找出key。而包2正好有个key.zip,进行导出:

image-20230910153507463

得到的key.zip不能直接解压,并且是真加密,同时也没法进行明文攻击,那么就ziprello爆破吧,最后得到密码是we1l(并且后来Hint给了)。

打开key文件:

image-20230910153756977

显然有零宽字符,利用在线网站Unicode Steganography with Zero-Width Characters (330k.github.io)进行零宽字符解密:

image-20230910154112768

这里要注意在网页下方勾选该文本中所有存在的零宽字符,不然解密会失败:

image-20230910154140388

因此就得到了AES的key,可以按照Ez_Shark的方式对包1的流量依次进行解密,能得到两个有用信息:

flag.txt:

1
SICTF{79e1755e-08a8-4d

key:

image-20230910154525684

如果做出来一起上号不那道题,那么对这串数据应该很熟悉,这就是.cobaltstrike.beacon_keys形式的密钥文件,将这段内容保存成文件key1.txt,后续的步骤就和前面那道题就一模一样了。

下面详细记录一下步骤(怕我自己忘):

1、解析key1.txt文件得到private_key

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
import base64

import javaobj.v2 as javaobj

with open("key1.txt", "rb") as fd:
pobj = javaobj.load(fd)
privateKey = pobj.array.value.privateKey.encoded.data
publicKey = pobj.array.value.publicKey.encoded.data


privateKey = (
b"-----BEGIN PRIVATE KEY-----\n"
+ base64.encodebytes(bytes(map(lambda x: x & 0xFF, privateKey)))
+ b"-----END PRIVATE KEY-----"
)
publicKey = (
b"-----BEGIN PUBLIC KEY-----\n"
+ base64.encodebytes(bytes(map(lambda x: x & 0xFF, publicKey)))
+ b"-----END PUBLIC KEY-----"
)
print(privateKey.decode())
print(publicKey.decode())

# print(
# list(
# map(
# lambda x: list(map(lambda y: (y[0].name, y[1]), x.items())),
# a.field_data.values(),
# )
# )
# )

2、根据private_key以及流量包中cookie解析出AES key和HMAC key:(其他信息有需要,解除掉注释即可,这里只需要AES与HMAC的key)

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
import hashlib
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64
import hexdump

PRIVATE_KEY = """-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAL0M6FR0Cb9dW52Nd5NTA1JUNAs1
thS8iXx6QB+UkN/vRJdfsKS8dnOfNuPuPDCtx26B2j8I1FuTJ1VrrfDkzN585sskmXYronFM98Dx
50vHaadOcDcDdBBqi8gC5/D3iKflX6T9pSL/5PVLfN1EIaFsyAS9jpWX2wGNi3C/QPSrAgMBAAEC
gYAdNhXeGtH4wkWqOhY8aurL+VvTUZjRanJ6C+/FkXCzUWbRVwVV5xMMeZEDNigRw4BZ2HGvJL+f
aMT+o3VMkCYBhGbi2/3RPRgigMG7Aa3LWWtYWsdbw8Mw6aqqbTjDUHrQ1kulMf1JvXJL5LBd+pBA
Q8kHaYJRMcmnLsT4NeXOFQJBAMNa2r+phrThTlagMB6bj6vl0IVbDy+TJT2VybCSJ76rPgVUQwtP
yX3z7UAjt27mE8KK+k7Jidi0drCEPv5Wo60CQQD3vQbO64fko1dlatkNn095GO9KoCuanrsLs+vY
Ohc0ltk4EhHHmP5hEE6dSMZNASKaN0wSYJ14xjnA+dJWOES3AkEApzyYF4vhLefTUIVBrHIvxFCw
+fjCP1AQiXA5gVcdfzTJm3ZPDtf2/kRbzpTE68M7F0gykFAoGcQj92i/JKy24QJAdyVbA+M07Ro9
qxHzJ+EJmMUMOMjFj8xtStiSQeDWTj2KZLQUBvmmxcnQ9UYN0PUNzjtwA5qhwXccSZoctcjECwJA
Zc0TZgGq/OwgnIyj/1+Q9D0A2eg3aw1k+6Vzkf/DdkuF6+XTkYTlBGiETIK/vm1rCH4NcOCL7eK5
qpA1grg+gg==
-----END PRIVATE KEY-----"""

encode_data = "j+ojKDVPlCr7lT9yzNinkj1DgdkcRaLMT2kL4U+9TvdFBZqGKk7/4WF/W7JhEieC3DoRfngRppMAVHa3yfhp4HZm/ZeNY4bc8rlYL11Q0dXDzpR5JjhqN+hGe9RBqPznoukShgQLhxT/DO7djxE5ROzi6NC52yZAaGPCSeLDyjg="
base64_key = """"""

private_key = RSA.import_key(PRIVATE_KEY.format(base64_key).encode())
cipher = PKCS1_v1_5.new(private_key)
ciphertext = cipher.decrypt(base64.b64decode(encode_data), 0)

def isFlag(var, flag):
return (var & flag) == flag


def toIP(var):
var2 = (var & -16777216) >> 24
var4 = (var & 16711680) >> 16
var6 = (var & 65280) >> 8
var8 = var & 255
return str(var2) + "." + str(var4) + "." + str(var6) + "." + str(var8)


def getName(var0):
if var0 == 37:
return "IBM037"
elif var0 == 437:
return "IBM437"
elif var0 == 500:
return "IBM500"
elif var0 == 708:
return "ISO-8859-6"
elif var0 == 709:
return ""
elif var0 == 710:
return ""
elif var0 == 720:
return "IBM437"
elif var0 == 737:
return "x-IBM737"
elif var0 == 775:
return "IBM775"
elif var0 == 850:
return "IBM850"
elif var0 == 852:
return "IBM852"
elif var0 == 855:
return "IBM855"
elif var0 == 857:
return "IBM857"
elif var0 == 858:
return "IBM00858"
elif var0 == 860:
return "IBM860"
elif var0 == 861:
return "IBM861"
elif var0 == 862:
return "IBM862"
elif var0 == 863:
return "IBM863"
elif var0 == 864:
return "IBM864"
elif var0 == 865:
return "IBM865"
elif var0 == 866:
return "IBM866"
elif var0 == 869:
return "IBM869"
elif var0 == 870:
return "IBM870"
elif var0 == 874:
return "x-windows-874"
elif var0 == 875:
return "IBM875"
elif var0 == 932:
return "Shift_JIS"
elif var0 == 936:
return "x-mswin-936"
elif var0 == 949:
return "x-windows-949"
elif var0 == 950:
return "Big5"
elif var0 == 1026:
return "IBM1026"
elif var0 == 1047:
return "IBM1047"
elif var0 == 1140:
return "IBM01140"
elif var0 == 1141:
return "IBM01141"
elif var0 == 1142:
return "IBM01142"
elif var0 == 1143:
return "IBM01143"
elif var0 == 1144:
return "IBM01144"
elif var0 == 1145:
return "IBM01145"
elif var0 == 1146:
return "IBM01146"
elif var0 == 1147:
return "IBM01147"
elif var0 == 1148:
return "IBM01148"
elif var0 == 1149:
return "IBM01149"
elif var0 == 1200:
return "UTF-16LE"
elif var0 == 1201:
return "UTF-16BE"
elif var0 == 1250:
return "windows-1250"
elif var0 == 1251:
return "windows-1251"
elif var0 == 1252:
return "windows-1252"
elif var0 == 1253:
return "windows-1253"
elif var0 == 1254:
return "windows-1254"
elif var0 == 1255:
return "windows-1255"
elif var0 == 1256:
return "windows-1256"
elif var0 == 1257:
return "windows-1257"
elif var0 == 1258:
return "windows-1258"
elif var0 == 1361:
return "x-Johab"
elif var0 == 10000:
return "x-MacRoman"
elif var0 == 10001:
return ""
elif var0 == 10002:
return ""
elif var0 == 10003:
return ""
elif var0 == 10004:
return "x-MacArabic"
elif var0 == 10005:
return "x-MacHebrew"
elif var0 == 10006:
return "x-MacGreek"
elif var0 == 10007:
return "x-MacCyrillic"
elif var0 == 10008:
return ""
elif var0 == 10010:
return "x-MacRomania"
elif var0 == 10017:
return "x-MacUkraine"
elif var0 == 10021:
return "x-MacThai"
elif var0 == 10029:
return "x-MacCentralEurope"
elif var0 == 10079:
return "x-MacIceland"
elif var0 == 10081:
return "x-MacTurkish"
elif var0 == 10082:
return "x-MacCroatian"
elif var0 == 12000:
return "UTF-32LE"
elif var0 == 12001:
return "UTF-32BE"
elif var0 == 20000:
return "x-ISO-2022-CN-CNS"
elif var0 == 20001:
return ""
elif var0 == 20002:
return ""
elif var0 == 20003:
return ""
elif var0 == 20004:
return ""
elif var0 == 20005:
return ""
elif var0 == 20105:
return ""
elif var0 == 20106:
return ""
elif var0 == 20107:
return ""
elif var0 == 20108:
return ""
elif var0 == 20127:
return "US-ASCII"
elif var0 == 20261:
return ""
elif var0 == 20269:
return ""
elif var0 == 20273:
return "IBM273"
elif var0 == 20277:
return "IBM277"
elif var0 == 20278:
return "IBM278"
elif var0 == 20280:
return "IBM280"
elif var0 == 20284:
return "IBM284"
elif var0 == 20285:
return "IBM285"
elif var0 == 20290:
return "IBM290"
elif var0 == 20297:
return "IBM297"
elif var0 == 20420:
return "IBM420"
elif var0 == 20423:
return ""
elif var0 == 20424:
return "IBM424"
elif var0 == 20833:
return ""
elif var0 == 20838:
return "IBM-Thai"
elif var0 == 20866:
return "KOI8-R"
elif var0 == 20871:
return "IBM871"
elif var0 == 20880:
return ""
elif var0 == 20905:
return ""
elif var0 == 20924:
return ""
elif var0 == 20932:
return "EUC-JP"
elif var0 == 20936:
return "GB2312"
elif var0 == 20949:
return ""
elif var0 == 21025:
return "x-IBM1025"
elif var0 == 21027:
return ""
elif var0 == 21866:
return "KOI8-U"
elif var0 == 28591:
return "ISO-8859-1"
elif var0 == 28592:
return "ISO-8859-2"
elif var0 == 28593:
return "ISO-8859-3"
elif var0 == 28594:
return "ISO-8859-4"
elif var0 == 28595:
return "ISO-8859-5"
elif var0 == 28596:
return "ISO-8859-6"
elif var0 == 28597:
return "ISO-8859-7"
elif var0 == 28598:
return "ISO-8859-8"
elif var0 == 28599:
return "ISO-8859-9"
elif var0 == 28603:
return "ISO-8859-13"
elif var0 == 28605:
return "ISO-8859-15"
elif var0 == 29001:
return ""
elif var0 == 38598:
return "ISO-8859-8"
elif var0 == 50220:
return "ISO-2022-JP"
elif var0 == 50221:
return "ISO-2022-JP-2"
elif var0 == 50222:
return "ISO-2022-JP"
elif var0 == 50225:
return "ISO-2022-KR"
elif var0 == 50227:
return "ISO-2022-CN"
elif var0 == 50229:
return "ISO-2022-CN"
elif var0 == 50930:
return "x-IBM930"
elif var0 == 50931:
return ""
elif var0 == 50933:
return "x-IBM933"
elif var0 == 50935:
return "x-IBM935"
elif var0 == 50936:
return ""
elif var0 == 50937:
return "x-IBM937"
elif var0 == 50939:
return "x-IBM939"
elif var0 == 51932:
return "EUC-JP"
elif var0 == 51936:
return "GB2312"
elif var0 == 51949:
return "EUC-KR"
elif var0 == 51950:
return ""
elif var0 == 52936:
return "GB2312"
elif var0 == 54936:
return "GB18030"
elif var0 == 57002:
return "x-ISCII91"
elif var0 == 57003:
return "x-ISCII91"
elif var0 == 57004:
return "x-ISCII91"
elif var0 == 57005:
return "x-ISCII91"
elif var0 == 57006:
return "x-ISCII91"
elif var0 == 57007:
return "x-ISCII91"
elif var0 == 57008:
return "x-ISCII91"
elif var0 == 57009:
return "x-ISCII91"
elif var0 == 57010:
return "x-ISCII91"
elif var0 == 57011:
return "x-ISCII91"
elif var0 == 65000:
return ""
elif var0 == 65001:
return "UTF-8"


if ciphertext[0:4] == b'\x00\x00\xBE\xEF':

# 16
raw_aes_keys = ciphertext[8:24]

# 2
var9 = ciphertext[24:26]
var9 = int.from_bytes(var9, byteorder='little', signed=False)
var9 = getName(var9)
# 2
var10 = ciphertext[26:28]
var10 = int.from_bytes(var10, byteorder='little', signed=False)
var10 = getName(var10)

# 4
id = ciphertext[28:32]
id = int.from_bytes(id, byteorder='big', signed=False)
#print("Beacon id:{}".format(id))

# 4
pid = ciphertext[32:36]
pid = int.from_bytes(pid, byteorder='big', signed=False)
#print("pid:{}".format(pid))

# 2
port = ciphertext[36:38]
port = int.from_bytes(port, byteorder='big', signed=False)
#print("port:{}".format(port))

# 1
flag = ciphertext[38:39]
flag = int.from_bytes(flag, byteorder='big', signed=False)
# print(flag)

if isFlag(flag, 1):
barch = ""
pid = ""
is64 = ""
elif isFlag(flag, 2):
barch = "x64"
else:
barch = "x86"

if isFlag(flag, 4):
is64 = "1"
else:
is64 = "0"

if isFlag(flag, 8):
bypassuac = "True"
else:
bypassuac = "False"

#print("barch:" + barch)
#print("is64:" + is64)
#print("bypass:" + bypassuac)

# 2
var_1 = ciphertext[39:40]
var_2 = ciphertext[40:41]
var_1 = int.from_bytes(var_1, byteorder='big', signed=False)
var_2 = int.from_bytes(var_2, byteorder='big', signed=False)
windows_var = str(var_1) + "." + str(var_2)
#print("windows var:" + windows_var)

# 2
windows_build = ciphertext[41:43]
windows_build = int.from_bytes(windows_build, byteorder='big', signed=False)
#print("windows build:{}".format(windows_build))

# 4
x64_P = ciphertext[43:47]

# 4
ptr_gmh = ciphertext[47:51]
# 4
ptr_gpa = ciphertext[51:55]

# if ("x64".equals(this.barch)) {
# this.ptr_gmh = CommonUtils.join(var10, this.ptr_gmh)
# this.ptr_gpa = CommonUtils.join(var10, this.ptr_gpa)
# }
#
# this.ptr_gmh = CommonUtils.bswap(this.ptr_gmh)
# this.ptr_gpa = CommonUtils.bswap(this.ptr_gpa)

# 4
intz = ciphertext[55:59]
intz = int.from_bytes(intz, byteorder='little', signed=False)
intz = toIP(intz)

if intz == "0.0.0.0":
intz = "unknown"
#print("host:" + intz)

if var9 == None:
ddata = ciphertext[59:len(ciphertext)].decode("ISO8859-1")
else:
# ??x-mswin-936
# ddata = ciphertext[59:len(ciphertext)].decode(var9)
ddata = ciphertext[59:len(ciphertext)].decode("ISO8859-1")

ddata = ddata.split("\t")
if len(ddata) > 0:
computer = ddata[0]
if len(ddata) > 1:
username = ddata[1]
if len(ddata) > 2:
process = ddata[2]

#print("PC name:" + computer)
#print("username:" + username)
#print("process name:" + process)

raw_aes_hash256 = hashlib.sha256(raw_aes_keys)
digest = raw_aes_hash256.digest()
aes_key = digest[0:16]
hmac_key = digest[16:]

print("AES key:{}".format(aes_key.hex()))
print("HMAC key:{}".format(hmac_key.hex()))



#print(hexdump.hexdump(ciphertext))

3、将流量包中数据写成base64形式:(数据指的是图中蓝色部分,每个tcp流中的流量均试一下即可)

image-20230910155301194

转换为原始数据:

image-20230910155542125

写成base64形式:

image-20230910155529969

4、最终解密:

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
68
69
70
71
'''
Beacon任务执行结果解密
'''
import hmac
import binascii
import base64
import struct
import hexdump
from Crypto.Cipher import AES

def compare_mac(mac, mac_verif):
if mac == mac_verif:
return True
if len(mac) != len(mac_verif):
print
"invalid MAC size"
return False

result = 0

for x, y in zip(mac, mac_verif):
result |= x ^ y

return result == 0

def decrypt(encrypted_data, iv_bytes, signature, shared_key, hmac_key):
if not compare_mac(hmac.new(hmac_key, encrypted_data, digestmod="sha256").digest()[0:16], signature):
print("message authentication failed")
return

cypher = AES.new(shared_key, AES.MODE_CBC, iv_bytes)
data = cypher.decrypt(encrypted_data)
return data

#key源自Beacon_metadata_RSA_Decrypt.py
SHARED_KEY = binascii.unhexlify("2f793b0251bb6c09bda982cb159cd611")
HMAC_KEY = binascii.unhexlify("e5695e8bf533009cd4a3c950d447b032")

encrypt_data="AAAAwNR1s4ymDHA08b2cCeYKryK3UKJK0G2nKl/svxd3sD2WvktAWL1hS0gvdfXP7XmLpCd3CgYHRMvh9bWGrKW/2ANbWBQEYp1Lv+iIsuBpLdxanTNqAEOnre/71JK8hUKuJ32lY88IsDwgFFjvH0l3lwDOwgtXtOe6mhxvhuxUK8ourv/sii2KGiMOacqaRI2bOtOBcEal00/bBj85FcE+W6PmmGbF0Q9BvUvQmDT9C+J2H12SZqwwAbFGVJwntkDq7Q=="

encrypt_data=base64.b64decode(encrypt_data)

encrypt_data_length=encrypt_data[0:4]

encrypt_data_length=int.from_bytes(encrypt_data_length, byteorder='big', signed=False)

encrypt_data_l = encrypt_data[4:len(encrypt_data)]

data1=encrypt_data_l[0:encrypt_data_length-16]
signature=encrypt_data_l[encrypt_data_length-16:encrypt_data_length]
iv_bytes = bytes("abcdefghijklmnop",'utf-8')

dec=decrypt(data1,iv_bytes,signature,SHARED_KEY,HMAC_KEY)


counter = dec[0:4]
counter=int.from_bytes(counter, byteorder='big', signed=False)
print("counter:{}".format(counter))

dec_length = dec[4:8]
dec_length=int.from_bytes(dec_length, byteorder='big', signed=False)
print("任务返回长度:{}".format(dec_length))

de_data= dec[8:len(dec)]
Task_type=de_data[0:4]
Task_type=int.from_bytes(Task_type, byteorder='big', signed=False)
print("任务输出类型:{}".format(Task_type))

print(de_data)

#print(hexdump.hexdump(dec))

可以看到一串base32数据:

image-20230910155718568

解密即得flag后半段:

image-20230910155756436

flag:

SICTF{79e1755e-08a8-4d3d-9385-4c0541549995}



总结

有些题的具体原理我确实也懂的不是很透彻,欢迎一起交流讨论!