K3RN3LCTF 2021 - Non Square Freedom 1
TL;DR
- という形のMulti-Prime RSA
- となるを用いてをくれる
- 一見それを文字列に直して終わりに見えるが、パディングのせいでフラグがの倍数になり、通常の復号が出来ない
- は求まるのでを求めてこれで法をとったりしながらフラグを導出する
Prerequisite
- RSA周りの細々とした数学
- 法を取らずに表したり、別の法とすり替えたりするのがメイン
Writeup
#!/usr/bin/env python3
#
# Polymero
#
# Imports
from Crypto.Util.number import getPrime
import os
# Local imports
with open('flag.txt','rb') as f:
FLAG = f.read()
f.close()
# Key gen
P = getPrime(512//8)
Q = getPrime(256)
R = getPrime(256)
N = P**8 * Q * R
E = 0x10001
def pad_easy(m):
m <<= (512//8)
m += (-(m % (P**2)) % P)
return m
# Pad FLAG
M = pad_easy(int.from_bytes(FLAG,'big'))
print('M < N :',M < N)
print('M < P**8 :',M < (P**8))
print('M < Q*R :',M < (Q*R))
# Encrypt FLAG
C = pow(M,E,N)
print('\nn =',N)
print('e =',E)
print('c =',C)
# Hint
F = P**7 * (P-1) * (Q-1) * (R-1)
D = inverse(E,F)
print('\nD(C) =',pow(C,D,N))
#----------------------------------------------------
# Output
#----------------------------------------------------
# M < N : True
# M < P**8 : True
# M < Q*R : True
#
# n = 68410735253478047532669195609897926895002715632943461448660159313126496660033080937734557748701577020593482441014012783126085444004682764336220752851098517881202476417639649807333810261708210761333918442034275018088771547499619393557995773550772279857842207065696251926349053195423917250334982174308578108707
# e = 65537
# c = 4776006201999857533937746330553026200220638488579394063956998522022062232921285860886801454955588545654394710104334517021340109545003304904641820637316671869512340501549190724859489875329025743780939742424765825407663239591228764211985406490810832049380427145964590612241379808722737688823830921988891019862
#
# D(C) = 58324527381741086207181449678831242444903897671571344216578285287377618832939516678686212825798172668450906644065483369735063383237979049248667084304630968896854046853486000780081390375682767386163384705607552367796490630893227401487357088304270489873369870382871693215188248166759293149916320915248800905458
#
(※普段Writeupを書く時の慣習のせいで、ソースコード上で大文字になっている値の多くを小文字にして書きます)
Multi-PrimeなRSAでとなっている。加えてというに対してとなるが定義され、が与えられる。
よく考えなくても、が暗号文の復号結果のように思えるが実は罠がある。暗号化する際に、フラグにパディングが加わるがこのせいでフラグはの倍数となってしまい、と互いに素で無いことから通常の復号が出来ない(フラグを何乗してもの倍数となってしまい、1になるような指数が存在しない)。このパディングは次のようになっている。
- をフラグを64bit左シフトした結果とする(23行目の
<<= (512//8)
に対応) - を計算する
- を計算する
- を返す
2より、、3より、となるような整数が存在する。よって、前者を後者に代入して移項すると、となって、右辺がの倍数であることは自明だから、パディング後のフラグであるもの倍数となる。
というわけで以後はとおく。したがってが成り立つ。これより、となるので、はの倍数となる。よって、となるから、これの8乗根を計算してを求めることが出来る。また、ついでにを求めることが出来、今後この値を法として使う事があるから計算しておく。
さて、与えられた値はだった。これをを用いて計算してみると、に関しては乗で元に戻ることから、次のようになる。
よってある整数が存在してとなるから両辺で割ると次のようになる。
これを両辺で法を取ることで次のようになる。
これを変形するとであるから、次が成り立ち、を求めることが出来る。
が求まったのでを計算するとフラグが求められる。
Code
from math import gcd
from Crypto.Util.number import isPrime, long_to_bytes
from xcrypto.num_util import int_nth_root
n = 68410735253478047532669195609897926895002715632943461448660159313126496660033080937734557748701577020593482441014012783126085444004682764336220752851098517881202476417639649807333810261708210761333918442034275018088771547499619393557995773550772279857842207065696251926349053195423917250334982174308578108707
e = 65537
c = 4776006201999857533937746330553026200220638488579394063956998522022062232921285860886801454955588545654394710104334517021340109545003304904641820637316671869512340501549190724859489875329025743780939742424765825407663239591228764211985406490810832049380427145964590612241379808722737688823830921988891019862
dc = 58324527381741086207181449678831242444903897671571344216578285287377618832939516678686212825798172668450906644065483369735063383237979049248667084304630968896854046853486000780081390375682767386163384705607552367796490630893227401487357088304270489873369870382871693215188248166759293149916320915248800905458
p8 = gcd(n,c)
p = int_nth_root(p8, 8)
print(p)
assert isPrime(p) and n % (p**8) == 0
qr = n // (p**8)
k = dc * pow(p, -1, qr) % qr
flag = k*p
print(long_to_bytes(flag))
Flag
flag{y34_th1s_1s_n0t_h0w_mult1pr1m3_RS4_w0rks_buddy}
Resources
- K3RN3LCTF 2021 - Non-Square Freedom (1 and 2) - Polymero | Sebastiaan Venendaal: 作問者Writeup
- これ読んでて気付いたけどなので↑みたいな遠回りなことをしなくて良い
- K3RN3LCTF-2021/nonsquarefreedom_easy.py at main · Kasimir123/K3RN3LCTF-2021: 問題リポジトリ
Thanks for reading! Read other posts?