2022网鼎杯青龙组密码wp

crypto091

根据描述和其中提到的论文,Hash值为电话号码的sha256

170号段首批放号的联通号码以1709开头,直接爆破即可

x = 'c22a563acc2a587afbfaaaa6d67bc6e628872b00bd7e998873881f7c6fdc62fc'
import hashlib
n = b'861709'
s = list('0123456789'.strip())
import itertools
for i in itertools.product(s,repeat = 7):
    d = ''.join(i).encode()
    g = n+d
    if hashlib.sha256(g).hexdigest() == x:
        print(g)
        break
# b'8617091733716'

crypto162

矩阵快速幂

通项公式为 f ( n ) = a ∗ f ( n − 1 ) + b ∗ f ( n − 2 ) + c ∗ f ( n − 3 ) f(n) = a*f(n-1)+b*f(n-2)+c*f(n-3) f(n)=af(n1)+bf(n2)+cf(n3)

转成矩阵相乘的形式为:
( a b c 1 0 0 0 1 0 ) ∗ ( f ( n − 1 ) f ( n − 2 ) f ( n − 3 ) ) = ( f ( n ) f ( n − 1 ) f ( n − 2 ) ) \begin{pmatrix} a & b & c\\ 1 & 0 & 0\\ 0 & 1 & 0\\ \end{pmatrix}*\begin{pmatrix} f(n-1)\\ f(n-2)\\ f(n-3)\\ \end{pmatrix}=\begin{pmatrix} f(n)\\ f(n-1)\\ f(n-2)\\ \end{pmatrix} a10b01c00 f(n1)f(n2)f(n3) = f(n)f(n1)f(n2)
则有:
( f ( n ) f ( n − 1 ) f ( n − 2 ) ) = ( a b c 1 0 0 0 1 0 ) n − 5 ∗ ( f ( 5 ) f ( 4 ) f ( 3 ) ) \begin{pmatrix} f(n)\\ f(n-1)\\ f(n-2)\\ \end{pmatrix}={\begin{pmatrix} a & b & c\\ 1 & 0 & 0\\ 0 & 1 & 0\\ \end{pmatrix}}^{n-5}*\begin{pmatrix} f(5)\\ f(4)\\ f(3)\\ \end{pmatrix} f(n)f(n1)f(n2) = a10b01c00 n5 f(5)f(4)f(3)

from hashlib import md5, sha256
from Crypto.Cipher import AES

cof_t = [[353, -1162, 32767], [206, -8021, 42110], [262, -7088, 31882], [388, -6394, 21225], [295, -9469, 44468], [749, -3501, 40559], [528, -2690, 10210], [354, -5383, 18437], [491, -8467, 26892], [932, -6984, 20447], [731, -6281, 11340], [420, -5392, 44071], [685, -6555, 40938], [408, -8070, 47959], [182, -9857, 49477], [593, -3584, 49243], [929, -7410, 31929], [970, -4549, 17160], [141, -2435, 36408], [344, -3814, 18949], [291, -7457, 40587], [765, -7011, 32097], [700, -8534, 18013], [267, -2541, 33488], [249, -8934, 12321], [589, -9617, 41998], [840, -1166, 22814], [947, -5660, 41003], [206, -7195, 46261], [784, -9270, 28410], [338, -3690, 19608], [559, -2078, 44397], [534, -3438, 47830], [515, -2139, 39546], [603, -6460, 49953], [234, -6824, 12579], [805, -8793, 36465], [245, -5886, 21077], [190, -7658, 20396], [392, -7053, 19739], [609, -5399, 39959], [479, -8172, 45734], [321, -7102, 41224], [720, -4487, 11055], [208, -1897, 15237], [890, -4427, 35168], [513, -5106, 45849], [666, -1137, 23725], [755, -6732, 39995], [589, -6421, 43716], [866, -3265, 30017], [416, -6540, 34979], [840, -1305, 18242], [731, -6844, 13781], [561, -2728, 10298], [863, -5953, 23132], [204, -4208, 27492], [158, -8701, 12720], [802, -4740, 16628], [491, -6874, 29057], [531, -4829, 29205], [363, -4775, 41711], [319, -9206, 46164], [317, -9270, 18290], [680, -5136, 12009], [880, -2940, 34900], [162, -2587, 49881], [997, -5265, 20890], [485, -9395, 23048], [867, -1652, 18926], [691, -7844, 11180], [355, -5990, 13172], [923, -2018, 23110], [214, -4719, 23005], [921, -9528, 29351], [349, -7957, 20161], [470, -1889, 46170], [244, -6106, 23879], [419, -5440, 43576], [930, -1123, 29859], [151, -5759, 23405], [843, -6770, 36558], [574, -6171, 33778], [772, -1073, 44718], [932, -4037, 40088], [848, -5813, 27304], [194, -6016, 39770], [966, -6789, 14217], [219, -6849, 40922], [352, -6046, 18558], [794, -8254, 29748], [618, -5887, 15535], [202, -9288, 26590], [611, -4341, 46682], [155, -7909, 16654], [935, -5739, 39342], [998, -6538, 24363], [125, -5679, 36725], [507, -7074, 15475], [699, -5836, 47549]]


def cal(i, cof):
    if i < 3:
        return i + 1
    else:
        return cof[2] * cal(i - 3, cof) + cof[1] * cal(i - 2, cof) + cof[0] * cal(i - 1, cof)


def cal_m(i, cof):
    M = Matrix(ZZ, [[cof[0], cof[1], cof[2]], [1, 0, 0], [0, 1, 0]])
    b = vector(ZZ, [cal(5, cof), cal(4, cof), cal(3, cof)])
    b = M ^ (i - 5) * b
    return int(b[0])


s = 0
for i in range(100):
    s += cal_m(200000, cof_t[i])

s = str(s)[-2000:-1000]
key = bytes.fromhex(md5(s.encode()).hexdigest())
check = sha256(key).hexdigest()
verify = '2cf44ec396e3bb9ed0f2f3bdbe4fab6325ae9d9ec3107881308156069452a6d5'
assert (check == verify)
aes = AES.new(key, AES.MODE_ECB)
# 4f12b3a3eadc4146386f4732266f02bd03114a404ba4cb2dabae213ecec451c9d52c70dc3d25154b5af8a304afafed87
c = '4f12b3a3eadc4146386f4732266f02bd03114a404ba4cb2dabae213ecec451c9d52c70dc3d25154b5af8a304afafed87'
c = bytes.fromhex(c)
print(aes.decrypt(c))
# b'flag{519427b3-d104-4c34-a29d-5a7c128031ff}\x00\x00\x00\x00\x00\x00'

crypto405

给了42个 g r a s s h o p p e r ∗ k 0 ∗ k 1 ∗ k 2 ∗ k 3 ∗ k 4 grasshopper*k0* k1* k2* k3* k4 grasshopperk0k1k2k3k4,不过每组 k k k都是有一定的规律

42长可以猜测flag 的形式为flag{uuid4}

那么前面5个 g r a s s h o p p e r grasshopper grasshopper就是已知的,列出开头五组的式子

flag = b'flag{'
var('k0 k1 k2 k3 k4')
k = [k0, k1, k2, k3, k4]
res = []
for i in range(len(flag)):
    grasshopper = flag[i]
    for j in range(5):
        k[i] = grasshopper = grasshopper * k[j]
    res.append(grasshopper)
print(res)

(C:\Users\mxx307\AppData\Roaming\Typora\typora-user-images\image-20220826164402055.png)]

这里就有五组等式,本来想着通过z3直接求,不过很遗憾不行(但是用Gröbner基能算)

后来又观察到,如果将乘法看成加法,次幂看成乘法,那么该五组式子就可以看成线性方程组,这样子更方便我们求解(实际就是消元法解方程)
( 1 1 1 1 1 5 4 3 2 1 15 10 6 3 1 35 20 10 4 1 70 35 15 5 1 ) \begin{pmatrix} 1 & 1 & 1 & 1 & 1\\ 5 & 4 & 3 & 2 & 1\\ 15 & 10 & 6 & 3 & 1\\ 35 & 20 & 10 & 4 & 1\\ 70 & 35 & 15 & 5 & 1\\ \end{pmatrix} 151535701410203513610151234511111
将该矩阵通过行列变换得到单位矩阵,那么就能求出 k k k(行列变化的加法和乘法分别为乘法和次幂,减法为乘上逆元)

其中我们并不知道 p p p,但 p p p m a x ( g r a s s h o p p e r ) < p < 2 16 max(grasshopper)<p<2^{16} max(grasshopper)<p<216的素数,可以直接爆破,通过求出 k k k后再爆破uuid4求出 g r a s s h o p p e r grasshopper grasshopper与原来 f l a g flag flag求出来的值相比较即可

from Crypto.Util.number import *
from gmpy2 import *


def tran1(n, base, arr, x, y):
    r = []
    for i in range(5):
        r.append(base[i] * n)
    res = pow(x, n, p)

    for i in range(5):
        r[i] = r[i] - arr[i]
    res = res * inverse(y, p) % p
    return r, res


def tran2(n, base, arr, x, y):
    r = []
    for i in range(5):
        r.append(base[i] * n)
    res = pow(x, n, p)

    for i in range(5):
        r[i] = arr[i] - r[i]
    res = y * inverse(res, p) % p
    return r, res


f = open('output.txt', 'r')
res = []
for i in range(42):
    res.append(int(f.readline()[-5:-1], 16))
y = res[:5]
yy = [102, 1192407267456, 1918196473060530916599580974905403195260928, 56112321905504104058889432264614118677688107359359075763851172322711550767834986156510191423865157053692191440896, 53396244662367707127856864007524389027579357260572582679744127850279999404450619312604004485139827409110793046460181646479623909080635340073160838110289140978788817626824929446784411034165296270303004366240008622426141394072733814130556872463873302593536]
p = next_prime(max(res))
while p < 2 ** 16:
    y = res[:5].copy()
    for i in range(5):
        y[i] = y[i] * inverse(yy[i], p)
    x = [[1, 1, 1, 1, 1], [5, 4, 3, 2, 1], [15, 10, 6, 3, 1], [35, 20, 10, 4, 1], [70, 35, 15, 5, 1]]
    for j in range(0, 4):
        for i in range(j + 1, 5):
            x[i], y[i] = tran1(x[i][j], x[j], x[i], y[j], y[i])
    for j in range(4, 0, -1):
        for i in range(j):
            x[i], y[i] = tran2(x[i][j], x[j], x[i], y[j], y[i])
    flag = b'flag{'
    for i in range(len(flag)):
        grasshopper = flag[i]
        for j in range(5):
            y[j] = grasshopper = grasshopper * y[j] % p
    for k in range(36):
        for i in '0123456789abcdef-':
            kkk = y.copy()
            grasshopper = ord(i)
            for j in range(5):
                kkk[j] = grasshopper = grasshopper * kkk[j] % p
            if grasshopper == res[5 + k]:
                y = kkk.copy()
                if p == 59441:
                    print(i, end='')
                # print(i,p)
                break
    p = next_prime(p)
# flag{749d39d4-78db-4c55-b4ff-bca873d0f18e}
  y = kkk.copy()
                if p == 59441:
                    print(i, end='')
                # print(i,p)
                break
    p = next_prime(p)
# flag{749d39d4-78db-4c55-b4ff-bca873d0f18e}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mxx307

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值