Junior.Crypt.2024 CTF Writeup | CTF-SPCS

Junior.Crypt.2024 CTF

题目附件链接https://pan.baidu.com/s/1LsAMYtO0uHb27UoYFMkQow?pwd=ouo3

Beginner

Deep stego in the office

题目:

We hide the flag in the standard way. Almost the same as in any type of file

解题:

解压 Borges-04.docx 在xml 中找 flag

grodno{The_kingdom_0f_heaven_is_taken_by_f0rce}

Virus

题目:

A very aggressive virus was discovered in the 101st package of European Union (EU) sanctions.

Hacker Anykey immediately managed to block access to it for everyone. Perhaps not for super cyber specialists…

Link to virus resource: in file

1
https://docs.google.com/document/d/9h0"q:fD!c9PHpU;cHL\<,,8\9JA:X<GkBQ9g`)P:hiI;@kq5+;,g^o=>;Wh<Gce2<bl2]9LCLO;H%[L>"!-b95QA#<HgSh

解题:

CyberChef 自动出解

grodno{2092d0_Zitie_mae_..._11397c}

Two points again

题目:

I received a file with huge numbers. Explicitly RSA

1
2
3
N = 894011376132861406416081994144221048298348543110763436400156707035479762291337096368301340210777912166253392435275663746074998964323198306974285233167719096055553347615918699581765041856450618725024365550285245909593290693757548300976025136185960841538482656726074757217987326418213368306947431668797511869941369363510575799319146232381645606378509284692783439527001482275434870365007864755014763434476875230779298152747668036103797086099448952638933614839186234115539057353208089196503236476069765055958643599622359809306429773621018079928117609961649006558217734057147235098517323614637509521563090769478823258676357262436290835475545437211168106617010859479612214627871047960151415095910992231687737019157788664429412462674876326653667300420128914036327499885103193423178025962079282185227746880809451234195481664650147610375976243181422075319601793906090392759832052648670731266344219250793991957964535801285606036631861341696305110038590888086491568683507575846576623827059055577036404611548224528600604898405714747157240730264673180051312634408192644777331633111950232485559076080686217541095754245034143596485147084607615402187454830802772582891800608645679493263524678084504132604846410243911260803002065871918398725293311473
e = 49999
c = 127990258916322713210704002931365496210647826869578493680557063836772515914303363145985391647430839311330158084206710072455465957218072448099969815961814463831667357474852426061475210363277306704257877402661232669936031043625938011115290529377505573367883714424182150449678726041360949463375982144652910707759221795772350872426009873120527309342093683340576731241704191541296890578962805029558926492259701366885936092059693759354255247540815813052543086204934376066884066060405947003334121725632674642690548675916126384013014552545338699198239765357561083183401525044638243204528501965028598782513999767237563252331767079569128151380305983732341553403814650118788711703476805307790685184506737890913441497269132749881622937761764492015610811577966553776703680435092016590690563200951474073620866158140866931856293211794418637441400021472249887178225738960768608549559781531479910409684884180658879621882231073123533851227894797415625533435081416099549459198508358607887551022339960981663266529984544362524495679204397590064106335341279871204905873532415276380340515150499389237587052633736125460704219829657692767592459700685070039056607335118481257774532132073976558433243315868939654221066341581052013795470559435542389710686098062

解题:

1
2
3
4
5
6
7
8
9
10
N = ...
e = ...
c = ...

phi = (N - 1)
d = inverse(e, phi)
m = pow(c, d, N)
print(long_to_bytes(m).decode('utf-8'))

# By harnessing the grodno{m@thematical_pr0perties_0f_l@rge_prime_numb3rs}, RSA provides a robust and efficient method for encrypting and decrypting information.

grodno{m@thematical_pr0perties_0f_l@rge_prime_numb3rs}

Forensics

Admin rights

题目:

Help me understand which ACTIVE account has administrator rights Account of the form user_xxxx

Flag in the format grodno{user_xxxx}

解题:

使用 Windows Registry Recovery 打开SAM 文件进行分析 查看结构

对比 SAM\Domains\Account\Users 键下的 F 值 每一个子健对应一个用户 二进制数据记录这账户的状态 但是具体每一位的意思不知道

使用对比 Administrator (Администратор) 账户 寻找特征 特殊的用户

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
# pip install python-registry
from Registry import Registry

# 打开指定注册表文件
registry = Registry.Registry(r"D:\Users\jack\Downloads\SAM")

# 打开包含用户数据的键
users_key = registry.open("SAM\\Domains\\Account\\Users")
names_key = registry.open("SAM\\Domains\\Account\\Users\\Names")

# 遍历所有用户的键,排除 "Names" 键
for subkey in users_key.subkeys():
if subkey.name() != "Names":
user_name = subkey.name()
f_value = subkey.value("F").value().hex()
hex_list = [f_value[i:i + 2] for i in range(0, len(f_value), 2)]
# print(user_name, ' '.join(hex_list))
if hex_list[-12] != '00':
print(user_name, ' '.join(hex_list))

# 遍历 Names 键下的所有子键,查找指定 SID 的用户
for ns in names_key.subkeys():
user_name = ns.name()
SID = ns.value("(default)").value_type_str()[-5:]
if SID in ['0x1f4', '0x516']:
print(f"User: {user_name}, SID: {SID}")

# User: user_7565, SID: 0x516
# User: Администратор, SID: 0x1f4

grodno{user_7565}

RDP

题目:

The user from which country connected via RDP?

Log-file

Flag format: grodno{Country}

解题:

搜索 RDP 日志记录在那个文件夹

查看 日志

打开日志

查询ip 103.109.92.4

grodno{Bangladesh}

Series SAM

题目:

Your task is to extract the password of the Tilen2000 user.

Data file

Flag format: grodno{password_plain_text}
For example, grodno{password_12345}

解题:

使用kali impacket-secretsdump 提取hash 用户太多了 grep 下 Tilen2000

1
impacket-secretsdump -system SYSTEM -ntds ntds.dit LOCAL|grep Tilen2000

在线解密

grodno{Hello123}

Image

题目:

The key is hidden in Image. Explore Image to find the key. The search for the key must be carried out in Image

Data file

Flag in format grodno{name}

解题:

使用 diskgenius 打开 .img 文件

保存所有图片没有发现 flag 恢复文件也没发现flag

查看 desktop.ini

原本是有 -0.jpg 的 被删除了

查看 缩略图 使用 THUMBS VIEWER 查看 Thumbs.db

grodno{image_in_thumbnail}

FTP

Find your FTP password.

Link to file: https://disk.yandex.ru/d/-WgZgSBSqnmcIQ

Flag in format: grodno{password}

解题:

dnSyp 反编译 查看代码 发现password

grodno{12345_ftp_ctf}

SAMBO wrestler

题目:

From what ip was access to the network folder obtained?

File with data

Flag in the format grodno{xxx.xxx.xxx.xxx}

解题:

查看 Security.evtx

grodno{103.109.92.5}

Confusion

题目:

It was necessary to archive the document, and not vice versa

Flag in the format grodno{text}

解题:

解压 Doc1.docx 查看xml 文件 发现base64 编码的 rar

在线解码 导出文件

rar 要解压密码 先爆破

Advanced Archive Password Recovery 爆破密码

最终得到文本 ctf_zip_key

grodno{ctf_zip_key}

Misc

Found on my Windows

题目:

Found something on my Windows. Looks like hash.
Determine the hash type and get the original string - the password.

Hash: 35517451C7733D5B57F79E5FFF31DC63

Flag in the format grodno{password}

解题:

md5 在线解密

grodno{sakura}

Dogs running in a circle

题目:

Actually, I’m a fan of astronomy. But where would we be today without cybersecurity…
Determine the hash type and get the original string - the password.

Hash:

**7c7afb17ed0728e28f8835421cc66da5 **

**acf02cc7dbad40a2d61997bb0a3535e3 **

**a6484964aea8c7e02e0b5afe9c51b3f1 **

ec789a7de8e61033ba7e550b048c82b9

Flag in the format grodno{password}

解题:

md5 在线解密

grodno{trustno1}

Last hash

My latest find. I won’t look for hashes anymore.
Determine the hash type and get the original string - the password.

Hash:

**dc31d6b5e25f9fb3e75a40c26b88 **

9b4b9b76654c110dbda739a9e899

Flag in the format grodno{password}

grodno{lynlyn123}

Rivest, 1991

题目:

It seems that everything is clear…

解题:

随便拿几个 在线解密 发现都是 3个字符内的md5值 编写解密脚本

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 itertools
from hashlib import md5

# 从文件中读取所有行并存储到列表中
with open("Rivest_91.txt", "r") as f:
lines = f.read().splitlines()

# 使用字典来映射MD5值到原始字符串
md5_dict = {line: '' for line in lines}


def printable_char_combinations():
# 定义可打印字符范围,从ASCII的32(空格)到126(波浪号'~')
printable_chars = [chr(i) for i in range(32, 127)]

# 生成所有1到3位的字符组合
for r in range(1, 4): # r表示组合的长度
for combination in itertools.product(printable_chars, repeat=r):
yield ''.join(combination)


# 遍历所有可能的字符串组合
for combo in printable_char_combinations():
md5_hash = md5(combo.encode()).hexdigest() # 计算字符串的MD5值
if md5_hash in md5_dict:
md5_dict[md5_hash] = combo # 如果MD5值在字典中,更新字典以映射到原始字符串

# 输出所有找到的匹配字符串
print(''.join(md5_dict.values()))

# MD5 processes a variable-length message into afixed-lethoutput of 128 bits. grodno{no,_MD5_ws_n0t_invet3d_by_me,_its_invent_by_R1vesin_1991.} Theinput mesgs broken up io chunks of 512-bit blocks (siteen 32t wos);the agpadd so tha i lengt is diviible by 5. Thdding works flows:first, a sinle bit,, is appeed tohe end thsae. This followby as may zearequireo b lf tmee uto 64 fewerthamulof 512. Tremaints are flle u wi bs rpreh of orgial ge, mdul2**64.

grodno{no,_MD5_ws_n0t_invet3d_by_me,_its_invent_by_R1vesin_1991.}

Terms of Use

题目:

The rules of conduct when using Google services, as well as Google’s rights and responsibilities, are set forth in the “Terms of Use”. Violation of the Terms of Use of Google Services is a direct road to a ban on their use for you

Let’s look at this document

Archive password - infected

解题:

使用 infected 密码解压 使用 word 打开 Malware.docm

发现 一段base64 编码 解码出好多flag 迷惑行为

同时发现 宏报错

进行调试 发现代码底部的base64

解密得到flag

grodno{MS_0ffice_macros_are_a_source_of_malicious_code._B3_careful_with_the_functionality_in_active_MS_0ffice_documents}

PPC

l33t

Do you know what leetspeak is?

Same as eleet, l3375p34k, l337 or l33t

This is a style of using English that has spread on the Internet. The main differences are the replacement of Latin letters with similar numbers and symbols, imitation and parody of errors typical for fast typing, imitation of the jargon of hackers and gamers. More
details - see. Wikipedia or about converters with Leet

A “professional” Leet can use combinations of cryptological techniques that make what is written fundamentally incomprehensible to the uninitiated. Only a chosen one will be able to understand their letter.

Shall we play? Connect and show what you can do!

nc ctf.mf.grsu.by 9006

解题:

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 socket
import time

sock = socket.socket()
sock.connect(("ctf.mf.grsu.by", 9006))

for i in range(51):
time.sleep(1)
data = sock.recv(1024).decode('utf-8')
print(data)
x = data.split('\n')[-3]
y = (x.replace('4', 'a').
replace('@', 'a').
replace('3', 'e').
replace('0', 'o').
replace('1', 'l').
replace('5', 's').
replace('7', 't').
replace('9', 'g').
replace('8', 'b').
replace('6', 'b').
replace('2', 'z').
replace('!', 'i').
replace('+', 't')
)
print(y)
sock.send((str(y) + '\r\n').encode())

sock.close()

# grodno{54efd0leet_1s_a_system_0f_modified_spellings++6&0k!8f0ae2}

grodno{54efd0leet_1s_a_system_0f_modified_spellings++6&0k!8f0ae2}

Web

Buy a cat

题目:

解题:

随便买一个 发现请求了 如下url

1
https://ctf.mf.grsu.by/tasks/006a5dd1315a77da9f9f7f0ad78d7e29/?crypt_key1=d719b8adfc6e3841ffc856d52abc5fb9&chosen=Notebook&crypt_key2=d719b8adfc6e3841ffc856d52abc5fb9

将chosen=Notebook 改为 chosen=Cat 得到flag

1
https://ctf.mf.grsu.by/tasks/006a5dd1315a77da9f9f7f0ad78d7e29/?crypt_key1=d719b8adfc6e3841ffc856d52abc5fb9&chosen=Cat&crypt_key2=d719b8adfc6e3841ffc856d52abc5fb9

grodno{e4c370_1t_1s_v3ry_1mp0rt4nt_c4t_5f0ad0}

Very Secure App

题目:

All secrets become clear

http://109.107.157.141:8000/

解题:

随便输用户名和密码 登录

没有权限 无法得到flag

查看Cookie

是jwt 令牌 随便位置 admin 权限 发现有验证 需要找 secret_key

目录扫描发现 /robots.txt 打开空白 查看源代码 发现key

再次伪造 jwt

修改 Cookie 值 重新请求 /falg

grodno{r0b0ts_k3y_jwt}

Reverce

Random cipher

题目:

You have received an encryption procedure that uses random numbers and text encrypted with it.

Restore the original message and find the flag in it

code_terror.py

1
2
3
4
5
6
7
8
9
10
11
12
13
from random import randint


def encrypt(text):
key = randint(1, 2 * len(text))
print(ord(text[0]), key)
result = []

for c in text:
result.append(ord(c) + (ord(c) % key))
key = key + 1

return result

terror.txt

1
200 202 204 64 202 220 198 228 242 224 232 80 232 202 240 232 82 116 64 70 64 204 216 194 206 64 210 230 116 64 206 228 222 200 220 222 246 240 194 90 240 194 90 240 194 90 232 202 228 228 222 228 210 230 232 250 20 64 64 64 64 214 202 242 64 122 64 228 194 220 200 210 220 232 80 98 88 64 100 64 84 64 216 202 220 80 232 202 240 232 82 82 20 64 64 64 64 228 202 230 234 216 232 64 122 64 182 186 20 64 64 64 64 204 222 228 64 198 64 210 220 64 232 202 240 232 116 20 64 64 64 64 64 64 64 64 228 202 230 234 216 232 92 194 224 224 202 220 200 80 222 228 200 80 198 82 64 86 64 80 222 228 200 80 198 82 64 74 64 214 202 242 82 82 20 64 64 64 64 64 64 64 64 214 202 242 64 122 64 214 202 242 64 86 64 98 20 64 64 64 64 228 202 232 234 228 220 64 228 202 230 234 216 232

解题:

爆破求解 主要解密为 m = ord(c) + (ord(c) % key) 求m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# chatGPT:
def reverse_engineer(m, key):
for r in range(key):
if (m - r) % (1 + r // key) == 0:
n = (m - r) // (1 + r // key)
if n % key == r:
return chr(n)
return None # 如果没有找到有效的字符


# 使用示例
m = ord('A') + (ord('A') % 3) # 假设 key 是 3
key = 3
original_char = reverse_engineer(m, key)
print("Original character:", original_char)
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
def decrypt(encrypted, initial_key):
result = []
key = initial_key

for value in encrypted:
m = int(value)
for r in range(key):
if (m - r) % (1 + r // key) == 0:
n = (m - r) // (1 + r // key)
if n % key == r:
result.append(chr(n))
break
key += 1

return ''.join(result)


with open("terror.txt", "r") as f:
c = f.read().split(" ")

m = decrypt(c, 2 * len(c))
print(m)

'''
def encrypt(text): # flag is: grodno{xa-xa-xa-terrorist}
key = randint(1, 2 * len(text))
result = []
for c in text:
result.append(ord(c) + (ord(c) % key))
key = key + 1
return result
'''

grodno{xa-xa-xa-terrorist}

Mutated Caesar

题目:

The Caesar Cipher has mutated. Now it works not only with English alphabet characters, but also with some subset of ASCII characters

Caesare.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from hashlib import md5
from random import randint
from secret import flag

hash = md5(flag.encode()).hexdigest()

n1, n2 = randint(0x20, 0x41), randint(0x7d, 0x7e)
CN = {chr(i + n1): i for i in range(0, n2 - n1 + 1)}
NC = {i: chr(i + n1) for i in range(0, n2 - n1 + 1)}

N = len(CN.keys())
key = randint(0, N)
cipher = "".join([NC[(CN[c] + key) % N] for c in flag])

print(f"cipher = {cipher}")
print(f"md5 = {hash}")

# cipher = /:7,67Ct01;'1;'8:7*)*4A'.->-:'.:75'<0-'=88-:'n14-E
# md5 = 14927c0edb1bfaf21c81d6b88ca9472a

解题:

爆破求解 爆破所有 n1 ,n2 ,key 验证md5

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
from hashlib import md5

cipher = '''/:7,67Ct01;'1;'8:7*)*4A'.->-:'.:75'<0-'=88-:'n14-E'''
md5str = '14927c0edb1bfaf21c81d6b88ca9472a'

# 尝试所有可能的 n1 和 n2 范围内的值
for n1 in range(0x20, 0x42): # 包括0x41
for n2 in range(0x7d, 0x7f): # 包括0x7e
if n1 >= n2:
continue

# 生成映射字典
CN = {chr(i + n1): i for i in range(0, n2 - n1 + 1)}
NC = {i: chr(i + n1) for i in range(0, n2 - n1 + 1)}

N = len(CN.keys())

# 尝试所有可能的 key
for key in range(N):
try:
# 尝试解密
decrypted = "".join([NC[(CN[c] - key) % N] for c in cipher])
# 检查解密后的字符串是否符合 flag 格式
if decrypted.startswith('grodno{') and decrypted.endswith('}'):
if md5(decrypted.encode()).hexdigest() == md5str:
print(f"Found flag: {decrypted} with n1={n1}, n2={n2}, key={key}")
except KeyError:
# 如果 cipher 中有字符不在 CN 中,会抛出 KeyError
continue

# Found flag: grodno{This_is_probably_fever_from_the_upper_Nile} with n1=38, n2=125, key=32
# Found flag: grodno{This_is_probably_fever_from_the_upper_Nile} with n1=39, n2=126, key=32

grodno{This_is_probably_fever_from_the_upper_Nile}

Pizza

题目:

I was cutting pizza and accidentally cut the flag too. Help restore the flag (the pizza was delicious).

解题:

exeinfope打开exe查看信息

发现是.net Console 程序 使用 dnSpy 反编译

分析关键函数, 是对字符串逐字进行 整除2 和 判断取模否等于 0 并生成对应2个字符的结果

按照规则逐字爆破

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


def Transform(text): # 关键编码函数
text2 = ""
for c in text:
text2 += chr(ord(c) // 2)
text2 += "." if ord(c) % 2 == 0 else ","
return text2


s = "9,4,6,8.6.2,9.2,;.2,9.9,2,2,7.3,4,7.2,2,9.4,7.3,3.7,9.1,9,4.0,9.8."
l = [s[i:i + 2] for i in range(0, len(s), 2)] # 生成lsit 每个元素2字符

for i in l:
for j in string.printable: # 爆破所有可打印字符
if Transform(j) == i:
print(j, end="")
break
# simplereverseengineeringforcsharp

验证结果

grodno{simplereverseengineeringforcsharp}