Home PicoCTF 2018 Super Safe RSA 3
Writeup
Cancel

Super Safe RSA 3

Challenge

The more primes, the safer.. right.?.? Connect with nc 2018shell1.picoctf.com 54915.

Solution

We connect and get a set of RSA parameters:

1
2
3
c: 798969532868241034262201660820334428498697405198819266351660979640918089698370850085963580823359953106591774105288828682672867652949613335290035360447893613465055031850950614550860391928155270420985614349302804909553389682874636771202896787415532131111854204772669056806821882162359339598288501623562730
n: 3541776961350756146796799821164868207619475719115743434366890478881578624044753627501375811206039117157906709552318526962375639546716015765226846022541932426874729631398855600887631313842537323018023929885623095650914457879588746735283232366011283028664737579701177211757369241731005141006276936915308803
e: 65537

Based on the description this probably uses multi-prime RSA. This is identical to regular RSA except for the computation of the totient, which becomes

1
r = (p1-1) * (p2 - 1) * .. * (pn -1)

There is nothing wrong with using multiple primes, except when they become too small. We try to brute force the prime factors to find our flag:

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


c = 798969532868241034262201660820334428498697405198819266351660979640918089698370850085963580823359953106591774105288828682672867652949613335290035360447893613465055031850950614550860391928155270420985614349302804909553389682874636771202896787415532131111854204772669056806821882162359339598288501623562730
n = 3541776961350756146796799821164868207619475719115743434366890478881578624044753627501375811206039117157906709552318526962375639546716015765226846022541932426874729631398855600887631313842537323018023929885623095650914457879588746735283232366011283028664737579701177211757369241731005141006276936915308803
e = 65537

# find the prime factors
primes = list(primefac.primefac(n))

# compute totient
r = 1
for p in primes:
    r *= p-1

# decrypt
d = gmpy2.divm(1, e, r)
m = gmpy2.powmod(c, d, n)

# print flag
print("".join([chr((m >> j) & 0xff) for j in reversed(range(0, 1000 << 3, 8))]))

which prints our flag.

Flag

picoCTF{p_&_q_n0_r_$_t!!_6629910}