# Crypto - Freshman ## Phiphai > Free Fire la tua game ban sung sinh ton nhieu nguoi choi so 1 vi en Flag format: W1{A-Za-z0-9_} Author: dvck13 Source chall: ```python3= from Crypto.Util.number import * flag = b'W1{?????????????}' m = bytes_to_long(flag) e = 0x10001 p = getPrime(1024) q = getPrime(1024) n = p*q e = 65537 phi = (p-1)*(q-1) d = pow(e, -1, phi) hint = p+q c = pow(m,e,n) print(f"e={e}") print(f"d={d}") print(f"hint={hint}") print(f"c={c}") ''' e=65537 d=4504287984018183537713208161402766323065548618393723872837173606374276398491834181934336417310620387990925189536232872881499528612504958202701279049935780903977608853793957819684386053139789777966936156264230499424635837453895019683637553474699470241265384239892304309743522811693909773853204104744746499940669186347989219693819334120860342801601135658920550816397929837218587842050717426094705159184294217221659550021174121437354727563286401517383250923022292331155286641664114777714280910808217996581853423619501922201519238297960634332127751600929842715997073072544823353485994644594610107896462399877655553045761 hint=231925193905919836406214406898885408169720762556845482044575179755202576770665967750292209535638389585617923204488598005919071680696574306168950409350364369661185363429309191455686049593246205245617043129829360203967945465085196018291809693305049028207915207766096530755343783712735226590596701430255772594556 c=6217038084836470023310381029897048208087224587728895918727075557465841714766785434203795384404277685883194699549944699326316064489862857903738642081680285228167738881574533344177255570731527611503589831001734795490242158816621194509455025049486128406587545324515046616431849802141624745659660349892441242897503306780984369111460208907969417056103375189617092555003582813739896435112054576310776891033107119212517760203084951964632014280482552024983115272574743031704179104705817029355755554440364213319205880788661502753344785708858216051846295494426952842154398100557142240912181225765846610290283305931102820798460 ''' ``` Ở bài này, là một bài mã hóa RSA cơ bản. Đầu tiên ta có công thức RSA như sau: ![image](https://hackmd.io/_uploads/HkPUvP1Ceg.png) Với bài trên đã cho $e$, $d$, $c$ và $hint$ với $hint$ = $p$ + $q$ Đầu tiên ta cần tìm được $n$ Ta có: $phi$ = $(p - 1)$$(q - 1)$ = $pq$ - $(p + q)$ + $1$ = $n$ - $hint$ + $1$ $d = pow(e, -1, phi)$ => $e*d$ = $1 + k*phi$ => $e*d -1$ = $k*phi$ => $e*d$ = $k * (n - hint + 1)$ Sau đó ta sẽ brute force $k$ và giải mã RSA để tìm flag. Sau đây là sol script: ```python3= from Crypto.Util.number import long_to_bytes e=65537 d=4504287984018183537713208161402766323065548618393723872837173606374276398491834181934336417310620387990925189536232872881499528612504958202701279049935780903977608853793957819684386053139789777966936156264230499424635837453895019683637553474699470241265384239892304309743522811693909773853204104744746499940669186347989219693819334120860342801601135658920550816397929837218587842050717426094705159184294217221659550021174121437354727563286401517383250923022292331155286641664114777714280910808217996581853423619501922201519238297960634332127751600929842715997073072544823353485994644594610107896462399877655553045761 hint=231925193905919836406214406898885408169720762556845482044575179755202576770665967750292209535638389585617923204488598005919071680696574306168950409350364369661185363429309191455686049593246205245617043129829360203967945465085196018291809693305049028207915207766096530755343783712735226590596701430255772594556 c=6217038084836470023310381029897048208087224587728895918727075557465841714766785434203795384404277685883194699549944699326316064489862857903738642081680285228167738881574533344177255570731527611503589831001734795490242158816621194509455025049486128406587545324515046616431849802141624745659660349892441242897503306780984369111460208907969417056103375189617092555003582813739896435112054576310776891033107119212517760203084951964632014280482552024983115272574743031704179104705817029355755554440364213319205880788661502753344785708858216051846295494426952842154398100557142240912181225765846610290283305931102820798460 tmp = d * e - 1 for i in (range(1,100000)): if tmp % i == 0: phi = tmp // i n = phi + hint - 1 m = pow(c,d,n) flag = long_to_bytes(m) if b'W1{' in flag: print(flag) ``` **Flag: W1{phi_phai_la_game_rac_so_1_vn}** ## phiphai2 > Just kidding, I play this game too Flag Format: W1{A-Za-z0-9_} Author: dvck13 Source chall: ```python3= from Crypto.Util.number import * flag = b'W1{???????????}' p = getPrime(1024) q = getPrime(1024) e = 65537 n = p*q leak = (p**2+q**2) % n ct = pow(bytes_to_long(flag),e, n) print(f'{n = }') print(f'{leak = }') print(f'{ct = }') ''' n = 20842938351896783351765564497257406689875073939168847270109018452331595953195137925905407574790509131975169442262183423216630782056006817670026102637100795102868553295795605909294220001159170312214938967565708237131119660898946450453038715919305770854433454485282482531591669338374784896696254086081923985254456532726474557269047987653955703675146699130077388795028830171715932232259532178061195603162554212575207799198670246556909810593997402979919324116015029695269687378794139114073155816838415492318483626370434226417328166879349978988600491401399315534138391936796615782306743416152563145103425347897571269559877 leak = 1246889223294307854370712989427585884021285335323141671816486223380713311286629425480810174036551750931478373626071781038942054037291709281118654737087599035092443005799430352628570933778452108536502272580400092528062848455445985692614774855796791907610933670663580901476953467808284328166657791568856558571935788405193538986947393116928493787198798661826785549975721130971676199856446097879499458065034678153636052702160287204920680541565366139294026010089009061274372587986143754097126566624340639998228509117420424679732985956823117206903025894886029533740978018513157416105341714161360196840042575896512731742096 ct = 3088291167300681828911890341254838261507896143994085977627215978594078495952883007565773809797879150841185401282724413230256089706081482055304607098189837372445021022139016449305819308800001848241222118389290692225549475347019810385147707744883436586629808823247373108273012523932858309484832402796522454251129915341722714855738383668651266661352021406899104266596812402238487015961091455318371807234925900608259741913811110018686747303985152505270333578971573169716269092799613880511496142576903738948348527279101539196915559331086705114365249818982213416798535758240324625059044600889754519687795415852504666992830 ''' ``` Tiếp tục là một bài RSA, với bài trên đã cho $n$, $ct$ với $ct$ là ciphertext và $leak$ với $leak$ = $p^2$ + $q^2$ $mod\ n$ Ta có cách giải bài này như sau: ``` Đặt tmp = p + q Ta có: leak = (p^2 + q^2) mod n = ((p + q) ^ 2 - 2*p*q) mod n = ((p + q) ^ 2 - 2 * n) mod n = ((p + q) ^ 2) mod n => (p + q) ^ 2 = leak + k * n => tmp ^ 2 = leak + k * n phi = (p - 1) * (q - 1) = p * q - (p + q) + 1 => phi = n - tmp + 1 n = p * q ct = (flag ^ e) mod n d = e ^ -1 mod phi flag = ct ^ d mod n ``` Sau đây là solve script: ```python3= from Crypto.Util.number import * from math import isqrt n = 20842938351896783351765564497257406689875073939168847270109018452331595953195137925905407574790509131975169442262183423216630782056006817670026102637100795102868553295795605909294220001159170312214938967565708237131119660898946450453038715919305770854433454485282482531591669338374784896696254086081923985254456532726474557269047987653955703675146699130077388795028830171715932232259532178061195603162554212575207799198670246556909810593997402979919324116015029695269687378794139114073155816838415492318483626370434226417328166879349978988600491401399315534138391936796615782306743416152563145103425347897571269559877 leak = 1246889223294307854370712989427585884021285335323141671816486223380713311286629425480810174036551750931478373626071781038942054037291709281118654737087599035092443005799430352628570933778452108536502272580400092528062848455445985692614774855796791907610933670663580901476953467808284328166657791568856558571935788405193538986947393116928493787198798661826785549975721130971676199856446097879499458065034678153636052702160287204920680541565366139294026010089009061274372587986143754097126566624340639998228509117420424679732985956823117206903025894886029533740978018513157416105341714161360196840042575896512731742096 ct = 3088291167300681828911890341254838261507896143994085977627215978594078495952883007565773809797879150841185401282724413230256089706081482055304607098189837372445021022139016449305819308800001848241222118389290692225549475347019810385147707744883436586629808823247373108273012523932858309484832402796522454251129915341722714855738383668651266661352021406899104266596812402238487015961091455318371807234925900608259741913811110018686747303985152505270333578971573169716269092799613880511496142576903738948348527279101539196915559331086705114365249818982213416798535758240324625059044600889754519687795415852504666992830 e = 65537 for i in range(1,100000): tmp = int(isqrt(leak + i * n)) phi = n - tmp + 1 d = pow(e,-1,phi) flag = long_to_bytes(pow(ct,d,n)) if b'W1{' in flag: print(flag) break ``` **FLag: W1{i_hope_you_like_this_one}** ## Vi-et > Vi-et is easy to cook! Author: Nhan_laptop Source chall: ```python3= import sympy as sp import random from Crypto.Util.number import * a = getPrime(128) b = getPrime(128) c = getPrime(128) x,y,z = sp.symbols('x y z') print(f'a * b * c = {a*b*c}') print(f'a + b + c = {a+b+c}') print(f'a*b + b*c + c*a = {a*b + b*c + c*a}') flag = f'W1{{{123*a + 456*b + 789*c}}}' """ a * b * c = 15864378984956659850534060107405422568891641699308509134070157505662198692417476378386001170963905568690006431674713 a + b + c = 779122598205443694565344617967399722167 a*b + b*c + c*a = 196487786916397904192643381759626074607590751745631772329891131596526673844879 """ ``` Ta cần tìm a,b,c khi đã biết $a+b+c$, $a*b*c$, $a*b + b*c + c*a$ Với bài trên, ta áp dụng định lý Vi-et ngược để giải, ta có định lý đó như sau: ![image](https://hackmd.io/_uploads/Sk33cDyRle.png) Sử dụng thư viện `sympy` có sẵn trên python để giải hệ phương trình và tìm nghiệm. Sau đây là solve script: ```python3= from sympy import symbols, Eq, solve a, b, c = symbols('a b c') plus = Eq(a + b + c, 779122598205443694565344617967399722167) plus_mul = Eq(a*b + b*c + c*a, 196487786916397904192643381759626074607590751745631772329891131596526673844879) mul = Eq(a*b*c, 15864378984956659850534060107405422568891641699308509134070157505662198692417476378386001170963905568690006431674713) ans = solve((plus, plus_mul, mul)) print(ans) ``` Code trên in ra như sau: ``` [{a: 173765774214092292255311904274089510307, b: 284881463704823367455830769292310355251, c: 320475360286528034854201944400999856609}, {a: 173765774214092292255311904274089510307, b: 320475360286528034854201944400999856609, c: 284881463704823367455830769292310355251}, {a: 284881463704823367455830769292310355251, b: 173765774214092292255311904274089510307, c: 320475360286528034854201944400999856609}, {a: 284881463704823367455830769292310355251, b: 320475360286528034854201944400999856609, c: 173765774214092292255311904274089510307}, {a: 320475360286528034854201944400999856609, b: 173765774214092292255311904274089510307, c: 284881463704823367455830769292310355251}, {a: 320475360286528034854201944400999856609, b: 284881463704823367455830769292310355251, c: 173765774214092292255311904274089510307}] ``` Vậy ta tìm được 3 số: ``` 173765774214092292255311904274089510307 284881463704823367455830769292310355251 320475360286528034854201944400999856609 ``` Thử 6 hoán vị để ghép vào a, b, c và có flag. **Flag: W1{318278380181268876680024363742066731941800}** ## Baby Crypto > Since I was a child, I have always been curious about three strange things: > > 1. The number 13 is a prime number but there is a meaning behind it that I do not know... > 2. Why can a mysterious string of characters lead me to a secret video? > 3. Why does a world exist where the myth: 1+1=0 happens? That journey of discovery turned into an adventure, opening the door between mathematics and virtual reality. Oh yeah, I forgot to give you the mysterious string of characters: XmoUNb2=|CcXxL#d2e-ebz)^MV{dIQcVTp6Xg_v6WKnlCcR5#QSYuH Author: R1muru Source chall: ```python3= #!/usr/bin/env python3 import os message = '???' FLAG = open("flag.txt").read().encode() assert FLAG in message def cauhoi1(text: bytes) -> bytes: return ??? def cauhoi2(text: bytes) -> bytes: return ??? def cauhoi3(a: bytes, b: bytes) -> bytes: return ??? enc = cauhoi1(message.encode()) weird = cauhoi2(enc) key1, key2, key3 = [os.urandom(len(weird)) for _ in range(3)] ct1 = cauhoi3(weird, key1) ct2 = cauhoi3(key1, key2) ct3 = cauhoi3(key2, key3) with open("output.txt", "w") as o: o.write(f'ct1: {ct1.hex()}\nct2: {ct2.hex()}\nct3: {ct3.hex()}\n') # I will give you a chance with my last key :D o.write(f'key3: {key3.hex()}') #ct1: 944073d9c2fdec4334375867fcd9b0c4545d20152151f6d008259a14ea339e4e0a38167ea99fd4817b4e22565772b28c5b6781c67bf16c0c4f4e0efdeaf21f0a5a7e96bff3e8a39008788fd8256c2b522c6d9b446a29e456dee859f536ba1241e5df09a25ea1abf820ab0358c554afaadf371e02b2dc6f949da28f539b4d9845d962a9899280c2301b8be293c69a241d8e39059e9fbf3fe3772b0500505867df29e4afacd12578114bbb48d17ebf9779d784d05e2479dfccc072c814a1b4d6d8286da2d553b1726a5f2590a9d80604fc7038bb6f2f3999f23d4e37626760d4035fb8cc10bdc66ea4b0a8b9a82283c1a1680f0ca91c226ee2a1af6e8dbd03b5d47c88d6e90f5505f02f7e4e5c03c3cd2ba4e66e2049ec32b4032aae025a9065dec4744aef76926beefe5f7a560a3d82e0c603348081889bcf4ec751be9b899cb23a0c117d8c15b0c9e7e217f92f024d8ed2c028e36eb5bbdc332f04981bf05226ab15dda261e569e8869b97228021c84f454d18570a6120dc40d30679154997b91d1398ef2dd166fa64ee1169c550f506013a327c34889eb0b172878f356ec042d3a22c52a3ed99536fbd6f6f1c2058f25c2314adf4190782e542644af809fd80728c7bfd9a53016565615f1cbe323ea5057679ffd8cdaaa29ea41cb3df37aecbb669e0339bbc52ab3885bbb7eef8273f5dbfeeca6d96efda197004473fe41ba54b1a898f0f30f3ec0b253b8d3555ae0a7948d74b2f083c3cf26035f9b97819124dd930c2747950bf0d6d35e7d82a7f8d3f0a7c8ef012b6926efea881d877e9acbf16a883a98d292193fcbf332cc8a5b6b732abc3cbff2e9e19531053759cae090eaf90b7b8357c9351aeacb13c4c03b1fbf8eea7a35ce1ee793f530eae06e55fe536d0ec0c5a4e70a4f6735a240ac0e38713d14ffa32c88927908b3f273febc81e268fe4a6473f8f0e3fca74c436e08e1f1b3690d0b41b29a519bdf7ba78e6fd0dc915dc78609eaf16c4cedc3a71c406b2bbfb0bfe6d86e9e2e00d6f7a1dc8be264751cf3e84bf58cd266b3f33e0948df9d5fcee3b1405192c5401d0bd3b97839260165935e254d64cbf4a2ea318bfe17fcf241f082e8b0ec78dc68369b02d1e1d9900184fe3b62bf56cc4ed66c0dccd433beb8585295cd478d3216eea43f258da09e7011549d9235e4763c57f46e985b6f2e9561157688e266e67b35e1ee8180c00d26b14cea81417b6244175d48d2381364d4fee04df5ea1aadacc07653f1e4857550648644dd62924caa4bf6d9df4cf2fb66e4b4287de8bcbb4fa45d06c1f54256e34639b2ec6cb8e9c9bbb0ad655b6e65c4372688ccf44e65f263f2b677f800e5b4a9464c611e51c1ad31637b7933313bd73e037e0a738ef0d782427a0b56c255dc9e1febf42ed6cbefc27f138aaf00336992a2e970d597bd037f05ff6cc92477a3528c5daaf6bd3c8d47c67ed6f91a4348ea43125352f34842843bb467220097384291a43b098a6c41611041fbfa9900a7733129710436da9c991a08c50eba4ebb7b22165a111cadbb0c86f6448f574857b561fa0813528ae886ad0e80192b53c21c831a317e7f2fea1521f8b3e237b79e40245feac47ae9a8d99fd1ee8f11aaaf8cc6fd7b1a066ae9299b210c55b7651b2052a4be88fd1eb3a85f515adb388d504507236464ef0c83151001e0035b6e55de0bd5091305cca1002de0d4b0fe920ddad16232d0cf82e0c7588399bad23a3bfdbcdda2fdaa532c2f421bc25480e395f5db0d724748b3751156c29348494c88d4fbc75b6a9997dd714a66228f1099f2d36ecab036d77728183c704beae2cfb594dd8484c0d2b299626e1413a584fef756c73945200f16cf05b79568dc94b56dab9569adcdd000d55aa04b35115ec11ba53bd8a05e576d5956b4df9170b6e65c9849a6204fb62c98ef2b8d3d138f95d0335180831ebee7f5583e737c4782895f082defaae68775825a2ab34403347261a6fd497ee7a9eadf050e9954a01b173aaf5e9a21a03d66f #ct2: 770178bcb4c79bb17a3e9d3fae37aff128817b9528af0fd6ba9b35638095318ca7c640c7b5f4ca9dd5621472887287fc07d9bdeea79c6c68d059cc3e497c036e8fbf6b9ed480d3b4be6069dd834c6a9a162ba2a879cdf7286697670c9d299086e79844760caff21366ebf507d59fe40a0a59fca4df49fb306937faeb4d3b6ad266c2def5b5d78ef5cb6fd66a2e4cbe251d54e71478f539a82683d7f403e583bddcd0db7bf992c6dc1d50de5066c209bf14995e92b0383437719e3f93ccbc9eda83674d770d7d29b182e7fe3f1b791de8231645dfd3c258ae65fec2e1f1e9693c4f138b3b3c714385285fe25c7ab1a7c77c64c974e003c2d0ca4c144f7a6ebeba7d556aefe0929658b96b9252e7c3682a611915583da9c20ca84d3ef1b551f41c5f2adfb76970f8653342064587693dba7318d8118dd1f31ef27f22caad90c1f9145d71074fed2d81928c29d077ad92b679fe8d79ded8c62ca8bf53218df5439b1a81d6f21df99e0432c67f6002a0155b82f0f6953b6c5a5324df90333fe1c731f792e3f27fdc09047b13de99fcc1763cd1fe7a0587becbbf2ce09b9897c6325258450055c49bcf3506db1a2b055f7a029e99f1343888d8d8fa4a84be11ca1f5b85ffbf00b96dc61d05db4b446eba1a53aae9bdbac981d7046ca3158e67cf7e3f9c357fea73718d61da1e0fe42a4e4f10490495deee5174f02326b591b7dbf8d0e52841faf4da6b469d250f65ed794f08c438307752ab5368db551da6aba167bbf3ddb34e54f4ce725512721343714338901492fa298db176449277011ae92d252a7a9c5aac970dfd004329fdb2b0ca7a6d543ee133ed5a3d31e0a1b15a07cb366a25d5569eb124d74237604688fabc5bdec532ef76825d8592e910f6e59b843e8487605e0d823af50b0dea4bd199a9e52818fd90de3194fc0c9e3d30de743301a154cf08e40068234acdc8b4e5b39ca8f0053439db32b029ecc44b74998635d433eaf174b5946715e5ffdb21e3315f3a412c7e2b6ff53832befd256164ef47697dece91de9e7bc2d0095bde64422ef708223d6c0e59f0e0762197d59846b0c9f3060edc4cabc79e01acc72c8580af50b959b2436dde3753fa316cfd9a789facb770c3afdf04a183e897ff5b5b8366f8c3092b1d1ab0975c0f83b0a1da0a1e105cc067339bdee25f82d9a5e02d8ce593691e370e1ca297849e9e932d0773590a61a4ff645b468ad0d9fc0d1899e2ff5aa168d61fda073792e33c50f4a566385b87566afc14449b4fb9ac662a0f9267a872565f6e3458c24999c3972524c7015ad02ed24d93268d362b32ea6f6ea00ebabbae9968cab114f8f835a03802850951f5c16c5446d5f2910b1e72618e453b21e132b2275608471915271e019efc6324a88af1ec0a2c0840f676c64636ac7e8801f67befe418557956f9fb8274031392cb121b5f73434f30436a486f13cb36e39a9ee3bef53a1acbb90340755c2a06a6f1c21fb9f9ac3e520e20a90b952378d2759ae789ab26acbed14fab5d2d5c40e420a356c7ff0050d7368efd10cea07d9a1d7eeecc91ce13a066c93690a513d3cc7b1bbd468575aeb7b3563d60b82613b9ae50c5df8f26ae5bfe84677cc54898d504644e5b423ba47b507b30d495dbaa2e5f87f780be3b9562c1bfe1a1f79d828c4867274d2b5b31ef750f965d4a84dbadef33871e435d61425578fec1f1f6651d615fde35697e31162658239110e4b0ccf1d05e50ac275a82ddc8f7920dda8021f7c14e36692eeba0f2421151f3496566e2e176c6a4d89058d19479b89e043e1e4bb63f892c9134a5100a3b574afa9f7e6c6688e71ad3038c37587a6efb417e0473e06e14ad083b825c7f1caf0e9e61003da38fe526e421e1abad336ffe81fa166d7ff8714bb1972547f08e0cbb80355387f87ffcea8219f96a108f71e1474b68fd46dfda7bcfe899b9e752f7dbc68cf252f31a68435165de7748460b86341f6e3b10d6f5c3f7e6e813fa5ef538380914e127f21f728e0eb3370597c #ct3: 9a1019a263bf5c2b7473e7afe4c447db8b621e1b68ff78306e2a9f179b0cd3cacc544c3dbf8051f4d4e8bd9f921d07a6a757016bacfcf5075e895f7076303f845a2e7b6971184040cd98d6ceb90ce321afc89374230910051da77a080f544bf0f2c59dade7cb76d055763a9759ef7063d603012e2e525a7801d7928cdf68346883580415447e297107822d298b21522c472a9828b19667dd83cd3250a656f0976a320c35af7660b40900a6b714d6d531a63ea20c1c1982a959d87fe5fc502a0932a688c4530ebb9abb5d696fb8f29eaefdbdd5683d44c3438418c3c8469345fbdb2de1c230c5d36a0aba17fb671dd5b952903e314cdbf467263feedfa1c470879a91b2008600af5f7b69004a34ac6274e4484ea383caf910be86dfa19c43a38518254a04699a54c5718363e9c2a16e56d91bb4e2373069fd9934bfef2b853a79554f57ea4a7c8f199853122df8e556c0b4cb51894c0f5a232555242d2e48ec554bbdadaf5b4baa2cb6cbefe4463422fad383723f9757ad71fd594dbc984a54939b37c19634e62cf10f859e2a712ec603c15bff5526ab6248be1f118c5afa84181d067e4e9f1c0176a2753880634c148518c169a3aa695f12b68d54c4a9f8f976d3a6b0420ac0a39d51638c71199d87b5f185fdc4298247dced58026e3f9ab79424ebda18e8053d5e508f66137fa632b9a5dcd4a25e4d9c5bda508ea9d1a2afb01511387e3b5d3f985e6ac97c7cb8614b316d3a3838acdd808c23d25c19cfd2116cecbda92cae83deb555c8ae8cc983aac571c9e4365a0c0d077a401df2bb8596f7d457f093367b0e49a1a11e79c7723d20a9e4b54d535a945e958323c4d39b648fd314dbb4afafad01c5504cc860f891f89d60a4d87dd90e53b89192bacc0a935c3253dc5f8454f776305d418734b3d5e4c71b6dabcc3230141f2e92129f415ccab55e1d81f07ea8709b008026001d994dad50cb1583a3b141e0a9fa5a2fb20b82558f04090f889b7f9bec4a5055a5f3ef60b278f5fc2c6ed8c51f826b9cc5be88cf667d8f7394342a7735b65001c766ec62f0a94970d90cf94d4d53f6ad8d273f2c6163390321578b2835e396072b6cbf7876e46e24c14a821b85a5be90b34147f0d8e553e361709c7871dda118dac4e1a11b254fe6eaeec628289e6a6fad2d1382c6602dd92b5026a123b1a6d972d9c4000c480574ce1c2c45e33c5437d469857a427964e05ec79ade151943ab01c33bc6e4eff64d81515851f08b3ba64854683217595397161173a47e5de056b290dc47324c68fa47ce7a53c19048d72b549bfa70f2d9f8e06e3d27214be154f9668b02bfcf69576c15ce42e6736e4dff74a21f3754ff7e4ad396132435f19ae605dbdbffba84f99898ca7fb51055af2093658eab899a06318a0e30b01c3b731df1f22751bbce2db6f2a1bd695b386b42203327fb51fddfc616c838f046e6aa6af7149335b43460d6e578eac6c0d3950c3577957ada59d1a68bf12b652a4bdde7cc7dbe304f3e608dd0581439394c3f3e73bb79ef288bdda8d7bc6d2f4b1d31997e320005a92426ea75264fce6fcfd256a17290cac2a62c29dfbfe7e9b0c31ce48643612a949277ac98b6403cd94a99a5c187067562f63377bf7819fa3f0a626dd9d3d53238e60b2603d5cf9ec83ef5c028841799fa11e213c43a549aa1916ad48b27bbd894a7a4825ad2cbf25cec2dacb1da3a22b916a5f2988c17c624f7100d8c9fe6331c3c04f81653798935dfb231ff2802cd8d01700f17e77fbb794dffd6bec64fb8158202f2b989d8a6df2d5970b83f75c9ea6d4b372069254d4bbb926db3cc2758c5a95e573a9af016ace085db954561900a867490a99df789435589bc471936e159521daea5e4a5a90fc37f657cb5c694ff39fa35ae59f45dad5088e923319caa5afd9c46d974a498d339c6b05cd06d07cdda7648d60c6153b452c734e4935cbb3bcf22b3433a8dcca328bc147e697cadd0bd2ff0d0f4c93bf17af2df0ff4a36808f9cc2f6f838518 #key3: 2b753a867adf4ee6123c63a3da5960a6d6f272bf0322e747bff70403bfd43d522ae42ce795840ebc3ba5e28a7b5c689dd6b87c2251ad9d01e5d3b5d08fdb46a7bc8ec51c753568284ffe7d995e5cd998f4dbcfbd6e8c250e989714b99588a176a8d8e50bec8d41485261bca97f7461a53332a6c91abfebe2a3289e66487fb0d7158f122a0f5726eeb25a79eb399f8b409a0620ce369236c9964ea3e1ded237b0fe230191c696814c10a9716c60820ab63f611bf9ea7b096f8075d229bc153a48c8fb20276c85a00731c032ba37ccd1ca8ae648a086cf4348b4f201018745bcef88c38dd0c245a675e565796c601c9b9527debed789987b3c688df53b07e336bff1354b3d3e8756bba71fe8279bf2901a18826bb9c7cd48fa7497656527e3560cea33892d0721f72d89fe3e9818858b4552410231122f600969b0aec134f641732d6f43c0b8dc7e69a2466d5dd86fbdbf249b9b63aa2854b982a750a3c378bcbfdc43d1a76b63308d43f726c893f49dab576dff84c372b3a6d304a58dd0c1626b4dd79ffb0bd202575852248c19c80d1072ab8a51c1d25c6655f943d69274046ba3c03e00b90b1f6191707bbc29665427b931b57b07c0cf11f1c9e37b116351d859e2108d019b01a46b92d66ca856ce2f13786be209f75e2f26304a0beb57301e6f9107ff519f8dad84508410c72364cefd30e4e787a04152a8434f3d69cd09aaf507a6538b9ad9518932aff7e4f5f663e74c9c5e0e22e395c47fd1606943ebd382ae0103294f7c71a440c0145ad0eb4f27300dbb959537bc7963d9f37c0c327e3a915f77c40877939b5851a5bef25ca780a84ccef204654e20547d92b51f992ec8600610ec65ceb15e68f1c61fe36a2f8fc1e98b4aec24328b4db20b877807b35ce79524321d7820baf3930e238f939211871ae3ce955c2a7746d8afade9cfe61fb127a69cf3583c753f45737de444fcf48c04136d7d29f05074360718a74816992e0fdcff8a307be089b8f6e82d6e9b46917e2c5125f394fdbd55bb3044770886039df83c23de68ad85b9116681e4f7d2f0ebd1e68f842ef65a7af782a5556be66acd8e91033a37ac673a7937705dfd1174359d80af5e0dccb1de9b259e27fe4c13c841a11de51bd25817eb129736d2cd4c3049209c88d717815bb77eaedf5540fa6300c11291d2032e2e173433e10ab545c2bfec4de29a82efe30b2b6ddd8fad574531b5170daf39c2dbb398693e37e548eb05f0636e72b36d477e4fc2a2a57f7da6ca08909262871cb365dd2c37d3745413960978a7db2cf72c553c20789ba26d6078be4754ab07b82c6fe833edcdd3694741c163ce7175a6f0b43b686d421f64ef084904ffe0f0ab7ccd4a8cb1c99a8a518a451371d0e1807d32c906d65fea33a5e3ed0a6c89e00323f12012e0902b1bbdefcdec190bb37d317ad26dbea94a006dbadf19b9ede96b8001f41da3986d8e57bfba946d43bd8d12972fa468492ff69b95ab527d69c8c66bce25a9227ef3b575c3995abb6659d1775130399f072ba53f8fb79cf166f03a4096692a4ee126f959691689268636b851bba66cc3061ce267a6661d4bf54e3e846a51520467ea582ade3a139af556f09bc9f985575c4035036f41aecdce899d2eace709ebc40d8854ea21ee4f890c8a49c995a8a73682890a6d8579621d05110b250c6b4402b7443d753dae85a2805a950a89b0c47c874bdd474f0ff3e4ba3ba571e198798f10f24ae84491cc5b1211f58ea07ec9a3314b76e1a945075de2b3d9012d5fe2c93d8d46b9ce72e3c1536e23d8b19dbf48147bdb73d8f58c3940b0dcccd8d1a9bcc3165da911fa13c5a038aa9f101e3bb01a6db3564afe83943ba24901d3749b9e7e2f13b7c4391922d93dbfe8d92726793f8f676c87099ab1f0ce5190f98c7c6a1f12762b8571e9195df6c460b97b9e5854baf40a04e0f24f28ad6de50d0faf31f623c61552ac5249472b921fd9178c96c667a5cfc4fb48e9c3c10e66f1f69e43b43a542c44820572c26c69 ``` Ở câu hỏi 3, 1+1 = 0 có vẻ đó là phép xor. Ta biết được ct1, ct2, ct3 và key3. Mà ct1 = cauhoi3(weird, key1) ct2 = cauhoi3(key1, key2) ct3 = cauhoi3(key2, key3) Nếu `cauhoi3` thật sự là phép xor => $weird = key3\ xor\ ct1\ xor\ ct2\ xor\ ct3$ Ở câu hỏi 2, khi ném đoạn secret đấy lên cyberchef thì nó đã phát hiện ra là base85 và nó decode ra được 1 đường link Ở câu hỏi 1, số 13 đó có vẻ là ROT13. Sau khi thử thì ta tìm ra được flag. ![image](https://hackmd.io/_uploads/r1Y1HOyAle.png) **Flag: W1{D1d_y0U_GeT_r1Ck_r0lL3d?}** ## Sor Sor Sor > Let's begin with an easy XOR challenge. Format flag: W1{A-Za-z0-9_} Author: L1ttl3 Source chall: ```python3= import random with open('flag.txt', 'rb') as f: flag = f.read().strip() assert len(flag) % 3 == 0 def xor(a, b): return bytes(x ^ y for x, y in zip(a, b)) blocks = [flag[i:i+3] for i in range(0, len(flag), 3)] ori_blocks = [flag[i:i+3] for i in range(0, len(flag), 3)] random.shuffle(blocks) assert all(ori_blocks[i] != blocks[i] for i in range(len(blocks))) print(xor(b''.join(blocks), flag).hex()) # 2f01090a6f042b4447101f0047460d6e0e5d001100422d156443022c4a3e074a392b033e531d1b47401b44423c411e08 ``` Bài này chia flag thành các block, mỗi block dài 3 bytes sau đó xáo trộn rồi xor lại với flag ban đầu. Để khôi phục lại, đầu tiên ta biết được format flag là `W1{` dựa trên nó, ta sẽ bruteforce ngược lại lần lượt các block bằng thuật toán backtrack. Solve script: ```python3= import re from itertools import product h = "2f01090a6f042b4447101f0047460d6e0e5d001100422d156443022c4a3e074a392b033e531d1b47401b44423c411e08" ct = bytes.fromhex(h) A = b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ{}_" X = lambda a,b: bytes(i^j for i,j in zip(a,b)) C = [ct[i:i+3] for i in range(0,len(ct),3)] m = len(C) T = [None]*m # plaintext blocks P = [-1]*m # pi R = [-1]*m # inverse T[0] = b"W1{" BRE = re.compile(br'^[0-9A-Za-z{}_]{3}$') FRE = re.compile(br'^W1\{[0-9A-Za-z_]*\}$') def ok(b,i): if not BRE.fullmatch(b): return False if b.find(b'{')!=-1 and i!=0: return False if b.find(b'}')!=-1 and i!=m-1: return False return True sol = [] def dfs(): # expand edges i->t where T[i] known but P[i] unknown for i in range(m): if T[i] is not None and P[i]==-1: v = X(T[i], C[i]) for t in range(m): if t==i or (R[t] not in (-1,i)): continue if T[t] is not None and T[t]!=v: continue if not ok(v,t): continue old = (T[t], P[i], R[t]) T[t]; P[i]; R[t] T[t], P[i], R[t] = v, t, i dfs() T[t], P[i], R[t] = old return # place a fresh plaintext block if any None if None in T: j = T.index(None) last = [ord('}')] if j==m-1 else list(A) for a,b,d in product(A, A, last): blk = bytes((a,b,d)) if not ok(blk,j): continue v = X(blk, C[j]) if not BRE.fullmatch(v) or b'{' in v: continue T[j] = blk dfs() T[j] = None return # all filled: final checks if not FRE.fullmatch(b"".join(T)): return for i in range(m): if P[i] in (-1,i) or X(T[P[i]], T[i])!=C[i]: return sol.append(b"".join(T)) dfs() print(len(sol)) for s in sol: print(s) ``` ![image](https://hackmd.io/_uploads/SktGz6wRxl.png) **Flag: W1{x0r_p3rmut4t1on_a3r_v3ry_3asy_t0_brut3f0rc3s}** ## System of Equations > Chắc hẳn bạn đã từng một lần đối mặt với một hệ phương trình trong quá khứ, đúng không? Nếu đã quen với những thử thách ấy, thì con đường dẫn tới lời giải cho thử thách này thực ra đang ở ngay trong tầm tay bạn. Điều quan trọng chỉ là sự kiên trì: dám mò mẫm từng ngõ ngách, thử nghiệm từng bước đi, và không ngần ngại bước vào những lối rẽ tưởng chừng bế tắc. Tôi đã rất dễ dãi khi chỉ đưa ra cho bạn vỏn vẹn ba phương trình. Còn lại, tất cả phụ thuộc vào khả năng và sự bền bỉ của bạn. Author: r1muru Source chall: ```python= from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad import hashlib import os FLAG = b'W1{???}' x = int(input("Nhap x nguyen: ")) y = int(input("Nhap y nguyen: ")) z = int(input("Nhap z nguyen: ")) assert x**2 + 2*x*y - 8 == 4*z**2 + 4*y - 8*z assert x**5 + y**3 == 10823714993004958804353333960725385073542379465721 - z**4 assert 8864612849141*x**2 + 8864612849141*y + 17729225698282*z == 205022233466935232483321764396 mode = str(input("Nhap phuong thuc (encrypt hoac decrypt): ")) secret = (str(x**10) + str(y**10) + str(z**10)).encode() key = hashlib.sha256(secret).digest() if mode == "encrypt": iv = os.urandom(16) c = AES.new(key, AES.MODE_CBC, iv).encrypt(pad(FLAG, 16)) print(f'iv = {iv}') print(f'ciphertext = {c}') elif mode == "decrypt": iv = b'\x8d\r\x19\xbc\xfd\x84\x13N,\xf85\xdb\xd3\x92i\x93' ciphertext = b'\xe9\xa2\x8c\x8b\xc3\xb4\x88\xe2\xbb\x96\xc6\xac`\x1c}\xd1\xca\xc1ZB\xf1@\x01\x92\xca\xc4Z[\x96o\xdeFv\xdf\r\x13u+\x89\xac3\xa3\xc9X\xfb\x07u\x1bO\x9c\xb0\xbdN\xa4\xb6\xca&T\xabmx\xdb\xae\xc2' print(key) FLAG = unpad(AES.new(key, AES.MODE_CBC, iv).decrypt(ciphertext), 16) print(FLAG.decode()) else: exit(1) ``` Ở code trên nó thực hiện mã hóa flag bằng AES mode CBC với padding là PKCS#7. IV và ciphertext đã được cho, còn key được thực hiện tạo bởi 3 số x,y,z bằng các lấy hash sha256 của `(str(x**10) + str(y**10) + str(z**10)).encode()` Ta còn biết: ``` assert x**2 + 2*x*y - 8 == 4*z**2 + 4*y - 8*z assert x**5 + y**3 == 10823714993004958804353333960725385073542379465721 - z**4 assert 8864612849141*x**2 + 8864612849141*y + 17729225698282*z == 205022233466935232483321764396 ``` Vậy nên việc của ta đơn giản là thực hiện giải hệ phương trình 3 ẩn trên là xong. Solve script: ```python3= from sympy import symbols, Eq, solve from Crypto.Cipher import AES from Crypto.Util.Padding import unpad import hashlib x, y, z = symbols('x y z') pt1 = Eq(x**2 + 2*x*y - 4*z**2 - 4*y + 8*z, 8) pt2 = Eq(x**5 + y**3 + z**4 , 10823714993004958804353333960725385073542379465721) pt3 = Eq(8864612849141*x**2 + 8864612849141*y + 17729225698282*z , 205022233466935232483321764396) ans = solve((pt1, pt2, pt3)) x_val = int(ans[0][x]) y_val = int(ans[0][y]) z_val = int(ans[0][z]) iv = b'\x8d\r\x19\xbc\xfd\x84\x13N,\xf85\xdb\xd3\x92i\x93' ciphertext = b'\xe9\xa2\x8c\x8b\xc3\xb4\x88\xe2\xbb\x96\xc6\xac`\x1c}\xd1\xca\xc1ZB\xf1@\x01\x92\xca\xc4Z[\x96o\xdeFv\xdf\r\x13u+\x89\xac3\xa3\xc9X\xfb\x07u\x1bO\x9c\xb0\xbdN\xa4\xb6\xca&T\xabmx\xdb\xae\xc2' secret = (str(x_val**10) + str(y_val**10) + str(z_val**10)).encode() key = hashlib.sha256(secret).digest() FLAG = unpad(AES.new(key, AES.MODE_CBC, iv).decrypt(ciphertext), 16) print(FLAG.decode()) ``` **Flag: W1{y0u_must_b3_th3_m4st3r_0f_3quat1ons_817e31a7ccdbe8fd}** ## Learning with BRUTEFORCE > Have you ever heard of "BRUTEFORCE," the GOAT of algorithms forever???? Author: Nhan_laptop Source chall: ```python3= from Crypto.Util.number import * from sage.all import * import numpy as np flag = b"W1{????????????????????????????????}" e = [2506,2006] def rebase(n,b): if n <= b: return [n] return [n%b] + rebase(n//b,b) s = rebase(bytes_to_long(flag),3671) n = len(s) A = np.random.randint(1,3671-1,(n,n)).tolist() s = vector(GF(3671),s) e = np.random.choice(e,size=n) A = matrix (GF(3671),A) e = vector(GF(3671),e.tolist()) print(f'b = {A * s + e}') print(f'A = {list(A)}') #b = (3142, 2772, 805, 2779, 2853, 1921, 535, 210, 1161, 989, 2484, 2104, 1594, 1048, 452, 3586, 56, 1370, 436, 1601, 512, 274) #A = [(2413, 2531, 3411, 2884, 2264, 377, 3514, 78, 1702, 3182, 3167, 20, 1054, 3422, 3177, 1535, 680, 3425, 3297, 535, 3390, 3619), (3236, 181, 2133, 1731, 844, 3201, 2176, 1268, 1285, 1692, 2874, 705, 1025, 2161, 1800, 992, 774, 625, 1897, 1823, 112, 2314), (1036, 1649, 317, 2345, 1900, 2149, 2964, 1518, 2909, 176, 3454, 2808, 465, 2940, 155, 2209, 3019, 1986, 1407, 2536, 3003, 155), (725, 237, 85, 2270, 1539, 1946, 1357, 1526, 759, 2183, 725, 1639, 2478, 2453, 2591, 520, 3060, 2483, 104, 1788, 1358, 1690), (2084, 1986, 1503, 560, 3033, 1451, 2721, 2749, 3537, 2408, 843, 1955, 498, 1849, 878, 2538, 2717, 3655, 3304, 2856, 926, 2658), (2431, 950, 953, 3046, 2543, 2422, 3552, 3656, 2063, 3585, 825, 2811, 497, 3635, 3445, 2579, 1882, 2003, 778, 2285, 866, 1288), (2859, 2257, 1451, 2988, 2568, 150, 2901, 3657, 1736, 2551, 3084, 3146, 2300, 3205, 3246, 909, 1574, 1345, 2087, 147, 584, 321), (3651, 1560, 3243, 1860, 1523, 1374, 1273, 1296, 1043, 1392, 3063, 2144, 21, 323, 3458, 2766, 2390, 2582, 2815, 211, 9, 1781), (2269, 2189, 1832, 1302, 2167, 2126, 863, 1101, 1177, 1689, 3631, 1722, 1933, 2429, 798, 912, 1360, 1811, 1740, 1759, 1981, 1266), (1788, 2524, 910, 448, 3558, 2913, 2309, 328, 404, 1995, 1633, 2605, 2421, 3488, 2860, 1259, 364, 1196, 1504, 1732, 2630, 587), (1975, 82, 3369, 129, 2504, 854, 1538, 3598, 953, 1324, 1469, 2984, 164, 2565, 744, 2792, 1196, 1383, 2922, 2544, 3609, 2630), (3120, 453, 248, 2510, 2464, 3098, 2459, 1219, 1179, 840, 1374, 2641, 1582, 304, 263, 186, 3191, 478, 988, 568, 3300, 929), (3401, 2877, 2106, 1352, 3664, 3069, 845, 1219, 1780, 3135, 2801, 251, 3617, 1195, 764, 2232, 2919, 693, 46, 3113, 2144, 874), (854, 2101, 3361, 2135, 1797, 3133, 2872, 3494, 2534, 1978, 1066, 1138, 439, 1503, 962, 1509, 2360, 1924, 1574, 483, 2641, 545), (2163, 3377, 253, 2530, 1968, 2470, 2662, 2807, 1264, 2924, 2528, 468, 729, 1707, 2692, 1960, 387, 3591, 800, 1428, 655, 2190), (1569, 3225, 3456, 1244, 157, 2438, 3248, 3443, 547, 967, 1107, 2571, 3068, 3578, 1799, 98, 452, 2108, 3462, 40, 2302, 41), (672, 2649, 1436, 2391, 2011, 2920, 2460, 1672, 3594, 2587, 1647, 1366, 3006, 1449, 2945, 2767, 3023, 991, 82, 1432, 1493, 1498), (1763, 3130, 948, 2461, 2695, 1362, 1558, 3344, 2710, 3397, 1845, 1735, 3493, 450, 407, 2907, 1564, 1203, 1497, 1656, 3651, 2348), (506, 1747, 50, 967, 1100, 2688, 283, 160, 3599, 2210, 3548, 3191, 252, 3519, 591, 3393, 3482, 1364, 1420, 425, 318, 2133), (2136, 625, 2454, 2764, 3635, 3514, 559, 1526, 1301, 2311, 837, 111, 3431, 1363, 3365, 2946, 1116, 1215, 1555, 3594, 973, 3622), (2464, 914, 3225, 706, 1804, 137, 2957, 1278, 766, 3570, 2155, 3634, 1960, 3482, 394, 2665, 896, 529, 1510, 1142, 656, 2868), (1080, 2030, 878, 945, 658, 1134, 2591, 1512, 313, 3348, 1329, 1571, 1108, 3279, 3185, 1188, 1330, 2315, 2885, 3190, 2141, 1307)] ``` ### Bài toán Cho hệ b = A·s + e (mod 3671). Vector s là “chữ số” của N = bytes_to_long(flag) trong cơ số 3671. Mỗi e_i thuộc {2006, 2506}. Biết flag ASCII, bắt đầu `W1{` và kết thúc `}`. ### Ý tưởng Viết e = 2006·1 + 500·z với z ∈ {0,1}^n. Đặt M = A^{-1}, y = M·b, c = M·1. Suy ra s = y − 2006·c − 500·M·z (mod 3671) ⇒ s là ánh xạ affine theo z. ### Khai thác - Chia 22 bit của z thành 11|11 và meet-in-the-middle trên các tổng con của −500·M[:, j]. - Lọc nhanh theo byte cuối: tính N mod 256 từ s (sau khi gộp mod 3671) và giữ ứng viên có 0x7D (‘}’). - Dựng N, đổi ra bytes, kiểm tra ASCII + định dạng `W1{...}`. ### Solve script ```python3= p = 3671 # --- nhập A, b từ đề (22x22 và 22 phần tử) --- b = (3142, 2772, 805, 2779, 2853, 1921, 535, 210, 1161, 989, 2484, 2104, 1594, 1048, 452, 3586, 56, 1370, 436, 1601, 512, 274) A = [(2413, 2531, 3411, 2884, 2264, 377, 3514, 78, 1702, 3182, 3167, 20, 1054, 3422, 3177, 1535, 680, 3425, 3297, 535, 3390, 3619), (3236, 181, 2133, 1731, 844, 3201, 2176, 1268, 1285, 1692, 2874, 705, 1025, 2161, 1800, 992, 774, 625, 1897, 1823, 112, 2314), (1036, 1649, 317, 2345, 1900, 2149, 2964, 1518, 2909, 176, 3454, 2808, 465, 2940, 155, 2209, 3019, 1986, 1407, 2536, 3003, 155), (725, 237, 85, 2270, 1539, 1946, 1357, 1526, 759, 2183, 725, 1639, 2478, 2453, 2591, 520, 3060, 2483, 104, 1788, 1358, 1690), (2084, 1986, 1503, 560, 3033, 1451, 2721, 2749, 3537, 2408, 843, 1955, 498, 1849, 878, 2538, 2717, 3655, 3304, 2856, 926, 2658), (2431, 950, 953, 3046, 2543, 2422, 3552, 3656, 2063, 3585, 825, 2811, 497, 3635, 3445, 2579, 1882, 2003, 778, 2285, 866, 1288), (2859, 2257, 1451, 2988, 2568, 150, 2901, 3657, 1736, 2551, 3084, 3146, 2300, 3205, 3246, 909, 1574, 1345, 2087, 147, 584, 321), (3651, 1560, 3243, 1860, 1523, 1374, 1273, 1296, 1043, 1392, 3063, 2144, 21, 323, 3458, 2766, 2390, 2582, 2815, 211, 9, 1781), (2269, 2189, 1832, 1302, 2167, 2126, 863, 1101, 1177, 1689, 3631, 1722, 1933, 2429, 798, 912, 1360, 1811, 1740, 1759, 1981, 1266), (1788, 2524, 910, 448, 3558, 2913, 2309, 328, 404, 1995, 1633, 2605, 2421, 3488, 2860, 1259, 364, 1196, 1504, 1732, 2630, 587), (1975, 82, 3369, 129, 2504, 854, 1538, 3598, 953, 1324, 1469, 2984, 164, 2565, 744, 2792, 1196, 1383, 2922, 2544, 3609, 2630), (3120, 453, 248, 2510, 2464, 3098, 2459, 1219, 1179, 840, 1374, 2641, 1582, 304, 263, 186, 3191, 478, 988, 568, 3300, 929), (3401, 2877, 2106, 1352, 3664, 3069, 845, 1219, 1780, 3135, 2801, 251, 3617, 1195, 764, 2232, 2919, 693, 46, 3113, 2144, 874), (854, 2101, 3361, 2135, 1797, 3133, 2872, 3494, 2534, 1978, 1066, 1138, 439, 1503, 962, 1509, 2360, 1924, 1574, 483, 2641, 545), (2163, 3377, 253, 2530, 1968, 2470, 2662, 2807, 1264, 2924, 2528, 468, 729, 1707, 2692, 1960, 387, 3591, 800, 1428, 655, 2190), (1569, 3225, 3456, 1244, 157, 2438, 3248, 3443, 547, 967, 1107, 2571, 3068, 3578, 1799, 98, 452, 2108, 3462, 40, 2302, 41), (672, 2649, 1436, 2391, 2011, 2920, 2460, 1672, 3594, 2587, 1647, 1366, 3006, 1449, 2945, 2767, 3023, 991, 82, 1432, 1493, 1498), (1763, 3130, 948, 2461, 2695, 1362, 1558, 3344, 2710, 3397, 1845, 1735, 3493, 450, 407, 2907, 1564, 1203, 1497, 1656, 3651, 2348), (506, 1747, 50, 967, 1100, 2688, 283, 160, 3599, 2210, 3548, 3191, 252, 3519, 591, 3393, 3482, 1364, 1420, 425, 318, 2133), (2136, 625, 2454, 2764, 3635, 3514, 559, 1526, 1301, 2311, 837, 111, 3431, 1363, 3365, 2946, 1116, 1215, 1555, 3594, 973, 3622), (2464, 914, 3225, 706, 1804, 137, 2957, 1278, 766, 3570, 2155, 3634, 1960, 3482, 394, 2665, 896, 529, 1510, 1142, 656, 2868), (1080, 2030, 878, 945, 658, 1134, 2591, 1512, 313, 3348, 1329, 1571, 1108, 3279, 3185, 1188, 1330, 2315, 2885, 3190, 2141, 1307)] # nghịch đảo modulo p (Gauss-Jordan) def inv_mod(a,p): t, newt, r, newr = 0, 1, p, a % p while newr: q = r//newr t, newt = newt, t-q*newt r, newr = newr, r-q*newr return t%p def mat_inv_mod(A,p): n = len(A) M = [[A[i][j]%p for j in range(n)] + [1 if i==j else 0 for j in range(n)] for i in range(n)] row = 0 for col in range(n): pivot = next((r for r in range(row,n) if M[r][col]%p), None) M[row], M[pivot] = M[pivot], M[row] inv = inv_mod(M[row][col], p) M[row] = [(x*inv)%p for x in M[row]] for r in range(n): if r!=row and M[r][col]%p: f = M[r][col]%p M[r] = [(M[r][c]-f*M[row][c])%p for c in range(2*n)] row += 1 return [r[n:] for r in M] def mat_vec(M,v,p): return [sum((M[i][j]*v[j])%p for j in range(len(v)))%p for i in range(len(M))] invA = mat_inv_mod(A,p) one = [1]*len(b) y = mat_vec(invA, b, p) c = mat_vec(invA, one, p) t = [(y[i]-2006*c[i])%p for i in range(len(b))] # cột của invA và delta cols = [[invA[r][c] for r in range(len(b))] for c in range(len(b))] dcols = [[(-500*x)%p for x in col] for col in cols] # chia 11|11 và dựng mọi tổng con H1, H2 = list(range(11)), list(range(11,22)) def all_subset_sums(idxs): S = [[0]*len(b)] for j in idxs: add = dcols[j] S += [[(S[i][k]+add[k])%p for k in range(len(b))] for i in range(len(S))] return S S1 = all_subset_sums(H1) # 2048 S2 = all_subset_sums(H2) # 2048 # chuẩn bị modulo 256 cho lọc nhanh r256 = [] pw = 1%256 for _ in range(len(b)): r256.append(pw); pw = (pw * (3671%256)) % 256 def last_byte(s): return sum((s[i]%256)*r256[i] for i in range(len(b))) % 256 # quét ứng viên, chọn byte cuối '}' = 0x7D cands = [] for v2 in S2: for v1 in S1: s = [(t[i] + v1[i] + v2[i]) % p for i in range(len(b))] if last_byte(s) == 0x7D: cands.append(s) # dựng số lớn và kiểm tra định dạng powB = [1] for _ in range(len(b)): powB.append(powB[-1]*3671) def s_to_int(s): return sum(int(s[i]) * powB[i] for i in range(len(s))) def int_to_bytes(N): if N==0: return b"\x00" L = (N.bit_length()+7)//8 return N.to_bytes(L, 'big') for s in cands: N = s_to_int(s) bs = int_to_bytes(N) if bs.startswith(b'W1{') and bs.endswith(b'}') and all(32<=c<=126 for c in bs): print(bs.decode()) # flag break ``` **Flag: W1{M3ss1_1s_t43_90AT!!!!!!!!!!!}** ## Bo tu sieu dang > You can't beat these 4 guards, or ...? Format flag: W1{A-Za-z0-9_} Author: L1ttl3 Source chall: ```python3= from Crypto.Util.number import * with open("flag.txt ", 'rb') as f: flag = f.read().strip() assert flag.startswith(b'W1{') and flag.endswith(b'}') m = bytes_to_long(flag) e = 0x10001 m1 = 2**1024 - 3 m2 = 2**1022 - 2 m3 = 2**1020 - 1 m4 = 2**1018 c = pow(m, e, m1) % m2 % m3 % m4 print(c) #c = 2027792127378145444099302510462900300257442068928010403052259994880511317607407514908720534902489134379904618947792557805368190009359079320337075768626232418980864987406619809977532904702783433112202254001367719098893178820312980355187703995660867067442830169498602243151057835147454968516377852012013934653 ``` **Bài toán.** Cho m = bytes_to_long(flag), e = 65537 và c = (m^e mod (2^1024 - 3)) mod (2^1022 - 2) mod (2^1020 - 1) mod 2^1018. Flag định dạng `W1{A-Za-z0-9_}` ⇒ m là số lẻ. **Ý chính** - Gọi r1 = m^e mod (2^1024 - 3). Từ chuỗi phép `%` suy ra: r1 ≡ c + t2·(2^1022 − 2) + t3·(2^1020 − 1) (mod 2^1018), với t2, t3 ∈ {0,1,2,3}. - Trên mô-đun 2^1018 (nhóm đơn vị có bậc 2^1017), ánh xạ x ↦ x^e là song ánh. Lấy d ≡ e^(-1) (mod 2^1017) ⇒ m ≡ r1^d (mod 2^1018). - Duyệt 16 khả năng, tính m (mod 2^1018), đổi ra bytes, giữ chuỗi khớp regex `^W1\{[A-Za-z0-9_]*\}$`. Kết quả duy nhất là flag. Solve script: ```python3= from sage.all import Integer, crt, inverse_mod, power_mod from itertools import product import re # --- tham số mô-đun --- mod1 = 2**1024 - 3 mod2 = 2**1022 - 2 mod3 = 2**1020 - 1 mod4 = 2**1018 C = Integer(2027792127378145444099302510462900300257442068928010403052259994880511317607407514908720534902489134379904618947792557805368190009359079320337075768626232418980864987406619809977532904702783433112202254001367719098893178820312980355187703995660867067442830169498602243151057835147454968516377852012013934653) E = Integer(65537) # các thừa số nguyên tố của mod1 PRIMES = list(map(Integer, [ 13, 107, 87671, 3870037838243, 279462107025143615623321823017, 1325706410421371952032007611396267 ])) # nghịch đảo mũ e modulo p-1 cho từng p inv_exps = [inverse_mod(E, p - 1) for p in PRIMES] # gom ứng viên flag hợp lệ (tuỳ chọn) rx_flag = re.compile(rb'^W1\{[A-Za-z0-9_]*\}$') seen = set() for t2, t3, t4 in product(range(4), repeat=3): # r1 ≡ C + t2*mod2 + t3*mod3 + t4*mod4 (theo mô tả phép chia dư xâu chuỗi) r1 = C + t2 * mod2 + t3 * mod3 + t4 * mod4 # m ≡ r1^{d_i} (mod p_i) cho từng p_i residues = [power_mod(r1, d, p) for d, p in zip(inv_exps, PRIMES)] # ghép bằng CRT để thu m (mod ∏p_i) m_rec = crt(residues, PRIMES) # đổi ra bytes (big-endian) blen = (int(m_rec).bit_length() + 7) // 8 or 1 fb = int(m_rec).to_bytes(blen, 'big') if fb not in seen: seen.add(fb) print(fb) # nếu muốn chỉ in flag hợp lệ, bỏ comment dòng dưới: # if rx_flag.fullmatch(fb): print(fb.decode()) ``` **Flag: W1{RSA_w1th_0v3rl4pp1ng_m0dulo}**