zer0ptsCTF 2022

zer0pts CTF

与HF同期的一个国外的比赛,简单地记录一下

anti_fermat

附件

题目提示了费马分解,我们看它pq的生成过程

q=p^(1<<1024-1)+r

于是我们可知p+q=21024-1+r

按照费马分解的方法构造等式

n=\((\frac{p+q}{2})^2-(\frac{p-q}{2})^2=(\frac{2^{1024}-1+r}{2})^2-s^2\)

r一般不会超过220,直接爆破即可

import gmpy2
from Crypto.Util.number import *
n = 0x1ffc7dc6b9667b0dcd00d6ae92fb34ed0f3d84285364c73fbf6a572c9081931be0b0610464152de7e0468ca7452c738611656f1f9217a944e64ca2b3a89d889ffc06e6503cfec3ccb491e9b6176ec468687bf4763c6591f89e750bf1e4f9d6855752c19de4289d1a7cea33b077bdcda3c84f6f3762dc9d96d2853f94cc688b3c9d8e67386a147524a2b23b1092f0be1aa286f2aa13aafba62604435acbaa79f4e53dea93ae8a22655287f4d2fa95269877991c57da6fdeeb3d46270cd69b6bfa537bfd14c926cf39b94d0f06228313d21ec6be2311f526e6515069dbb1b06fe3cf1f62c0962da2bc98fa4808c201e4efe7a252f9f823e710d6ad2fb974949751
c = 0x60160bfed79384048d0d46b807322e65c037fa90fac9fd08b512a3931b6dca2a745443a9b90de2fa47aaf8a250287e34563e6b1a6761dc0ccb99cb9d67ae1c9f49699651eafb71a74b097fc0def77cf287010f1e7bd614dccfb411cdccbb84c60830e515c05481769bd95e656d839337d430db66abcd3a869c6348616b78d06eb903f8abd121c851696bd4cb2a1a40a07eea17c4e33c6a1beafb79d881d595472ab6ce3c61d6d62c4ef6fa8903149435c844a3fab9286d212da72b2548f087e37105f4657d5a946afd12b1822ceb99c3b407bb40e21163c1466d116d67c16a2a3a79e5cc9d1f6a1054d6be6731e3cd19abbd9e9b23309f87bfe51a822410a62
t1=2**1024-1
for i in range(10000):
    t2,b=gmpy2.iroot((t1//2+i)**2-n,2)
    if b:
        k=2*t2
        t3=gmpy2.iroot((k**2)+4*n,2)[0]
        p=(k+t3)//2
        q=(t3-k)//2
        phi=(p-1)*(q-1)
        d=gmpy2.invert(65537,phi)
        m=pow(c,d,n)
        print(long_to_bytes(m))

CurveCrypto

附件

这题虽然不难但挺有意思的,类似于在椭圆曲线上任取一点G,通过对G的点加得到kG

然后对明文分块加密,依次使用kG进行异或操作

看上去和OTP类似,但是他这个密钥似乎不是很随机呀

利用G和2G之间的相关性等式列出式子,且考虑到异或过程中只会改变gx或gy的最后128bits,所以可以采用copper的方式还原

我自己直接套用的多元copper的脚本,后面在大佬那学了一手格子的构造方式

n = 144119247523820514307319742558945817289524321678464785828165262389987364282241677120346992289602773032781170623185859522408681068717004227361637296377314973988883717763449514502353544535632434189976809320943402560377421207936239458384129077990667822889168041784489265932700188699685494064706711885776064499497
a = 83982245487363010227377287615815704138676734572052340268107937333404040064487258387610318909300475704005267406361509228314981566916144028418544919408625857597243933586742790305821574823017061268314657578742703998273111267249007415214833152992932175602495617018238154444547422725699672732735594492967242602718
b = 102854241650706614574910858961148621902783569513613650939938174283440416794379436560775021794677794290971284767314108620894847399989166711219489947662922391647064573171363714323032220660223765035347554282052095512011142748460282601639626032525448005114625186640435086840602281790716023653081557628791656792754
c = [105112301098281496097034027523577403453326764144228787624401074405541577932642530851395484380691290162552636478481380927941044566041120344238783491322553291628678134801814105484196704974017218455216419335693731277825573231392222665423245586612395848380318111988284920983149197374154699808776545479724047776709, 119931822446994265076022490333904239240145849067899601686086810952135061724293475540637951596476598377673280140779509869539582077226280886787012312965074972316057414014195571814522208145587153069696640304889800585974357119323578638404957302760851214606619517664508954712497284900223656294050022339709410514520, 77449803463514047535477961978015960018035778347793833401263588747978475501148536780819549296447786417024775899457091074251167349568353877838782428368954481576827862607179873977973077737374411980559467128298050283927229354740670622117284854556777626729609958202274963553796799701913426256413699327094959918436, 19881898638980767541769585302774976337079209934548061143259050559139791898245439933411471322660256972236103364955342341822881304403603105610433373205174678091884754857958259183427619764249723943787639988589593508171175819610469625589807019978156747244656206732357606116993349990555417285468500357366492529137]
m=[]
def recover(x,y):
    M=Matrix(ZZ,[[1,0,0,0,0,0,1*2^1024],
                [0,2^128,0,0,0,0,3*x*2^1024],
                [0,0,2^256,0,0,0,(3*x^2+a)*2^1024],
                [0,0,0,2^128,0,0,-1*2^1024],
                [0,0,0,0,2^256,0,-2*y*2^1024],
                [0,0,0,0,0,2^1024,(x^3+a*x-y^2+b)*2^1024],
                [0,0,0,0,0,0,n*2^1024]])
    v=M.LLL()[-1]
    print(v)
    dx=int(v[2])//2^256
    dy=int(v[4])//2^256
    gx=x+dx
    gy=y+dy
    m.append(x^^gx)
    m.append(y^^gy)
recover(c[0],c[1])
recover(c[2],c[3])
out=b''
for i in m:
    out+=bytes.fromhex(hex(i)[2:])
print(out)

EDDH

附件

曲线加密所用的是Twisted Edwards,但是这里并不需要用到它的过多性质

仔细看看会发现他这里仍然没有检测输入点的合理性,之前是有见过ecc上的invalid point attack,所以考虑这里是否能构造出一些神奇的东西

image

在上面这个等式中我们令G(0,2)

=>新点的坐标为kG(0,2k)

利用交互过程中的数据处理上的一些问题可以把y坐标完整泄露,考虑到曲线所在的GF(p)上且p并不大,离散对数问题可解

首先输入00

注意到recv函数不进行padding,所以此处的异或不会带出y坐标

send函数有进行pad,于是总共只会异或一次y坐标,即收取的数据的后32个二进制数即为y的值

然后再输入flag的16进制最后需要加00,否则unpad的时候不会停住

share直接利用第一步解出的s在(0,2)上操作

先异或再解AES即可

import gmpy2
def xor(xs, ys):
    return bytes(x^^y for x, y in zip(xs, ys))

def pad(b, l):
    return b + b"\0" + b"\xff" * (l - (len(b) + 1))

def unpad(b):
    l = -1
    while b[l] != 0:
        l -= 1
    return b[:l]

def add(P, Q):
    (x1, y1) = P
    (x2, y2) = Q

    x3 = (x1*y2 + y1*x2) * gmpy2.invert(1 + d*x1*x2*y1*y2, p) % p
    y3 = (y1*y2 - a*x1*x2) * gmpy2.invert(1 - d*x1*x2*y1*y2, p) % p
    return (x3, y3)

def mul(x, P):
    Q = (0, 1)
    x = x % q
    while x > 0:
        if x % 2 == 1:
            Q = add(Q, P)
        P = add(P, P)
        x = x >> 1
    return Q

def to_bytes(P):
    x, y = P
    return int(x).to_bytes(n // 8, "big") + int(y).to_bytes(n // 8, "big")

n = 256
p = 64141017538026690847507665744072764126523219720088055136531450296140542176327
a = 362
d = 1
q = 64141017538026690847507665744072764126693080268699847241685146737444135961328
c = 4
gx = 36618472676058339844598776789780822613436028043068802628412384818014817277300
gy = 9970247780441607122227596517855249476220082109552017755637818559816971965596
s=0x931c3293ecc643523871ef406a939d0edc85fee2102f092f1bff73163467a160
c='d857a0a3dde42423ff12e2f0d08c6802833226bde3b3478a2f9c1cdbb27c98a966e0376268fe9bbfd5eba2861d79de752385fee2102f092f1bff73163467a160'
s=s^^(2^256-1)
G=GF(p)
s=G(s)
g=G(2)
e=discrete_log(s,g)
print(mul(e,(gx,gy)))
share=to_bytes(mul(e,(0,2)))
cc=xor(bytes.fromhex(c),share)
print(cc)
print(e)
#------
from hashlib import sha256
from Crypto.Cipher import AES
from Crypto.Util.number import long_to_bytes
c=b"\xd8W\xa0\xa3\xdd\xe4$#\xff\x12\xe2\xf0\xd0\x8ch\x02\x832&\xbd\xe3\xb3G\x8a/\x9c\x1c\xdb\xb2|\x98\xa9\n\x03\xfa\x0e{\xc7'\x12\x12e\xb29\x88\x15\xbc\x84\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
s=14184253412972592766450738355089096014649994062985550721785814980025031404544
aes = AES.new(key=sha256(long_to_bytes(s)).digest(), mode=AES.MODE_ECB)
print(aes.decrypt(c))

后面还有两个比较好的题目但是有点难留给以后复现吧

🏃

posted @ 2022-03-22 09:49  hash_hash  阅读(452)  评论(0)    收藏  举报