第二屆資料安全大賽“數信杯”資料安全大賽 WP

渗透测试中心發表於2024-07-21

1.pyc

使用pyc線上反編譯得到python原始碼:

 #!/usr/bin/env python
 # visit https://tool.lu/pyc/ for more information
 # Version: Python 3.8
 
 import random
 
 
 def encrypt_file(file_path):
     random.seed(114514)
 
 
 # WARNING: Decompyle incomplete
 
 file_path = "./flag"
 encrypt_file(file_path)

然後使用AI分析可得到它對應的解密指令碼

 import random
 import os
 
 def decrypt_data(encrypted_data):
     random.seed(114514)
     decrypted_data = bytearray()
     for byte in encrypted_data:
         key = random.randint(0, 128)
         decrypted_data.append(byte ^ key)
     return decrypted_data
 def read_file(file_path, mode='rb'):
     with open(file_path, mode) as file:
         return file.read()
 def write_file(file_path, data, mode='wb'):
     with open(file_path, mode) as file:
         file.write(data)
 def decrypt_file(encrypted_file_path, output_file_path):
     encrypted_data = read_file(encrypted_file_path)
     decrypted_data = decrypt_data(encrypted_data)
     write_file(output_file_path, decrypted_data)
 if __name__=='__main__':
     encrypted_file_path = 'flag.enc'
     output_file_path = 'flag_decrypted.txt'
     decrypt_file(encrypted_file_path, output_file_path)
     #flag{U_R_g00d_at_do1n_pyc}

2.MWatch

提示:資料安全研究員在分析智慧裝置實時採集的資料時,檢測到有一臺裝置使用者曾出現過某數值過高的情況,請你協助分析該數值最高是多少。flag{md5(資料採集裝置名稱資料接收裝置名稱數值)}

多次出現Heart Rate,結合題目描述應該就是找這個,只檢視Heart Rate相關

image-20240428205017240

image-20240428205017240

flag{md5(Mi Smart Band 5_Redmi K40_128)}

flag{453d8feda5adb6e7b4d54f71a9ce9e14}

3.BabyRSA

提示:某員工有一個生成素數的初始值,這個演算法他跑了很長時間。程式不小心終端,還不小心刪了了初始值,還能恢復明文嗎

原始碼:

 #task.py
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 
 from secret import flag,init
 from Crypto.Util.number import *
 from sage.all import *
 from gmpy2 import iroot
 m = bytes_to_long(flag.encode())
 r = getPrime(128)
 
 p = init
 # for i in range(r-1):
 #     p += next_prime(init)
 
 # assert iroot(p,3)[1] == 1
 q = getPrime(12)
 # N = p*q*r
 N = r**4*q
 e = getPrime(17)
 c = pow(m,e,N)
 print(f"r = {r}")
 print(f"e = {e}")
 print(f"c = {c}")
 
 # r = 287040188443069778047400125757341514899
 # e = 96001
 # c = 7385580281056276781497978538020227181009675544528771975750499295104237912389096731847571930273208146186326124578668216163319969575131936068848815308298035625

爆破12位元的素數得到q,然後解密即可

 from Crypto.Util.number import long_to_bytes, inverse
 
 r = 287040188443069778047400125757341514899
 e = 96001
 c = 7385580281056276781497978538020227181009675544528771975750499295104237912389096731847571930273208146186326124578668216163319969575131936068848815308298035625
 
 # Assuming the modulus for the exponentiation should indeed be r**4
 n = r**4
 
 # Compute the modular inverse of e mod φ(n), where φ(n) could be a function of r, like (r-1)*(r**3)
 # We need the correct value of φ(n) for the RSA decryption formula m = c^d mod n, where d = e^(-1) mod φ(n)
 # Here, assuming φ(n) = r^4 - r^3 as a simplification, you might need to adjust this based on actual RSA setup
 phi_n = r**4 - r**3
 d = inverse(e, phi_n)
 
 # Decrypt message
 m = pow(c, d, n)
 
 # Convert number to bytes
 message = long_to_bytes(m)
 print(message)
 #flag{3b0ce326141ea4f6b5bf2f37efbd1b42}

4.Backpack

揹包加密,用BKZ演算法可以求解到一組基

 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 
 from sage.all import *
 from secret import flag
 from Crypto.Util.number import *
 from math import log2
 
 class Knapsack:
     def __init__(self,n,m):
         self.M = []
         self.n = n
         self.m = self.pre(m)
         self.A = 0
         self.B = 0
     def pre(self,m):
         tmp_m = bin(m)[2:]
         t = []
         for tmp in tmp_m:
             t.append(int(tmp))
         return t
     def get_M(self):
         seq = [randint(2**34,2**35) for _ in range(self.n)]
         self.M = seq
     def calc_density(self):
         t = log2(max(self.M))
         d = self.n/t
         print(d)
 
     def enc(self):
         self.get_M()
         self.calc_density()
         C = 0
         for t in range(len(self.m)):
             C += self.m[t] * self.M[t]
         print(f"C = {C}")
         print(f"M = {self.M}")
 if __name__=="__main__":
     m = bytes_to_long(flag.encode())
     n = m.bit_length()
     k = Knapsack(n,m)
     k.enc()
 
 # C = 231282844744
 # M = [27811518167, 19889199464, 19122558731, 19966624823, 25670001067, 30690729665, 23936341812, 31011714749, 30524482330, 21737374993, 17530717152, 19140841231, 33846825616, 17334386491, 28867755886, 29354544582, 21758322019, 27261411361, 31465376167, 26145493792, 27075307455, 33514052206, 25397635665, 21970496142, 30801229475, 22405695620, 18486900933, 27071880304, 17919853256, 18072328152, 21108080920]
 

sagemath中執行:

from Crypto.Util.number import long_to_bytes
 
 C = 231282844744
 M = [27811518167, 19889199464, 19122558731, 19966624823, 25670001067, 30690729665, 
      23936341812, 31011714749, 30524482330, 21737374993, 17530717152, 19140841231, 
      33846825616, 17334386491, 28867755886, 29354544582, 21758322019, 27261411361, 
      31465376167, 26145493792, 27075307455, 33514052206, 25397635665, 21970496142, 
      30801229475, 22405695620, 18486900933, 27071880304, 17919853256, 18072328152, 
      21108080920]
 
 L = block_matrix([[1, matrix(ZZ, M).T], [0, C]]).LLL()
 
 for row in L:
     if row[-1] == 0 and len(set(row[:-1])) == 1:
         # Assuming all elements in the row, except the last one, are the same
         ans = [abs(i) for i in row[:-1]]
         ans = int(''.join(map(str, ans)), 2)
         print(long_to_bytes(ans))

5.定向資料採集

 
import openpyxl
 import requests
 import time
 from urllib.parse import urlencode
 burp0_url = "http://121.40.65.125:23328/submit"
 
 def separate_name_and_id(input_file, output_file):
     wb = openpyxl.load_workbook(input_file)
     ws = wb.active
 
     for row in ws.iter_rows(min_row=1, max_col=1, max_row=ws.max_row, values_only=True):
         if row[0]:
             name, id_number = row[0].split('----') #提取名字和身份證
             print(name, id_number)
             age = 2024-int(id_number[6:10])
             if(int(id_number[10:12])>4):
                 age -= 1
             sexx=u""
             burp0_json={"address": "asd", "age": str(age), "ethnicity": "as", "experience": "1", "idcard": id_number, "name": "a", "phonenumber": "12312331233", "position": "as", "sex": sexx}
             sexx2 = u""
             burp0_json1={"address": "asd", "age": str(age), "ethnicity": "as", "experience": "1", "idcard": id_number, "name": "a", "phonenumber": "12312331233", "position": "as", "sex": sexx2}
             try:
                 r0=requests.post(burp0_url, json=burp0_json)
                 r1=requests.post(burp0_url, json=burp0_json1)
                 print(r0.request.body)
                 print(r0.text,r1.text)
                 #time.sleep(0.5)
             except requests.exceptions:
                 print("err")
             #time.sleep(2)
             #ws.append([name.strip(), id_number.strip()])
 
     #wb.save(output_file)
     wb.close()
 
 if __name__ == "__main__":
     input_file = "data1.xlsx"
     output_file = "separated_data.xlsx" #沒啥用,廢棄掉了
     separate_name_and_id(input_file, output_file)

6.weather

審下bundle.js

image-20240428213212351

image-20240428213230335

帶引數去訪問

Image

7.mysql 清理

提示:

根據要求,現在要從資料庫中徹底刪除一些使用者的資料,請連線提供的mysql容器,刪除ctf所有表中,使用者id為5142、2123、1169、8623這四個使用者的資料。要求徹底清理這些使用者,不能在伺服器[中找到殘留,同時不能改動其他使用者資料。當操作成功後,系統會在ctf.flag表中錄入flag資料。(mysql ctf使用者密碼 pswd@123)

 DELETE FROM ShoppingCart WHERE user_id in ("5142","2123","1169","8623");
 DELETE FROM TransactionHistory WHERE user_id in ("5142","2123","1169","8623");
 DELETE FROM UserLog WHERE user_id in ("5142","2123","1169","8623");
 DELETE FROM Wallet WHERE user_id in ("5142","2123","1169","8623");
 DELETE FROM User WHERE id in ("5142","2123","1169","8623");

再重建一下表,清掉刪除之後的殘留資料

 
alter table User engine = innodb;
alter table UserLog engine = innodb;
alter table TransactionHistory engine = innodb;
alter table ShoppingCart engine = innodb;
alter table Orders engine = innodb;

image-20240428213639377

8.幻方

三階幻方只有八種結果,認準一個多試幾次就行

 
import hashlib
 import random
 import string
 
 # Define the character set as alphanumeric characters
 charset = string.ascii_letters + string.digits
 
 while True:
     # Generate a random 4-character string from the charset
     rand_str = ''.join(random.choice(charset) for _ in range(4)) + 'CyhQp8lsgzYjTNUD'
     
     # Calculate the SHA-256 hash of the string
     hash_output = hashlib.sha256(rand_str.encode()).hexdigest()
     
     # Check if the hash matches the target hash
     if hash_output == '11f8af166cc28e24b4646cc300436f4d4bf8e11b2327379331a3eca2d5fc7c0c':
         print(rand_str[:4])  # Print the first 4 characters if a match is found
         break
 '''
 [2, 7, 6, 9, 5, 1, 4, 3, 8]
 [2, 9, 4, 7, 5, 3, 6, 1, 8]
 [4, 3, 8, 9, 5, 1, 2, 7, 6]
 [4, 9, 2, 3, 5, 7, 8, 1, 6]
 [6, 1, 8, 7, 5, 3, 2, 9, 4]
 [6, 7, 2, 1, 5, 9, 8, 3, 4]
 [8, 1, 6, 3, 5, 7, 4, 9, 2]
 [8, 3, 4, 1, 5, 9, 6, 7, 2]
 4 3 8
 9 5 1
 2 7 6
 '''

image-20240428214506459

9.Prime Conundrum

知道了delta可以對leak的那條式子進行二元copper求解s,t,透過hint和s求解p, 算私鑰解密即可

 
import itertools
 from tqdm import tqdm
 def small_roots(f, bounds, m=1, d=None):
     if not d:
         d = f.degree()
     R = f.base_ring()
     N = R.cardinality()
     f /= f.coefficients().pop(0)
     f = f.change_ring(ZZ)
     G = Sequence([], f.parent())
     for i in range(m + 1):
         base = N ^ (m - i) * f ^ i
         for shifts in itertools.product(range(d), repeat=f.nvariables()):
             g = base * prod(map(power, f.variables(), shifts))
             G.append(g)
     B, monomials = G.coefficient_matrix()
     monomials = vector(monomials)
     factors = [monomial(*bounds) for monomial in monomials]
     for i, factor in enumerate(factors):
         B.rescale_col(i, factor)
     B = B.dense_matrix().LLL()
     B = B.change_ring(QQ)
     for i, factor in enumerate(factors):
         B.rescale_col(i, 1 / factor)
     H = Sequence([], f.parent().change_ring(QQ))
     for h in filter(None, B * monomials):
         H.append(h)
         I = H.ideal()
         if I.dimension() == -1:
             H.pop()
         elif I.dimension() == 0:
             roots = []
             for root in I.variety(ring=ZZ):
                 root = tuple(R(root[var]) for var in f.variables())
                 roots.append(root)
             return roots
     return []
 P = 91307300383014465303389363075431698588933838431961163766796972428733255940234665671679789435258337578396879726483195947952476118985507696067550566875810703327064257916213956673893327976728584687137639337961422903593701591152074826447530099276756806166361533554689114264018344629905535188048343259754284652017
 Q = 149089411480331249267443825847904508235946280550542428853480950085018092182435890098430254117786823782088885695848943795846175490059759543848516828825072642481794902650586147465149175976488985613001468444893241645390860978312924241181340390543064512602477917112031391367608345501790785857442379515898677467337
 n = 97339579366356507946846401691835843338581994635020856947574389213640653953117584127557153363761256108433474475102197685296591968229050609482457622390855692102761025647645801250282912327521623082583744902369819132264725498938021235699466656447009532567358416017236962637028458839659218745744825556065623673913
 N = 72077628115206161977315177371814064093288033362281459918751639032623658967593542855291047617938064177930014574391486973767462937337649946356572406647109942552336519343063401327708412361664750917582404375485334706345485264831286788789648126355202140531434534406410829696252616051882952860015344370516517084357909896281965899571934196572691
 leak = 45439323369250400352006541741265096780554398472451037280607564706700682873365442581062404781075514235328183754475227917775810587457541607767765455164339314322631781126065808432845447798024685402323868389611285038950397054020330610558058133599416135943335731904873776868614834960217751934513462319743149481906
 c = 31456530156035981140909630437789986968079386074106871160743980387785993275753486380185420818239283975922682050323918081691381897642776414263991442096807392948925867761878299044300335666219533277719472330029607869735373712681522022301659090108633692457216985013550482473362675907949633024047291607542103649091410575340884845190483766424507
 hint = 13318665442465244206832303588726230530847297247590371628366697082014350966833522479782161994817212671730145702818662148370306660550486536176566012104254910
 z = 740476059013240018009340328107
 PR.<x,y>=PolynomialRing(Zmod(n))
 f=P*x + Q*y + z -leak
 ans=small_roots(f,bounds=(2^70,2^70),m=3,d=3)
 ans
 s = 30656796668419630391
 t = 35875762848049841267
 p = hint + s
 q  = n // p 
 assert p*q == n
 e = 65537
 from Crypto.Util.number import *
 d = inverse(e,(p-1)*(q-1)*(z-1))
 m = pow(c,d,n)
 long_to_bytes(int(m))

10.fun

遍歷爆破滿足條件的x,y然後解密即可

 # from z3 import *
 A = []
 for x in range(101):
     for y in range(101):
         z  = x^y 
         if (x+y)*z == x**2 + y**2:
             if x*y != z:
                 if x != y:
                     A.append([x,y,z])
 from Crypto.Cipher import AES
 import random
 # 與加密時相同的種子,確保生成相同的金鑰
 for i in A:
     x,y,z = i
     random.seed(x+y+z)
     key = random.randbytes(16)
     # print(key)
     # 讀取加密的資料
     PATH = r"encrypted_flag.bin"
     with open(PATH, "rb") as file_in:
         nonce = file_in.read(16)  # Nonce 的長度為 16 位元組
         tag = file_in.read(16)    # Tag 通常與塊大小相同,對於 AES 為 16 位元組
         ciphertext = file_in.read()  # 讀取剩餘部分作為密文
     # 解密過程
     # print(nonce)
     # print(tag)
     # print(ciphertext)
     cipher = AES.new(key, AES.MODE_EAX,nonce=nonce)
     try:
         decrypted_text = cipher.decrypt_and_verify(ciphertext, tag)
         print("The flag is:", decrypted_text)
     except:
         pass

11.好大的公鑰

boneh and durfee 一把梭

 from libnum import *
 N = 73662176635930217145588251109582598744318418885493494845859692592990304301546996154904097420724904838772056137908521735803973827790665774255932629529776216900362889972771913683024723128622502292694632281143536586986352764727899291750703185204118126673717387089701233154888606074285445820360105604776003690487 
 e = 26083019178473123328452230832076345302834454225396475868531519193551971982955975631443131705619185405190763284436613436828597887376946206551305947183212830810924956452635880343496593901027606468731840531964306285933726727512533644720818081124507069662781291949841231431546394148749720394411454774153995026037 
 c = 46149785989975097887441076951612740430034092652052333486778189200068487460813449057674051203125773261695615434443270333980225346411838188124458064365680435783802887397970067324393852247219619820813993601444322710186223021625645961186730735728928546458428244830359782270698452792224875596683123815246426241726 
 """
 Setting debug to true will display more informations
 about the lattice, the bounds, the vectors...
 """
 debug = False
 """
 Setting strict to true will stop the algorithm (and
 return (-1, -1)) if we don't have a correct
 upperbound on the determinant. Note that this
 doesn't necesseraly mean that no solutions
 will be found since the theoretical upperbound is
 usualy far away from actual results. That is why
 you should probably use `strict = False`
 """
 strict = False
 """
 This is experimental, but has provided remarkable results
 so far. It tries to reduce the lattice as much as it can
 while keeping its efficiency. I see no reason not to use
 this option, but if things don't work, you should try
 disabling it
 """
 helpful_only = True
 dimension_min = 7  # stop removing if lattice reaches that dimension
 ############################################
 # Functions
 ##########################################
 # display stats on helpful vectors
 def helpful_vectors(BB, modulus):
     nothelpful = 0
     for ii in range(BB.dimensions()[0]):
         if BB[ii, ii] >= modulus:
             nothelpful += 1
     print(nothelpful, "/", BB.dimensions()[0], " vectors are not helpful")
 
 # display matrix picture with 0 and X
 def matrix_overview(BB, bound):
     for ii in range(BB.dimensions()[0]):
         a = ('%02d ' % ii)
         for jj in range(BB.dimensions()[1]):
             a += '0' if BB[ii, jj] == 0 else 'X'
             if BB.dimensions()[0] < 60:
                 a += ' '
         if BB[ii, ii] >= bound:
             a += '~'
         print(a)
 # tries to remove unhelpful vectors
 # we start at current = n-1 (last vector)
 def remove_unhelpful(BB, monomials, bound, current):
     # end of our recursive function
     if current == -1 or BB.dimensions()[0] <= dimension_min:
         return BB
     # we start by checking from the end
     for ii in range(current, -1, -1):
         # if it is unhelpful:
         if BB[ii, ii] >= bound:
             affected_vectors = 0
             affected_vector_index = 0
             # let's check if it affects other vectors
             for jj in range(ii + 1, BB.dimensions()[0]):
                 # if another vector is affected:
                 # we increase the count
                 if BB[jj, ii] != 0:
                     affected_vectors += 1
                     affected_vector_index = jj
             # level:0
             # if no other vectors end up affected
             # we remove it
             if affected_vectors == 0:
                 # print("* removing unhelpful vector", ii)
                 BB = BB.delete_columns([ii])
                 BB = BB.delete_rows([ii])
                 monomials.pop(ii)
                 BB = remove_unhelpful(BB, monomials, bound, ii - 1)
                 return BB
             # level:1
             # if just one was affected we check
             # if it is affecting someone else
             elif affected_vectors == 1:
                 affected_deeper = True
                 for kk in range(affected_vector_index + 1, BB.dimensions()[0]):
                     # if it is affecting even one vector
                     # we give up on this one
                     if BB[kk, affected_vector_index] != 0:
                         affected_deeper = False
                 # remove both it if no other vector was affected and
                 # this helpful vector is not helpful enough
                 # compared to our unhelpful one
                 if affected_deeper and abs(bound - BB[affected_vector_index, affected_vector_index]) < abs(
                         bound - BB[ii, ii]):
                     # print("* removing unhelpful vectors", ii, "and", affected_vector_index)
                     BB = BB.delete_columns([affected_vector_index, ii])
                     BB = BB.delete_rows([affected_vector_index, ii])
                     monomials.pop(affected_vector_index)
                     monomials.pop(ii)
                     BB = remove_unhelpful(BB, monomials, bound, ii - 1)
                     return BB
     # nothing happened
     return BB
 """ 
 Returns:
 * 0,0   if it fails
 * -1,-1 if `strict=true`, and determinant doesn't bound
 * x0,y0 the solutions of `pol`
 """
 def boneh_durfee(pol, modulus, mm, tt, XX, YY):
     """
     Boneh and Durfee revisited by Herrmann and May
     finds a solution if:
     * d < N^delta
     * |x| < e^delta
     * |y| < e^0.5
     whenever delta < 1 - sqrt(2)/2 ~ 0.292
     """
     # substitution (Herrman and May)
     PR.<u,x,y> = PolynomialRing(ZZ)
     Q = PR.quotient(x * y + 1 - u)  # u = xy + 1
     polZ = Q(pol).lift()
     UU = XX * YY + 1
     # x-shifts
     gg = []
     for kk in range(mm + 1):
         for ii in range(mm - kk + 1):
             xshift = x ^ ii * modulus ^ (mm - kk) * polZ(u, x, y) ^ kk
             gg.append(xshift)
     gg.sort()
     # x-shifts list of monomials
     monomials = []
     for polynomial in gg:
         for monomial in polynomial.monomials():
             if monomial not in monomials:
                 monomials.append(monomial)
     monomials.sort()
     # y-shifts (selected by Herrman and May)
     for jj in range(1, tt + 1):
         for kk in range(floor(mm / tt) * jj, mm + 1):
             yshift = y ^ jj * polZ(u, x, y) ^ kk * modulus ^ (mm - kk)
             yshift = Q(yshift).lift()
             gg.append(yshift)  # substitution
     # y-shifts list of monomials
     for jj in range(1, tt + 1):
         for kk in range(floor(mm / tt) * jj, mm + 1):
             monomials.append(u ^ kk * y ^ jj)
     # construct lattice B
     nn = len(monomials)
     BB = Matrix(ZZ, nn)
     for ii in range(nn):
         BB[ii, 0] = gg[ii](0, 0, 0)
         for jj in range(1, ii + 1):
             if monomials[jj] in gg[ii].monomials():
                 BB[ii, jj] = gg[ii].monomial_coefficient(monomials[jj]) * monomials[jj](UU, XX, YY)
     # Prototype to reduce the lattice
     if helpful_only:
         # automatically remove
         BB = remove_unhelpful(BB, monomials, modulus ^ mm, nn - 1)
         # reset dimension
         nn = BB.dimensions()[0]
         if nn == 0:
             print("failure")
             return 0, 0
     # check if vectors are helpful
     if debug:
         helpful_vectors(BB, modulus ^ mm)
     # check if determinant is correctly bounded
     det = BB.det()
     bound = modulus ^ (mm * nn)
     if det >= bound:
         # print("We do not have det < bound. Solutions might not be found.")
         # print("Try with highers m and t.")
         if debug:
             diff = (log(det) - log(bound)) / log(2)
             # print("size det(L) - size e^(m*n) = ", floor(diff))
         if strict:
             return -1, -1
     else:
         print("det(L) < e^(m*n) (good! If a solution exists < N^delta, it will be found)")
     # display the lattice basis
     if debug:
         matrix_overview(BB, modulus ^ mm)
     # LLL
     if debug:
         print("optimizing basis of the lattice via LLL, this can take a long time")
     BB = BB.LLL()
     if debug:
         print("LLL is done!")
     # transform vector i & j -> polynomials 1 & 2
     if debug:
         print("looking for independent vectors in the lattice")
     found_polynomials = False
     for pol1_idx in range(nn - 1):
         for pol2_idx in range(pol1_idx + 1, nn):
             # for i and j, create the two polynomials
             PR.<w,z> = PolynomialRing(ZZ)
             pol1 = pol2 = 0
             for jj in range(nn):
                 pol1 += monomials[jj](w * z + 1, w, z) * BB[pol1_idx, jj] / monomials[jj](UU, XX, YY)
                 pol2 += monomials[jj](w * z + 1, w, z) * BB[pol2_idx, jj] / monomials[jj](UU, XX, YY)
             # resultant
             PR.<q> = PolynomialRing(ZZ)
             rr = pol1.resultant(pol2)
             # are these good polynomials?
             if rr.is_zero() or rr.monomials() == [1]:
                 continue
             else:
                 # print("found them, using vectors", pol1_idx, "and", pol2_idx)
                 found_polynomials = True
                 break
         if found_polynomials:
             break
     if not found_polynomials:
         # print("no independant vectors could be found. This should very rarely happen...")
         return 0, 0
     rr = rr(q, q)
     # solutions
     soly = rr.roots()
     if len(soly) == 0:
         # print("Your prediction (delta) is too small")
         return 0, 0
     soly = soly[0][0]
     ss = pol1(q, soly)
     solx = ss.roots()[0][0]
     #
     return solx, soly
 delta = .271  # this means that d < N^delta
 m = 8  # size of the lattice (bigger the better/slower)
 t = int((1 - 2 * delta) * m)  # optimization from Herrmann and May
 X = 2 * floor(N ^ delta)  # this _might_ be too much
 Y = floor(N ^ (1 / 2))  # correct if p, q are ~ same size
 P.<x,y> = PolynomialRing(ZZ)
 A = int((N + 1) / 2)
 pol = 1 + x * (A + y)
 solx, soly = boneh_durfee(pol, e, m, t, X, Y)
 d = int(pol(solx, soly) / e)
 print(d)
 m = power_mod(c, d, N)
 print(n2s(int(m)))

12.Notebook

複製文字到瀏覽器檢索,發現有200C,所以直接零寬字元,用Cyberchef轉換為Escape Unicode,發現大量出現了以下零寬字元

u202C\u200B\u2062\uFEFF最後找到了

https://lazzzaro.github.io/2020/05/24/misc-%E9%9B%B6%E5%AE%BD%E5%BA%A6%E5%AD%97%E7%AC%A6%E9%9A%90%E5%86%99/index.html

發現330k有自定義碼錶的功能

http://330k.github.io/misc_tools/unicode_steganography.html

最後發現MACOSX_裡面裡面其實hint了330k.github.io。

https://www.mzy0.com/ctftools/zerowidth1/

也可以處理。

選中需要的編碼之後即可解析,解析後如下:

K|2+YG3-hfl|&_U8檢索一整段之後沒有什麼資訊,放入隨波逐流裡面發現該編碼可以被base92解碼解碼後可知洩露源。

image-20240414192310831

wangdalei0527然後找了半天flag提交格式結果發現只用提交wangdalei就行,0527猜測是手機尾號

flag{wangdalei}

13.UnsetData

發現是一個類似於記憶體映象的東西,使用R-studio進行恢復找到了data.jpg,發現左上角有東西,有隱隱約約的字元,使用盲水印發現flag,然後調十幾次引數找到相對清晰的圖片之後抄10分鐘flag即可得

img

image-20240414184342639

flag{0531d7d9-65fb-49ae-87c1-639fff783338}

14.RWZIP

發現該壓縮包資料校驗不透過,說明包體被修改過,修改前發現壓縮加密格式為ZipCrypto沒找到其他資訊,使用passware toolkit爆破,可得壓縮包密碼為114514,再觀察下包體發現他被ZipCrypto加密後卻不需要輸入密碼,將加密為從08改為09正常輸入密碼即可解壓解壓後發現採用了特殊的字符集,目測是將左右進行翻轉替換後可得flag

 ʇlɒϱ{85ɘdɒʇ8245754b9ɘd09045087ʇɘ28392}
flag{85ebaf8245754d9eb09045087fe28392}

15.USBHacker

wireshark開啟後USBHID長度為16,知道該流量為鍵盤流量

過濾Source 1.5.1之後,匯出json,

 import json
 datainput = open('USB3.json', "r", encoding="utf-8")
 output = open("USB3.txt", "w",encoding="utf-8")
 d = json.load(datainput)
 for i in d:
     print(i["_source"]["layers"]["usbhid.data"])
     output.write(i["_source"]["layers"]["usbhid.data"]+'\n')

然後再進行解析

 
normalKeys = {
     "04":"a", "05":"b", "06":"c", "07":"d", "08":"e",
     "09":"f", "0a":"g", "0b":"h", "0c":"i", "0d":"j",
      "0e":"k", "0f":"l", "10":"m", "11":"n", "12":"o",
       "13":"p", "14":"q", "15":"r", "16":"s", "17":"t",
        "18":"u", "19":"v", "1a":"w", "1b":"x", "1c":"y",
         "1d":"z","1e":"1", "1f":"2", "20":"3", "21":"4",
          "22":"5", "23":"6","24":"7","25":"8","26":"9",
          "27":"0","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t",
          "2c":"<SPACE>","2d":"-","2e":"=","2f":"[","30":"]","31":"\\",
          "32":"<NON>","33":";","34":"'","35":"<GA>","36":",","37":".",
          "38":"/","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>",
          "3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>",
          "44":"<F11>","45":"<F12>"}
 shiftKeys = {
     "04":"A", "05":"B", "06":"C", "07":"D", "08":"E",
      "09":"F", "0a":"G", "0b":"H", "0c":"I", "0d":"J",
       "0e":"K", "0f":"L", "10":"M", "11":"N", "12":"O",
        "13":"P", "14":"Q", "15":"R", "16":"S", "17":"T",
         "18":"U", "19":"V", "1a":"W", "1b":"X", "1c":"Y",
          "1d":"Z","1e":"!", "1f":"@", "20":"#", "21":"$",
           "22":"%", "23":"^","24":"&","25":"*","26":"(","27":")",
           "28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t","2c":"<SPACE>",
           "2d":"_","2e":"+","2f":"{","30":"}","31":"|","32":"<NON>","33":"\"",
           "34":":","35":"<GA>","36":"<","37":">","38":"?","39":"<CAP>","3a":"<F1>",
           "3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>",
           "41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"}
 output = []
 keys = open('usb2.txt','r')
 for line in keys:
     try:
         if line[0]!='0' or (line[1]!='0' and line[1]!='2') or line[3]!='0' or line[4]!='0' or line[9]!='0' or line[10]!='0' or line[12]!='0' or line[13]!='0' or line[15]!='0' or line[16]!='0' or line[18]!='0' or line[19]!='0' or line[21]!='0' or line[22]!='0' or line[6:8]=="00":
              continue
         if line[6:8] in normalKeys.keys():
             output += [[normalKeys[line[6:8]]],[shiftKeys[line[6:8]]]][line[1]=='2']
         else:
             output += ['[unknown]']
     except:
         pass
 keys.close()
 flag=0
 print("".join(output))
 for i in range(len(output)):
     try:
         a=output.index('<DEL>')
         del output[a]
         del output[a-1]
     except:
         pass
 for i in range(len(output)):
     try:
         if output[i]=="<CAP>":
             flag+=1
             output.pop(i)
             if flag==2:
                 flag=0
         if flag!=0:
             output[i]=output[i].upper()
     except:
         pass
 print ('output :' + "".join(output))

發現是身份證號,缺失校驗位,計算得出校驗位為3,md5後即為flag

相關文章