BSidesSF CTF 2022

BSidesSF CTF 2022 中 rsalab 的题解。

Crypto

rsalab

这题其实是三题。一共三个flag。nc连上一共有8题,可以算是对RSA算法的攻击的一个总结入门。这种题我觉得还不错。

beginner

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

Before your start on attacking RSA, it's important to first understand
basic RSA operations like encryption and decryption. For this
challenge, we have generated a public key. Your job is to encrypt the
provided message with that public key to get the ciphertext.

RSA encryption uses the encrypting exponent, e. Decryption is the same
mathematical operation except that it uses the decrypting exponent, d.
If you can encrypt with the provided e then you could decrypt (if you
had d) just as easily.

== Generated Public Key ==
Public Modulus (n): 93750367580497259754994151096824772408757991545943269927577541702139349923031
Encrypting Exponent (e): 65537

Message to encrypt (m): 1234567890

What is the ciphertext (c) for the message (m) using the public key?

# 43342627728594194709171852585342053543398971218485131355267815503043000363802

这里叫你计算一下密文。很简单。

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
Challenge 2:

One of the most intimidating things about RSA when you first read
about it is the notion of a "modular inverse". In our everyday lives
we're pretty familiar with the idea that (1/3) * 3 = 1 or that (5/7) *
(7/5) = 1. That is, 1/3 is the inverse of 3 and 5/7 is the inverse of
7/5. What happens though when the numbers "wrap around" because of a
modulus? As one example, you can verify easily that the inverse of 2
mod 5 is 3 mod 5 because 2 * 3 = 6 and 6 mod 5 = 1. The idea that 2
and 3 are inverses mod 5 is not at all obvious. Or, even if mod 5 is
obvious, in the general case where the modulus is large inverses are
not obvious.

In this challenge you are given e and n (as well as the factors of n,
p and q)and you need to find the modular inverse of e mod
phi(n). Recall that when n has two factors phi(n) is (p - 1) * (q - 1).

== Generated Public Key ==
Public Modulus (n): 98160686216077010306650598451384523493996357373041397278666044179163041918013
Encrypting Exponent (e): 65537
== Secret Primes ==
Prime p: 296478161395804220864289487232795949083
Prime q: 331089095243782724782290601373623640711


What is secret decrypting exponent (d) that is the couterpart of e?

# 9919865492913591395104245136999247739392732302988070705640903774535857754853

这里叫你算d,也就是私钥。q,p都给了,直接套公式就行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Challenge 3:

RSA is an "asymmetric" encryption algorithm because the key used to
decrypt (d) is not the same key that is used to encrypt (e). This
challenge will let you experience that first-hand. You provide your
public key (n) and (e) and this challenge will encrypt a secret
message (m) and provide you the ciphertext (c). Then using your
decrypting exponent (d) you can decrypt the ciphertext back to the
secret message.

You are highly encouraged to generate your own key here instead of
finding RSA keys somewhere.

To pass this challenge the n value you provide must be at least 512
bits, not be prime and the e value you choose must be at least
100. 65537 is a good choice for e.


What is n for your public key?

这里叫我们自己输入一个n。这个n必须是512位以上的。而且e要大于100。这里我们就用自己的代码生成就行了。

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

while True:
p = getPrime(512)
q = getPrime(512)
n = p*q
if n.bit_length() == 1024:
print(p)
print(q)
print(n)
break

"""
10875694991805645215254668135517324330391142280861231776571929186459042877139016119856783459429519225579891325084663062250827914530190529161309788675368217
9773480664355160440812724403080078613458928203389458915050187577280165834669443777233680522860771163143570050265715266656546946475962420080769836027441389
106293394713836728584770048927645487102102551426684751134581194296372962576295840454537397021655815550308189352325607048529938553341796769007606529397626198231177636817810729599073564849299319322213650544188212299806442994412502877875106694978621139604395094335492409498378148226052685740633787250985960933413
"""
1
2
3
4
5
6
7
8
What is n for your public key? 106293394713836728584770048927645487102102551426684751134581194296372962576295840454537397021655815550308189352325607048529938553341796769007606529397626198231177636817810729599073564849299319322213650544188212299806442994412502877875106694978621139604395094335492409498378148226052685740633787250985960933413

What is e for your public key? 65537
The ciphertext you must decrypt is 10747018944552439199720581255039720388084637469960708491916798595496468141161787523686458134928624981502687900182498988328445362551185644407711340320568644670092570168829217359152240930612218395791282480938275664550764054659163828364062000797849017204210153179497288454002327624996357110961011485773669626403

What was m (decrypt with the d you've made for your key!)?

# 193394912730819321447795805382820639777

这里就叫我们解密了,也是直接用rsa的公式就可以。

1
# CTF{right_so_awesome!}

Intermediate

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

RSA is only secure when factoring n is hard. If you can factor n into
p and q then you can compute Euler's phi(n) (the totient function)
which, when n only has two prime factors, is just (p - 1) * (q -
1). With phi(n) you can use e to find d which gives you the private
key!

In this challenge, a secret message has been encrypted with a very
weak RSA key. The RSA key's n is approximately 128 bits meaning
(assuming they are the same size) p and q are about 64 bit each. It's
your job to decrypt the secret message by breaking the RSA key (factor
n!) and then determining d using n's prime factors. 128-bit RSA keys
are just big enough you can't use trivial methods like trial division
but are easily small enough that almost anything more sophisticated
will factor them in seconds.

== Generated Public Key ==
Public Modulus (n): 232425609894096576101162633852002477913
Encrypting Exponent (e): 65537

Message to decrypt (c): 191481802973151280528876229812887781569

What is the plaintext (m) for the encrypted message (c) for the public key?

这里说的是如果能分解n的话就能得到私钥对密文进行解密。给出的n很小,可以直接进行分解的。使用yafu来分解这个数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
F:\CTFTools\yafu-1.34>yafu-x64.exe
factor(232425609894096576101162633852002477913)


fac: factoring 232425609894096576101162633852002477913
fac: using pretesting plan: normal
fac: no tune info: using qs/gnfs crossover of 95 digits
div: primes less than 10000
fmt: 1000000 iterations
rho: x^2 + 3, starting 1000 iterations on C39
rho: x^2 + 2, starting 1000 iterations on C39
rho: x^2 + 1, starting 1000 iterations on C39
pm1: starting B1 = 150K, B2 = gmp-ecm default on C39
Total factoring time = 0.0350 seconds


***factors found***

P20 = 15829756971946610401
P20 = 14682828694464462713

ans = 1

得到了p,q就可以对密文进行解密了。

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

RSA's security relies on factorization being a hard
problem. Unfortunately there are many different factorization
algorithms that are quite fast in certain special cases. This makes
generating secure RSA keys quite challenging because tons of gotchas
and pitfalls must be avoided. One pitfall is when p and q are too
close together because an algorithm known as "Fermat's Factorization"
can be used.

In this challenge, a 2048 bit RSA key has been generated using two
1024 bit primes, p and q. The flaw is that p and q share approximately
their first 500 bits. That may not sound that bad since they still are
different in their lower ~524 bits but you'll see that isn't nearly
enough.

== Generated Public Key ==
Public Modulus (n): 25240054906527308715123083513191206839625173490523222251828485342363714336785380565865997526799064756242760495920245470292094107572885037758544627319924131106469206061990262762473830559723089863710658174860933300953411483624472662692904888669381554917178242116550796585404855973132973772929016519378021061815488878618803864877487986518434955737510882129986289035083960210216734245350444938463326983372446311710518586992606167860499851814468283028623132695394370326534082149664539102785030529344576581865843167524739917242789374803048921371234481347145388496209423571350226798734660569948183356006127158058090767513593
Encrypting Exponent (e): 65537

Message to decrypt (c): 10426074392847872381473627569957969180320053109752606227916079994083532053799703036065905282122615431437721866313171294013350515428252537309345482269880415619442294601156752585446010009194624361395148280761278099888525138605830066285813688990522801677857932428538220521983981413448850469004996008927906933730792935466887940039979883069300623808947669972015213977651647997784626563669640738954071792582917241174307901215091315797664765124678924852716239603589657100939596203624339673928916386333510127266261894581633834712017193560070996878504040955960547901590264230976711955989542053963668368387177301946035693856117

What is the plaintext (m) for the encrypted message (c) for the public key?

这里说的是如果生成n的两个素数相距很近的话,很容易被分解出来。p和q的高位大部分相同,但是这不安全。这可以使用费马分解法来对n进行分解。也就是他说的 “Fermat’s Factorization”。yafu里面集成了很多n的分解方法所以这里我们使用yafu进行分解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
F:\CTFTools\yafu-1.34>yafu-x64.exe
factor(25240054906527308715123083513191206839625173490523222251828485342363714336785380565865997526799064756242760495920245470292094107572885037758544627319924131106469206061990262762473830559723089863710658174860933300953411483624472662692904888669381554917178242116550796585404855973132973772929016519378021061815488878618803864877487986518434955737510882129986289035083960210216734245350444938463326983372446311710518586992606167860499851814468283028623132695394370326534082149664539102785030529344576581865843167524739917242789374803048921371234481347145388496209423571350226798734660569948183356006127158058090767513593)


fac: factoring 25240054906527308715123083513191206839625173490523222251828485342363714336785380565865997526799064756242760495920245470292094107572885037758544627319924131106469206061990262762473830559723089863710658174860933300953411483624472662692904888669381554917178242116550796585404855973132973772929016519378021061815488878618803864877487986518434955737510882129986289035083960210216734245350444938463326983372446311710518586992606167860499851814468283028623132695394370326534082149664539102785030529344576581865843167524739917242789374803048921371234481347145388496209423571350226798734660569948183356006127158058090767513593
fac: using pretesting plan: normal
fac: no tune info: using qs/gnfs crossover of 95 digits
div: primes less than 10000
fmt: 1000000 iterations
Total factoring time = 7.6796 seconds


***factors found***

P309 = 158871189668005283415144657986551193302869428022001726220647816798498163786655160734083642077926887626968994149548144770437583756497334125901064680461238653949200872152467592040526765560776849130898789230056872627669722209677289335370789152455332871728170193718878900033253778086216110326217359038965751457767
P309 = 158871189668005283415144657986551193302869428022001726220647816798498163786655160734083642077926887626968994149548144770437583756497334125901064680461234832110504013303470429626460988959707000583806418183588832922742389554954078372113253029216897932455245679734943989771289650860903610854223547207721942050079

ans = 1

这里我们就得到了p与q。进行解密即可。

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

It is critically important that the primes used in an RSA key have
never been used in any other RSA key. If two keys happen to share a
prime then a quick comparison using the GCD algorithm between the two
n values will find a common prime. This is a common flaw for keys
generated on devices with poor (or no) entropy on first boot.

This challenge generates two keys that share a prime. Use the GCD
between the two n to find the common prime.

== Generated Public Key 1 ==
Public Modulus (n): 25766855849012170602215974276512994665527760103232878510877708579134451117925205685988667478305686774909581308048305405982227012155215071376134036940929029662904505877622287438422321334710416342122246755031087867738529234615302073381335900455830870395122148361228482894414857023560773160530764583158671668598804795236806439696444767416669004606904236852625407455032822014231606087073213831281114887244532839729675040811323228917519504038450191315875150823702300759184612618800826323992940766242448628052050372979262990010935907002585341542207395142877707331416760094045455941053408610742527475497038936581984374880709
Encrypting Exponent (e): 65537
Encrypted message (c): 10525814866510137434899274998082698726988868256233514176953502719354264032410185277614127761527071749571758119230375451756494965691920242823875047761236402904697195895757175042349370909038642191817523007191322103279536254571467901947532676209111044078805574511874421763608159336854724603736343437950821917939678565773065914042640814861551433414991462029439854218529934675178281414333981877196921950767775395220428028907601554437040987071711361174143526222051997404012801968532202680596542050070864790765315160191871148699455255350919126797448710611287281082665133892808503848186989158095870812598832558333246789042676

== Generated Public Key 2 ==
Public Modulus (n): 23029445296375982244621042067356938067600932656366159682913502418113458794974570308801738092925111529731228548404356478117663790755942048917363075846055763270676348368932404632553120873938932115409549042302048379540139242329521312179497517707113409555264863436910061516286482903931874204248958042186907817570230042112727883343124487662643844328226394430868012939455393801202299874213974171731230732650780391625138430545738601970201658394385606885566557862983885797334286100689371547075235155161498539779469617285566915877747705913072389949483202393235902365901491091866493162015415874138858126412365811099585224212299
Encrypting Exponent (e): 65537
Encrypted message (c): 15825489607550127439145806852385542839567883239057363905562871179426946402042942076016730509123999510531814642125437244542503343524213169970527943119058139473890975392849048101137592242977766658809403638381196910489834667796018783886181113320540459578692631939111357899549377553003879410941929489345106395564870136122987632435751994319822778186510306221275589605892748144352896531387710390605511956945032387237242470561632107510753242284083264220415607441731463294577007558615036100651711547573054889611720078234249393852435728233068931521415540782361953536967033384859985153392456809560643291691859128343066976633307

The same message (m) was encrypted with both keys, what was the message?

这里说的是一个素数参与了两个n的生成,那么我们可以使用GCD来计算这个素数,从而破解两个N的分解。

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

n1 = 25766855849012170602215974276512994665527760103232878510877708579134451117925205685988667478305686774909581308048305405982227012155215071376134036940929029662904505877622287438422321334710416342122246755031087867738529234615302073381335900455830870395122148361228482894414857023560773160530764583158671668598804795236806439696444767416669004606904236852625407455032822014231606087073213831281114887244532839729675040811323228917519504038450191315875150823702300759184612618800826323992940766242448628052050372979262990010935907002585341542207395142877707331416760094045455941053408610742527475497038936581984374880709
n2 = 23029445296375982244621042067356938067600932656366159682913502418113458794974570308801738092925111529731228548404356478117663790755942048917363075846055763270676348368932404632553120873938932115409549042302048379540139242329521312179497517707113409555264863436910061516286482903931874204248958042186907817570230042112727883343124487662643844328226394430868012939455393801202299874213974171731230732650780391625138430545738601970201658394385606885566557862983885797334286100689371547075235155161498539779469617285566915877747705913072389949483202393235902365901491091866493162015415874138858126412365811099585224212299
p = gmpy2.gcd(n1,n2)
assert sympy.isprime(p)
q1 = n1//p
q2 = n2//p

e = 65537

c1 = 10525814866510137434899274998082698726988868256233514176953502719354264032410185277614127761527071749571758119230375451756494965691920242823875047761236402904697195895757175042349370909038642191817523007191322103279536254571467901947532676209111044078805574511874421763608159336854724603736343437950821917939678565773065914042640814861551433414991462029439854218529934675178281414333981877196921950767775395220428028907601554437040987071711361174143526222051997404012801968532202680596542050070864790765315160191871148699455255350919126797448710611287281082665133892808503848186989158095870812598832558333246789042676
c2 = 15825489607550127439145806852385542839567883239057363905562871179426946402042942076016730509123999510531814642125437244542503343524213169970527943119058139473890975392849048101137592242977766658809403638381196910489834667796018783886181113320540459578692631939111357899549377553003879410941929489345106395564870136122987632435751994319822778186510306221275589605892748144352896531387710390605511956945032387237242470561632107510753242284083264220415607441731463294577007558615036100651711547573054889611720078234249393852435728233068931521415540782361953536967033384859985153392456809560643291691859128343066976633307

d1 = gmpy2.invert(e, (p-1)*(q1-1))
d2 = gmpy2.invert(e, (p-1)*(q2-1))

print(gmpy2.powmod(c1,d1,n1))
print(gmpy2.powmod(c2,d2,n2))

# 49298732203100844089802796111250631496813870200781244531168768869337723564648
# 49298732203100844089802796111250631496813870200781244531168768869337723564648

得到flag为

1
# CTF{ready_some_attacks!}

Advanced

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
Challenge 7:

The modular arithmetic aspect of RSA is one of the main security
features that prevent trivial decryption of messages. It's important
that the modulus n reduces the resulting value's size. For example, if
the encrypting exponent were 3 and the ciphertext were 125 then a
simple cube root would reveal that the encrypted message was
5. Because of this, RSA is generally considered insecure when used
"raw" like in this challenge. Messages are supposed to be padded in
size so that 5 becomes something like 100000000...000005. Exact
padding schemes vary and are supposed to have some randomness to
them. Also, the encrypting exponent needs to be big enough that
encryption operations produce results many times the size of n so that
the modulus by n reduces them greatly. Finally, it's important that
the same message is not encrypted with multiple keys. Using "Chinese
Remainder Theorem" (CRT) a message encrypted with multiple keys can be
reconstructed if the sum of the modulus size for all the key exceeds
the size of the encrypted result (pre-modulus).

In this challenge, the message getting encrypted is 64 bits and the
encrypting exponent is 101. This produces a result that is
approximately 101 * 64 = 6500 bits. The message is then encrypted
with four different 2048 bit RSA keys. The four keys combined are
about 8200 bits which is bigger than the 6500 bit intermediate result
of the encryption operation. Using CRT the 6500 bit encrypted message
can be recovered and then the 101st integer root can be taken to
recover the original 64 bit message.


== Generated Public Key 1 ==
Public Modulus (n): 23149105273119856627850090136919929723261823943624757765177549219866234384407443983691092738521031053203614477766656986767286266446444753737595544946472216224508161386171999255740873450148968555277596893973797691032923207849752189313156941377324765127716924091042774578614137857563130021083931714855059086528319464004755957875715598938914828284652002920579316752760142748768497603128211200838068910581466727558789046853980447659618327548379965828203663511630084649428450353266659376896302538711661311614077550561369584239426264779153594798510395598348794151054501986173283660486525134797651978877284141209813142620353
Encrypting Exponent (e): 101
Encrypted message (c): 4133098674895364475122584859727936636319542148084723385127010324327313789334393930206458052870325462125129516244259655103297937948615632716958036799846515784943596344659171054099447520291118273021064059336853671027556967972413169273404209750919489026617828517460910331013223288149485999850602777587671440578608610811039866904431406022561453341605551948558124880741033754123533721467625272714253906039692619129939195122566028002230169531368415886389935020627567435607209913240567022647994916867444034515723636583599469039313449903333413389457244138789788808665623522246598817641042647619000635273611183224626880248944

== Generated Public Key 2 ==
Public Modulus (n): 27505003639755307755377499909116790316666559241048462052708838019026245876061305032506336142607123275928140916064623611321267478241118533648691082780205975675848930891049661612587641417134731442097549122052889052873494510311763619581247175094225425295301201416148508869270650795946882209628169916402212595347072398536774964258765618683344988682136591522691855765474591800551003356738950115475986218748865738256040385018144667288963471023985981776397834650529125410415157989610913249638002630420759275424711122746274087218674581203767628461879942706575343687840846649398728521575759042643850479174348322700725152859179
Encrypting Exponent (e): 101
Encrypted message (c): 1739787364426947826729125390015498042633640345967134916542238682709304408943088145667424845845517943847244192660150225311643364678630739496448816122882054922412037008580775971375290713350552018895747047751648267738492662247630323384176319114392074862370478124092683816850069295355099746484470004393034493698412438690692636346398477331324809186840095746501169042776273857686097678768604865263346852531284195968241769030057050871599017420069734395480513006992209345486383715490267735794610384399680997873975671890958828764776368371097805716088332777475179458219585218216497145123375660441094713278890674938571932381488

== Generated Public Key 3 ==
Public Modulus (n): 23943992665005716914265748181378044020163225463944348787139747620070493441066981349214063664476165988435985828513188893343155039302311995874372727359429651639443442258295642274472710398428893112110181883065676797050367135114334409107720580674354846328795686014101403670618429882603919281846439213906309422478551046883785057516103930044593323333307553091446120290651424839856749893243675869030846434162150766596575521905731655641301802636196920315967062547856059292665187665794385263754141467629309390311239484966966962304043655439642471022652647482083941901373189746935767061122773274542240116211061429832031627444639
Encrypting Exponent (e): 101
Encrypted message (c): 19767759825914120713480654388913002907682584898016181997793326000329269531331547744785734164928410151086832198173774683214897941427775071585114906921627736047610200414157221293720422178460316657569689615289690667699532754041172774690035641861841049734906636233903208024641071920381980528962741503024268715672111438448667026120256281719821441794618486573597045681470587530870988650916524194457151054045651116850560891414366638095586467350677980494433751521957595486130004535388092882581591841627178062736831925448026071811776224612588994657584656478966565710308371560272935517045167518919934363672571637207453820737908

== Generated Public Key 4 ==
Public Modulus (n): 23764882147307056027005386922771967158083000845038109106003774249423632198485870921435962915038604258992363942683714487677164840502159532488262243238422271988447264107769115146700709762088120987424670297526032023889996339452998923199685412788748818176001822310309065993936711895735716914143587537590216206044501353689058205837089559899900836823313025042963189643956178442108568422925457393179572553420165084207399626407406447085305010961166687962292136079785531624901866292850569253781233922810459554095009877264479825892076775128519566724087703837984362767805722834293423659825643823352593873758485964298109062499299
Encrypting Exponent (e): 101
Encrypted message (c): 4200591912955199563979501872447323146617285786017413457040833853096647252495282176757667370964891089582307763252793332014110634684577275241510438935460795623158895099508356538022570772990943795127101179891821312550040505597385238071003932128751650976515586342666263903701969711589529513715648354184394669982822015645429160867813979611140609363112226286104769818496188762050564612227378368967743343698409735242567687523483613871073583201483076450563741645337691456798723334003820025909864260550025607987279304993898490653449697341369989367293215886097687051801809614329388180441198807195809708893458983328341875490575

The same message (m) was encrypted with all keys, what was the message?

这里说的是用不同的n对同一m进行多组的加密,会造成明文的泄露,因为这样我们可以使用中国剩余定理来求解对应的m。

关于中国剩余定理网上的资料很多这里我就不再赘述了。

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
import gmpy2
import sympy

e = 101
n1 = 23149105273119856627850090136919929723261823943624757765177549219866234384407443983691092738521031053203614477766656986767286266446444753737595544946472216224508161386171999255740873450148968555277596893973797691032923207849752189313156941377324765127716924091042774578614137857563130021083931714855059086528319464004755957875715598938914828284652002920579316752760142748768497603128211200838068910581466727558789046853980447659618327548379965828203663511630084649428450353266659376896302538711661311614077550561369584239426264779153594798510395598348794151054501986173283660486525134797651978877284141209813142620353
c1 = 4133098674895364475122584859727936636319542148084723385127010324327313789334393930206458052870325462125129516244259655103297937948615632716958036799846515784943596344659171054099447520291118273021064059336853671027556967972413169273404209750919489026617828517460910331013223288149485999850602777587671440578608610811039866904431406022561453341605551948558124880741033754123533721467625272714253906039692619129939195122566028002230169531368415886389935020627567435607209913240567022647994916867444034515723636583599469039313449903333413389457244138789788808665623522246598817641042647619000635273611183224626880248944
n2 = 27505003639755307755377499909116790316666559241048462052708838019026245876061305032506336142607123275928140916064623611321267478241118533648691082780205975675848930891049661612587641417134731442097549122052889052873494510311763619581247175094225425295301201416148508869270650795946882209628169916402212595347072398536774964258765618683344988682136591522691855765474591800551003356738950115475986218748865738256040385018144667288963471023985981776397834650529125410415157989610913249638002630420759275424711122746274087218674581203767628461879942706575343687840846649398728521575759042643850479174348322700725152859179
c2 = 1739787364426947826729125390015498042633640345967134916542238682709304408943088145667424845845517943847244192660150225311643364678630739496448816122882054922412037008580775971375290713350552018895747047751648267738492662247630323384176319114392074862370478124092683816850069295355099746484470004393034493698412438690692636346398477331324809186840095746501169042776273857686097678768604865263346852531284195968241769030057050871599017420069734395480513006992209345486383715490267735794610384399680997873975671890958828764776368371097805716088332777475179458219585218216497145123375660441094713278890674938571932381488
n3 = 23943992665005716914265748181378044020163225463944348787139747620070493441066981349214063664476165988435985828513188893343155039302311995874372727359429651639443442258295642274472710398428893112110181883065676797050367135114334409107720580674354846328795686014101403670618429882603919281846439213906309422478551046883785057516103930044593323333307553091446120290651424839856749893243675869030846434162150766596575521905731655641301802636196920315967062547856059292665187665794385263754141467629309390311239484966966962304043655439642471022652647482083941901373189746935767061122773274542240116211061429832031627444639
c3 = 19767759825914120713480654388913002907682584898016181997793326000329269531331547744785734164928410151086832198173774683214897941427775071585114906921627736047610200414157221293720422178460316657569689615289690667699532754041172774690035641861841049734906636233903208024641071920381980528962741503024268715672111438448667026120256281719821441794618486573597045681470587530870988650916524194457151054045651116850560891414366638095586467350677980494433751521957595486130004535388092882581591841627178062736831925448026071811776224612588994657584656478966565710308371560272935517045167518919934363672571637207453820737908
n4 = 23764882147307056027005386922771967158083000845038109106003774249423632198485870921435962915038604258992363942683714487677164840502159532488262243238422271988447264107769115146700709762088120987424670297526032023889996339452998923199685412788748818176001822310309065993936711895735716914143587537590216206044501353689058205837089559899900836823313025042963189643956178442108568422925457393179572553420165084207399626407406447085305010961166687962292136079785531624901866292850569253781233922810459554095009877264479825892076775128519566724087703837984362767805722834293423659825643823352593873758485964298109062499299
c4 = 4200591912955199563979501872447323146617285786017413457040833853096647252495282176757667370964891089582307763252793332014110634684577275241510438935460795623158895099508356538022570772990943795127101179891821312550040505597385238071003932128751650976515586342666263903701969711589529513715648354184394669982822015645429160867813979611140609363112226286104769818496188762050564612227378368967743343698409735242567687523483613871073583201483076450563741645337691456798723334003820025909864260550025607987279304993898490653449697341369989367293215886097687051801809614329388180441198807195809708893458983328341875490575

# CRT
M = n1*n2*n3*n4
M1 = M//n1
M2 = M//n2
M3 = M//n3
M4 = M//n4
M1_ = gmpy2.invert(M1,n1)
M2_ = gmpy2.invert(M2,n2)
M3_ = gmpy2.invert(M3,n3)
M4_ = gmpy2.invert(M4,n4)
m_e = (c1*M1*M1_ + c2*M2*M2_ + c3*M3*M3_ + c4*M4*M4_) % M

print(gmpy2.iroot(m_e, e))

# (mpz(2703076773593937933), True)
# 2703076773593937933
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
Challenge 8:

One of the slowest aspects of RSA encryption and decryption operations
is the need to perform modular arithmetic mod n. The other operations
that are slow are the ones that use the decrypting exponent, d, since
d tends to be quite large like n.

One common optimization is to implement RSA operations mod p and mod q
and then use the Chinese Remainder Theorem to assemble the smaller
results into the final result mod n. This is called RSA-CRT.

Although RSA-CRT can be substantially faster than traditional RSA, it
requires saving p and q as part of the private key and then the
intermediate steps to perform an RSA operation use p and q. If a
hardware fault (like a bit flip) occurs during an operation with p or
q there is risk that p or q could get exposed in the final calculation
result.

In this challenge, two signatures are provided. One signature is valid
and the other signature was produced using RSA-CRT with a fault,
resulting in an invalid signature.

Using the faulty signature you need to recover the private key.

See https://eprint.iacr.org/2002/073.pdf for a discussion of this
issue and section 2.2 for specifics.

== Generated Public Key ==
Public Modulus (n): 23154885630854261581442853508324093951285850590669895605587380575521607235130640544163038357995530183077307108610005939771651006915357243729445798049117319493254714109948731131702737721279228901692687894303893338872375856964797219358972744318545166050544352909134282184933180708435651918762591420996061517085207453652776549270709284644419226914688644151059035005050410930727981245377188391115441239955392677194034468965281888607451952614751181223872620212423712394604641694913836491081539520184795848120063846286690175706164225270915188223556103208363481609433822007116992669527079368460205470274996573363959160287149
Encrypting Exponent (e): 65537

Signed Message (m): 76589046204045860242452095050720941865379417190758198073582782077942829633646

Good Message Signature (s): 17325267447814446311355159968784166643403597062830555186292278909407730058965908425047388536352948396884805415515011080230756248824282492130908750756123192695675198318659278263688404328209023590879438869601583177837203307625831869828767421917697572620208858182749108816360161491597773218856070998037376245034974546384410507173259914610628592075718146841935598464732970089109029209226228627059215763957981996096436107902541481923438970091699518171836243620582740860277567287363646182037455413444739511958943032953778117438478454480617990915477445067705592198996202631720932689361239443694873608130401548530381941318233

Bad Message Signature (s): 15560881472440963776812355687263772526799224459493465055411530467812341984615805222376647328602748875265740363403184343010139401584450440120706769134393997687683465315417839518347583296628663097911219566569959436210328102687469397856364290519652485072922276969140055247679930269523169632492462567935396255717642826528934615993335270136129635684773184252764824838098967401117436037823782028218281686360820286858701887330347540973559854295889323011981842854554834266081896736088393072010095414016636556324175277435257379852551709036180461462719357770502022163873660878350507927593844159774420414635489802142702898337920


What is the private decrypting exponent (d) for the public key?

这里说的是如果在使用RSA-CRT的情况下我们的q,p存在随机的错误,例如一个比特位的反转,那么我们可以通过明文和错误的签名来解出对应的私钥d。

这个实际上是一个论文里的攻击方法。

https://eprint.iacr.org/2002/073.pdf

计算的公式为:

gcd((mSe)modN,N)gcd((m-S'{^e})\,mod\,N,N)

当然这里的mod N这个操作我们要放到括号里面进行操作不然是算不出来的。实际上可以直接把括号去了。

gcd((m(SemodN))modN,N)gcd((m-(S'{^e}\,mod\,N))\,mod\,N,N)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import gmpy2
import sympy

n = 23154885630854261581442853508324093951285850590669895605587380575521607235130640544163038357995530183077307108610005939771651006915357243729445798049117319493254714109948731131702737721279228901692687894303893338872375856964797219358972744318545166050544352909134282184933180708435651918762591420996061517085207453652776549270709284644419226914688644151059035005050410930727981245377188391115441239955392677194034468965281888607451952614751181223872620212423712394604641694913836491081539520184795848120063846286690175706164225270915188223556103208363481609433822007116992669527079368460205470274996573363959160287149
e = 65537
m = 76589046204045860242452095050720941865379417190758198073582782077942829633646
S_ = 15560881472440963776812355687263772526799224459493465055411530467812341984615805222376647328602748875265740363403184343010139401584450440120706769134393997687683465315417839518347583296628663097911219566569959436210328102687469397856364290519652485072922276969140055247679930269523169632492462567935396255717642826528934615993335270136129635684773184252764824838098967401117436037823782028218281686360820286858701887330347540973559854295889323011981842854554834266081896736088393072010095414016636556324175277435257379852551709036180461462719357770502022163873660878350507927593844159774420414635489802142702898337920

q = gmpy2.gcd(m % n - gmpy2.powmod(S_,e,n), n)
assert sympy.isprime(q)
assert n % q == 0
p = n//q
d = gmpy2.invert(e, (p-1)*(q-1))
print(d)

# 20573248550965769746668559131325998913337123760543021821465022367710197129890858581970699354350667906077354668879574070721931704726814658931071437819859034043246135810646117670919486969346926147757224408888348705655407573600563682855073971980238415232970652759492946757231168845876497417177254046486727530095271650359462396290554836565176988899415082048105336042121088708283121986247556337347604042496257691259888576934466183675054053890063203431358068667198782590000357554673617263489038364827366999921718083027059336746228419784063284929696543875661848541932537305031733107915291818420264919805043139999822520672873

得到flag为

1
# CTF{rekt_security_algorithm!}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!