X marks the spot, but not where the Pigpen lies; there, secrets hide in plain sight.
猪圈密码。
[WarmUp]Emails
We’ve recovered some of Chase’s emails from his inbox. It seems he was conspiring with someone, but the last email is encrypted. Maybe the other emails contain clues that will help us decrypt it?
题目给了一些明文,还有一组密文,根据文章内容发现是MTP。
1 2 3 4 5 6 7 8
Good morning,
How are you? I've become concerned about the security of this email service. It's only a matter of time before your inbox gets leaked. To deal with this, I suggest we encrypt our emails. If you have any further ideas, please let me know.
Thanks, - Your Secret Conspirator
1 2 3 4 5 6 7
Good morning,
I need to send you the flag, but as I mentioned in my last email, I don't want to send it unencrypted. Please continue to look into possible encryption methods.
Thanks, - Your Secret Conspirator
1 2 3 4 5 6 7
Good evening,
I see you mentioned a One Time Pad. Looking into it, that might be useful. It apparently is secure against infinite computational resources. Do you think we can use that?
Thanks, - Your Secret Conspirator
1 2 3 4 5 6 7
Good afternoon,
Okay so I have developed a secure channel for sending the key to the one time pad. The only problem is it's really slow. I'll send you the key, but I think we should limit the key size to 32 bytes.
Thanks, - Your Secret Conspirator
1 2 3 4 5 6
Good evening,
It's simple. Just repeat the key over the whole message. That way you can encrypt the whole email with the smaller key.
Thanks, - Your Secret Conspirator
在几篇文章中发现I think we should limit the key size to 32 bytes.,MTP的key长度为32,从网上找了个MTP的模版,根据已知分组的内容推测相同的内容,进而求出所有的明文:
import Crypto.Util.strxor as xo import numpy as np
defisChr(x): iford("a") <= x and x <= ord("z"): returnTrue iford("A") <= x and x <= ord("Z"): returnTrue returnFalse
definfer(index, pos): if msg[index, pos] != 0: return msg[index, pos] = ord(" ") for x inrange(len(c)): if x != index: msg[x][pos] = xo.strxor(c[x], c[index])[pos] ^ ord(" ")
defknow(index, pos, ch): msg[index, pos] = ord(ch) for x inrange(len(c)): if x != index: msg[x][pos] = xo.strxor(c[x], c[index])[pos] ^ ord(ch)
dat = []
defgetSpace(): for index, x inenumerate(c): res = [xo.strxor(x, y) for y in c if x != y] f = lambda pos: len(list(filter(isChr, [s[pos] for s in res]))) cnt = [f(pos) for pos inrange(len(x))] for pos inrange(len(x)): dat.append((f(pos), index, pos))
# get cipher f = open("email5.enc", "rb").read() c = [ b"[P\xc9I\xb2\x16S \x0f=\x99|\x7f\x931\x0cI\x83p\xffMX[,\xc0\x15\xab\xee\x87\xe2\xe7\x16", b"<S\xcfF\xf7SL1F'\xd7h2\xf8^!7\xaa9\xe2IZSu\x95Z\x97\xee\x95\xef\xe7Z", b"zS\xc7J\xbcSl1F'\xcd\x16Y\xcchz\x17\xad-\xc5\x0bGh;\xdca\xbd\xa6\xd1\xf0\xdd#", b",J\xf9X\xa7@z\n5\x04\x8a\x16Y\xdaTod\xb19\xe2DUE0\xcc\\\x96\xee\x96\xee\xf6\x12", b"<^\xc8T\xfd\x1d@d@t\xbeot\xed\x1bw&\xb7`\xb1_QT'\x89A\xc3\xc3\xeb\x8a\x88.", b"t^\xc8F\xe1_(OLt\xaet&\xec\x1bR&\xa6k\xf4X\x14t:\x82F\x92\xa7\x93\xe6\xf6\x15", ]
# infer possible bytes msg = np.zeros([len(c), len(c[0])], dtype=int) getSpace() dat = sorted(dat)[::-1] for w, index, pos in dat: infer(index, pos)
# show results print("".join(["".join([chr(c) for c in x]) for x in msg])) key = xo.strxor(c[5], "".join([chr(c) for c in msg[5]]).encode()) print(key)
Failed File Transfer
Hello, Investigator,
We have intercepted a transmission that was sent to the thief of Anthon‘s invention. We believe it may contain information pertinent to your investigation! Additionally, the sender accidentally failed to encrypt the file with the thief’s most recent provisioned key, requiring them to resend the message. I am not sure why, but the keys don’t seem all that different. There may be a vulnerability with the provisioning process. Nevertheless, we have provided you with all attempts captured in transmission and the keys used for posterity. Good luck!
Oh no! A brilliant scientist with questionable ethics has encrypted Anthony’s important research. Luckily, the scientist who did this was overconfident, and gave us both the encrypted research and the contraption used to encrypt it. Can you get Anthony’s research back before it’s too late?
print("Here's the flag (in hex):", flag.hex()) print("=" * 64) print("Encrypt something if you want, you can choose the key and the plaintext :)") whileTrue: try: key = bytes.fromhex(input("Key (in hex): ")) plaintext = bytes.fromhex(input("Message to encrypt (in hex): ")) print("=" * 64) cipher = DES.new(key, DES.MODE_ECB) ciphertext = cipher.encrypt(pad(plaintext, BLOCK_SIZE)) print("Here's your message! (in hex):", ciphertext.hex()) print("Here's your message! (in bytes):", ciphertext) print("=" * 64) except KeyboardInterrupt: break
Here's the flag (in hex): 28e3a0ff9089aecc83465e470624a89253a1aac856a4f7ff08b4648b7c5eff9aa41a0dd1c7fc15995382dc3149dfcccf82241fb566fb5a0382241fb566fb5a03 ================================================================ Encrypt something if you want, you can choose the key and the plaintext :) Key (in hex): 0101010101010101 Message to encrypt (in hex): 28e3a0ff9089aecc83465e470624a89253a1aac856a4f7ff08b4648b7c5eff9aa41a0dd1c7fc15995382dc3149dfcccf82241fb566fb5a0382241fb566fb5a03 ================================================================ Here's your message! (in hex): 76d130969ee4b561b2f06fdd76172ddb8ad06cef10c62fa36eab80f508a94c7b02767cd689836c5b5e4e1cd11a794155cea388ef1fd8d5f9cea388ef1fd8d5f9e32a4d9e277d5a85e32a4d9e277d5a85e32a4d9e277d5a85e32a4d9e277d5a85e32a4d9e277d5a85e32a4d9e277d5a85e32a4d9e277d5a85e32a4d9e277d5a85 Here's your message! (in bytes): b"v\xd10\x96\x9e\xe4\xb5a\xb2\xf0o\xddv\x17-\xdb\x8a\xd0l\xef\x10\xc6/\xa3n\xab\x80\xf5\x08\xa9L{\x02v|\xd6\x89\x83l[^N\x1c\xd1\x1ayAU\xce\xa3\x88\xef\x1f\xd8\xd5\xf9\xce\xa3\x88\xef\x1f\xd8\xd5\xf9\xe3*M\x9e'}Z\x85\xe3*M\x9e'}Z\x85\xe3*M\x9e'}Z\x85\xe3*M\x9e'}Z\x85\xe3*M\x9e'}Z\x85\xe3*M\x9e'}Z\x85\xe3*M\x9e'}Z\x85\xe3*M\x9e'}Z\x85" ================================================================ Key (in hex): FEFEFEFEFEFEFEFE Message to encrypt (in hex): 28e3a0ff9089aecc83465e470624a89253a1aac856a4f7ff08b4648b7c5eff9aa41a0dd1c7fc15995382dc3149dfcccf82241fb566fb5a0382241fb566fb5a03 ================================================================ Here's your message! (in hex): 7cfa67f67ea05058ddeee341128568201e578b8fd2c28d09cbb9493a6210513fef4d20ba1175ea8bdb4134891e589f6682ef96dc95c3ff6a82ef96dc95c3ff6ad3256ca1b68f5658d3256ca1b68f5658d3256ca1b68f5658d3256ca1b68f5658d3256ca1b68f5658d3256ca1b68f5658d3256ca1b68f5658d3256ca1b68f5658 Here's your message! (in bytes): b'|\xfag\xf6~\xa0PX\xdd\xee\xe3A\x12\x85h \x1eW\x8b\x8f\xd2\xc2\x8d\t\xcb\xb9I:b\x10Q?\xefM \xba\x11u\xea\x8b\xdbA4\x89\x1eX\x9ff\x82\xef\x96\xdc\x95\xc3\xffj\x82\xef\x96\xdc\x95\xc3\xffj\xd3%l\xa1\xb6\x8fVX\xd3%l\xa1\xb6\x8fVX\xd3%l\xa1\xb6\x8fVX\xd3%l\xa1\xb6\x8fVX\xd3%l\xa1\xb6\x8fVX\xd3%l\xa1\xb6\x8fVX\xd3%l\xa1\xb6\x8fVX\xd3%l\xa1\xb6\x8fVX' ================================================================ Key (in hex): E0E0E0E0F1F1F1F1 Message to encrypt (in hex): 28e3a0ff9089aecc83465e470624a89253a1aac856a4f7ff08b4648b7c5eff9aa41a0dd1c7fc15995382dc3149dfcccf82241fb566fb5a0382241fb566fb5a03 ================================================================ Here's your message! (in hex): 52537b5730575f544831535f4b335953503443335f31535f34535f464c34545f34535f33345254487d1717171717171717171717171717171717171717171717c205d5d08d44e30bc205d5d08d44e30bc205d5d08d44e30bc205d5d08d44e30bc205d5d08d44e30bc205d5d08d44e30bc205d5d08d44e30bc205d5d08d44e30b Here's your message! (in bytes): b'RS{W0W_TH1S_K3YSP4C3_1S_4S_FL4T_4S_34RTH}\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\xc2\x05\xd5\xd0\x8dD\xe3\x0b\xc2\x05\xd5\xd0\x8dD\xe3\x0b\xc2\x05\xd5\xd0\x8dD\xe3\x0b\xc2\x05\xd5\xd0\x8dD\xe3\x0b\xc2\x05\xd5\xd0\x8dD\xe3\x0b\xc2\x05\xd5\xd0\x8dD\xe3\x0b\xc2\x05\xd5\xd0\x8dD\xe3\x0b\xc2\x05\xd5\xd0\x8dD\xe3\x0b' ================================================================
Forensics
Ransom Note
After the break-in to his lab Anthony found a suspicious new file on his desktop named README.txt. Anthony opened the file and found that it was a ransom demand from whomever stole his invention. Perhaps the contents of the ransom note contain a clue to the attacker’s identity.
提供了一些信息:
1 2 3 4 5 6 7 8 9 10
-----BEGIN BITCOIN SIGNED MESSAGE----- Your invention has been taken. If you ever want to see it again send 10 BTC to this address:
bc1qd7qtdayjnl382qmfl4tl4yaejuv5py0n3uwq6p
You have 3 days. -----BEGIN BITCOIN SIGNATURE----- H3zAMJyVW2j1+Y7A+w8wflZRUmggR+Sn532ZuAGtGLcxEERvymcPrtnXVkB+0mBqCUAb0AQwyPFJfGxvIeQDPpE= -----END BITCOIN SIGNATURE-----
Dive into the digital currents of Decrypt the Flood! Navigate through encrypted waters, uncovering clues hidden within the network flow. Will you decrypt the mystery behind Anthony’s vanished invention, or will it remain lost in the flood?
提供了一个流量包,直接搜索字符串flag头RS{就能找到flag。
B01lersCTF
choose_the_param
I wounder why we need to specify parameter length in the spec…
#!/usr/bin/python3 from Crypto.Util.number import long_to_bytes, bytes_to_long, getPrime import os from secret import flag
padded_flag = os.urandom(200) + flag + os.urandom(200) m = bytes_to_long(padded_flag)
defchal(): print("""Choose your parameter Enter the bit length of the prime! I'll choose two prime of that length, and encrypt the flag using rsa. Try decrypt the flag! """) whileTrue: bits = input("Enter the bit length of your primes> ") try: bit_len = int(bits) except: print("please enter a valid intergar") continue
p1 = getPrime(bit_len) p2 = getPrime(bit_len)
n = p1 * p2 e = 65537 c = pow(m, e, n) print(f"n = {n:x}") print(f"e = {e:x}") print(f"c = {c:x}")
from pwn import * from Crypto.Util.number import * import gmpy2 from sympy import * from libnum import * from tqdm import *
r = remote("gold.b01le.rs", 5001) n_list = [] c_list = []
for i in tqdm(range(50)): r.recvuntil(b"Enter the bit length of your primes> ", drop=1) r.sendline(b"48") n = int(r.recvline().strip().decode().split("=")[-1], 16) e = int(r.recvline().strip().decode().split("=")[-1], 16) c = int(r.recvline().strip().decode().split("=")[-1], 16) n_list.append(n) c_list.append(c)
C = solve_crt(c_list, n_list) phi = 1 for i in tqdm(n_list): phi *= int(totient(i)) N = 1 for i in n_list: N *= i d = gmpy2.invert(e, phi) print(long_to_bytes(pow(C, d, N))[200:-200])
half-big-rsa
Prime numbers are the best numbers. So, you should let me use it for my modulus!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
import math from Crypto.Util.number import getPrime, bytes_to_long, long_to_bytes import os
num_bits = 4096 e = (num_bits - 1) * 2 n = getPrime(num_bits)
e = 8190 n = 665515140120452927777672138241759151799589898667434054796291409500701895847040006534274017960741836352283431369658890777476904763064058571375981053480910502427450807868148119447222740298374306206049235106218160749784482387828757815767617741823504974133549502118215185814010416478030136723860862951197024098473528800567738616891653602341160421661595097849964546693006026643728700179973443277934626276981932233698776098859924467510432829393769296526806379126056800758440081227444482951121929701346253100245589361047368821670154633942361108165230244033981429882740588739029933170447051711603248745453079617578876855903762290177883331643511001037754039634053638415842161488684352411211039226087704872112150157895613933727056811203840732191351328849682321511563621522716119495446110146905479764695844458698466998084615534512596477826922686638159998900511018901148179784868970554998882571043992165232556707995154316126421679595109794273650628957795546293370644405017478289280584942868678139801608538607476925924119532501884957937405840470383051787503858934204828174270819328204062103187487600845013162433295862838022726861622054871029319807982173856563380230936757321006235403066943155942418392650327854150659087958008526462507871976852849 c = 264114212766855887600460174907562771340758069941557124363722491581842654823497784410492438939051339540245832405381141754278713030596144467650101730615738854984455449696059994199389876326336906564161058000092717176985620153104965134542134700679600848779222952402880980397293436788260885290623102864133359002377891663502745146147113128504592411055578896628007927185576133566973715082995833415452650323729270592804454136123997392505676446147317372361704725254801818246172431181257019336832814728581055512990705620667354025484563398894047211101124793076391121413112862668719178137133980477637559211419385463448196568615753499719509551081050176747554502163847399479890373976736263256211300138385881514853428005401803323639515624537818822552343927090465091651711036898847540315628282568055822817711675290278630405760056752122426935056309906683423667413310858931246301024309863011027878238814311176040130230980947128260455261157617039938807829728147629666415078365277247086868327600962627944218138488810350881273304037069779619294887634591633069936882854003264469618591009727405143494184122164870065700859379313470866957332849299246770925463579384528152251689152374836955250625216486799615834558624798907067202005564121699019508857929778460
e = 8190 n = 665515140120452927777672138241759151799589898667434054796291409500701895847040006534274017960741836352283431369658890777476904763064058571375981053480910502427450807868148119447222740298374306206049235106218160749784482387828757815767617741823504974133549502118215185814010416478030136723860862951197024098473528800567738616891653602341160421661595097849964546693006026643728700179973443277934626276981932233698776098859924467510432829393769296526806379126056800758440081227444482951121929701346253100245589361047368821670154633942361108165230244033981429882740588739029933170447051711603248745453079617578876855903762290177883331643511001037754039634053638415842161488684352411211039226087704872112150157895613933727056811203840732191351328849682321511563621522716119495446110146905479764695844458698466998084615534512596477826922686638159998900511018901148179784868970554998882571043992165232556707995154316126421679595109794273650628957795546293370644405017478289280584942868678139801608538607476925924119532501884957937405840470383051787503858934204828174270819328204062103187487600845013162433295862838022726861622054871029319807982173856563380230936757321006235403066943155942418392650327854150659087958008526462507871976852849 c = 264114212766855887600460174907562771340758069941557124363722491581842654823497784410492438939051339540245832405381141754278713030596144467650101730615738854984455449696059994199389876326336906564161058000092717176985620153104965134542134700679600848779222952402880980397293436788260885290623102864133359002377891663502745146147113128504592411055578896628007927185576133566973715082995833415452650323729270592804454136123997392505676446147317372361704725254801818246172431181257019336832814728581055512990705620667354025484563398894047211101124793076391121413112862668719178137133980477637559211419385463448196568615753499719509551081050176747554502163847399479890373976736263256211300138385881514853428005401803323639515624537818822552343927090465091651711036898847540315628282568055822817711675290278630405760056752122426935056309906683423667413310858931246301024309863011027878238814311176040130230980947128260455261157617039938807829728147629666415078365277247086868327600962627944218138488810350881273304037069779619294887634591633069936882854003264469618591009727405143494184122164870065700859379313470866957332849299246770925463579384528152251689152374836955250625216486799615834558624798907067202005564121699019508857929778460
res = Zmod(n)(c).nth_root(e, all=True) for m in res: flag = long_to_bytes(int(m)) print(flag)
fragments = [bytes_to_long(flag[5*i:5*i+5]) for i inrange(25)]
e = 31337
topG = matrix(Zmod(n), [[fragments[5*i + j] for j inrange(5)] for i inrange(5)]) bottomG = topG ** e
withopen("output.txt", "w") as file: file.write(f"n = {n}\n\n") file.write("Ciphertext Matrix:\n\n") for row in bottomG: for num in row: file.write(str(num) + " ") file.write("\n\n")
1 2 3 4 5 6 7 8 9 10 11 12 13
n = 515034877787990680304726859216098826737559607654653680536655175803818486402820694536785452537613547240092505793262824199243610743308333164103851365420630137187276313271869670701737383708742526677
from Crypto.Util.number import * import gmpy2 from libnum import * from tqdm import *
n = 515034877787990680304726859216098826737559607654653680536655175803818486402820694536785452537613547240092505793262824199243610743308333164103851365420630137187276313271869670701737383708742526677 res = gmpy2.iroot(n // 1701, 5)[0] for i inrange(1000): if n % (res - i) == 0: p = res - i break print(p)
接下来的操作是进行了一个矩阵运算:
1 2 3 4
fragments = [bytes_to_long(flag[5*i:5*i+5]) for i inrange(25)] e = 31337 topG = matrix(Zmod(n), [[fragments[5*i + j] for j inrange(5)] for i inrange(5)]) bottomG = topG ** e
from Crypto.Util.number import * import gmpy2 from libnum import * from tqdm import *
n = 515034877787990680304726859216098826737559607654653680536655175803818486402820694536785452537613547240092505793262824199243610743308333164103851365420630137187276313271869670701737383708742526677 res = gmpy2.iroot(n // 1701, 5)[0] for i inrange(1000): if n % (res - i) == 0: p = int(res - i) break
import sys from Crypto.Util import number from Crypto.Hash import SHA512
withopen("flag.txt") as f: flag = f.read()
# FIPS 186-4 Appendix A.1/A.2 compliant prime order q group and prime order p field #from Crypto.PublicKey import DSA as FFCrypto #(p,q,g) = FFCrypto.generate(2048).domain() p = 32148430219533869432664086521225476372736462680273996089092113172047080583085077464347995262368698415917196323365668601969574610671154445337781821758494432339987784268234681352859122106315479086318464461728521502980081310387167105996276982251134873196176224643518299733023536120537865020373805440309261518826398579473063255138837294134742678213639940734783340740545998610498824621665838546928319540277854869576454258917970187451361767420622980743233300167354760281479159013996441502511973279207690493293107263225937311062981573275941520199567953333720369198426993035900390396753409748657644625989750046213894003084507 q = 25652174680121164880516494520695513229510497175386947962678706338003 g = 23174059265967833044489655691705592548904322689090091191484900111607834369643418104621577292565175857016629416139331387500766371957528415587157736504641585483964952733970570756848175405454138833698893579333073195074203033602295121523371560057410727051683793079669493389242489538716350397240122001054430034016363486006696176634233182788395435344904669454373990351188986655669637138139377076507935928088813456234379677586947957539514196648605649464537827962024445144040395834058714447916981049408310960931998389623396383151616168556706468115596486100257332107454218361019929061651117632864546163172189693989892264385257
defprove(): print("The oracles say that X is g^x and A is g^a. Be that as it may...") print("Perhaps there exists a way to make their confidence sway!")
# (Sorry, can't choose a :) A = 30210424620845820052071225945109142323820182565373787589801116895962027171575049058295156742156305996469210267854774935518505743920438652976152675486476209694284460060753584821225066880682226097812673951158980930881565165151455761750621260912545169247447437218263919470449873682069698887953001819921915874928002568841432197395663420509941263729040966054080025218829347912646803956034554112984570671065110024224236097116296364722731368986065647624353094691096824850694884198942548289196057081572758803944199342980170036665636638983619866569688965508039554384758104832379412233201655767221921359451427988699779296943487
h = SHA512.new(truncate="256") h.update(number.long_to_bytes(g) + number.long_to_bytes(p) + number.long_to_bytes(A)) c = number.bytes_to_long(h.digest()) % p
z = int(input("a + cx = ")) % p return (A,c,z)
defsetup(): print("> I'm so sleepy, I almost forgot; we should share what we ought.") print("> Just between you and me, can we agree on a verifying key...?") X = int(input("> X = ")) % p return X
defverify(A,c,z,X): h = SHA512.new(truncate="256") h.update(number.long_to_bytes(g) + number.long_to_bytes(p) + number.long_to_bytes(A)) cp = number.bytes_to_long(h.digest()) % p if c != cp orpow(g, z, p) != ((A * pow(X, c, p)) % p): print("> Oh, even my bleary eyes can tell your evidence is fau x !!") print("> Are you sure that what you say is what you truly know?") sys.exit() else: print("> ", end="") print(flag)
if __name__ == "__main__": (A,c,z) = prove() X = setup() verify(A,c,z,X)
这题实现了一个验证程序,简单看了下代码发现需要验证c != cp or pow(g, z, p) != ((A * pow(X, c, p)) % p),前半部分发现计算都用的程序内部的数据,不需要管,主要是后面这个计算: $$ g^z\equiv AX^c\pmod p $$ 在这个题目中,$z,X$是我们需要给的,$c$是可以通过计算得到的。剩下的就是提供这两个值满足方程,考虑特殊值$z=0$,移项得到: $$ A^{-1}\equiv X^c\pmod p $$ 发现这样可以通过RSA解密直接计算出一个$X$,有$cd\equiv 1\pmod {p-1}$: $$ X\equiv (A^{-1})^d\pmod p $$ 事实上这个$c$经过计算后发现不互素,并不能计算出逆元,也不能直接求解不互素问题,因为是进行交互验证。还注意到题目还给了一个$q$值,注释中提到了这个模$p$下的阶为$q$:
1 2 3
# FIPS 186-4 Appendix A.1/A.2 compliant prime order q group and prime order p field #from Crypto.PublicKey import DSA as FFCrypto #(p,q,g) = FFCrypto.generate(2048).domain()
直接尝试用$cd\equiv 1\pmod q$,计算出$X$,发送相关参数得到flag:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
from Crypto.Util.number import * from Crypto.Hash import SHA512 import gmpy2
p = 32148430219533869432664086521225476372736462680273996089092113172047080583085077464347995262368698415917196323365668601969574610671154445337781821758494432339987784268234681352859122106315479086318464461728521502980081310387167105996276982251134873196176224643518299733023536120537865020373805440309261518826398579473063255138837294134742678213639940734783340740545998610498824621665838546928319540277854869576454258917970187451361767420622980743233300167354760281479159013996441502511973279207690493293107263225937311062981573275941520199567953333720369198426993035900390396753409748657644625989750046213894003084507 q = 25652174680121164880516494520695513229510497175386947962678706338003 g = 23174059265967833044489655691705592548904322689090091191484900111607834369643418104621577292565175857016629416139331387500766371957528415587157736504641585483964952733970570756848175405454138833698893579333073195074203033602295121523371560057410727051683793079669493389242489538716350397240122001054430034016363486006696176634233182788395435344904669454373990351188986655669637138139377076507935928088813456234379677586947957539514196648605649464537827962024445144040395834058714447916981049408310960931998389623396383151616168556706468115596486100257332107454218361019929061651117632864546163172189693989892264385257 A = 30210424620845820052071225945109142323820182565373787589801116895962027171575049058295156742156305996469210267854774935518505743920438652976152675486476209694284460060753584821225066880682226097812673951158980930881565165151455761750621260912545169247447437218263919470449873682069698887953001819921915874928002568841432197395663420509941263729040966054080025218829347912646803956034554112984570671065110024224236097116296364722731368986065647624353094691096824850694884198942548289196057081572758803944199342980170036665636638983619866569688965508039554384758104832379412233201655767221921359451427988699779296943487
h = SHA512.new(truncate="256") h.update(long_to_bytes(g) + long_to_bytes(p) + long_to_bytes(A)) c = bytes_to_long(h.digest()) % p
d = gmpy2.invert(c, q) X = pow(pow(A, -1, p), d, p) print(X)
p = int(root[1][0]) q = n // p d = gmpy2.invert(65537,(p-1)*(q-1)) m = pow(c,d,n) print(long_to_bytes(int(m)))
江枫渔火对愁眠
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
from Crypto.Util.number import * flag = b'paluctf{******************}' p = getPrime(512) q = getPrime(512) m = bytes_to_long(flag) n = p * q e = 0x10001 c = pow(m, e, n) leak1 = p & q leak2 = p | q print(n) print(leak1) print(leak2) print(c)
from Crypto.Util.number import getStrongPrime, GCD, bytes_to_long import os from flag import flag
deflong_to_bytes(long_int, block_size=None): """Convert a long integer to bytes, optionally right-justified to a given block size.""" bytes_data = long_int.to_bytes((long_int.bit_length() + 7) // 8, 'big') return bytes_data ifnot block_size else bytes_data.rjust(block_size, b'\x00')
defgen_keys(bits=512, e=5331): """Generate RSA modulus n and public exponent e such that GCD((p-1)*(q-1), e) == 1.""" whileTrue: p, q = getStrongPrime(bits), getStrongPrime(bits) n = p * q if GCD((p-1) * (q-1), e) == 1: return n, e
defpad(m, n): """Pad the message m for RSA encryption under modulus n using PKCS#1 type 1.""" mb, nb = long_to_bytes(m), long_to_bytes(n) assertlen(mb) <= len(nb) - 11 padding = os.urandom(len(nb) - len(mb) - 3).replace(b'\x01', b'') return bytes_to_long(b'\x00\x01' + padding + b'\x00' + mb)
defencrypt(m, e, n): """Encrypt message m with RSA public key (e, n).""" returnpow(m, e, n)
n, e = gen_keys() m = pad(bytes_to_long(flag), n) c1, c2 = encrypt(m, e, n), encrypt(m // 2, e, n)
print(f"n = {n}\ne = {e}\nc1 = {c1}\nc2 = {c2}")
# n = 128134155200900363557361770121648236747559663738591418041443861545561451885335858854359771414605640612993903005548718875328893717909535447866152704351924465716196738696788273375424835753379386427253243854791810104120869379525507986270383750499650286106684249027984675067236382543612917882024145261815608895379 # e = 5331 # c1 = 60668946079423190709851484247433853783238381043211713258950336572392573192737047470465310272448083514859509629066647300714425946282732774440406261265802652068183263460022257056016974572472905555413226634497579807277440653563498768557112618320828785438180460624890479311538368514262550081582173264168580537990 # c2 = 43064371535146610786202813736674368618250034274768737857627872777051745883780468417199551751374395264039179171708712686651485125338422911633961121202567788447108712022481564453759980969777219700870458940189456782517037780321026907310930696608923940135664565796997158295530735831680955376342697203313901005151
from Crypto.Util.number import * from tqdm import trange n = 128134155200900363557361770121648236747559663738591418041443861545561451885335858854359771414605640612993903005548718875328893717909535447866152704351924465716196738696788273375424835753379386427253243854791810104120869379525507986270383750499650286106684249027984675067236382543612917882024145261815608895379 e = 5331 c1 = 60668946079423190709851484247433853783238381043211713258950336572392573192737047470465310272448083514859509629066647300714425946282732774440406261265802652068183263460022257056016974572472905555413226634497579807277440653563498768557112618320828785438180460624890479311538368514262550081582173264168580537990 c2 = 43064371535146610786202813736674368618250034274768737857627872777051745883780468417199551751374395264039179171708712686651485125338422911633961121202567788447108712022481564453759980969777219700870458940189456782517037780321026907310930696608923940135664565796997158295530735831680955376342697203313901005151
p = 151832619619952089992267716058068444251307600220706203871589765844990819175654042917774490787590849720202969240992246624166668570786235406779778934647681250166384828094778797880304323848041273713831052602978130708287523575488166230706021974231380611512371425017998262828486267505916086636495016213117818476079 q = 136011049679334940861511595857042329781653809853866436171389745534855895446196665892885140663304371230055953209984856118200410958041858815679721863717912611066674050454954534686280510303474769670492647228370259394337403855556056590338482704020086450814990436480639792318856245688841995452742464887239898730723 n = p*q d = gmpy2.invert(e,phi) m = pow(c,d,n) print(bytes.fromhex(hex(int(m))[2:]))