DASCTF2024

DASCTF2024

Crypto

数论的香氛

题目:

from sympy import isprime
from sympy.ntheory import legendre_symbol
import random
from Crypto.Util.number import bytes_to_long

k=79    #<-- i couldn't stress more

def get_p():
    global k
    while True:
        r=random.randint(2**69,2**70)
        p=2**k*r+1
        if isprime(p):
            return p
        else:
            continue

def get_q():
    while True:
        r=random.randint(2**147,2**148)
        q=4*r+3
        if isprime(q):
            return q
        else:
            continue


def get_y():
    global n,p,q
    while True:
        y=random.randint(0,n-1)
        if legendre_symbol(y,p)==1:
            continue
        elif legendre_symbol(y,q)==1:
            continue
        else:
            return y


flag=b'DASCTF{redacted:)}'
flag_pieces=[flag[0:10],flag[11:21],flag[22:32],flag[33:43],flag[44:]]
#assert int(bytes_to_long((flag_pieces[i] for i in range(5)))).bit_length()==k

p=get_p()
q=get_q()
n=p*q
print(f'{n=}')

y=get_y()
print(f'{y=}')


def encode(m):
    global y,n,k
    x = random.randint(1, n - 1)
    c=(pow(y,m,n)*pow(x,pow(2,k),n))%n
    return c

cs=[]
for i in range(len(flag_pieces)):
    ci=encode(bytes_to_long(flag_pieces[i]))
    cs.append(ci)

print(f'{cs=}')

'''
n=542799179636839492268900255776759322356188435185061417388485378278779491236741777034539347
y=304439269593920283890993394966761083993573819485737741439790516965458877720153847056020690
cs=[302425991290493703631236053387822220993687940015503176763298104925896002167283079926671604, 439984254328026142169547867847928383533091717170996198781543139431283836994276036750935235, 373508223748617252014658136131733110314734961216630099592116517373981480752966721942060039, 246328010831179104162852852153964748882971698116964204135222670606477985487691371234998588, 351248523787623958259846173184063420603640595997008994436503031978051069643436052471484545]
'''

首先注意到n很短,使用sage可以在大概十几分钟分解n(实际上factordb.com可以直接分解n,比赛时候忘记用了)

y设置为J(y/p) = J(y/q) = -1,很容易想到Goldwasser-Micali公钥加密系统,但Goldwasser-Micali 算法一次只能加密1bit,而题目中加密长度达到了k bits,且在计算c时多乘了pow(x,pow(2,k),n)。这实际上是为减少带宽的浪费而实现的更高效的GM算法。于是我们可以找到论文Efficient Cryptosystems From 2^k-th Power Residue Symbols,利用论文给出的方法我们便可以编写解密脚本

exp

from sympy import mod_inverse
from Crypto.Util.number import *

def decrypt(c, p, k, D):
    m = 0
    B = 1
    C = pow(c, (p - 1) // (2**k), p)
    
    for j in range(1, k):
        z = pow(C, 2**(k-j), p)
        if z != 1:
            m += B
            C = (C * D) % p
        B <<= 1  # B = 2 * B
        D = (D * D) % p
    
    if C != 1:
        m += B
    
    return m

q = 863327174253852394776516978368858092781662547
p = 628729403897154553626034231171921094272614401
n = 542799179636839492268900255776759322356188435185061417388485378278779491236741777034539347
y = 304439269593920283890993394966761083993573819485737741439790516965458877720153847056020690
k = 79

k = 79
D = pow(y, -(p - 1) // 2**k, p)  
print(D)
cs = [
    302425991290493703631236053387822220993687940015503176763298104925896002167283079926671604,
    439984254328026142169547867847928383533091717170996198781543139431283836994276036750935235,
    373508223748617252014658136131733110314734961216630099592116517373981480752966721942060039,
    246328010831179104162852852153964748882971698116964204135222670606477985487691371234998588,
    351248523787623958259846173184063420603640595997008994436503031978051069643436052471484545
]

decrypted_messages = [decrypt(ci, p, k, D) for ci in cs]

for i, m in enumerate(decrypted_messages):
    print(f"Decrypted message {i}: {m}")
    print(long_to_bytes(m))

DASCTF{go0_j06!let1sm0v31n_t0_th3r_chanlenges~>_<}

MISC

弹道偏下

打开流量包,发现是SMB2流量加密

按照以下格式构造hash

username::domain::NTLMServerChallenge:NTProofStr:NTLMv2Response

share::MicrosoftAccount:0a08d9f15eb53eea:a20aec951c89961f2e81bf0917d8990a:0101000000000000cfebd19d3636db01022ada3cfbb5b30e0000000002001e004400450053004b0054004f0050002d004800440039004b0051004e00540001001e004400450053004b0054004f0050002d004800440039004b0051004e00540004001e004400450053004b0054004f0050002d004800440039004b0051004e00540003001e004400450053004b0054004f0050002d004800440039004b0051004e00540007000800cfebd19d3636db01060004000200000008003000300000000000000001000000002000004c3c615542417f8e002c772c6064cc84d886fec17c1ed7cceea68daf7f6954fc0a001000000000000000000000000000000000000900280063006900660073002f003100390032002e003100360038002e003100340039002e003100350035000000000000000000

hashcat爆破

hashcat -a 0 -m 5600  v2.txt ./rockyou.txt  --force

解密流量包,导出doc文件

winhex打开明显是逆序,拿工具改一下

(比赛时候只做到这里~~ಠ_ಠ)

新建一个doc文件,对比发现少了一大段文件头,把文件头复制过去

打开doc发现需要密码,放passware跑

img

得到密码36521478(和刚才的SMB2密码一样)打开文件flag就在第一行

flag{u_are_a_g00d_OLE_Repairer}

RE

tryre


换表base64加密

逐字节异或2

脚本如下:

import base64
import string
encode = "M@ASL3MF`uL3ICT2IhUgKSD2IeDsICH7Hd26HhQgKSQhNCX7TVL3UFMeHi2?"
str1 = ""
for i in range(len(encode)):
  str1 = str1 + chr(ord(encode[i]) ^ 2)
string1 = "ZYXABCDEFGHIJKLMNOPQRSTUVWzyxabcdefghijklmnopqrstuvw0123456789+/"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
print (str(base64.b64decode(str1.translate(str.maketrans(string1,string2)))))

得到flag:DASCTF{454646fa-2462-4392-82ea-5f809ad5ddc2}

posted @ 2024-12-22 17:05  miffya  阅读(39)  评论(0)    收藏  举报