上海市大学生CTF(华东杯CTF) Crypto 全解

Crypto


bird

什么鸟???

google搜一下bird cipher就找到了

在线解密

https://www.dcode.fr/birds-on-a-wire-cipher


dirty_flag

多线程爆破,什么tree构造不用关,爆破完了适当调顺序就OK了

对4位爆破是秒解

然后对6位使用多进程,5分钟可解

exp

import hashlib
import string
from multiprocessing import Pool
from tqdm import *
FLAG='flag{09***********************************755ca2}'
# 45ef
# 5a04
# bde0
all_hash=['55cfb0b1cf88f01fc9ed2956a02f90f9014d47ad303dbb52fe7d331ddea37d88',
   'b665a90585127215c576871b867e203e5a00107d11824d34ba2cb5f7c4fd9682',
   '4cac70a760893573e0e5e90f44547e9dc5a53a9f414d36bc24d2d6fd03970ec2',
   '28c372a73cc57472fd1f0e8442115ee2ac53be83800eae6594b8aa9b4c7d48f6',
   '398563820c257329e66a7fffe9e0ce512b54261378dbd329222a7729ca0484fc',
   'a36ac422a339e2b40596b5162b22f89d27a27dbbc8c7292c709a069673eb470b',
   'd35886043eee094a310136ae21c4c7af5bcd7c68e6a547cbd5069dd6baee1a63',
   '41a5f7781dc69308b187e24924e0a0a337cdcc36f06b736dd99810eda7bb867b',
   '41a5f7781dc69308b187e24924e0a0a337cdcc36f06b736dd99810eda7bb867b',
   'a64cd974e0dbd6f6a289ebd2080ffb6e8ac47f794e02cde4db2239c42f63b6ba',
   'e813a50278e41a5ea532c95f99ab616d4ec1ffabad99e1c8fde23886bb600005',
   '8d4bd8d58ddd11cea747d874e676582bb219b065b2989d96b566f0689a3aaff5',
   '8d4bd8d58ddd11cea747d874e676582bb219b065b2989d96b566f0689a3aaff5',
   'e477515e963dc46294e815f9b1887541d225f4b027a7129608302ba8d07faef2',
   'e477515e963dc46294e815f9b1887541d225f4b027a7129608302ba8d07faef2']


def hash(val):
    return hashlib.sha256(val.encode('utf-8')).hexdigest()
key=string.digits+string.ascii_lowercase
def burp(i,j):
    for i in tqdm(key[i:j]):
        for j in string.digits+string.ascii_lowercase:
            for m in string.digits+string.ascii_lowercase:
                for n in string.digits+string.ascii_lowercase:
                    for o in string.digits+string.ascii_lowercase:
                        for p in string.digits+string.ascii_lowercase:
                            val1='flag{09'+i+j+m+n+o+p
                            val2=i+j+m+n+o+p+'755ca2}'
                            if hash(hash(val1)) in all_hash:
                                print(val1)
                            if hash(hash(val2)) in all_hash:
                                print(val2)
p = Pool(12)
for i in range(0,len(key),len(key)//12):
    p.apply_async(burp, args = (i, i+3,))
p.close()

最后适当微调四个字节的排序确认flag

flag = "flag{09806994-5a04-45ef-bde0-c69658755ca2}"

Twice

两次解密

第一次
n ∗ d = 1 + k ∗ ( p − 1 ) ∗ ( q − 1 ) ∗ ( r − 1 ) 2 n ∗ d = 2 ∗ 2 k ∗ ( p − 1 ) ∗ ( q − 1 ) ∗ ( r − 1 ) 2 k ∗ ( p − 1 ) ∗ ( q − 1 ) ∗ ( r − 1 ) = 1   m o d   p ∗ q ∗ r 2 n ∗ d − 2 = 0   m o d   p ∗ q ∗ r p ∗ q ∗ r = g c d ( 2 n ∗ d − 2 , n ) c p r i   m o d   p ∗ q ∗ r = m n*d=1+k*(p-1)*(q-1)*(r-1)\\ 2^{n*d}=2*2^{k*(p-1)*(q-1)*(r-1)}\\2^{k*(p-1)*(q-1)*(r-1)}=1\ mod\ p*q*r\\ 2^{n*d}-2=0\ mod\ p*q*r\\ p*q*r=gcd(2^{n*d}-2,n)\\ c^{pri}\ mod\ p*q*r =m nd=1+k(p1)(q1)(r1)2nd=22k(p1)(q1)(r1)2k(p1)(q1)(r1)=1 mod pqr2nd2=0 mod pqrpqr=gcd(2nd2,n)cpri mod pqr=m
第二次

gcd(a0*b1-a1*b0,N)

gcd一下就行,具体可参考NSSCTF round11,我的前面wp有写

然后常规解密

exp

from Crypto.Util.Padding import pad,unpad
from Crypto.Util.number import *
n1= 87665217778729524993118310155129480311708534438704150676980835344891979982717119161254489670350577173938239682286759779547789055360697960379769693294306641200724257991678505629369338313581657539655057636732714452287023658150014746541718058750871927050204352584824130972892779877896415568548748364583880371427
a0= 9362970563807702423162361787386216886594085863490420184497563324865248429693287404341206766515622648778272030443641712923250846610046357375553046092690266
a1= 9362970563807702423162361745963275441706212437133735476965289880825874017106479792816846422940594285630367772490647779230476318907092613021181772527068514
b0= 74836747076024432741470938222753940689278814091833170112470104078475118700897724833941621360216319460657128947837095907483
b1= 93520964011413593176393772179429258741894666938448164504029535235899813670669478849381259720656022408302270582527720184427
c2= 7090659117351297531755883438960933877263181849815568437232708639999747137583085680350909771730266998763362206865224473283130982570816918537377058225538656521223617210560656370841094169187300346437355127376920626133248983100115455529533265136725274741407727211587363755394889303944789720637515498330115070515942678821608630620272575086220037432383957991049220528177053370450234486390431027269543481157974773863005279984438957464388749795275109730696430700744950555993640720758137888948464005039907816169108829675809911658280616090368129767282407708640291466242813209343944276906740181222776418701978734705056220412984
pub= 15393634704241437811571407047965218207529278849238950329420499882359515149154462592674433680412129087082275102567406550543503710118161775213536183656910892279726520148202227312448507629264239427121015706092403872586978266402316447553116208411724407465368711586887621447872002364407809592953543797319646692321612541334341183378900324146713189121105760280994702695266049904020810024990537652609099294535255399210219454610583930829883737909993183476961897889084229322415995483397484414924734020539093114397393070394929656598174957126771887906087335882580049097369036955153036983424389092042285637185882327630117320615769
pri= 424184707992085368727036634979681060339188016631126395371395132791009626692092220877797321952063158959159298372653275672949543326347146732580465753892335912633332743258010037527036987474957662424735475674152462914082526658466925646224968182493094690460023505421720259663381122409147914948696061450626153526908753546708693503710352787787701648821693599138777500334149879355898444355846028142814267511986218166066642222930494985736426837825122392760739011897554697
pqr=ZZ(gcd(pow(2,pub*pri,pub)-2,pub))
c1=ZZ(pow(c2,pri,pqr))
c1=bytes_to_long(unpad(long_to_bytes(c1),190))

p=gcd(a0*b1-a1*b0,n1)
q=n1//p
assert p*q==n1
e=(n1-a0^2)//(b0^2)
d=inverse(e,(p-1)*(q-1))
long_to_bytes(ZZ(pow(c1,d,n1)))

RSA_like

参考上周的mini L一样的解法

s = p + q e d = k ∗ ( p 2 + p + 1 ) ∗ ( q 2 + q + 1 ) + 1 f = k ∗ ( n 2 + n ∗ s + s 2 − n + s + 1 ) + 1 = 0 m o d    e 二元 c o p 可解 s=p+q\\ ed=k*(p^2+p+1)*(q^2+q+1)+1\\ f=k*(n^2+n*s+s^2-n+s+1)+1=0\mod e\\ 二元cop可解 s=p+qed=k(p2+p+1)(q2+q+1)+1f=k(n2+ns+s2n+s+1)+1=0mode二元cop可解

解得s然后分解n,表达phi,求出d

后续的解密按照他实现的运算就行

exp

import itertools
def small_roots(f, bounds, m=1, d=None):
    if not d:
        d = f.degree()

    R = f.base_ring()
    N = R.cardinality()

    f /= f.coefficients().pop(0)
    f = f.change_ring(ZZ)

    G = Sequence([], f.parent())
    for i in range(m + 1):
        base = N ^ (m - i) * f ^ i
        for shifts in itertools.product(range(d), repeat=f.nvariables()):
            g = base * prod(map(power, f.variables(), shifts))
            G.append(g)

    B, monomials = G.coefficient_matrix()
    monomials = vector(monomials)

    factors = [monomial(*bounds) for monomial in monomials]
    for i, factor in enumerate(factors):
        B.rescale_col(i, factor)

    B = B.dense_matrix().LLL()

    B = B.change_ring(QQ)
    for i, factor in enumerate(factors):
        B.rescale_col(i, 1 / factor)

    H = Sequence([], f.parent().change_ring(QQ))
    for h in filter(None, B * monomials):
        H.append(h)
        I = H.ideal()
        if I.dimension() == -1:
            H.pop()
        elif I.dimension() == 0:
            roots = []
            for root in I.variety(ring=ZZ):
                root = tuple(R(root[var]) for var in f.variables())
                roots.append(root)
            return roots

    return []
c = (59282499553838316432691001891921033515315025114685250219906437644264440827997741343171803974602058233277848973328180318352570312740262258438252414801098965814698201675567932045635088203459793209871900350581051996552631325720003705220037322374626101824017580528639787490427645328264141848729305880071595656587, 73124265428189389088435735629069413880514503984706872237658630813049233933431869108871528700933941480506237197225068288941508865436937318043959783326445793394371160903683570431106498362876050111696265332556913459023064169488535543256569591357696914320606694493972510221459754090751751402459947788989410441472)
n = 114781991564695173994066362186630636631937111385436035031097837827163753810654819119927257768699803252811579701459939909509965376208806596284108155137341543805767090485822262566517029632602553357332822459669677106313003586646066752317008081277334467604607046796105900932500985260487527851613175058091414460877
e = 4252707129612455400077547671486229156329543843675524140708995426985599183439567733039581012763585270550049944715779511394499964854645012746614177337614886054763964565839336443832983455846528585523462518802555536802594166454429110047032691454297949450587850809687599476122187433573715976066881478401916063473308325095039574489857662732559654949752850057692347414951137978997427228231149724523520273757943185561362572823653225670527032278760106476992815628459809572258318865100521992131874267994581991743530813080493191784465659734969133910502224179264436982151420592321568780882596437396523808702246702229845144256038

beta = 0.397
bounds = (floor(n^beta) // 2, floor(n^0.5))
PR.<k,s>=PolynomialRing(Zmod(e))

f=k*(n^2+n*s+s^2-n+s+1)+1
small_roots(f, bounds, m=3, d=4)
#[(622388446837437742717907189821104799227621425864896467926829525917356157945038443057723315324154820787694801673,
  21581081267317264057300397805667850767978100748500497887465036772601909848077661066029306567420215347344093486009661621345217539597125914633479358949462578)]
s=21581081267317264057300397805667850767978100748500497887465036772601909848077661066029306567420215347344093486009661621345217539597125914633479358949462578

x=var('x')
f=x*(s-x)-n
p,q=f.roots()[0][0],f.roots()[1][0]
# n==p*q
psi = ZZ((p ** 2 + p + 1) * (q ** 2 + q + 1))
d=inverse(e,psi)
d
#1928162174341217691501073396348543374914457726701746377207373957621633937288084167870015912332959632509771228593

crackme

总之是界限卡的很死,只能爆破最后一位大写字母,后面的AES解密都还好。

首先要知道使用crt来把方程提升到模数为 n 1 ∗ n 2 ∗ n 3 ∗ n 4 n_1*n_2*n_3*n_4 n1n2n3n4上。

写一段测试代码来看一看求解的下界。这里epsilon肯定要下调的0.03,求较小解是这样的。

from Crypto.Util.number import *
edge=474
m=getrandbits(edge)
fs=[]
ns=[]
cs=[]
for i in range(4):
    p,q = getPrime(260),getPrime(260)
    n = p * q
    F = Zmod(n)
    k = randint(2, n-1)
    P.<x> = PolynomialRing(Zmod(n))
    cs.append(F(m)^4 + F(m)^3 + 5*F(m)^2 + k*F(m))
    f=x^4+x^3+5*x^2+k*x-ZZ(cs[-1])
    fs.append(f.monic().change_ring(ZZ))
    ns.append(n)
ff=crt(fs,ns)
N=prod(ns)
ff=ff.change_ring(Zmod(N))
ff.small_roots(X=2^(edge),epsilon=0.03)

这里当未知474bits或更小时是可以使用small_roots算出来的,在高了就不行了。

这里题目是未知60*8为480bits,可以选择爆破26的解空间和爆破最后一位大写字母26个解空间。当然是选择后者。这里就算不知道原始理论上界,也可以通过依次下调的方法知道edge。

然后就是爆破求解了

电脑好像被我老用多进程玩坏了

exp

from multiprocessing import Pool, cpu_count,Queue
from tqdm import *
from Crypto.Util.number import *
res=[(2576060676691912599041453221402687596761165416186144521390999188188054810790689875123147391567468904152433767494418025426036536791888845362051620957584796173, 1404599252224589102680100215102065783794937466885641804474763659235753882248281509918047703883314262151887636018214889908296113219929390525312856531057598511, 1546582168511591297246236466785228284146606446580424428788321134907243444000276185636702416300856423264943202370285590133353315898209756704105928659504125280), (1856479428320393184826066814134098589741228855450025333688188120575929163866515585497402286516300870767597286796830194179897319803359819777070606158997326687, 1739911445273397715994715373821615268097813691506341592399828911490088434888870095909648380238843690112973622076731513477307870982775256397102986545585042307, 1404715712359273595839731798473935119428618634487647011136927974988040980856414867101421603849272449005576218478139726706896369717995173978540209876272991559), (2297431461807762915467529671075083216743767671815011184905660952239533101846545054093337929863732257767151231036542977019155281482916017336942426284877952589, 1229262703524979999066414868366795977860845915873708036053137031236650917419418563435203159859588413392034711023934730032791107827617980777011168968597093740, 948124104672656112191612153338861115247358886514962328044734247511665786771053972281157125837946402243709012378636236994494243608157138428623815232812105126), (3259684917460943558806503540406726793994425276515494389101605804265114363982952363351874215959189233202709599069554855887866747319958581801738676836732154639, 2498703813681156495356941255793430828832266261028869209649186668471521794564165492313310602470142029945552478625127582808859576924652319577668651211062402358, 2626606161752306212066637131911545589457511068105752968019561674772422135733149538237136201363338821026926398176115395623371696564683341772942172012193929801)]
def func(i,j):
    for i in tqdm(range(i,j)):
        fs=[]
        ns=[]
        for v in res:
            n=v[0]
            k=v[1]
            c=v[2]
            P.<m> = PolynomialRing(Zmod(n))
            x = bytes_to_long(b'Key_') * 2^(60 * 8) + m * 2^8 + i
            f = x^4 + x^3 + 5*x^2 + x*k - c
            fs.append(f.monic().change_ring(ZZ))
            ns.append(n)
        ff=crt(fs,ns).change_ring(Zmod(prod(ns)))
        if ff.small_roots(X=2^472,epsilon = 0.03):
            print(long_to_bytes(ZZ(ff.small_roots(X=2^472,epsilon = 0.03)[0])))
            exit()
num=6
p = Pool(num)
for i in range(65,91,26//num):
    p.apply_async(func, args = (i, i+26//num,))
p.close()
#func(65,91)

多线程慎用,跟电脑性能有关系

b'You_RealLY_KNOw_CoPp3rsmith!zm\xe50\xfe\xc4\xaf\x83\x0c\x84\xa7\xf2\xb9\x9e\x94\x99\xf3\xa4\x11\x81\xdc\x1b\xaf\x96\xabdV\xe1\x85\xe4\x83'

后面的AES,CBC模式就不用多说了


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值