MTCTF

  • easy_RSA
  • Random
  • 后记

一共有四道,做出了前两道,bob师傅ak了,记录一下

easy_RSA

第一步给了这些信息:

n:0x9371c61a2b760109781f229d43c6f05b58de65aa2a674ff92334cb5219132448d72c1293c145eb6f35e58791669f2d8d3b6ce506f4b3543beb947cf119f463a00bd33a33c4d566c4fd3f4c73c697fa5f3bf65976284b9cc96ec817241385d480003cdda9649fa0995b013e66f583c9a9710f7e18396fbf461cb31720f94a0f79L
e:0x3
encrypt(m):0x5f4e03f28702208b215f39f1c8598b77074bfa238dfb9ce424af7cc8a61f7ea48ffbbd5a5e1a10f686c3f240e85d011f6c8b968d1d607b2e1d5a78ad6947b7d3ec8f33ad32489befab601fe745164e4ff4aed7630da89af7f902f6a1bf7266c9c95b29f2c69c33b93a709f282d43b10c61b1a1fe76f5fee970780d7512389fd1L
encrypt(m+1):0x5f4e03f28702208b215f39f1c8598b77074bfa238dfb9ce424af7cc8a61f7ea48ffc5c26b0c12bcff9f697f274f59f0e55a147768332fc1f1bac5bbc8f9bb508104f232bdd20091d26adc52e36feda4a156eae7dce4650f83fabc828fdcfb01d25efb98db8b94811ca855a6aa77caff991e7b986db844ff7a140218449aaa7e8L

显然是个Franklin-Reiter攻击,解密算法是coppersmith,于是用sagemath解:

def short_pad_attack(c1, c2, e, n):PRxy.<x,y> = PolynomialRing(Zmod(n))PRx.<xn> = PolynomialRing(Zmod(n))PRZZ.<xz,yz> = PolynomialRing(Zmod(n))g1 = x^e - c1g2 = (x+y)^e - c2q1 = g1.change_ring(PRZZ)q2 = g2.change_ring(PRZZ)h = q2.resultant(q1)h = h.univariate_polynomial()h = h.change_ring(PRx).subs(y=xn)h = h.monic()kbits = n.nbits()//(2*e*e)diff = h.small_roots(X=2^kbits, beta=0.5)[0]  # find root < 2^kbits with factor >= n^0.5return diff
def related_message_attack(c1, c2, diff, e, n):PRx.<x> = PolynomialRing(Zmod(n))g1 = x^e - c1g2 = (x+diff)^e - c2def gcd(g1, g2):while g2:g1, g2 = g2, g1 % g2return g1.monic()return -gcd(g1, g2)[0]n=103538999170707880415519495082746399624588432789977421406368980946804918838661315818490990720238430199853735835314279220543849187855536479273346661124943692747785561204014667595291985197472099558155942787887737269419606791177476419064861261537496866747881857408366084925531284142362626719096547205061506895737
e=3
c1=66925269811650981821227959859586784493110324331861364665148735168580155885055306700063738530802991072945263035966847007672831546078947147437704784378852465264721011186196139469374189536612608862442812168338813841666743718085960320452818524339178893764083039821915277663138316978251744969992231200498535407569
c2=66925269811650981821227959859586784493110324331861364665148735168580155885055306714758487614591737128789440678469431513168060638418391926079830877473690259031930508456232414891405790482123922059095778216110701924539262214177070523859560037230631273898273416223096540589043022873118948569559698941410852644840nbits = n.nbits()
kbits = nbits//(2*e*e)
print ("padding lenght %d bytes " % (kbits/8))
print ("upper %d bits (of %d bits) is same" % (nbits-kbits, nbits))
diff = 1m = related_message_attack(c1, c2, diff, e, n)
print(m)

参考链接
需要注意的是,这里已知m和m+1的加密结果,所以diff=1,并不需要用到short_pad_attack函数
然后得到压缩包的密码:everything_is_easy_in_this_question
里面的信息如下:280316470206017f5f163a3460100b111b2c254e103715600f13, 091b0f471d05153811122c70340c0111053a394e0b39500f0a18, 4638080a1e49243e55531a3e23161d411a362e4044111f374409, 0e0d15470206017f59122935601405421d3a244e10371560140f, 031a08080e1a540d62327f242517101d4e2b2807177f13280511, 0a090f001e491d2c111d3024601405431a36231b083e022c1d, 16000406080c543854077f24280144451c2a254e093a0333051a, 02050701120a01334553393f32441d5e1b716027107f19334417, 131f15470800192f5d167f352e0716481e2b29010a7139600c12, 1609411e141c543c501d7f232f0812544e2b2807177f00320b1f, 0a090c470a1c1d3c5a1f2670210a0011093a344e103715600712, 141e04040f49153142043a22601711520d3a331d0826
标题就告诉你是one time cipher,脚本很乱,就不放了

Random

连接端口后得到两个信息:

e*d+n=3563329754048976946603729466426236052000141166700839903323255268203185709020494450173369806214666850943076188175778667508946270492708397447950521732324059148390232744011000065982865974194986726739638097566303135573072114448615095262066554751858952042395375417151593676621825939069783767865138657768553767717034970
e*d-n=3563121718917234588723786463275555826875232380691165919033718924958406353810813480184744219046717838078497090403751007254545187720107602959381881715875898243474504999760208133192572812110967142474619366650504948619637909653723376917174456091396220576841259798792078769198369072982063716206690589554604992470787752

也就是给了e*d和n,RSA已知edn分解pq,数学原理大致就是利用一个很小的数对幂进行分解一直到不能再分解为止,爆破出p,q

from gmpy2 import next_prime, gcddef Factorize(n, ed):g = 2while True:k = ed-1while not k & 1:k //= 2p = int(gcd(pow(g, k, n) - 1, n)) % nif p > 1:print(g)return (p, n // p)g = int(next_prime(g))if __name__ == "__main__":n = 104017565871178939971501575340112562454393004836992144768171622389677604840484994312793583974506432289548886013830127200541386300397244284320008224080452457863872125395966395146581042009792132509365457899093476717102397445859172446049330231365732777057809179757453711728433043860025829224034106974387623123609ed=3563225736483105767663757964850895939437686773696002911178487096580796031415653965179057012630692344510786639289764837381745729106408000203666201724099978695932368871885604099587719393152976934607128732108404042096355012051169236089620505421627586309618317607971836222910097506025923742035914623661579380093911361print(Factorize(n, ed))

得到:

p=10980405508174271259925333166343579553719061316941945190323939083665489902286168861229664589365210026388298173482496757264697996404794685064674668272479771
q=9473016801951797771267846445459738473973421588058140695253031511700407533935872397264731631901174665159278878658035094231228063878480145556088206641042779

之后爆破e,d,在十万以内有三组解:

e=[45687, 65553, 75247]

然后挨个试,在e=65553时成功了,下一阶段就是LCG,已知10个连续生成值得到seed,脚本如下:

from gmpy2 import gcd,invert
from functools import reduce
from Crypto.Util.number import *
lcg=[3732074616716238200873760199583586585380050413464247806581164994328669362805685831589304096519259751316788496505512, 8890204100026432347745955525310288219105398478787537287650267015873395979318988753693294398552098138526129849364748 , 3443072315415198209807083608377973177101709911155814986883368551162572889369288798755476092593196361644768257296318 , 4505278089908633319897964655164810526240982406502790229247008099600376661475710376587203809096899113787029887577355 , 9059646273291099175955371969413555591934318289156802314967132195752692549263532407952697867959054045527470269661073 , 3085024063381648326788677294168591675423302286026271441848856369032582049512915465082428729187341510738008226870900 , 8296028984288559154928442622341616376293205834716507766500770482261973424044111061163369828951815135486853862929166 , 2258750259954363171426415561145579135511127336142626306021868972064434742092392644953647611210700787749996466767026 , 4382123130034944542655156575000710851078842295367353943199512878514639434770161602326115915913531417058547954936492 , 10982933598223427852005472748543379913601896398647811680964579161339128908976511173382896549104296031483243900943925 ]def crack_unknown_modulus(states):diffs = [s1 - s0 for s0, s1 in zip(states, states[1:])]zeroes = [t2*t0 - t1*t1 for t0, t1, t2 in zip(diffs, diffs[1:], diffs[2:])]modulus = abs(reduce(gcd, zeroes))return crack_unknown_multiplier(states, modulus)
def crack_unknown_multiplier(states, modulus):multiplier = (states[2] - states[1]) * invert(states[1] - states[0], modulus) % modulusreturn crack_unknown_increment(states, modulus, multiplier)
def crack_unknown_increment(states, modulus, multiplier):increment = (states[1] - states[0]*multiplier) % modulusreturn modulus, multiplier, increment
modulus, multiplier, increment=crack_unknown_modulus(lcg)
remultiplier=invert(multiplier,modulus)
seed=(lcg[0]-increment)*remultiplier% modulus
print(long_to_bytes(seed))

然后就得到了flag

后记

还是太菜了呀,前两道题很多细节都把握不住,在bob师傅耐心的指导下做出来了。
之前太懈怠了了,要开始多做题了。

MTCTF_Crypto相关推荐

最新文章

  1. error LNK2001: 无法解析的外部符号 “void __cdecl cv::cvtColor
  2. java中的强制类型转换:int和byte
  3. Visual Studio 2010 单元测试之一---普通单元测试:http://blog.csdn.net/tjvictor/archive/2011/02/09/6175362.aspx...
  4. Atitti.java exp ast java表达式语法ast构造器
  5. 手也很光滑的飞鸽传书
  6. Docker快速搭建Bugzilla
  7. 对团队成员公开感谢博客
  8. NUDT硕士论文LaTeX模板
  9. 模拟登陆qq空间实现(3)
  10. 手动编译源代码安装wget
  11. C++:Hello C++!
  12. Linux audit详解
  13. Win7计算机内存不足,请保存文件并关闭这些程序
  14. ArcMap学习笔记(十一)数字地形模型分析
  15. st_atime、st_mtime和st_ctime
  16. google gms包各apk的包名和类名
  17. 双链表的初始化(带头结点)
  18. aix还原Oracle数据库,【案例】Oracle数据恢复思路 Oracle FOR AIX
  19. 高中计算机选修代码,高中信息技术新课标(完整版)
  20. 【弱监督视频异常检测】2020-SPL-A Self-Reasoning Framework for Anomaly Detection Using Video-Level Labels

热门文章

  1. Struts2类型转换的说明及案例分析
  2. 博通Broadcom SDK源码学习与开发3——Cable Modem Docsis3.0
  3. python自然语言处理之lda
  4. git stash 贮藏你的修改
  5. 【Linux入门学习教程】
  6. PB导出规定格式DBF文件 dBase 3 格式 222个字段
  7. layuiadmin(iframe)+tp5开发一个小型后台内容管理系统入门
  8. 远程缝制葡萄皮,成本仅1万元,华为200万年薪博士杰作
  9. char*和char[]的区别
  10. 麒麟 android os,国内不再需要安卓系统? 麒麟OS摆脱依赖