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跑

得到密码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}
本文来自博客园,作者:miffya,转载请注明原文链接:https://www.cnblogs.com/miffya/p/18622265

浙公网安备 33010602011771号