2023年国家基地“楚慧杯”网络安全实践能力竞赛初赛-Crypto+Misc WP ...

打印 上一主题 下一主题

主题 844|帖子 844|积分 2542

Misc

ez_zip

题目
4096个压缩包套娃
我的解答:
写个脚本直接解压即可:
  1. import zipfile
  2. name = '附件路径\\题目附件.zip'
  3. for i in range(4097):
  4.     f = zipfile.ZipFile(name , 'r')
  5.     f.extractall(pwd=name[:-4].encode())
  6.     name = f.filelist[0].filename
  7.     print(name[:-4],end="")
  8.     f.close()
复制代码
得到
  1. +-+++-++ +-+++++- +-+-++-- +-++++-- +-+-+-++ +-+++--+ +----+-- ++--+++- ++--++++ +--+++-- ++--+-+- ++---+++ ++--++-+ ++--+-+- ++---+++ +--+++-- +--+++-- +--++--+ ++--+++- +--++-+- ++--+--- +--+++-- ++--+--+ ++--++-- ++--+++- +--++-+- ++--+-+- ++---++- ++--+++- ++--+++- +--++-+- +--++-++ ++--+--+ +--++++- +--+++-- +--+++-- ++--+-++ +--++-+- +--++-++ +-----+-
复制代码
一眼丁真01,将+改成0,-改成1
  1. x='''01000100 01000001 01010011 01000011 01010100 01000110 01111011 00110001 00110000 01100011 00110101 00111000 00110010 00110101 00111000 01100011 01100011 01100110 00110001 01100101 00110111 01100011 00110110 00110011 00110001 01100101 00110101 00111001 00110001 00110001 01100101 01100100 00110110 01100001 01100011 01100011 00110100 01100101 01100100 01111101'''
  2. s=x.split(' ')
  3. print(''.join(chr(int(c,2)) for c in s))
  4. 'DASCTF{10c58258ccf1e7c631e5911ed6acc4ed}'
复制代码
easy取证

题目

我的解答:
一个取证问题,简单来分析一下:
本人是在windows下使用,参考:https://blog.csdn.net/m0_68012373/article/details/127419463
我们先查看镜像信息
  1. volatility.exe -f mem.raw imageinfo
复制代码

然后我们可以利用插件grep查找一下常见的信息,例如:zip,txt,docx,png,jpg等
测试之后发现桌面有个docx文档
  1. volatility.exe -f mem.raw --profile Win7SP1x64 filescan | grep .docx
复制代码

我们需要提取出来
  1. volatility.exe -f mem.raw --profile=Win7SP1x64 dumpfiles -Q 0x000000003dceaf20 -D ./
复制代码
得到

修改后缀为docx打开,复制内容到txt里面

一眼丁真snow隐写,但需要找到密码,我们使用mimikatz(mimikatz插件可以获取系统明文密码,网上有安装教程)获取密码
得到
  1. H7Qmw_X+WB6BXDXa
复制代码
然后直接解码即可
  1. SNOW.EXE -C -p "H7Qmw_X+WB6BXDXa" White.txt
复制代码

Crypto

so-large-e

题目

公钥
  1. -----BEGIN PUBLIC KEY-----
  2. MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKBgQCl7ZhtXDOIFdSnnejtOn2W
  3. OdcqyzrvKMVFTIqSyPV3Tkj5m9ETc/rlvLJLcQvI0V6tr+u5Tq+zqWBQzsvRsvKt
  4. +ap0JW8up0qD1nGIvcJVdsWAjdse7AH/N3+xg8NrH3nO0OIWzMpkGH+4TVsOBu8M
  5. nhnR9SxTkDp+gUtHtPR/awKBgQChjp2PFfpCV4hrVyPJrKP2gHbW+o7mBNiUd3Av
  6. Ucbkr7rA6Sj3tU33yGKIoXbmZC4rWNcuqrsoCPvIFl/YHYPKVDOl2PlLaDVi/Q5E
  7. ymGkUfPXoZsScxvkZtkOt9XY4wWEeDMtxF/swnV0nhAUSJEHamFL3i0PAWf9uBdd
  8. VheH4Q==
  9. -----END PUBLIC KEY-----
复制代码
  1. from Crypto.Util.number import *
  2. from Crypto.PublicKey import RSA
  3. from flag import flag
  4. import random
  5. m = bytes_to_long(flag)
  6. p = getPrime(512)
  7. q = getPrime(512)
  8. n = p*q
  9. e = random.getrandbits(1024)
  10. assert size(e)==1024
  11. phi = (p-1)*(q-1)
  12. assert GCD(e,phi)==1
  13. d = inverse(e,phi)
  14. assert size(d)==269
  15. pub = (n, e)
  16. PublicKey = RSA.construct(pub)
  17. with open('pub.pem', 'wb') as f :
  18.     f.write(PublicKey.exportKey())
  19. c = pow(m,e,n)
  20. print('c =',c)
  21. print(long_to_bytes(pow(c,d,n)))
  22. #c = 6838759631922176040297411386959306230064807618456930982742841698524622016849807235726065272136043603027166249075560058232683230155346614429566511309977857815138004298815137913729662337535371277019856193898546849896085411001528569293727010020290576888205244471943227253000727727343731590226737192613447347860
复制代码
我的解答:
我们先分解公钥得到n,e
  1. from gmpy2 import *
  2. from Crypto.Util.number import *
  3. from Crypto.PublicKey import RSA
  4. # 公钥提取
  5. with open("pub.pem","r",encoding="utf-8") as file:
  6.     text=file.read()
  7. key=RSA.import_key(text)
  8. e=key.e
  9. n=key.n
  10. print(e)
  11. print(n)
  12. 113449247876071397911206070019495939088171696712182747502133063172021565345788627261740950665891922659340020397229619329204520999096535909867327960323598168596664323692312516466648588320607291284630435682282630745947689431909998401389566081966753438869725583665294310689820290368901166811028660086977458571233
  13. 116518679305515263290840706715579691213922169271634579327519562902613543582623449606741546472920401997930041388553141909069487589461948798111698856100819163407893673249162209631978914843896272256274862501461321020961958367098759183487116417487922645782638510876609728886007680825340200888068103951956139343723
复制代码
发现这个e很大,我们根据题目代码可知它跟n一个数量级。而d很小,想到维纳攻击或低解密指数攻击。但尝试无果有报错。问题就在于他的私钥太小d < N^0.292并不满足维纳或低解密d的要求。
因此我们需要爆出真正的满足题目条件的d,利用LLL-attacks解出d
详细解析可参考:https://github.com/Gao-Chuan/RSA-and-LLL-attacks/blob/master/boneh_durfee.sage
  1. from __future__ import print_function
  2. import time
  3. ############################################
  4. # Config
  5. ##########################################
  6. """
  7. Setting debug to true will display more informations
  8. about the lattice, the bounds, the vectors...
  9. """
  10. debug = True
  11. """
  12. Setting strict to true will stop the algorithm (and
  13. return (-1, -1)) if we don't have a correct
  14. upperbound on the determinant. Note that this
  15. doesn't necesseraly mean that no solutions
  16. will be found since the theoretical upperbound is
  17. usualy far away from actual results. That is why
  18. you should probably use `strict = False`
  19. """
  20. strict = False
  21. """
  22. This is experimental, but has provided remarkable results
  23. so far. It tries to reduce the lattice as much as it can
  24. while keeping its efficiency. I see no reason not to use
  25. this option, but if things don't work, you should try
  26. disabling it
  27. """
  28. helpful_only = True
  29. dimension_min = 7 # stop removing if lattice reaches that dimension
  30. ############################################
  31. # Functions
  32. ##########################################
  33. # display stats on helpful vectors
  34. def helpful_vectors(BB, modulus):
  35.     nothelpful = 0
  36.     for ii in range(BB.dimensions()[0]):
  37.         if BB[ii,ii] >= modulus:
  38.             nothelpful += 1
  39.     print(nothelpful, "/", BB.dimensions()[0], " vectors are not helpful")
  40. # display matrix picture with 0 and X
  41. def matrix_overview(BB, bound):
  42.     for ii in range(BB.dimensions()[0]):
  43.         a = ('%02d ' % ii)
  44.         for jj in range(BB.dimensions()[1]):
  45.             a += '0' if BB[ii,jj] == 0 else 'X'
  46.             if BB.dimensions()[0] < 60:
  47.                 a += ' '
  48.         if BB[ii, ii] >= bound:
  49.             a += '~'
  50.         print(a)
  51. # tries to remove unhelpful vectors
  52. # we start at current = n-1 (last vector)
  53. def remove_unhelpful(BB, monomials, bound, current):
  54.     # end of our recursive function
  55.     if current == -1 or BB.dimensions()[0] <= dimension_min:
  56.         return BB
  57.     # we start by checking from the end
  58.     for ii in range(current, -1, -1):
  59.         # if it is unhelpful:
  60.         if BB[ii, ii] >= bound:
  61.             affected_vectors = 0
  62.             affected_vector_index = 0
  63.             # let's check if it affects other vectors
  64.             for jj in range(ii + 1, BB.dimensions()[0]):
  65.                 # if another vector is affected:
  66.                 # we increase the count
  67.                 if BB[jj, ii] != 0:
  68.                     affected_vectors += 1
  69.                     affected_vector_index = jj
  70.             # level:0
  71.             # if no other vectors end up affected
  72.             # we remove it
  73.             if affected_vectors == 0:
  74.                 print("* removing unhelpful vector", ii)
  75.                 BB = BB.delete_columns([ii])
  76.                 BB = BB.delete_rows([ii])
  77.                 monomials.pop(ii)
  78.                 BB = remove_unhelpful(BB, monomials, bound, ii-1)
  79.                 return BB
  80.             # level:1
  81.             # if just one was affected we check
  82.             # if it is affecting someone else
  83.             elif affected_vectors == 1:
  84.                 affected_deeper = True
  85.                 for kk in range(affected_vector_index + 1, BB.dimensions()[0]):
  86.                     # if it is affecting even one vector
  87.                     # we give up on this one
  88.                     if BB[kk, affected_vector_index] != 0:
  89.                         affected_deeper = False
  90.                 # remove both it if no other vector was affected and
  91.                 # this helpful vector is not helpful enough
  92.                 # compared to our unhelpful one
  93.                 if affected_deeper and abs(bound - BB[affected_vector_index, affected_vector_index]) < abs(bound - BB[ii, ii]):
  94.                     print("* removing unhelpful vectors", ii, "and", affected_vector_index)
  95.                     BB = BB.delete_columns([affected_vector_index, ii])
  96.                     BB = BB.delete_rows([affected_vector_index, ii])
  97.                     monomials.pop(affected_vector_index)
  98.                     monomials.pop(ii)
  99.                     BB = remove_unhelpful(BB, monomials, bound, ii-1)
  100.                     return BB
  101.     # nothing happened
  102.     return BB
  103. """
  104. Returns:
  105. * 0,0   if it fails
  106. * -1,-1 if `strict=true`, and determinant doesn't bound
  107. * x0,y0 the solutions of `pol`
  108. """
  109. def boneh_durfee(pol, modulus, mm, tt, XX, YY):
  110.     """
  111.     Boneh and Durfee revisited by Herrmann and May
  112.    
  113.     finds a solution if:
  114.     * d < N^delta
  115.     * |x| < e^delta
  116.     * |y| < e^0.5
  117.     whenever delta < 1 - sqrt(2)/2 ~ 0.292
  118.     """
  119.     # substitution (Herrman and May)
  120.     PR.<u, x, y> = PolynomialRing(ZZ)
  121.     Q = PR.quotient(x*y + 1 - u) # u = xy + 1
  122.     polZ = Q(pol).lift()
  123.     UU = XX*YY + 1
  124.     # x-shifts
  125.     gg = []
  126.     for kk in range(mm + 1):
  127.         for ii in range(mm - kk + 1):
  128.             xshift = x^ii * modulus^(mm - kk) * polZ(u, x, y)^kk
  129.             gg.append(xshift)
  130.     gg.sort()
  131.     # x-shifts list of monomials
  132.     monomials = []
  133.     for polynomial in gg:
  134.         for monomial in polynomial.monomials():
  135.             if monomial not in monomials:
  136.                 monomials.append(monomial)
  137.     monomials.sort()
  138.    
  139.     # y-shifts (selected by Herrman and May)
  140.     for jj in range(1, tt + 1):
  141.         for kk in range(floor(mm/tt) * jj, mm + 1):
  142.             yshift = y^jj * polZ(u, x, y)^kk * modulus^(mm - kk)
  143.             yshift = Q(yshift).lift()
  144.             gg.append(yshift) # substitution
  145.    
  146.     # y-shifts list of monomials
  147.     for jj in range(1, tt + 1):
  148.         for kk in range(floor(mm/tt) * jj, mm + 1):
  149.             monomials.append(u^kk * y^jj)
  150.     # construct lattice B
  151.     nn = len(monomials)
  152.     BB = Matrix(ZZ, nn)
  153.     for ii in range(nn):
  154.         BB[ii, 0] = gg[ii](0, 0, 0)
  155.         for jj in range(1, ii + 1):
  156.             if monomials[jj] in gg[ii].monomials():
  157.                 BB[ii, jj] = gg[ii].monomial_coefficient(monomials[jj]) * monomials[jj](UU,XX,YY)
  158.     # Prototype to reduce the lattice
  159.     if helpful_only:
  160.         # automatically remove
  161.         BB = remove_unhelpful(BB, monomials, modulus^mm, nn-1)
  162.         # reset dimension
  163.         nn = BB.dimensions()[0]
  164.         if nn == 0:
  165.             print("failure")
  166.             return 0,0
  167.     # check if vectors are helpful
  168.     if debug:
  169.         helpful_vectors(BB, modulus^mm)
  170.    
  171.     # check if determinant is correctly bounded
  172.     det = BB.det()
  173.     bound = modulus^(mm*nn)
  174.     if det >= bound:
  175.         print("We do not have det < bound. Solutions might not be found.")
  176.         print("Try with highers m and t.")
  177.         if debug:
  178.             diff = (log(det) - log(bound)) / log(2)
  179.             print("size det(L) - size e^(m*n) = ", floor(diff))
  180.         if strict:
  181.             return -1, -1
  182.     else:
  183.         print("det(L) < e^(m*n) (good! If a solution exists < N^delta, it will be found)")
  184.     # display the lattice basis
  185.     if debug:
  186.         matrix_overview(BB, modulus^mm)
  187.     # LLL
  188.     if debug:
  189.         print("optimizing basis of the lattice via LLL, this can take a long time")
  190.     BB = BB.LLL()
  191.     if debug:
  192.         print("LLL is done!")
  193.     # transform vector i & j -> polynomials 1 & 2
  194.     if debug:
  195.         print("looking for independent vectors in the lattice")
  196.     found_polynomials = False
  197.    
  198.     for pol1_idx in range(nn - 1):
  199.         for pol2_idx in range(pol1_idx + 1, nn):
  200.             # for i and j, create the two polynomials
  201.             PR.<w,z> = PolynomialRing(ZZ)
  202.             pol1 = pol2 = 0
  203.             for jj in range(nn):
  204.                 pol1 += monomials[jj](w*z+1,w,z) * BB[pol1_idx, jj] / monomials[jj](UU,XX,YY)
  205.                 pol2 += monomials[jj](w*z+1,w,z) * BB[pol2_idx, jj] / monomials[jj](UU,XX,YY)
  206.             # resultant
  207.             PR.<q> = PolynomialRing(ZZ)
  208.             rr = pol1.resultant(pol2)
  209.             # are these good polynomials?
  210.             if rr.is_zero() or rr.monomials() == [1]:
  211.                 continue
  212.             else:
  213.                 print("found them, using vectors", pol1_idx, "and", pol2_idx)
  214.                 found_polynomials = True
  215.                 break
  216.         if found_polynomials:
  217.             break
  218.     if not found_polynomials:
  219.         print("no independant vectors could be found. This should very rarely happen...")
  220.         return 0, 0
  221.    
  222.     rr = rr(q, q)
  223.     # solutions
  224.     soly = rr.roots()
  225.     if len(soly) == 0:
  226.         print("Your prediction (delta) is too small")
  227.         return 0, 0
  228.     soly = soly[0][0]
  229.     ss = pol1(q, soly)
  230.     solx = ss.roots()[0][0]
  231.     #
  232.     return solx, soly
  233. def example():
  234.     ############################################
  235.     # How To Use This Script
  236.     ##########################################
  237.     #
  238.     # The problem to solve (edit the following values)
  239.     #
  240.     # the modulus
  241.     e = 113449247876071397911206070019495939088171696712182747502133063172021565345788627261740950665891922659340020397229619329204520999096535909867327960323598168596664323692312516466648588320607291284630435682282630745947689431909998401389566081966753438869725583665294310689820290368901166811028660086977458571233
  242.     N = 116518679305515263290840706715579691213922169271634579327519562902613543582623449606741546472920401997930041388553141909069487589461948798111698856100819163407893673249162209631978914843896272256274862501461321020961958367098759183487116417487922645782638510876609728886007680825340200888068103951956139343723
  243.     # the hypothesis on the private exponent (the theoretical maximum is 0.292)
  244.     delta = .27 # this means that d < N^delta
  245.     #
  246.     # Lattice (tweak those values)
  247.     #
  248.     # you should tweak this (after a first run), (e.g. increment it until a solution is found)
  249.     m = 6 # size of the lattice (bigger the better/slower)
  250.     # you need to be a lattice master to tweak these
  251.     t = int((1-2*delta) * m)  # optimization from Herrmann and May
  252.     X = 2*floor(N^delta)  # this _might_ be too much
  253.     Y = floor(N^(1/2))    # correct if p, q are ~ same size
  254.     #
  255.     # Don't touch anything below
  256.     #
  257.     # Problem put in equation
  258.     P.<x,y> = PolynomialRing(ZZ)
  259.     A = int((N+1)/2)
  260.     pol = 1 + x * (A + y)
  261.     #
  262.     # Find the solutions!
  263.     #
  264.     # Checking bounds
  265.     if debug:
  266.         print("=== checking values ===")
  267.         print("* delta:", delta)
  268.         print("* delta < 0.292", delta < 0.292)
  269.         print("* size of e:", int(log(e)/log(2)))
  270.         print("* size of N:", int(log(N)/log(2)))
  271.         print("* m:", m, ", t:", t)
  272.     # boneh_durfee
  273.     if debug:
  274.         print("=== running algorithm ===")
  275.         start_time = time.time()
  276.     solx, soly = boneh_durfee(pol, e, m, t, X, Y)
  277.     # found a solution?
  278.     if solx > 0:
  279.         print("=== solution found ===")
  280.         if False:
  281.             print("x:", solx)
  282.             print("y:", soly)
  283.         d = int(pol(solx, soly) / e)
  284.         print("private key found:", d)
  285.     else:
  286.         print("=== no solution was found ===")
  287.     if debug:
  288.         print(("=== %s seconds ===" % (time.time() - start_time)))
  289. if __name__ == "__main__":
  290.     example()
复制代码

之后直接解即可
  1. import gmpy2
  2. from Crypto.Util.number import *
  3. d=663822343397699728953336968317794118491145998032244266550694156830036498673227937
  4. c = 6838759631922176040297411386959306230064807618456930982742841698524622016849807235726065272136043603027166249075560058232683230155346614429566511309977857815138004298815137913729662337535371277019856193898546849896085411001528569293727010020290576888205244471943227253000727727343731590226737192613447347860
  5. n=116518679305515263290840706715579691213922169271634579327519562902613543582623449606741546472920401997930041388553141909069487589461948798111698856100819163407893673249162209631978914843896272256274862501461321020961958367098759183487116417487922645782638510876609728886007680825340200888068103951956139343723
  6. m=pow(c,d,n)
  7. print(long_to_bytes(m))
  8. #DASCTF{6f4fadce-5378-d17f-3c2d-2e064db4af19}
复制代码
matrixequation

题目
  1. from sage.all import *
  2. import string
  3. from myflag import finalflag, flag
  4. A = matrix([[0 for i in range(11)] for i in range(11)])
  5. for k in range(len(flag)):
  6.         i, j = 5*k // 11, 5*k % 11
  7.         A[i, j] = alphabet.index(flag[k])
  8. from hashlib import md5
  9. assert(finalflag == 'DASCTF{' + f'{md5(flag.encode()).hexdigest()}' + '}')
  10. key = getKey()
  11. R, leftmatrix, matrixU = key
  12. tmpMatrix = leftmatrix * matrixU
  13. X = A + R
  14. Y = tmpMatrix * X
  15. E = leftmatrix.inverse() * Y
  16. f = open('output','w')
  17. f.write(str(E)+'\n')
  18. f.write(str(leftmatrix * matrixU * leftmatrix)+'\n')
  19. f.write(str(f'{leftmatrix.inverse() * tmpMatrix**2 * leftmatrix}\n'))
  20. f.write(str(f'{R.inverse() * tmpMatrix**8}\n'))
  21. A = matrix([[0 for i in range(11)] for i in range(11)])
  22. for k in range(len(flag)):
  23.         i, j = 5*k // 11, 5*k % 11
  24.         A[i, j] = alphabet.index(flag[k])
  25. from hashlib import md5
  26. assert(finalflag == 'DASCTF{' + f'{md5(flag.encode()).hexdigest()}' + '}')
  27. key = getKey()
  28. R, leftmatrix, matrixU = key
  29. tmpMatrix = leftmatrix * matrixU
  30. X = A + R
  31. Y = tmpMatrix * X
  32. E = leftmatrix.inverse() * Y
  33. f = open('output','w')
  34. f.write(str(E)+'\n')
  35. f.write(str(leftmatrix * matrixU * leftmatrix)+'\n')
  36. f.write(str(f'{leftmatrix.inverse() * tmpMatrix**2 * leftmatrix}\n'))
  37. f.write(str(f'{R.inverse() * tmpMatrix**8}\n'))
复制代码
  1. [53 19 40  7 22 46 69 11 31 48 57]
  2. [66 47 13 39  1 34 26 15 52 18 55]
  3. [47  1  9 14 58 34 40 27  9  1 36]
  4. [36 19 38 30 39 30 21 27  1  4 13]
  5. [25 10 52 45 69 63  3 64 13 51 44]
  6. [48  2 64 19 49 51 39 29 22 35 17]
  7. [69 48 27 17 15 42 60 42 15 43  7]
  8. [39 37 56  5 49 57 51 49  3 53 25]
  9. [50 39  9 30 19 63 20 12  8 55 35]
  10. [24 26 58 56 43 70 66 27 32 70 59]
  11. [ 9 34 18 31 65  3 48 39 39 40 53]
  12. [62 17 50 41  4  7  5  4 20 15 45]
  13. [ 8 59 38 18 42 31 60 58 35  1 46]
  14. [25 20 45 31 69 45 59 34 46 63 69]
  15. [ 6  2 65 44 53 59 11 52 37 48 40]
  16. [33 52  4  9  6  7 34  4 59 59  6]
  17. [65 64 53 22 49 22 58 50 48 66 25]
  18. [ 0 43 42 68 16 35 20 69  1 14 18]
  19. [23 61 44 20 30 38 10 68 52 39  4]
  20. [ 1  8 31 31 11 54 41 70 49 40  1]
  21. [58 29 28 60 23 13 67 33 14 15  2]
  22. [23 25 70  1 13 57 52 21 54 64 26]
  23. [10  5 15 49 12 53 46 23 44 40 67]
  24. [41 21 62 22 40 69 59  0 28 42 52]
  25. [ 9 66 44  3 48  2 53  8 46 52  4]
  26. [ 8 50 15 56 16 31 47  5 70  6 43]
  27. [59 34 48  5 55 50 61 39 38  7 60]
  28. [46 46  9 36 12 49 48 30 64 30 45]
  29. [62 33  2 19  3 15 69 25  0 51 69]
  30. [27 10 48 26 11 32  1 40 29 59 16]
  31. [18 60 33 64 15 41 22  9 11 60 22]
  32. [32 52 15 27  1 63 55 54 70 17 52]
  33. [22 27 33 38 68 36 59 17 64 18 65]
  34. [43 68 27 18 44 32 47 21 46 44 14]
  35. [12 52 44 61 26 34 53 36 18  3 61]
  36. [10 59 14  2 42 63 31  9 53  4 55]
  37. [63 48 59 11 54  9 54 50 68  5 28]
  38. [66 12 58 68 52 50  5 39 19  6 70]
  39. [42 23 24 54 54 64  3 16 20 67 28]
  40. [60 68 63 63 34  7  0 36  3 22 68]
  41. [10 23  0  9 64  0 52  1 24 52 21]
  42. [65 52 42  9 43 39 15  3 36 28 28]
  43. [21 32 35 69 49 55  0 23  4 32 42]
  44. [61 52 49 46 50 34 70 35 39  1 16]
复制代码
我的解答:
线性代数问题,题目把flag转成了矩阵A,我们要做的就是求出A
已知题目信息(由于变量较长,这里用缩略单词代替)
R, S = random_matrix
S = L * U
E = L^(-1) * S * (A + R)
a = L * U * L
b = L^(-1) * S^2 * L
c = R^(-1) * S^8
求解过程
b * a^(-1) = L^(-1) * S  (S = L * U = U * L)
a * b^(-1) * E = A + R   (上式^(-1) * E)
a * b * a^(-1) = S^2     (define ss)
c * ss^(-4) = R^(-1)
a * b^(-1) * E - c * ss^(-4) = A  (solve)
exp:
  1. import re
  2. import string
  3. alphabet = string.printable[:71]
  4. p = len(alphabet)
  5. with open('output', 'r') as f:
  6.   data = f.read().split('\n')[:-1]
  7. data = [re.findall(r'\d+', d) for d in data]
  8. data = [[Integer(di) for di in d] for d in data]
  9. n = 11
  10. E = matrix(GF(p), data[:11])
  11. LUL = matrix(GF(p), data[11: 22])
  12. ULUL = matrix(GF(p), data[22: 33])
  13. RiLU8 = matrix(GF(p), data[33: 44])
  14. Ui = LUL * ULUL^(-1)
  15. Ri = RiLU8 * Ui * (ULUL^(-1))^3 * LUL^(-1)
  16. U = Ui^(-1)
  17. assert Ri * (LUL * U)^4 == RiLU8
  18. R = Ri^(-1)
  19. AR = Ui * E
  20. A = AR - R
  21. print(A)
  22. flag = ''
  23. for k in range(24):
  24.   i, j = 5*k // 11, 5*k % 11
  25.   flag += alphabet[A[i, j]]
  26. print(flag)
  27.   
  28. from hashlib import md5
  29. flag = 'DASCTF{' + f'{md5(flag.encode()).hexdigest()}' + '}'
  30. print(flag)
复制代码

 


 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

来自云龙湖轮廓分明的月亮

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表