Misc p11n-trophy(签到题): 题目描述:
我们首先会得到这样一份证书:
第一题签到题的答案就是证书下面正中间的“This certificate does not grant the rank of Master”。
trophy-plus + trophy-plus64: 这两道目描述一模一样
其中一个flag是藏在certificate周围一圈的位置:
人工将这些内容识别,再翻译成二进制然后解码就会得到flag
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 decode_binary (content, mapping ): binary_str = '' .join(mapping[char] for char in content if char in mapping) bytes_list = [binary_str[i:i+8 ] for i in range (0 , len (binary_str), 8 )] decoded_text = '' .join(chr (int (byte, 2 )) for byte in bytes_list if len (byte) == 8 ) return decoded_text c_1 = "MVVVVMMMMMVVMMVVMVVMMMVVMVVVVMVVMVVM VMMV MV MVVVVVMVVMM VMM MMVVMMMV" c_2 = "MVVMM VMMMVVMVVVMMM VMMVVVMVVVMV MMM VMVVVVVMVVM VMVVMVVMVVVMMMVVMMMMMVVVMVVVM VMVVVVV" c_3 = "VMMMVVMMM VMMMVVMVVVVVM VMMV MMVVVMMMMMVVMMMVVMMVVMVVVVVM VMMM VMMVVMVVMMVVMMVVMMVVVM VMV MVVVMVVVVVM VM VM VMMVVMMV MMMVVMVVVVVMV MMMV MMVVMMMVVMVVM VMV MVVVMMMMMVVMMVVMMMVVMVVVVVM VMV MVVMVVMMVVMVVVM VMVVMVVM" reversed_c_3 = c_3[::-1 ] c_4 = "MMV MMVVMMMMMVVMMVVMMMVVMMVVVMVVMVVMMVVMMVVVVVM VMV MMVVVVMMV MMVVVMMM VMVVMMMVVVMVVM" reversed_c_4 = c_4[::-1 ] c_5 = "MMVVMMM VMVVMVVVMMVVMMVVVM VMVVVVVMVVMVVMMMMVVMMMMMVVMVVMMMVVVVVMV" mapping1 = {'M' : '1' , 'V' : '0' } mapping2 = {'M' : '0' , 'V' : '1' } print (decode_binary(c_1, mapping2)+decode_binary(c_2, mapping2) + decode_binary(reversed_c_3, mapping2) + decode_binary(reversed_c_4, mapping2) + decode_binary(c_5, mapping2) )
另外一个flag则是藏在右下角的勋章里:
人工将这些内容识别出来然后用base64进行解码即可。
内容大概为:
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 -----BEGIN CERTIFICATE----- MIIDyjCCAlCgAwIBAgISBKmF/S4TYSXpTzcor9eZJ/GrMAoGCC qGSM49BAMDMDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEwlMZXQn cyBFbmNyeXB0MQswOQYDVQQDEwJFNjAeFw0yNTAxMDYyMDM2MD FaFw0yNTA0MDYyMDM2MDBaMEAxPjA8BgNVBAMMNXgzY3ttdTV0 X2IzX2Zlbl90eXAxbmdfdGgxcl9ieV9oNG5kXzEzNzUxMDUzMD QyNDgzNjF9MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcYu3 flnEI2dttI5lQQmzRld72SDdBqCDtfto9pg5t/NFFIolkY8W8C ryM9XlJEx3NAOGTgBoeUNTuWgiCseQeaOCAjYwggIyMA4GA1Ud DwEB/wQEAwIHgDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQ UHAwIwDAYDVR0TAQH/BAIwADAdBgNVRQ4EFgQUrbtyF28hjw8o IqwXpakw8t7J9jQwHwYDVR0jBBgwFoAUkydGmAOpUWiOmNbEQk jbI79YlNIwVQYIKwYBBQUHAQEESTBHMCEGCCsGAQUFBzABhhVo dHRwOi8vZTYuby5sZW5jci5vcmcwIgYIKwYBBQUHMAKGFmh0dH A6Ly91Ni5pLmxlbmNyLm9yZy8wQAYDVR0RBDkwN4IleDNje2ll NXRfYjNfZnVuX3R5cDFuZl90aDFzX2J5X2g0bmRfMTM3NTEwNT MwNDI0ODM2MX0wEwYDVR0gBAwwCjAIBgZngQwBAgEwggEDBgor BgEEAdZ5AgQCBIH0BIHxAO8AdQB9WR4S4XggexxhZ3xe/fjQhl w0oE6VnrkDL9kOjC55uAAAAZQ9inTEAAAEAwBGMEQCIENpWRg9 8SQo5JdzyjgnyFeUY0WnNVzn5NkdDA3bzeKbAiBsAkk3fe5esm 7A0efsLN/EyFjEK/NBGqYxgOucgZheQwB2ABNK3xglmEIjeAxv 70x6kaQWtyNJzlhXat+u2qfCq+AiAAAB1D2KdXoAAAQDAEcwRQ IgBfU4pkiNyNsl+I6skjXz6qqu+mNoI4JvtDsoYxoI+ZoCIQCR iMQSCEwahN0ImXu3cwDeyM+AbNeve0VgSLMSUBdxvTAKBggghk jOPQQDAwNoADBlAjEAvxa6nSpUMl7NuDB/+LJfzTskR498vLoe tnZuHo14J6d9zuFRGQ8Dk4w2aQNsbuVsAjB9fE6GJYBiebb4aH u/J2amych3KP//D951/CdmiV5PKZqXWWdpaQZL+pbmsXRa8rM= -----END CERTIFICATE-----
会有一些误差,所以最后提交flag时需要多试几次。
foundations (Osint): 题目描述:
使用https://archive.org/来搜索这个比赛网站的历史纪录内容
可以在这里发现最早的纪录是在2024年7月14日:
点进去会发现:
x3CTF{m4yb3_w3ll_m4ke_4_ch4ll3nge_0u7_0f_7h1s}
mvm:
打开下载文件会得到
1 2 MMVMVMVVMMVMVMVVMVMVVMVVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVVVVVMMMVMVMVVMMVVVVMMMVMVVVMVMMVVVVVMMMVMVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVVVMMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVVMMMVMVVMVMVMVVMVVMMVMVVMVMMVVVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVVVVMMMVMVVVMVMMVVVVVMMMVMVVMVMMVMVVVMMMVMVMVVMVMVVMVVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVVVVVMMMVMVMVVMMVVVVMMMVMVVVMVMMVVVVVMMMVMVMVVMMVMVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVVVMMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVVMMMVMVVMVMVMVVMVVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVVVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVVVVMMMVMVVVMVMMVVVVVMMMVMVVVMMMVMVMVVMVMVVMVVMMVMVVMVMMVMVVMVMMVMVVMVMMVVVVVMMMVMVMVVMMVMVMVVMMVVVVMMMVMVVVMVMMVVVVVMMMVMVMVVMMVMVMVVMMVMVVVMMMVVVVVMMMVMVVMVMVMVVMVVMMVMVVMVMMVMVVMVMMVMVVMVMMVVVVVMMMVMVMVVMMVVVVMMMVMVVVMVMMVVVVVMMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVVMMMVMVVMVMMVMVVMVMVMVVMVVMMVMVVMVMMVVVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVVVVMMMVMVVVMVMMVVVVVMMMVMVMVVMMVMVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVVVMMVMVVMVVMMVMVVMVMMVMVVMVMMVVVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVVVVMMMVMVVVMVMMVVVVVMMMVMVVVMMVMVVMVVMMVMVVMVMMVMVVMVMMVMVVMVMMVVVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVVVVMMMVMVVVMVMMVVVVVMMMVMVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVVVMMMVMVVMVMVMVVMVVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVVVVVMMMVMVMVVMMVVVVMMMVMVVVMVMMVVVVVMMMVMVVVMMMVVVVVMMMVMVVMVMVMVVMVVMMVMVVMVMMVMVVMVMMVMVVMVMMVVVVVMMMVMVMVVMMVVVVMMMVMVVVMVMMVVVVVMMMVMVVVMMMVMVVMVMVMVVMVVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVVVVVMMMVMVMVVMMVVVVMMMVMVVVMVMMVVVVVMMMVMVVMVMMVMVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVVVMMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVVMMMVMVVMVMMVMVVVMMMVMVMVVMMVMVMVVMVMVVMVVMMVMVVMVMMVVVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVVVVMMMVMVVVMVMMVVVVVMMMVMVMVVMMVMVVVMMVMVVMVVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVVVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVVVVMMMVMVVVMVMMVVVVVMMMVMVMVVMMVMVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVMVVMMVMVVVMMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVMVMMVMVVVMMMVVVVVMMMVMVVMVMMVMVVMVMVMVVMVVMMVMVVMVMMVMVVMVMMVVVVVMMMVMVMVVMMVMVMVVMMVMVMVVMMVVVVMMMVMVVVMVMMVVVVVMMMVMVVVM
跟之前一样,将其转成二进制再解码会得到
1 ++[---------->+<]>.+++++++++.---------.-[->+++++<]>-.+[----->+<]>+.+++++++++.---------.-[---->+++++<]>.+[--->++<]>++.>-[--->+<]>---.--[->++++<]>+.++++++++.+++++.[-->+++++++++<]>.[--->+++++<]>.++++++++++.++++++++++++.-[----->+<]>.>-[--->+<]>.-[----->+<]>-.++++++++.------.-.++[->+++++<]>+.[----->++++<]>+.+++++++++.---------.>--[-->+++<]>.
很显然这是Brainfuck,所以找个在线的intepreter运行一下就可以得到flag:
MVM{MVM_BRAIN_IS_FUCKED_MVM}
count-the-mvms 主要是数背景的mvm个数,发现它们的像素点是一样的。所以写个图像匹配脚本即可.
首先要把pdf转换成 png,推荐 adobe acrobat
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 import cvlibim = cvlib.read_img("certificate_h4tum.png" ) sim = cvlib.subrectimg(im, 605 , 516 , 837 , 665 ) sim2 = cvlib.subrectimg(sim, 44 , 32 , 79 , 48 ) mvm = cvlib.subrectimg(sim2, 2 , 2 , 32 , 13 ) print ("read success" )def match (im, x,y ): if x+len (mvm) > len (im): return False if y+len (mvm[0 ]) > len (im[0 ]): return False for i in range (len (mvm)): for j in range (len (mvm[i])): [r,g,b] = mvm[i][j] [ri,gi,bi] = im[x+i][y+j] if r != ri or g != gi or b != bi: return False return True def count_matches (im ): cnt = 0 for i in range (len (im)): print (i) for j in range (len (im[i])): if match (im, i,j): cnt += 1 j += len (mvm[0 ]) - 1 return cnt print (count_matches(im))print ("finish" )
Crypto man-vs-matrix: 题目描述:
打开下载文件会看到:
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 sage.all import *from Crypto.Util.number import bytes_to_longclass RNG : def __init__ (self, seed ): self .p = next_prime(2 **24 ) self .F = GF(self .p) self .M = matrix(self .F, 3 ,3 , [bytes_to_long(seed[i:i+3 ]) for i in range (0 , len (seed), 3 )]) self .state = vector(self .F, map (ord , "Mvm" )) self .gen = self .F(2 ) def get_random_num (self ): out = self .M * self .state for i in range (len (self .state)): self .state[i] = self .gen**self .state[i] return out * self .state flag = b"MVM{???????????????????????????}" seed = flag[4 :-1 ] rng = RNG(seed) samples = [] for i in range (9 ): samples.append(rng.get_random_num()) print (f"{samples = } " )
是几个随机数的生成器(RNG),但生成逻辑非常简单。
每次会计算
(括号外的乘法是内积。在sage里,矩阵与矩阵/向量的乘法和向量与向量的内积都是用*)。并且有
这里的初始state是已知的,所以我们只需要建立一个9元1次线性方程组即可。
我们可以写一段sagemath的代码来通过解方程逆推出matrix以及flag内容:
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 p = 16777259 F = GF(p) samples = [6192533 , 82371 , 86024 , 4218430 , 12259879 , 16442850 , 6736271 , 7418630 , 15483781 ] S0 = vector(F, [77 , 118 , 109 ]) def next_state (st ): return vector(F, [F(2 )^int (x) for x in st]) S = [None ]*10 S[0 ] = S0 for i in range (1 , 10 ): S[i] = next_state(S[i-1 ]) X = matrix(F, 9 , 9 ) Y = vector(F, 9 ) for i in range (9 ): row_coeffs = [] for k in range (3 ): for j in range (3 ): row_coeffs.append(S[i][j] * S[i+1 ][k]) X[i] = row_coeffs Y[i] = samples[i] M_vec = X.solve_right(Y) M_mat = matrix(F, 3 , 3 , M_vec) print ("Recovered M =" )print (M_mat)m_ints = [] for i in range (3 ): for j in range (3 ): val = int (M_mat[i, j]) m_ints.append(val) seed_recovered = b"" .join(val.to_bytes(3 , "big" ) for val in m_ints) flag_recovered = b"MVM{" + seed_recovered + b"}" print ("Recovered seed =" , seed_recovered)print ("Recovered flag =" , flag_recovered)