0%

NSSCTF Crypto 02

[HGAME 2022 week2]RSA Attack2

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import re
from math import ceil
from Crypto.Util.number import getPrime
from libnum import s2n
from secret import flag

flag_parts = list(map(s2n, re.findall(rf".{{,{ceil(len(flag) / 3)}}}", flag)))

print("# task1")
m = flag_parts[0]
e = 65537
p = getPrime(1024)
q = getPrime(1024)
r = getPrime(1024)
n1 = p * q
c1 = pow(m, e, n1)
n2 = r * q
c2 = pow(m, e, n2)
print("e =", e)
print("n1 =", n1)
print("c1 =", c1)
print("n2 =", n2)
print("c2 =", c2)

print("# task2")
m = flag_parts[1]
e = 7
p = getPrime(1024)
q = getPrime(1024)
n = p * q
c = pow(m, e, n)
print("e =", e)
print("n =", n)
print("c =", c)

print("# task3")
m = flag_parts[2]
p = getPrime(1024)
q = getPrime(1024)
n = p * q
e1 = getPrime(32)
e2 = getPrime(32)
c1 = pow(m, e1, n)
c2 = pow(m, e2, n)
print("n =", n)
print("e1 =", e1)
print("c1 =", c1)
print("e2 =", e2)
print("c2 =", c2)

WP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
from Crypto.Util.number import long_to_bytes
import gmpy2
# task1 共享素数
e = 65537
n1 = 14611545605107950827581005165327694782823188603151768169731431418361306231114985037775917461433925308054396970809690804073985835376464629860609710292181368600618626590498491850404503443414241455487304448344892337877422465715709154238653505141605904184985311873763495761345722155289457889686019746663293720106874227323699288277794292208957172446523420596391114891559537811029473150123641624108103676516754449492805126642552751278309634846777636042114135990516245907517377320190091400729277307636724890592155256437996566160995456743018225013851937593886086129131351582958811003596445806061492952513851932238563627194553
c1 = 965075803554932988664271816439183802328812013694203741320763105376036912584995031647672348468111310423680858101990670067065306237596121664884353679987689532305437801346923070145524106271337770666947677115752724993307387122132705797012726237073550669419110046308257408484535063515678066777681017211510981429273346928022971149411064556225001287399141306136081722471075032423079692908380267160214143720516748000734987068685104675254411687005690312116824966036851568223828884335112144637268090397158532937141122654075952730052331573980701136378212002956719295192733955673315234274064519957670199895100508623561838510479
n2 = 20937478725109983803079185450449616567464596961348727453817249035110047585580142823551289577145958127121586792878509386085178452171112455890429474457797219202827030884262273061334752493496797935346631509806685589179618367453992749753318273834113016237120686880514110415113673431170488958730203963489455418967544128619234394915820392908422974075932751838012185542968842691824203206517795693893863945100661940988455695923511777306566419373394091907349431686646485516325575494902682337518438042711296437513221448397034813099279203955535025939120139680604495486980765910892438284945450733375156933863150808369796830892363
c2 = 11536506945313747180442473461658912307154460869003392732178457643224057969838224601059836860883718459986003106970375778443725748607085620938787714081321315817144414115589952237492448483438910378865359239575169326116668030463275817609827626048962304593324479546453471881099976644410889657248346038986836461779780183411686260756776711720577053319504691373550107525296560936467435283812493396486678178020292433365898032597027338876045182743492831814175673834198345337514065596396477709839868387265840430322983945906464646824470437783271607499089791869398590557314713094674208261761299894705772513440948139429011425948090

# n1 n2 存在公共因子q
q = gmpy2.gcd(n1,n2)
print(q)
# n1 = p * q
# n2 = r * q
p = n1 // q
r = n2 // q
print(p)
print(r)

d1 = gmpy2.invert(e,(p-1)*(q-1))
d2 = gmpy2.invert(e,(r-1)*(q-1))
m1 = pow(c1,d1,n1)
m2 = pow(c2,d2,n2)
print(long_to_bytes(m1))
print(long_to_bytes(m2))
# b'hgame{RsA@hAS!a&VArIETY?of.'

# task2 低指数e 小明文攻击 直接开根
e2 = 7
n = 14157878492255346300993349653813018105991884577529909522555551468374307942096214964604172734381913051273745228293930832314483466922529240958994897697475939867025561348042725919663546949015024693952641936481841552751484604123097148071800416608762258562797116583678332832015617217745966495992049762530373531163821979627361200921544223578170718741348242012164115593777700903954409103110092921578821048933346893212805071682235575813724113978341592885957767377587492202740185970828629767501662195356276862585025913615910839679860669917255271734413865211340126544199760628445054131661484184876679626946360753009512634349537
c = 10262871020519116406312674685238364023536657841034751572844570983750295909492149101500869806418603732181350082576447594766587572350246675445508931577670158295558641219582729345581697448231116318080456112516700717984731655900726388185866905989088504004805024490513718243036445638662260558477697146032055765285263446084259814560197549018044099935158351931885157616527235283229066145390964094929007056946332051364474528453970904251050605631514869007890625

m2 = gmpy2.iroot(c,e2)[0]
print(long_to_bytes(m2))

# task3 共模攻击
n = 18819509188106230363444813350468162056164434642729404632983082518225388069544777374544142317612858448345344137372222988033366528086236635213756227816610865045924357232188768913642158448603346330462535696121739622702200540344105464126695432011739181531217582949804939555720700457350512898322376591813135311921904580338340203569582681889243452495363849558955947124975293736509426400460083981078846138740050634906824438689712748324336878791622676974341814691041262280604277357889892211717124319329666052810029131172229930723477981468761369516771720250571713027972064974999802168017946274736383148001865929719248159075729
e31 = 2519901323
c31 = 3230779726225544872531441169009307072073754578761888387983403206364548451496736513905460381907928107310030086346589351105809028599650303539607581407627819797944337398601400510560992462455048451326593993595089800150342999021874734748066692962362650540036002073748766509347649818139304363914083879918929873577706323599628031618641793074018304521243460487551364823299685052518852685706687800209505277426869140051056996242882132616256695188870782634310362973153766698286258946896866396670872451803114280846709572779780558482223393759475999103607704510618332253710503857561025613632592682931552228150171423846203875344870
e32 = 3676335737
c32 = 940818595622279161439836719641707846790294650888799822335007385854166736459283129434769062995122371073636785371800857633841379139761091890426137981113087519934854663776695944489430385663011713917022574342380155718317794204988626116362865144125136624722782309455452257758808172415884403909840651554485364309237853885251876941477098008690389600544398998669635962495989736021020715396415375890720335697504837045188626103142204474942751410819466379437091569610294575687793060945525108986660851277475079994466474859114092643797418927645726430175928247476884879817034346652560116597965191204061051401916282814886688467861


def rsa_gong_N_def(e1,e2,c1,c2,n): #共模攻击函数
e1, e2, c1, c2, n=int(e1),int(e2),int(c1),int(c2),int(n)
s = gmpy2.gcdext(e1, e2)
s1 = s[1]
s2 = s[2]
if s1 < 0:
s1 = - s1
c1 = gmpy2.invert(c1, n)
elif s2 < 0:
s2 = - s2
c2 = gmpy2.invert(c2, n)
m = (pow(c1,s1,n) * pow(c2 ,s2 ,n)) % n
return int(m)

m3 = rsa_gong_N_def(e31,e32,c31,c32,n)
print(long_to_bytes(m3))

flag = long_to_bytes(m1)+long_to_bytes(m2)+long_to_bytes(m3)
print(flag)
# b'hgame{RsA@hAS!a&VArIETY?of.AttacK^mEThodS^whAT:other!AttACK|METHOdS~do@you_KNOW}'

[鹤城杯 2021]BabyRSA

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from Crypto.Util.number import getPrime, bytes_to_long
from secret import flag

p = getPrime(1024)
q = getPrime(1024)
n = p * q
e = 65537
hint1 = p >> 724
hint2 = q % (2 ** 265)
ct = pow(bytes_to_long(flag), e, n)
print(hint1)
print(hint2)
print(n)
print(ct)

1514296530850131082973956029074258536069144071110652176122006763622293335057110441067910479
40812438243894343296354573724131194431453023461572200856406939246297219541329623
21815431662065695412834116602474344081782093119269423403335882867255834302242945742413692949886248581138784199165404321893594820375775454774521554409598568793217997859258282700084148322905405227238617443766062207618899209593375881728671746850745598576485323702483634599597393910908142659231071532803602701147251570567032402848145462183405098097523810358199597631612616833723150146418889589492395974359466777040500971885443881359700735149623177757865032984744576285054725506299888069904106805731600019058631951255795316571242969336763938805465676269140733371287244624066632153110685509892188900004952700111937292221969
19073695285772829730103928222962723784199491145730661021332365516942301513989932980896145664842527253998170902799883262567366661277268801440634319694884564820420852947935710798269700777126717746701065483129644585829522353341718916661536894041337878440111845645200627940640539279744348235772441988748977191513786620459922039153862250137904894008551515928486867493608757307981955335488977402307933930592035163126858060189156114410872337004784951228340994743202032248681976932591575016798640429231399974090325134545852080425047146251781339862753527319093938929691759486362536986249207187765947926921267520150073408188188

题目分析

已知e n c,

hint1 p的高300位

hint2 q的低265位

如果想用高位攻击 那么1024位至少需要已知一半以上才行【网上说要570位】 300+265=565位 还差5位

目前已知 300+265位【565位】 还剩中间未知459位 需要通过coppersmith求解

正常情况下需要知道 570位

# q0 = q % 2**265

# q = q0 + k*2**265

# n = pq = pq0 + pk * 2**265

# 两边同除p

# n * p**(-1) = q0 + pk * 2**265 * p**(-1)

# q0 = n * p**(-1) - pk* 2**265 * p**(-1)

# q0 = n * p**(-1) - pk*p**(-1) % 2**265

# p q换下位置

# p0 = n * q**(-1) - qk*q**(-1) % 2**265

# p0 = (n * q**(-1) ) % 2**265

WP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from Crypto.Util.number import long_to_bytes
import gmpy2

e = 65537
# hint1 = p >> 724 p高300[1024-724]位
hint1 = 1514296530850131082973956029074258536069144071110652176122006763622293335057110441067910479
ph = hint1 << 724
# hint2 = q % (2 ** 265) q 低265位
q0 = 40812438243894343296354573724131194431453023461572200856406939246297219541329623
n = 21815431662065695412834116602474344081782093119269423403335882867255834302242945742413692949886248581138784199165404321893594820375775454774521554409598568793217997859258282700084148322905405227238617443766062207618899209593375881728671746850745598576485323702483634599597393910908142659231071532803602701147251570567032402848145462183405098097523810358199597631612616833723150146418889589492395974359466777040500971885443881359700735149623177757865032984744576285054725506299888069904106805731600019058631951255795316571242969336763938805465676269140733371287244624066632153110685509892188900004952700111937292221969
c = 19073695285772829730103928222962723784199491145730661021332365516942301513989932980896145664842527253998170902799883262567366661277268801440634319694884564820420852947935710798269700777126717746701065483129644585829522353341718916661536894041337878440111845645200627940640539279744348235772441988748977191513786620459922039153862250137904894008551515928486867493608757307981955335488977402307933930592035163126858060189156114410872337004784951228340994743202032248681976932591575016798640429231399974090325134545852080425047146251781339862753527319093938929691759486362536986249207187765947926921267520150073408188188

mod = pow(2,265)
# 根据q低位 求p低265位
# pl = (n * q**(-1) ) % 2**265
pl = n*gmpy2.invert(q0,mod) % mod
# print(pl)
pbar = ph+pl
# print(pbar)

#SAGE#####
PR.<x> = PolynomialRing(Zmod(n))
for i in range(2^5):
f = pbar + x*mod*2^5
f = f.monic()
roots = f.small_roots(X=2^454,beta=0.4)
if(roots):
break
pbar += mod

p = pbar + roots[0]*mod*2^5

assert n%p ==0
print("p =",p)
##########
p = 133637329398256221348922087205912367118213472434713498908220867690672019569057789598459580146410501473689139466275052698529257254973211963162087316149628000798221014338373126500646873612341158676084318494058522014519669302359038980726479317742766438142835169562422371156257894374341629012755597863752154328407
q = n//p
print(q)
phi = (q-1)*(p-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
print(long_to_bytes(m))
# b'flag{ef5e1582-8116-4f61-b458-f793dc03f2ff}'

[鹤城杯 2021]Crazy_Rsa_Tech

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from Crypto.Util.number import *
from Crypto.Util.Padding import *

FLAG = bytes_to_long(pad(b"flag{??????}",64))
def init_key():
p, q = getPrime(512), getPrime(512)
n = p*q
e = 9
while(GCD((p-1)*(q-1),e)!=1):
p, q = getPrime(512), getPrime(512)
n = p*q
d = inverse(e,(p-1)*(q-1))
return n,e,d

n_list=list()
c_list=list()
for i in range(9):
N,e,d=init_key()
n_list.append(N)
c=pow(FLAG,e,N)
c_list.append(pow(FLAG,e,N))
assert(pow(c,d,N)==FLAG)
print("n_list:",n_list)
print("c_list:",c_list)



题目分析

如果选取的加密指数较低,并使用同一个加密指数e 加密密文,可通过广播攻击得到明文

中国剩余定理

随机生成9组 n d 公用同一个e 输出密文c 求m

e值较低 可考虑低加密指数广播攻击【如果e值较低 且使用同一个e 进行密文加密 可通过广播攻击得到明文】

所以这题 对m开9次根可得到 flag

WP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
n_list = [71189786319102608575263218254922479901008514616376166401353025325668690465852130559783959409002115897148828732231478529655075366072137059589917001875303598680931962384468363842379833044123189276199264340224973914079447846845897807085694711541719515881377391200011269924562049643835131619086349617062034608799, 92503831027754984321994282254005318198418454777812045042619263533423066848097985191386666241913483806726751133691867010696758828674382946375162423033994046273252417389169779506788545647848951018539441971140081528915876529645525880324658212147388232683347292192795975558548712504744297104487514691170935149949, 100993952830138414466948640139083231443558390127247779484027818354177479632421980458019929149817002579508423291678953554090956334137167905685261724759487245658147039684536216616744746196651390112540237050493468689520465897258378216693418610879245129435268327315158194612110422630337395790254881602124839071919, 59138293747457431012165762343997972673625934330232909935732464725128776212729547237438509546925172847581735769773563840639187946741161318153031173864953372796950422229629824699580131369991913883136821374596762214064774480548532035315344368010507644630655604478651898097886873485265848973185431559958627423847, 66827868958054485359731420968595906328820823695638132426084478524423658597714990545142120448668257273436546456116147999073797943388584861050133103137697812149742551913704341990467090049650721713913812069904136198912314243175309387952328961054617877059134151915723594900209641163321839502908705301293546584147, 120940513339890268554625391482989102665030083707530690312336379356969219966820079510946652021721814016286307318930536030308296265425674637215009052078834615196224917417698019787514831973471113022781129000531459800329018133248426080717653298100515701379374786486337920294380753805825328119757649844054966712377, 72186594495190221129349814154999705524005203343018940547856004977368023856950836974465616291478257156860734574686154136925776069045232149725101769594505766718123155028300703627531567850035682448632166309129911061492630709698934310123778699316856399909549674138453085885820110724923723830686564968967391721281, 69105037583161467265649176715175579387938714721653281201847973223975467813529036844308693237404592381480367515044829190066606146105800243199497182114398931410844901178842049915914390117503986044951461783780327749665912369177733246873697481544777183820939967036346862056795919812693669387731294595126647751951, 76194219445824867986050004226602973283400885106636660263597964027139613163638212828932901192009131346530898961165310615466747046710743013409318156266326090650584190382130795884514074647833949281109675170830565650006906028402714868781834693473191228256626654011772428115359653448111208831188721505467497494581]
c_list = [62580922178008480377006528793506649089253164524883696044759651305970802215270721223149734532870729533611357047595181907404222690394917605617029675103788705320032707977225447998111744887898039756375876685711148857676502670812333076878964148863713993853526715855758799502735753454247721711366497722251078739585, 46186240819076690248235492196228128599822002268014359444368898414937734806009161030424589993541799877081745454934484263188270879142125136786221625234555265815513136730416539407710862948861531339065039071959576035606192732936477944770308784472646015244527805057990939765708793705044236665364664490419874206900, 85756449024868529058704599481168414715291172247059370174556127800630896693021701121075838517372920466708826412897794900729896389468152213884232173410022054605870785910461728567377769960823103334874807744107855490558726013068890632637193410610478514663078901021307258078678427928255699031215654693270240640198, 14388767329946097216670270960679686032536707277732968784379505904021622612991917314721678940833050736745004078559116326396233622519356703639737886289595860359630019239654690312132039876082685046329079266785042428947147658321799501605837784127004536996628492065409017175037161261039765340032473048737319069656, 1143736792108232890306863524988028098730927600066491485326214420279375304665896453544100447027809433141790331191324806205845009336228331138326163746853197990596700523328423791764843694671580875538251166864957646807184041817863314204516355683663859246677105132100377322669627893863885482167305919925159944839, 2978800921927631161807562509445310353414810029862911925227583943849942080514132963605492727604495513988707849133045851539412276254555228149742924149242124724864770049898278052042163392380895275970574317984638058768854065506927848951716677514095183559625442889028813635385408810698294574175092159389388091981, 16200944263352278316040095503540249310705602580329203494665614035841657418101517016718103326928336623132935178377208651067093136976383774189554806135146237406248538919915426183225265103769259990252162411307338473817114996409705345401251435268136647166395894099897737607312110866874944619080871831772376466376, 31551601425575677138046998360378916515711528548963089502535903329268089950335615563205720969393649713416910860593823506545030969355111753902391336139384464585775439245735448030993755229554555004154084649002801255396359097917380427525820249562148313977941413268787799534165652742114031759562268691233834820996, 25288164985739570635307839193110091356864302148147148153228604718807817833935053919412276187989509493755136905193728864674684139319708358686431424793278248263545370628718355096523088238513079652226028236137381367215156975121794485995030822902933639803569133458328681148758392333073624280222354763268512333515]

# print(len(n_list))
# print(len(c_list))
# 9

import gmpy2
from Crypto.Util.number import *
from functools import reduce
import sympy

def chinese_remainder(n, a):
sum = 0
prod = reduce(lambda a, b: a * b, n)

for n_i, a_i in zip(n, a):
p = prod // n_i
sum += a_i * sympy.invert(p, n_i) * p
return int(sum % prod)

m_e = chinese_remainder(n_list,c_list)
e = 9

m , f = gmpy2.iroot(m_e,e) # m^e 开e次根
# print('e = %d'%e)
print(m)
flag = long_to_bytes(m)
print(flag)
# b'flag{H0w_Fun_13_HAstads_broadca5t_AtTack!}\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16'

[鹤城杯 2021]A_CRYPTO

题目

4O595954494Q32515046324757595N534R52415653334357474R4N575955544R4O5N4Q46434S4O59474253464Q5N444R4Q51334557524O5N4S424944473542554O595N44534O324R49565746515532464O49345649564O464R4R494543504N35rot47 解码得到

cdhdhdcchc"badd_cebacfdfdhd}dbc#dacdedbbbcbdfcfc#c}dfdhdddcc#cd}c"cecbc\(c~dhcfcadbcec"d}ccc#c"d`bbcddfdac~d}c\)cachcccfbdcaddcdhd}ccdbcbac#chdedfced`ddbacecchbcdechdeccec#c#chcdcbd_c}bd

这里rot47不行 需要用rot13解码

WP

1
2
3
4
5
6
7
8
9
10
11
12
13
import base64
cipher = '4O595954494Q32515046324757595N534R52415653334357474R4N575955544R4O5N4Q46434S4O59474253464Q5N444R4Q51334557524O5N4S424944473542554O595N44534O324R49565746515532464O49345649564O464R4R494543504N35'
rot13cipher = '4B595954494D32515046324757595A534E52415653334357474E4A575955544E4B5A4D46434F4B59474253464D5A444E4D51334557524B5A4F424944473542554B595A44534B324E49565746515532464B49345649564B464E4E494543504A35'
rot47cipher = 'c~dhdhdcchc"bad`d_cebacfdfdhd}dbc#dac`dedbbbcbdfcfc#c}dfdhdddcc#c~d}c"cecbc$c~dhcfcadbcec"d}ccc#c"d`bbcddfdac~d}c$cachcccfbdcaddc~dhd}ccdbc~bac#chdedfced`ddbacec~chbcdechdec~cec#c#chcdcbd_c}bd'

print(base64.b16decode(rot13cipher))
# KYYTIM2QPF2GWYZSNRAVS3CWGNJWYUTNKZMFCOKYGBSFMZDNMQ3EWRKZOBIDG5BUKYZDSK2NIVWFQU2FKI4VIVKFNNIECPJ5
print(base64.b32decode(base64.b16decode(rot13cipher)))
# b'V143Pytkc2lAYlV3SlRmVXQ9X0dVdmd6KEYpP3t4V29+MElXSER9TUEkPA=='
print(base64.b64decode(base64.b32decode(base64.b16decode(rot13cipher))))
# b'W^7?+dsi@bUwJTfUt=_GUvgz(F)?{xWo~0IWHD}MA$<'
print(base64.b85decode(base64.b64decode(base64.b32decode(base64.b16decode(rot13cipher)))))
# b'flag{W0w_y0u_c4n_rea11y_enc0d1ng!}'

[鹤城杯 2021]easy_crypto

题目

公正公正公正诚信文明公正民主公正法治法治诚信民主自由敬业公正友善公正平等平等法治民主平等平等和谐敬业自由诚信平等和谐平等公正法治法治平等平等爱国和谐公正平等敬业公正敬业自由敬业平等自由法治和谐平等文明自由诚信自由平等富强公正敬业平等民主公正诚信和谐公正文明公正爱国自由诚信自由平等文明公正诚信富强自由法治法治平等平等自由平等富强法治诚信和谐

WP

https://atool.vip/corevalue/ 社会主义核心价值观编码 直接接触flag

flag{IlUqU9O5guX6YiITsRNPiQmbhNRjGuTP}

[羊城杯 2022]EasyRsa 【共享素数】

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from flag import flag
from Crypto.Util.number import *

m = bytes_to_long(flag)
e = 65537
f = open("output.txt", "r")
a = f.readlines()
for i in a:
n = int(i)
c = pow(m, e, n)
m = c

# c1 m1=c1
# c2 = pow(c1,e,n)
# ci = pow(ci-1,e,n)
# 每次取文本中的数作为 加密的模数
# 每次得到的密文会作为下一次的明文进行加密
# 也就可以理解为 连续加密了len(a)遍 每次都用不同的模数

# 已知最后一次加密的密文 c 最后一次加密的模数n 指数e
# 使用多组模数 可以有限考虑 模数共用素因子


print 'c = %s' % (m)
f.close()

c = 38127524839835864306737280818907796566475979451567460500065967565655632622992572530918601432256137666695102199970580936307755091109351218835095309766358063857260088937006810056236871014903809290530667071255731805071115169201705265663551734892827553733293929057918850738362888383312352624299108382366714432727


65439077968397540989065489337415940784529269429684649365065378651353483030304843439003949649543376311871845618819107350646437252980144978447924976470943930075812834237368425374578215977641265884859875440799334807607478705932175148673160353577875890074101393042506714001617338265284910381849259298772642190619
86843235426823545017422014398916780909062053456790256392304973548517489132984667679637386416948409930796162377844525829968317585749956057149930523547463230147376192820753802868362225137830225967953826475779047454555958271846035526319036389127587352017149417549187850782892924691511398536178090031958365483499
57839320383142814687522363258949714784622321678585619281948174372461045134361003939684803510572969567182690634502610963365500727981041136988638273942465134797850643121827808482673619534240872593224537996099454035648829692386918230535360101064254854063175494150147494342652670585674593236663514793256521719547
52668168898129361356420333177679019946307853075463961068071790653159090226904625885080236174231665178538405547828768043706515464922611051221394704678558922339886480247663138702481349098077291584992082414494275463670330534613607852999291645500391111597009868188974671249118213040057429113174377610094956993269
79875848044631194160351918105738804229446748736206976033243436373010695259945613104837645712048695514204494137005015770637421510392760763371639480133851920449252506525423837434811693638210458851990502785655738042348115385964604080872180121543147063180945532713593712726527002909054818485584237993215139630243
73100501797447180147684637554796375398455002202770022931512541062214916136294604754404667725341796896161398464327153718845280194035978972665664657052946003418121755545770123205426883869361411412259838522099085901563107814985172942977520233320215882707710717870398128412272218474014381169303848087621856187879
89149546555397759430343098936690138982544367561661914051499112345535238108800665531588376806546499374457634397161670140520060064963391826220177798442707381640723248034061313974522233415815795656570220902974484865176728535660627712374835329967608728216749734529761431592345816592875807318876347151421393671763
66449107450661172442868032153863675098235855689218695279414435182923510356012957155941548483160873271040452368644926703812707864779900715051152673705082002761445847561495295455460041902473282731259268870375921215589157288622757488879539441498396276257589120302991242300378364101246448094955634459779361686643
79694880331320743031437708811856697413105291652061062223857313580221562305807771003185061831752133665835648647560103986928466217390444724672894866216636981793418219455653595717274553950715056120806463449033181486699963584346517910081706586345546292894426402568226579894766693070066214488743160957135286739213
70521001788476157145543175674209083194325853388116385624440232036679708917857095748070597575068955423165296665429648694541353249787337464272095260410717659726012806836884799476995758902361678737968193674368688353935424186389207123637734230550266810766585903134004322848985320790788169777840924595645463787189
51801430118171456966246071852561156183140136541960623661080056673664466785669585092926482194691254461430866302262960624015915371927788809661387318097968209364907625599562339722700041444342116899266802018340155635959614677597708758012024981583143521259152639480003228924151971208695043251548758407218187895663
87310111118839703578797261862424304499548882114635944516216618095145194843718635007052242072452831460162126955481326379219639313067967998826898344673513019946299427614605216960081461930080199023399060417820769438661351988322185620598552697590115678078498754112860310272842870106790357443602405008865116282919

WP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from Crypto.Util.number import long_to_bytes
import gmpy2
c = 38127524839835864306737280818907796566475979451567460500065967565655632622992572530918601432256137666695102199970580936307755091109351218835095309766358063857260088937006810056236871014903809290530667071255731805071115169201705265663551734892827553733293929057918850738362888383312352624299108382366714432727

e = 65537

with open("output.txt","r") as fp:
n_list = fp.read().splitlines()
print(n_list)
print(type(int(n_list[0])))
print(len(n_list))

p = gmpy2.gcd(int(n_list[0]),int(n_list[1]))

for i in range(len(n_list)-1):
assert gmpy2.gcd(int(n_list[0]),int(n_list[1])) == p
print("[+] 存在公因数",p)

for n in n_list[::-1]:
q = int(n) // p
d = gmpy2.invert(e,(q-1)*(p-1))
m = pow(c,d,int(n))
c = m
print(long_to_bytes(m))
# b'GWHT{gixkJl7SJTcpLOL9zqwo}'

[zer0pts 2020]ROR

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import random
from secret import flag

ror = lambda x, l, b: (x >> l) | ((x & ((1<<l)-1)) << (b-l))
# 循环右移 2|n -> c的最低位就是m的最低位
# 遍历所有的 c的最低位 合并即可得到m

N = 1
for base in [2, 3, 7]:
N *= pow(base, random.randint(123, 456))
# N = 2^x * 3^y * 7^z

# 奇 * 奇 = 奇
# 偶 * 偶 = 偶
# 奇 * 偶 = 奇
# 所以 N最终为2的倍数 为偶数 对应的最后一个二进制字符为 1

# 当A > B时:
# 若B为偶数,A % B的奇偶性同A的奇偶性一致
# 若B为奇数,A % B的奇偶性同A的奇偶性相反
# 当A < B时:
# A % B的奇偶性与A一致

# N > m N为偶数 所以m 也就是偶数
# 对应 pow(c,d,n) 也为偶数
# 所以每次得到的结果中 最后一个 1bit位 和 m的最后一个bit位一样
# 所以求每个C的最后一个二进制位 组合起来就是 m

e = random.randint(271828, 314159)

m = int.from_bytes(flag, byteorder='big')
assert m.bit_length() < N.bit_length()

for i in range(m.bit_length()):
print(pow(ror(m, i, m.bit_length()), e, N))


# C = ( ror(m,i,m.len) ) ^e mod n

WP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from Crypto.Util.number import long_to_bytes

flag=''
f=open('chall.txt','r').readlines()
li=[]
for i in f:
li.append(int(i.strip('\n')))
# print(li)

for i in li:
flag+=bin(i)[-1]

print(flag)
print(hex(int(flag,2)))
print(long_to_bytes(eval('0b'+flag[::-1])))

#zer0pts{0h_1t_l34ks_th3_l34st_s1gn1f1c4nt_b1t}

[2020年第三届安洵杯] easyaes

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/usr/bin/python
from Crypto.Cipher import AES
import binascii
from Crypto.Util.number import bytes_to_long
from flag import flag
import random
import string
import os

def genkey(l):
return random.getrandbits(l)
# 求iv 去除掉收尾指定字符串
iv = flag.strip(b'flag{').strip(b'}')

key = ''.join([random.choice(string.ascii_letters+string.digits) for _ in xrange(16)])
LENGTH = len(key)
# 16字节 所以会使用16个字符或长度为16的字符串做密码
assert LENGTH == 16

# 32字节 且为4个字符(32bit)的重复 32bit*8
# 每个字节由 2个十六进制字符表示 所以有 32*2=64个十六机制字符
hint = os.urandom(4) * 8
print(bytes_to_long(hint)^bytes_to_long(key))

# 64 / 16 =4
msg = b'Welcome, ctfer. Dont try too hard, its no use. Have a good day!!'

def encrypto(message):
aes = AES.new(key,AES.MODE_CBC,iv)
return aes.encrypt(message)

# 对msg AES加密后 转十六进制后 输出后32位
print(binascii.hexlify(encrypto(msg))[-32:])

'''
99748265546679089946917295913637945222843938798184123305418691873367322323659
bc03f3ac4ff8064acbcfaf0b0bf2ba7b
'''

题目分析

http://f0und.icu/article/27.html 刚接触时候跟着看了下wp和解题思路学习了下

解密流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
msg[0] = decrypt(enc1,key)^iv
msg[1] = decrypt(enc2,key)^enc1
msg[2] = decrypt(enc3,key)^enc2
msg[3] = decrypt(enc4,key)^enc3
msg = msg[0]+msg[1]+msg[2]+msg[3]


iv = msg[0] ^ decrypt(enc1,key)
enc1 = msg[1] ^ decrypt(enc2,key)
enc2 = msg[2] ^ decrypt(enc3,key)
enc3 = msg[3] ^ decrypt(enc4,key)


其中 已知如下:
hint^key = tmp -> key = tmp^hint
enc4
msg[0] msg[1] msg[2] msg[3]
所以可以推出iv来 得到flag

WP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/python
from Crypto.Util.number import long_to_bytes
import binascii, sys
from Crypto.Util.strxor import strxor
from Crypto.Cipher import AES

# -----------get key---------

# tmp = hint ^ key -> key = tmp ^ hint
tmp = 99748265546679089946917295913637945222843938798184123305418691873367322323659
# hint为32字节 key为16字节 所以异或后 tmp高位就是 hint的高位
# [2:10] 前面有0x 所以从第二位开始取8位
# 32字节 64个十六进制字符
hint = int(str(hex(tmp))[2:10] * 8, 16)
key = long_to_bytes(tmp ^ hint)

# ----------get iv-----------
msg = b'Welcome, ctfer. Dont try too hard, its no use. Have a good day!!'
msgs = [msg[ii:(ii + 16)] for ii in range(0, len(msg), 16)]

print(msgs)
# [b'Welcome, ctfer. ', b'Dont try too har', b'd, its no use. H', b'ave a good day!!']

msgs.reverse()
# msg[3] msg[2] msg[1] msg[0]
# [b'ave a good day!!', b'd, its no use. H', b'Dont try too har', b'Welcome, ctfer. ']


IV = binascii.unhexlify('bc03f3ac4ff8064acbcfaf0b0bf2ba7b')


# iv = msg[0] ^ decrypt(enc1,key)
# enc1 = msg[1] ^ decrypt(enc2,key)
# enc2 = msg[2] ^ decrypt(enc3,key)
# enc3 = msg[3] ^ decrypt(enc4,key)

def decry(key, IV, ms):
aes = AES.new(key, AES.MODE_ECB)
return strxor(aes.decrypt(IV), ms)


for ms in msgs:
IV = decry(key, IV, ms)
print(b'flag{' + IV + b'}')

[ACTF新生赛2020]crypto-aes

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from Cryptodome.Cipher import AES
import os
import gmpy2
from flag import FLAG
from Cryptodome.Util.number import *

def main():
key=os.urandom(2)*16
iv=os.urandom(16)
print(bytes_to_long(key)^bytes_to_long(iv))
aes=AES.new(key,AES.MODE_CBC,iv)
enc_flag = aes.encrypt(FLAG)
print(enc_flag)
if __name__=="__main__":
main()

# 91144196586662942563895769614300232343026691029427747065707381728622849079757
# b'\x8c-\xcd\xde\xa7\xe9\x7f.b\x8aKs\xf1\xba\xc75\xc4d\x13\x07\xac\xa4&\xd6\x91\xfe\xf3\x14\x10|\xf8p'

题目分析

1
2
3
bit位  bytes字节
1 bytes = 8bits
1 字节 = 2个十六进制字符

key 32bytes 256bits

iv 16bytes 128bits

key和iv 进行低128位进行异或,所以key的高128bits固定不变,所以输出结果的高128bits即 key的高128bits tmp[16:]

tmp = key ^ iv -> iv = tmp ^ key 与key低16位异或 得到iv

所以可以得到key全部256bits

1
2
3
4
5
6
7
8
9
10
11
12
out = 91144196586662942563895769614300232343026691029427747065707381728622849079757
tmp = long_to_bytes(out)
key = tmp ^ iv
iv = key ^ tmp


aes=AES.new(key,AES.MODE_CBC,iv)
enc_flag = aes.encrypt(FLAG)
需要知道 key 和 iv 就可以得到flag

其中 key 32字节 iv 16字节
已知 tmp = key ^ iv -> iv = tmp ^ key

wp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

#python3
from Crypto.Cipher import AES
import os
from Crypto.Util.number import*

xor = 91144196586662942563895769614300232343026691029427747065707381728622849079757
tmp = long_to_bytes(xor)
print(tmp)

enc_flag = b'\x8c-\xcd\xde\xa7\xe9\x7f.b\x8aKs\xf1\xba\xc75\xc4d\x13\x07\xac\xa4&\xd6\x91\xfe\xf3\x14\x10|\xf8p'
# key 为啥低16字节也是呢 key = tmp[:16]*2 ??
# key=os.urandom(2)*16 前面题目给出高低16字节相同 所以直接*2即可
key = tmp[:16]*2
print(key)
# iv = key^tmp
iv = bytes_to_long(key[16:])^bytes_to_long(tmp[16:])
print(iv)
iv = long_to_bytes(iv)
print(iv)
aes = AES.new(key,AES.MODE_CBC,iv)
flag = aes.decrypt(enc_flag)
print(flag)

babyAES

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from Crypto.Cipher import AES
import os
iv = os.urandom(16)
key = os.urandom(16)
my_aes = AES.new(key, AES.MODE_CBC, iv)
flag = open('flag.txt', 'rb').read()
flag += (16 - len(flag) % 16) * b'\x00'
c = my_aes.encrypt(flag)
print(c)
print(iv)
print(key)

'''
b'C4:\x86Q$\xb0\xd1\x1b\xa9L\x00\xad\xa3\xff\x96 hJ\x1b~\x1c\xd1y\x87A\xfe0\xe2\xfb\xc7\xb7\x7f^\xc8\x9aP\xdaX\xc6\xdf\x17l=K\x95\xd07'
b'\xd1\xdf\x8f)\x08w\xde\xf9yX%\xca[\xcb\x18\x80'
b'\xa4\xa6M\xab{\xf6\x97\x94>hK\x9bBe]F'
'''

题目分析

已知 iv key 密文c CBC模式

直接 aes解密可得到明文

WP

1
2
3
4
5
6
7
8
9
from Crypto.Cipher import AES
c = b'C4:\x86Q$\xb0\xd1\x1b\xa9L\x00\xad\xa3\xff\x96 hJ\x1b~\x1c\xd1y\x87A\xfe0\xe2\xfb\xc7\xb7\x7f^\xc8\x9aP\xdaX\xc6\xdf\x17l=K\x95\xd07'
iv = b'\xd1\xdf\x8f)\x08w\xde\xf9yX%\xca[\xcb\x18\x80'
key = b'\xa4\xa6M\xab{\xf6\x97\x94>hK\x9bBe]F'

Cipher = AES.new(key,AES.MODE_CBC,iv)
decrypted = Cipher.decrypt(c)
print(decrypted)
# b'Dest0g3{d0e5fa76-e50f-76f6-9cf1-b6c2d576b6f4}\x00\x00\x00'

MyOwnCBC

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-

from Crypto.Cipher import AES
from Crypto.Random import random
from Crypto.Util.number import long_to_bytes

def MyOwnCBC(key, plain):
# key 32位 但key未知
if len(key)!=32:
return "error!"
cipher_txt = b""
cipher_arr = []
# 自定义加密 ECB
cipher = AES.new(key, AES.MODE_ECB, "")
# 等价于 cipher = AES.new(key, AES.MODE_ECB)
plain = [plain[i:i+32] for i in range(0, len(plain), 32)]
# 32位(16字节)为一组 然后进行ECB加密
print plain
# 加密后 存入密文数组
cipher_arr.append(cipher.encrypt(plain[0]))
cipher_txt += cipher_arr[0]

# cipher_txt = [cipher_arr[i]]
# 上一个密文 作为 下一个密文的密钥key进行加密
# key0 为第一组的密文 即 key0 = cipher[0:32]
# 然后以 前一个 cipher_arr[i-1]作为key 进行ecb加密
# cipher_arr[i-1] ^ cipher_arr[i]
for i in range(1, len(plain)):
cipher = AES.new(cipher_arr[i-1], AES.MODE_ECB, "")
cipher_arr.append(cipher.encrypt(plain[i]))
cipher_txt += cipher_arr[i]
return cipher_txt

# 生成256位的随机整数
key = random.getrandbits(256)
key = long_to_bytes(key)

s = ""
with open("flag.txt","r") as f:
s = f.read()
f.close()

# 密文写入到flag_cipher 是已知项
# 长度为 6A0h = 1696
# 1696 / 32 = 53组
# 由于上一个密文作为key 参与下一次密文加密 所以长度都相同
with open("flag_cipher","wb") as f:
f.write(MyOwnCBC(key, s))
f.close()

题目分析

plain = [plain[i:i+32] for i in range(0, len(plain), 32)] # 32位一组

第一次密文 作为密钥key0参与ECB加密 key = cipher[:32]

WP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from Crypto.Cipher import AES
from Crypto.Util.number import long_to_bytes

with open("flag_cipher", "rb") as fp:
# print(len(fp.read()))
cipher = fp.read()
fp.close()

key0 = cipher[:32]
print(key0)

def MyOwnCBC(key0,cipher):
cipher = [cipher[i:i + 32] for i in range(0, len(cipher), 32)]
m = b''
tmpkey = key0
# 上一次的密文作为key参与下一次ECB
for i in range(1,len(cipher)):
aes = AES.new(tmpkey,AES.MODE_ECB)
m += aes.decrypt(cipher[i])
tmpkey = cipher[i]
return m

print(MyOwnCBC(key0,cipher))
#b'\xe5\xdf\x94sJ\xc2\xcd\x04\xeb\xb7\xcf\x05(\xbe\x98\\\xe9\xc3^\x1f!\xfb\xea6\xdac\x1f\xfe\x901\xbb\x13'
#b"mode of operation is an algorithm that uses a block cipher to provide an information service such as confidentiality or authenticity. A block cipher by itself is only suitable for the secure cryptographic transformation (encryption or decryption) of one fixed-length group of bits called a block. A mode of operation describes how to repeatedly apply a cipher's single-block operation to securely transform amounts of data larger than a block.\n\nMost modes require a unique binary sequence, often called an initialization vector (IV), for each encryption operation. The IV has to be non-repeating and, for some modes, random as well. The initialization vector is used to ensure distinct ciphertexts are produced even when the same plaintext is encrypted multiple times independently with the same key. Block ciphers have one or more block size(s), but during transformation the block size is always fixed. Block cipher modes operate on whole blocks and require that the last part of the data be padded to a full block if it is smaller than the current block size. There are, however, modes that do not require padding because they effectively use a block cipher as a stream cipher.\n\nHistorically, encryption modes have been studied extensively in regard to their error propagation properties under various scenarios of data modification. Later development regarded integrity protection as an entirely separate cryptographic goal. Some modern modes of operation combine confidentiality and authenticity in an efficient way, and are known as authenticated encryption modes.\n\nAh you found it~ afctf{Don't_be_fooled_by_yourself}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"


moectf ez_cbc

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from Crypto.Util.number import *
import random
from secret import flag

IV = bytes_to_long(b'cbc!')
K = random.randrange(1,1<<30)

assert flag[:7] == b'moectf{'
assert flag[-1:] == b'}'

block_length = 4
flag = flag + ((block_length - len(flag) % block_length) % block_length) * b'\x00'
plain_block = [flag[block_length * i: block_length * (i + 1)] for i in range(len(flag) // block_length)]

c = []
c0 = (IV ^ bytes_to_long(plain_block[0])) ^ K
c.append(c0)

for i in range(len(plain_block)-1):
c.append(c[i] ^ bytes_to_long(plain_block[i+1]) ^ K)

print(c)

'''
[748044282, 2053864743, 734492413, 675117672, 1691099828, 1729574447, 1691102180, 657669994, 1741780405, 842228028, 1909206003, 1797919307]
'''
# flag = moectf{ }

题目分析

block_length =4 且 已知flag前四位为 moec

所以可以通过此去恢复K

密文块 = 明文块 ^ iv ^ K

明文块 = 密文块 ^ iv ^ K

K = 密文块 ^ 明文块 ^ iv

K = IV ^ bytes_to_long(plain_block[0]) ^ c[0]

WP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from Crypto.Util.number import *

c = [748044282, 2053864743, 734492413, 675117672, 1691099828, 1729574447, 1691102180, 657669994, 1741780405, 842228028, 1909206003, 1797919307]
IV = bytes_to_long(b'cbc!')
block_length = 4

flag = b'moectf{'
plain_block = [flag[block_length * i: block_length * (i + 1)] for i in range(len(flag) // block_length)]

K = IV ^ bytes_to_long(plain_block[0]) ^ c[0]
print(K)

m = b''
for i in range(len(c)-1):
m += long_to_bytes(c[i]^c[i+1]^K)
print(m)

print(b'moec'+m)
# 580598200
# b'tf{es72b!a5-njad!@-#!@$sad-6bysgwy-1adsw8}\x00\x00'
# b'moectf{es72b!a5-njad!@-#!@$sad-6bysgwy-1adsw8}\x00\x00'

moectf ez_chain

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from Crypto.Util.number import *

with open("key.txt", "r") as fs:
key = int(fs.read().strip())
with open("flag.txt", "rb") as fs:
flag = fs.read().strip()
assert len(flag) == 72

m = bytes_to_long(flag)

base = bytes_to_long(b"koito")
iv = 3735927943

def blockize(long):
out = []
while long > 0:
out.append(long % base)
long //= base
return list(reversed(out))

blocks = blockize(m)

def encrypt_block_cbc(blocks, iv, key):
encrypted = [iv]
for i in range(len(blocks)):
encrypted.append(blocks[i] ^ encrypted[i] ^ key)
return encrypted[1:]

print(encrypt_block_cbc(blocks, iv, key))
# [8490961288, 122685644196, 349851982069, 319462619019, 74697733110, 43107579733, 465430019828, 178715374673, 425695308534, 164022852989, 435966065649, 222907886694, 420391941825, 173833246025, 329708930734]

题目分析

写一个 decrypt_block_cbc 和 deblockize函数

K = 密文块 ^ 明文块 ^ iv

WP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from Crypto.Util.number import *

base = bytes_to_long(b"koito")
iv = 3735927943

blocks = [8490961288, 122685644196, 349851982069, 319462619019, 74697733110, 43107579733, 465430019828, 178715374673, 425695308534, 164022852989, 435966065649, 222907886694, 420391941825, 173833246025, 329708930734]

def blockize(long):
out = []
while long > 0:
# 取余数 存入 out
out.append(long % base)
long //= base
return list(reversed(out))

def deblockize(blocks):
out = 0
for block in blocks:
out = out * base + block
return out

def encrypt_block_cbc(blocks, iv, key):
encrypted = [iv]
for i in range(len(blocks)):
encrypted.append(blocks[i] ^ encrypted[i] ^ key)
return encrypted[1:]
# blocks[0] ^ iv ^ key = flag[0]

def decrypt_block_cbc(blocks, iv, key):
# iv 初始化向量
encrypted = [iv, *blocks]
decrypted = []
for i in range(len(blocks)):
decrypted.append(encrypted[i] ^ encrypted[i + 1] ^ key)
return decrypted

# flag = moectf{xxx}
# 72个字符 其中 moectf 6 {} 2 72-2-6=64个
# flag[0] = blocks[0] ^ key ^ iv
# key = iv ^ blocks[0] ^ flag[0]
print("flag:",blockize(bytes_to_long(b"moectf{" + b"0"*64 + b"}"))[0] )
# print(blockize(bytes_to_long(b"moectf{" + b"0"*64 + b"}")))
key = blockize(bytes_to_long(b"moectf{" + b"0"*64 + b"}"))[0] ^ iv ^ blocks[0]
m = long_to_bytes(deblockize(decrypt_block_cbc(blocks, iv, key)))

print("key:",key)
print(m)

aes3

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
rom Crypto.Cipher import AES
import binascii
import hashlib
from secret import flag

assert flag[:5] == "flag{" and flag[-1:] == "}"

key = b"J1fx2g1jDak1c***"
l = len(key)

message = b"I have had my invitation to this world's festival, and thus my life has been blessed" + binascii.unhexlify(hashlib.sha256(key).hexdigest())[:10]

iv = flag[5:-1]
message = message + bytes((l - len(message) % l) * chr(l - len(message) % l), encoding = "utf-8")
aes = AES.new(key, AES.MODE_CBC, iv)
print(binascii.hexlify(aes.encrypt(message)))
#******************************************************************************************************************************************************6ece036e495d363b647d7f2749c4c2f3dd78f8637b

题目分析

1.key后三位未知 可爆破

2.明文message 分3部分 第一部分明文已知,中间部分 10个十六进制字符 后部分为 2个0x02 共192个十六进制字符

message = message + bytes((l - len(message) % l) * chr(l - len(message) % l), encoding = "utf-8")

即 bytes((16-94)%16 * chr((16-(94%16))))

= bytes(2 * chr (2) ) -> 0x02 0x02

3.iv = flag[5:-1] 即flag{iv} 求出iv即flag

4.已知明文后21字节 根据分组 每组16字节 所以已知最后一块明文 及 倒数第二块后5字节明文

在CBC中 与ECB相比 多的部分为IV 异或一步

密文 ^ key (AES_ECB) ^ IV → 明文

最后一块的明文已知

key 可通过爆破后三位

最后一块的密文为 b"ssed" + binascii.unhexlify(hashlib.sha256(key).hexdigest())[:10] + bytes((l - len(message) % l) * chr(l - len(message) % l) 如果key已知 则密文也就是已知的

我们还知道倒数第二块中的后5个字节 可以作为最后一次加密的IV 的一部分进行校验

IV = 明文 ^ ( 密文 ^ key )

如果 结果中包含 已知的5个字节 说明key正确

求得key后 可进而推出 IV 即 flag

Plaintext[0] = Ciphertext[0] ^ key ^ IV

Plaintext[1] = Ciphertext[1] ^ key ^ Ciphertext[0]

Plaintext[2] = Ciphertext[2] ^ key ^ Ciphertext[1]

知道最后一个明文 密文 key 以此反复推出IV

WP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from Crypto.Cipher import AES
from tqdm import tqdm
import binascii
import hashlib


# 1. 生成key字典
import string

dic = string.printable[:62]
# print(dic)
# 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
with open('key_table.txt','wb') as file:
for i in dic:
for j in dic:
for k in dic:
key = b"J1fx2g1jDak1c"+i.encode()+j.encode()+k.encode()
file.write(key+b'\n')

file.close()

# 2.爆破key
def xor(m: bytes, c: bytes):
return bytes([i ^ j for i, j in zip(m, c)])

enc = binascii.unhexlify('5d363b647d7f2749c4c2f3dd78f8637b')
five_part = binascii.unhexlify(b"6ece036e49")
f = open("key_table.txt","rb+")
pbar = tqdm(range(238328))
for i in f:
key = i[:16]
aes = AES.new(key, AES.MODE_ECB)
dec = aes.decrypt(enc)
# 一块 16个字节 4+10+2
m = b"ssed" +binascii.unhexlify(hashlib.sha256(key).hexdigest())[:10]+b'\x02\x02'
xor_result = xor(m,dec)
pbar.update(1)
if five_part in xor_result:
print("[+] key:",key)
break
f.close()

# 3.求IV
l = len(key)
# 192
message = b"I have had my invitation to this world's festival, and thus my life has been blessed" + binascii.unhexlify(hashlib.sha256(key).hexdigest())[:10]
message = message + bytes((l - len(message) % l) * chr(l - len(message) % l), encoding="utf-8")
for i in range(0,len(message),16):
aes_ecb = AES.new(key,AES.MODE_ECB)
dec_c = aes_ecb.decrypt(enc)
enc = xor(message[len(message)-i-16:len(message)-i],dec_c)
print(b'flag{'+enc+b'}')

欢迎关注我的其它发布渠道

------------- 💖 🌞 本 文 结 束 😚 感 谢 您 的 阅 读 🌞 💖 -------------