MTCTF 2022

感觉题目的质量一般,但是学了一下Groebner basis的理论。

strange_rsa1

利用p和q之间的倍数关系和pq=n可以求出q的近似值,然后再小范围爆破一下就能恢复q了。

e = 0x10001
n = 108525167048069618588175976867846563247592681279699764935868571805537995466244621039138584734968186962015154069834228913223982840558626369903697856981515674800664445719963249384904839446749699482532818680540192673814671582032905573381188420997231842144989027400106624744146739238687818312012920530048166672413
c = 23970397560482326418544500895982564794681055333385186829686707802322923345863102521635786012870368948010933275558746273559080917607938457905967618777124428711098087525967347923209347190956512520350806766416108324895660243364661936801627882577951784569589707943966009295758316967368650512558923594173887431924
gift = 0.9878713210057139023298389025767652308503013961919282440169053652488565206963320721234736480911437918373201299590078678742136736290349578719187645145615363088975706222696090029443619975380433122746296316430693294386663490221891787292112964989501856435389725149610724585156154688515007983846599924478524442938
nn = int(n/gift)

from gmpy2 import *
from Crypto.Util.number import *
gift = 0.9878713210057139023298389025767652308503013961919282440169053652488565206963320721234736480911437918373201299590078678742136736290349578719187645145615363088975706222696090029443619975380433122746296316430693294386663490221891787292112964989501856435389725149610724585156154688515007983846599924478524442938

for i in range(-20000,20000):
    j = iroot(nn+i,2)
    if j[1]:
        print(j[0])
        break
q = 10481297369477678688647473426264404751672609241332968992310058598922120259940804922095197051670288498112926299671514217457279033970326518832408003060034369
p = n//q
phi = (p-1)*(q-1)
d = invert(65537,phi)
print(long_to_bytes(int(pow(c,d,n))))

strange_rsa2

未知数有p,a,t,可以设两个未知数a和t,在模n下建立方程组。模n和模p理论上是一样的,利用groebner_basis()可以在求出a和t的时候把p求出来,主要是因为ka-k * a等于p的某个倍数。exp:

from Crypto.Util.number import *

def my_poly(coes,x):
    res=0
    for i in range(1,513):
        res+=coes[i-1]*(x^i)
    return res

e = 0x10001
flag1 = b'flag{a5537b232c1ab750e0db61ec352504a301b7b212}'
k = bytes_to_long(flag1)
open('strange_rsa_output.txt','r').read()
R.<a,ka>=PolynomialRing(Zmod(n))
coes1=gift[0][1:]
coes2=gift[1][1:]
f1=my_poly(coes1,a)+gift[0][0]
f2=my_poly(coes2,ka)+gift[1][0]
# 这里modn和modp对比 只是整体系数多乘了某个常数 所以结果是一样的
res=Ideal([f1,f2,ka-k*a]).groebner_basis()
print(res)
# 常数项的值
res=[x.constant_coefficient() for x in res]
a,ka,p=list(map(int,res))
print(a,t,p)
q=n//p
d=inverse(e,(p-1)*(q-1))
m=pow(c,d,n)
print(long_to_bytes(int(m)))

关于Groebner basis,参考文章,这篇是相对比较容易理解的。
关于这个知识点还有红帽杯的相关题目,参见12.

strange_rsa3

这道题目是和t5uppari师傅一起交流做出来的,考点也就是AGCD和一些数论推导。具体过程见exp吧,时间有点长记不清了。

from Crypto.Util.number import long_to_bytes

n = [334024028297795358428409534536782438908850190596668304865805437854374647984162763213581202801755428896203566172506219587266859416880045688129543855047675462354257676254231028533265496444966553195988075269677126779791155950793986187076641998741755872346979307739639779735262978907659727511419480461209503641512912873117056664008629779726881137366723127568036608925132936367006658464077463797854166622020483102972486974655232026096153672010479488999300909745157075526157596970246521452157940857495163175605553461432715056788388724755538433445976849818771932805940067427962262593386608298455471107791678224956504101174392785507134071131842103995133811964997751791768061100121699973057595724142612170517768245173187399850847945628945800042668385798893530527806229363060713249, 270672332309468804376393577492871858269490099887383011988714622534037610808764741901954257217313289938393835900354736668003700671505047142365053976908516056996483106174902631762442253779775073373220342445779447626486345253598470015470094856727845150372622299396840670432953284676150980428391739322739397783248924710490946083987879121564403742528241040454099534823772379455574658130173290640751198753015984316400694738114541263533626932367096040344071742474883684682734122111076840572805111010694147825191233741720325878397443178835435703420465683485344417909319591496135706730327376897531024858122747777315158814568580929655522627811650949169204543250919027738723235091257934106114809110289433115714333069841583284243937630033653684708127947780848521445941847102881070046]
c = 24426016715355498456650532748209528249200902516644306644652290745346403378221744208791754411669322694597831272399935610924080672864361088045894354412944203199767471898920740773322967470374385635042086816010876203117884874681450622109443867183037282062248951073356702181165103759051513426785435705002047708435055880616309144483691648077981524802908185706596363674820857151388761087408514551645305031742705266691826719380663571699663832536944531865183586885154128228789310222929701360939023228059118720311899056620389378996862413971733056546988166759451010742768802840638380019172710929867945108511664271273569394689619
g = 173299379625576798749821685155193435290573235640007530711924098468561852299646118206367598564087551037396665586630782838190274697684611102346492601699992667822233634078800006099513099432664305226448819277556828816420517850404262393535832488384876680039695417291460237594174659357055221582914415278609167623124281569332881993050546046852564902573985929794261636296569394448935231131668411811662581097119330330246497311885207256858435515769776396794250803110128999

mat = [[2 ^ 1024,n[1]],[0,-n[0]]]
mat = matrix(ZZ,mat)
L = mat.LLL()[0]
p = mat.solve_left(L)
p = [-i for i in p]
print(p)

mat = [
    [2 ** 1024,n[1]],
    [0,-n[0]]
]
mat = matrix(ZZ,mat)
r = mat.LLL()[0]
p = r * mat ** (-1)

p = [int(abs(p[0])),int(abs(p[1]))]

k = (-p[1] * inverse_mod(g,p[0]) % p[0]) + p[0] * 0
print(int(k).bit_length())
print(k)
a = (g * k * inverse_mod(p[0],p[1]) % p[1]) + p[1] * 1
print(int(a).bit_length())
print(a)

qh = ((int(n[0] // p[0]) >> 600) * 2 ** 600)
# print(qh)
# print((q >> 600))
ql = ((a * n[0] - n[1] - g * k * qh) * inverse_mod(g * k,p[1] ** 2) % p[1] ** 2)
print(int(ql).bit_length())
# print(qh + ql - q)
# q = qh + ql
# # print(q)
e = 65537
q = qh + ql
d = inverse_mod(e,q - 1)
m = pow(c,d,q)
print(long_to_bytes(int(m)))

至此,MTCTF的三道题目全部解答完毕。

posted @ 2022-11-26 18:08  ZimaB1ue  阅读(313)  评论(0编辑  收藏  举报