nullcon HackIM CTF 2023

感觉没啥长进,类似于hxp那种大型国际赛还是打不动,深感无力与挫败...但还是得加油,至少要尽力复现。

Crypto

twin

共模攻击。

from Crypto.PublicKey import RSA
import sys
from gmpy2 import gcdext,invert,gcd,iroot
from Crypto.Util.number import *

sys.setrecursionlimit(100000)

key1 = RSA.import_key(open('key1.pem','rb').read())
key2 = RSA.import_key(open('key2.pem','rb').read())

c1 = 198851474377165718028112972842265639215206348877016608622627311171042209963702835769614338398847455363946863082762173236373502223802847244557769309152020719377009343678096323767255545133734392981272835212545353488715110156427711111525743585480758640009319505322315888005188276904901023280620051538053743929669167795850860335549768969166461593906239357372330505433946129717041834475732372670961026001478227254999273718196250867204510681064391880099449164629711720021122445665846890550815079811041241824128791656795460007230003283109669795738520458565694688073372232365469969279979269172335621053156518588065204669164636568515585968088715299221616098448196835007486026306834585857385394379932580809203103023106229424720660096661585932612179471986633721231396764156601845262479014417201866703796806022479395694033815788446795158605478744234679438921219482709321859861288988156224563399413134218092016216147313958327131507901433719054874275160651556856183380492151746510052730242685874618761355215984376265719715473363476986957901445315504092719499838417381325617015369293491930133307630128865051357500960150518954750856507501366553062420719464692404538472137892443679198526541754483324903275970820090884602410278644781399298682978387326
c2 = 541940109836125333895781430104885967485013462238357425709353944075428304212181613346342168833632915771850317706081582413750750719712828061669251836467513116815496399077435572514863813419820177695716122433176805528532535188403726732767914692088563121640407878586264559446821905465347721083017105647280563402969518765808190495949892463753148040234604183497869168213134441134251591933907135463336654029223065998877557269475470179804195639035481928376550039377473960558788269310431313825888988908660191302311385846641723702093086996138971258640836061285893970041520552244977929645483977290602241276584136088984907441193129409236710662584843118801800457934169438121910252362434716190064236551302755562358860534549136237814085075287652312464795604230258140807652348468032431267225399615168922885291236301151723996369977845223020976025668767146139688511344868583917521559162297134719274102553947904603784500638033579530233721139319885875767560434666844423652986065991855466499543496592686627509183766091917402747468665062914322631033890742828511915046161646985793301031872822709060588586773552581644418553383314263000798086024158809854568189418235663070035600457464233007552461215491869285368208456103672933515573777187729174614608959934215
print(key2.n == key1.n)
print(gcd(key1.e,key2.e))
def gongmogongji(n, c1, c2, e1, e2):
    s = gcdext(e1, e2)
    s1 = s[1]
    s2 = s[2]

    # 求模反元素
    if s1 < 0:
        s1 = - s1
        c1 = invert(c1, n)
    elif s2 < 0:
        s2 = - s2
        c2 = invert(c2, n)
    m = pow(c1, s1, n) * pow(c2, s2, n) % n
    return m

m = gongmogongji(key1.n,c1,c2,key1.e,key2.e)
print(long_to_bytes(iroot(m,17)[0]))
# ENO{5har1ng_is_n0t_c4r1ng}

bmpass

用ECB加密过后的图像会暴露一定的明文特性,攻击原理和用法参考:tool.直接梭哈即可。

breaking news

对于key1,可以用Boneh and Durfee attack,解出d1,利用d1可以分解n,从而求出d2解密另一半flag。

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from binascii import unhexlify
import random
import gmpy2

c1 = '3b6ccd7fa1de0455945998bc024adc6c2b60ccc8f020cbf024c3d4f98eafdf6a43afd15ec4d9a32f84cb61f7a5462547f2e3622b547c3e9ccb723102805544b373a80f4d252a1081db6d5c5499b222093fd4bb7997c68ab0ed8a9ac3bd0dae64cdfb946da1e311ef6e216ddf2dac14ea3710d5622269f08073598c24a3000a6dd6270ca0db5c304102bc9a5cd104484a2c0ced339121f13499c795de343ad2e655d4ace726654ee9f110e4bee3db95d8e514bd6e658769a01638ff2e9ce954dc09def3b01f6d598ddae2ca9735c8e8f9b71c96984a114084fb0a25b3646481e8c8d4d8adfedc7afad7be7a009c6d12753db4216ab9fd7fc8c37c819aef6a8bce'
c2 = '998d5eeb0c048ade8cd807cb582b15a7799e8481a7476dbe8e0310b5ffc5161add92539bc0a374333c11f5f2008195782a44e45f2394fe3115af59fbc73ad24c4d084d79ba8e5896b644917335fd9a0e07c1d1d316e50480ba44c67b6fc04a2ce33dbc721768f1f874ff2ce1ec0503a4a7c67d10119ff9f79030459068de24ff24593e16877fd74c5a12d0e64a3d62e61b13c403aad2fe605601e8a097aba99707e305e3125a3c89f3d6beccc2f19a32fdac9ab7df181938b9b80d83a54c9c23ef11affff0fca67ecd9d45c58ece90a44ecd60aff7be05bf97cb554c563a3f9139d99f7c76a07acaaa261b1d6cb41e228fb2aca02ed1c64d468aabb8cfaa9210'
c1 = unhexlify(c1)
c2 = unhexlify(c2)
# 这是公钥
key1 = RSA.import_key(open('k1.pem','rb').read())
key2 = RSA.import_key(open('k2.pem','rb').read())

print(key1.n == key2.n)
print(key1.e/key1.n)
print(key2.e/key2.n)
print(key2.n,key2.e)
print(key1.n,key1.e)

d1 = 3142948387612230061712223313218058768177264054157930977501720905159512174225
def getpq(n,e,d):
    while True:
        k = e * d - 1
        g = random.randint(0, n)
        while k%2==0:
            k=k//2
            temp=gmpy2.powmod(g,k,n)-1
            if gmpy2.gcd(temp,n)>1 and temp!=0:
                return gmpy2.gcd(temp,n)

p = getpq(key1.n,key1.e,d1)
q = key1.n//p
assert p * q == key1.n
phi = (p-1)*(q-1)
d2 = gmpy2.invert(key2.e,phi)

# 注意这里要用RSA.construct重新构建私钥结构
privkey1 = RSA.construct((key1.n, key1.e,d1))
cipher = PKCS1_OAEP.new(privkey1)
m1 = cipher.decrypt(c1)


privkey2 = RSA.construct((key2.n, key2.e,int(d2)))
cipher = PKCS1_OAEP.new(privkey2)
m2= cipher.decrypt(c2)
print(m1 + m2)
# ENO{n3ver_reus3_your_pr1mes_4_a_new_k3y_you_have_2_p4y_th3_pr1ce}

collector

关键在于key = RSA.generate(N, e = (1<<(1<<random.randint(0,4))) + 1),这里的e只有几种可能取值,3,5,17,257,65537,注意到flag为非动态,seed、mask等参数也是固定的,因此可以考虑多次连接server得到几组e=3时的密文,利用广播攻击求pad(flag),再通过混淆过程的逆运算去掉pad得到flag。exp如下:

from pwn import *
from Crypto.PublicKey import RSA
from sympy.ntheory.modular import crt
from gmpy2 import *
from Crypto.Util.number import *

N = 2048
hLen = 256

def MGF(seed, length):
    random.seed(seed)
    return [random.randint(0,255) for _ in range(length)]

n_list = []
c_list = []
while True:
    sh = remote('52.59.124.14', 10005)
    pub = sh.recvline().decode()[2:-2].replace(r'\n','\n')
    #print(pub)
    c = eval(sh.recvline().strip().decode())
    if RSA.import_key(pub).e == 3:
        n_list.append(RSA.import_key(pub).n)
        c_list.append(c)
    if len(n_list) == 3:
        break

pad_flag3 = crt(n_list,c_list)[0]
pad_flag = iroot(pad_flag3,3)[0]
assert pad_flag ** 3 == pad_flag3

pad_flag_list = list(long_to_bytes(pad_flag))
# masked_seed长度为32,因此maskedDB长度为255-32 = 223
maskedDB = pad_flag_list[32:]
masked_seed = pad_flag_list[:32]
seedmask = MGF(bytes_to_long(bytes(maskedDB)), hLen // 8)
seed = bytes([masked_seed[i] ^ seedmask[i] for i in range(hLen // 8)])
mask = MGF(seed, 223)
DB = [maskedDB[i] ^ mask[i] for i in range(223)]
print(bytes(DB))
# ENO{com3_to_Nu1lCon_bu1_do_n0t_tel1_B0b}

noble collector

考点是Håstad's broadcast attack(coppersmith)。由于e的取值和上题一致,所以我们可以接收e=3的若干组(本题是没有限制的,所以比特不够或者卡界就多一些组),令接收的参数三元组为(n,c,name),根据加密关系有\(\small (name \cdot 256^L+m)^3-c\equiv0\;mod\;n\),我取了四组数据,crt提升界,再遍历一下L(invitation的长度)就出了。exp如下:

from pwn import *
from Crypto.PublicKey import RSA

n_list = []
c_list = []
name_list = []
while True:
    sh = remote('52.59.124.14', 10006)
    name = b'Dear ' + sh.recvline().strip()[15:]
    pub = sh.recvline().decode()[2:-2].replace(r'\n','\n')
    #print(pub)
    c = eval(sh.recvline().strip().decode())
    if RSA.import_key(pub).e == 3:
        n_list.append(RSA.import_key(pub).n)
        c_list.append(c)
        name_list.append(name)
    if len(n_list) == 4:
        break

print(n_list)
print(c_list)
print(name_list)

from Crypto.Util.number import *

n_list = [22819237538564709288276017849944416991400691126324584426300413429416319035739697913320235604375647210349751267666885945585168482505850456201282668877499957235590871167017034319619481945000725338433114841957524516707974199769112509884849321542688477636619768523453348414561337875679387541183325061018066264226227366704368905018002871717815633526003469467196870508245652886125516368301400615246421924258834971831491771147211795135714443205927004413890585767773133464579176664609422554537276165301456902628097992212498153029124882609784508924692729811701799420048263715129583234315903143706037923845915759494857179922091, 28134462918873282061603645430133732078482912779281507959177514751148010893662900594383027490207670777741780631437712046818487993843209487582148749317285608896845239428037688741085783776998276830104992835086602559084612912102611320382195560237993103073412703879517581036384374969566753535647759492136813352102537431507801750765710480495451698930459810948897826802283088632498218964100288357298302591247408844891845631940028980010653477953057851886728803230419650555930571693619075569024031925795702013619502064815087494274141444891021139050676831319790501427826168623926022378151955000637584659183862728204735657271127, 26230282162099979242443971614662213358757822115397753403116269474399348882819611280017842312392738417735080586900979251387953336711163188558151000626431185570767540654252517550427031294833613644459188771846245015991251611027254725188045506937743652168786264329395328216970453951039554822256580586049918038119785999535051053468438768121738037098850887908539526566799314649743370115389708802847129713874963287296591502171445912667140087165247236140296612904635898574174755462770265652769511650913356189487560035343148080960044586897103788131794676615408530150511262270700055158756665485393738822475482578494519399969479, 29941662107985811214485977952923402409802379707073660949227356151031981357820517620919540900355586393245992477523595908894929329856408105993844806618114450269792668304104098196179639697138821378638767763499798509653329136473624102911363176456694890042275740026890051975018477879552593619375411598446992538862592779966322408836333192967280819025643788716227830477365760414904067966392673765769062665705378739881428335127318761013277799993901713161280349630322106511287127987356964448454681929415466918109182752374380840301515702350323627336130797417836670573954929159653828307715405593645844686503753695025367683532549]
c_list = [21543548102736631246553286898992635230654748785809754725150618242875083650458566463479969366041960538432494806350702796011675261873761429955076120029452674260458485593572854625620976763520838999401948503953789354920369929980807742379567479346790733892904213145516770086578861068604414740824997130716654209084037566520556813727042145675948477317341591564927595691076901323265413808151277798759816940529302526238395637789061495898844729895450691537927468739353700775508568016589865313842729301620312384508564425534606585936422199827698137178305894552966492789026925398297646500340311458408488481077705743382344531300594, 4586776972776204252144597869608582274197006449845346128610272934850693759258961745171021484192717400191635304298862604928252158998718579260937591249790543890295278703524388725996942105114836328827580277833700401762593389980803897270304847539678771844290394767790808544952597446791642348807983758527096179181541986723392132373016479550184545043128078361073169233364067140132506875594155804942120658103235514082039713571328471087104548862322589543681509432586454661150649065656265192173154420695948129103729588049193725689281667616483793629528056488030299329810491918834143159396573657058232083537420508528689637994685, 20440190303884359236482158644038819569612659869072039115457930674493393352112686437977144738154336379435976361334660541942832775410748727270052485234431789567842022895074739006813679242892976740754364763799191865592766182717259473145561863770235933354448740690596623845714272028940756407921863606454825685767821353776312037256911449745480644060891116009960557579809804332161143389901314579298701427410508841758699082943801934429909665106116722006377116565451082499049316788801406608768121668076053875588748738191336578704552605555684372640511432568613007193726815366862560000673704497559960061548677883207531563576751, 9794043857728804629847203240855646377830742501595450537513909480999837198009231694153666934188560005737343405021586336899777636313598204116095039663258856313379659912672158318623020276060400117485646864247213752062993852422104283512316742441342602097062734589185632488783928536391460368873463350350061617702905037638260329623958172445061553990156303471763171128444377421445137858180256013597311929034003534426297001471295392248492876674483723686751336008627492988545072067392952726371498109550759559589133659913678545873984510238195777082678881454492002954825183488077881998580593970202287503624640452519688689360942]
name_list = [b'Dear DEANDRE JUDSON IRVIN HANSEN', b'Dear DANE FLOYD FRED COLLINS', b'Dear MARVA PAIGE NOEL NORMAN', b'Dear DOREEN MARI PETRA HARRIS']
def Function(n,c,name,L):
    P.<m> = PolynomialRing(Zmod(n))
    a = bytes_to_long(name)
    f = (a * (256 ^ L) + m) ^ 3 - c
    return f

for L in range(33,1000):
    fs = []
    for i in range(4):
        fs.append(Function(n_list[i],c_list[i],name_list[i],L).monic().change_ring(ZZ))
    F = crt(fs,n_list)
    N = prod(n_list)
    FF = F.change_ring(Zmod(N))
    try:
        roots = FF.small_roots()
        print(roots)
        m = long_to_bytes(int(roots[0]))
        print(m)
    except:
        continue

image

Misc

babyrand

MT19937随机数预测。

from randcrack import RandCrack
from pwn import *

sh = remote('52.59.124.14',10011)
rc = RandCrack()
for i in range(69):
    print(f'{i+1}轮...')
    sh.recvuntil(b'Hints:\n')
    for j in range(9):
        t = int(sh.recvline())
        #print(t)
        rc.submit(t)
    sh.recvuntil(b'Guess:\n')
    sh.sendline(b'2')

sh.recvline()
for j in range(3):
    t = int(sh.recvline())
    print(t)
    rc.submit(t)
for i in range(7):
    r = rc.predict_getrandbits(32)
print(sh.recvuntil(b'Guess:\n'))
sh.sendline(str(r).encode())
sh.interactive()
posted @ 2023-03-18 15:45  ZimaB1ue  阅读(256)  评论(0编辑  收藏  举报