## PAPAPA ![](https://hackmd.io/_uploads/rkTEcHdt3.png) [Attachment](https://storage.googleapis.com/gctf-2023-attachments-project/d2e5b38d584108c2b63150e7a073b8c104972ee59b83f5ee44d9ef6ae0118b4ad57e64cb328d7e8b839989ae741f793ded5fef7f51f7ecbbaaeaa716312f18c9.zip) Challenge này mình không có học được gì nhiều. Lần đầu khi mở hex của hình lên thì thấy rất nhiều byte 00, nên mình xoá thử vài byte xem có gì lạ xảy ra không thì thấy một chuỗi có vẻ là flag. ![](https://hackmd.io/_uploads/rkg6q6HuF3.png) ## Symmatrix ![](https://hackmd.io/_uploads/HkiFqS_Kh.png) [Attachment](https://storage.googleapis.com/gctf-2023-attachments-project/aba60aa2e9c806187f88279742c2ced243dd73b142c5c5bac1327956975e4d3add04afad77cfd823dd4f00847f6334b294ab058308639f8cb52897e8f1be769e.zip) Chall này ban đầu khi nhìn vào có vẻ như phải reverse các hàm trong C. Nhưng khi xem kỹ lại thì mình thấy được các comment liên quan đến dòng mà code python đó được chạy ![](https://hackmd.io/_uploads/Hyqzys5Fh.png) Script để recover python code: ```python= with open ('encoder.c','r') as f: d = f.readlines() x = "" lmao = {} for i in range(len(d)): if 'encoder.py\":' in d[i]: for line in d[i:i+5]: if "<<<<<" in line: lmao[int(d[i].split(":")[-1].strip("\n"))] = line[3:] x += "".join(d[i:i+5]) sorted_dict = dict(sorted(lmao.items())) print(sorted_dict) to_write = "" for k,v in sorted_dict.items(): to_write+=v.replace("\n * ","\n") with open('out.py','w') as wf: wf.write(to_write) ``` Recovered code: ```python= from PIL import Image from random import randint import binascii def hexstr_to_binstr(hexstr): n = int(hexstr, 16) bstr = '' while n > 0: bstr = str(n % 2) + bstr n = n >> 1 if len(bstr) % 8 != 0: bstr = '0' + bstr return bstr def pixel_bit(b): return tuple((0, 1, b)) def embed(t1, t2): return tuple((t1[0] + t2[0], t1[1] + t2[1], t1[2] + t2[2])) def full_pixel(pixel): return pixel[1] == 255 or pixel[2] == 255 print("Embedding file...") bin_data = open("./flag.txt", 'rb').read() data_to_hide = binascii.hexlify(bin_data).decode('utf-8') base_image = Image.open("./original.png") x_len, y_len = base_image.size nx_len = x_len*2 new_image = Image.new("RGB", (nx_len, y_len)) base_matrix = base_image.load() new_matrix = new_image.load() binary_string = hexstr_to_binstr(data_to_hide) remaining_bits = len(binary_string) nx_len = nx_len - 1 next_position = 0 for i in range(0, y_len): for j in range(0, x_len): pixel = new_matrix[j, i] = base_matrix[j, i] if remaining_bits > 0 and next_position <= 0 and not full_pixel(pixel): new_matrix[nx_len - j, i] = embed(pixel_bit(int(binary_string[0])),pixel) next_position = randint(1, 17) binary_string = binary_string[1:] remaining_bits -= 1 else: new_matrix[nx_len - j, i] = pixel next_position -= 1 new_image.save("./symatrix_new_out.png") new_image.close() base_image.close() print("Work done!") exit(1) ``` khi xem cách làm việc của của hàm thì thấy được là nó set bit của flag như sau: pixel_x = (0, 1, flag_bit) mỗi random(1,17) pixel sau đó flip cả tấm hình sang bên phải. vậy mình tìm tấm hình bên phải pixel nào có pixel[1] = 1 thì sẽ lấy pixel[3] để làm flag. ```python= from PIL import Image img = Image.open("./symatrix.png") x_len, y_len = img.size matrix = img.load() flag_bin_str = "" flag = "" nx_len = x_len - 1 for i in range(0, y_len): for j in range(0, x_len): pixel = matrix[nx_len - j, i] # print(pixel) if pixel[1]==1: flag_bin_str +=str(pixel[2]) # print(flag_bin_str) if len(flag_bin_str)%8==0 and len(flag_bin_str)!=0: flag+=chr(int(flag_bin_str[-8:],2)) print(flag) ``` ![](https://hackmd.io/_uploads/HkXFFscY2.png) ## NPC ![](https://hackmd.io/_uploads/S1Bs5rdFh.png) [Attachment](https://storage.googleapis.com/gctf-2023-attachments-project/9a8f5d47fab0a460f9826c4f13aa1dff2809140e68325fb21edab674ee5ec2476b902d2797c41bd6d9311e3510c9366d739d9404e00aa9d4ffd6a0d88e5bf2ef.zip) *Note to self: detailed wu* Script: Parse Graph ```python import re def get_word_list(): with open('USACONST.TXT', encoding='ISO8859') as f: text = f.read() return list(set(re.sub('[^a-z]', ' ', text.lower()).split())) word_lists = get_word_list() numCharDict = {} Edges = list() with open('hint.dot','r') as f: a = f.readlines() for i in a: if "label" in i: i = i.split() # print("label",i) numCharDict[int(i[0])] = i[1][-3] elif "--" in i: i = i.strip().split('--') print("Edges",i) Edges.append((int(i[0]),int(i[1][:-1]))) with open('parseGraph.txt','w') as w: w.writelines("letters = " + str(numCharDict) + '\nedge_list =' + str(Edges)) # print("letters =",numCharDict) # print("edge_list =",Edges) ``` Get Password ```python import re letters = {1051081353: 'a', 66849241: 'a', 53342583: 'n', 213493562: 'd', 4385267: 'i', 261138725: 'o', 51574206: 't', 565468867: 'e', 647082638: 'r', 177014844: 'd', 894978618: 'e', 948544779: 'n', 572570465: 'n', 582531406: 'r', 264939475: 'a', 415170621: 's', 532012257: 't', 151901859: 'v', 346347468: 'g', 148496047: 'g', 125615053: 's', 723039811: 'e', 962878065: 'i', 112993293: 'w', 748275487: 'n', 120330115: 's', 76544105: 'c', 186790608: 'h'} edge_list =[(53342583, 565468867), (582531406, 76544105), (125615053, 120330115), (264939475, 572570465), (53342583, 565468867), (532012257, 264939475), (346347468, 532012257), (125615053, 582531406), (177014844, 120330115), (264939475, 962878065), (647082638, 1051081353), (346347468, 112993293), (120330115, 151901859), (647082638, 125615053), (532012257, 66849241), (582531406, 894978618), (582531406, 572570465), (125615053, 532012257), (948544779, 261138725), (748275487, 894978618), (112993293, 177014844), (532012257, 4385267), (415170621, 962878065), (723039811, 962878065), (120330115, 151901859), (51574206, 76544105), (415170621, 532012257), (53342583, 120330115), (723039811, 582531406), (186790608, 112993293), (148496047, 582531406), (4385267, 125615053), (151901859, 962878065), (582531406, 894978618), (76544105, 748275487), (261138725, 186790608), (948544779, 346347468), (565468867, 213493562), (213493562, 261138725), (565468867, 894978618), (572570465, 264939475), (415170621, 151901859), (582531406, 962878065), (112993293, 346347468), (66849241, 1051081353), (894978618, 264939475), (647082638, 66849241), (894978618, 148496047), (213493562, 748275487), (572570465, 120330115), (565468867, 264939475), (148496047, 948544779), (186790608, 76544105), (177014844, 647082638), (125615053, 186790608), (112993293, 76544105), (582531406, 415170621), (151901859, 177014844), (346347468, 565468867), (148496047, 151901859), (723039811, 415170621), (1051081353, 415170621), (261138725, 76544105), (894978618, 723039811), (66849241, 112993293), (264939475, 112993293), (346347468, 748275487), (647082638, 948544779), (962878065, 647082638), (948544779, 962878065), (723039811, 120330115), (572570465, 51574206), (565468867, 151901859), (213493562, 76544105), (1051081353, 213493562), (962878065, 151901859), (112993293, 948544779), (186790608, 948544779), (346347468, 4385267), (565468867, 66849241), (1051081353, 177014844), (962878065, 148496047), (748275487, 264939475), (4385267, 565468867), (565468867, 1051081353), (51574206, 76544105), (532012257, 213493562), (532012257, 894978618), (723039811, 415170621), (264939475, 51574206), (572570465, 723039811), (894978618, 532012257), (66849241, 186790608), (213493562, 261138725), (415170621, 261138725), (125615053, 177014844), (186790608, 53342583), (565468867, 120330115), (51574206, 120330115), (186790608, 748275487), (213493562, 1051081353), (76544105, 53342583), (148496047, 565468867)] ans = set() adj = {} for edge in edge_list: try: adj[edge[1]].append(edge[0]) except: adj[edge[1]] = [edge[0]] # print(len(adj['4385267'])) # exit(0) def get_word_list(): with open('USACONST.TXT', encoding='ISO8859') as f: text = f.read() return list(set(re.sub('[^a-z]', ' ', text.lower()).split())) word_list = get_word_list() ma = 0 for x in word_list: if ma < len(x): ma = len(x) concat_word = ' ' + ' '.join(word_list) + ' ' def backtrack(u, list_node, w, last): # print(w, last, len(list_node), len(letters), sep='|') global concat_word, word_list, ma if (len(list_node) == len(letters)): # with open('ans', 'a') as f: # f.write(w + '\n') ans.add(w.replace(' ','')) return for v in adj[u]: old_last = last if v not in list_node: if ' ' + last + letters[v] in concat_word and len(last) < ma: last += letters[v] w += letters[v] list_node.append(v) backtrack(v, list_node, w, last) list_node.pop() last = old_last w = w[:-1] if ' ' + letters[v] not in concat_word or ' ' + old_last + ' ' not in concat_word: continue last = letters[v] list_node.append(v) w += ' ' + letters[v] backtrack(v, list_node, w, last) list_node.pop() last = old_last w = w[:-2] for i in letters: backtrack(i, [i], letters[i], letters[i]) with open('ans','w') as w: for i in ans: w.writelines(i+'\n') ``` Decrypt ```python from pyrage import passphrase from multiprocessing import Process passwords = [i.strip().split('|')[0].replace(' ','') for i in open('ans','r').readlines()] # print(passwords) lmao = open('secret.age','rb').read() if __name__ == '__main__': for passw in passwords: try: print(passphrase.decrypt(lmao,passw)) print(passw) except: pass ```