window.onload=function(){ /*页面加载完成之后生成博客目录*/ BlogDirectory.createBlogDirectory("cnblogs_post_body","h2","h3",20); }

[LitCTF 2023]baby_xor

题目分数:447

题目评分:3.8

题目标签: RSAcoppersmith

题目描述:

- 题目描述:探姬姐姐也很疑惑捏!
- 出题人:3tefanie丶zhouflag以NSSCTF{}形式提交

附件:

附件信息
 from Crypto.Util.number import *
from secret import flag

m = bytes_to_long(flag)
assert len(flag)==32
p = getPrime(512)
q = getPrime(512)
n = p*q
e = 65537
c1 = p^m
c2 = pow(m,e,n)
print(f'n = {n}')
print(f'c1 = {c1}')
print(f'c2 = {c2}')
"""
n = 139167681803392690594490403105432649693546256181767408269202101512534988406137879788255103631885736461742577594980136624933914700779445704490217419248411578290305101891222576080645870988658334799437317221565839991979543660824098367011942169305111105129234902517835649895908656770416774539906212596072334423407
c1 = 11201139662236758800406931253538295757259990870588609533820056210585752522925690049252488581929717556881067021381940083808024384402885422258545946243513996
c2 = 112016152270171196606652761990170033221036025260883289104273504703557624964071464062375228351458191745141525003775876044271210498526920529385038130932141551598616579917681815276713386113932345056134302042399379895915706991873687943357627747262597883603999621939794450743982662393955266685255577026078256473601
"""

解题:

1、分析附件c1 = p ^ m,可知想要得到m需要知道p,问题就是p如何得到?

本题考查的是RSA中coppersmith定理,在了解定理后便可入手了。

首先,明文长度已知,p的总长位数pbits=512,因此需要利用c1对p的高位进行爆破,通常取pbits的一半

import gmpy2
from tqdm import *

n = 139167681803392690594490403105432649693546256181767408269202101512534988406137879788255103631885736461742577594980136624933914700779445704490217419248411578290305101891222576080645870988658334799437317221565839991979543660824098367011942169305111105129234902517835649895908656770416774539906212596072334423407
c1 = 11201139662236758800406931253538295757259990870588609533820056210585752522925690049252488581929717556881067021381940083808024384402885422258545946243513996
e=65537
pbits = 512
p_high = c1 >> 256
for i in trange(2**8):
     p4 = p_high<<8
     p4 = p4 + i
     kbits = pbits - p4.nbits()
     p4 = p4 << kbits
     PR.<x> = PolynomialRing(Zmod(n))
     f = x + p4
     roots = f.small_roots(X=2^kbits, beta=0.4, epsilon=0.01)
     if roots:
         p = p4 + int(roots[0])
         break
print(p)

运行结果:

得到:

p = 11201139662236758800406931253538295757259990870588609533820056210585752522925662842097418194280333596411677923137891577493678147771013147838272857867768049

注意:这里我是在VS code里面跑的,需要借助Jupyter来实现,因为pycharm里面有PR.<>的问题有点恶心,不想解决了。使用Jupyter方法可以参考

https://blog.csdn.net/Z987421/article/details/123892074

安装好后,右上角默认是Python处理内核,Python是不行的,需要切换内核,即下图右上角红色圈住部分,至于如何切换内核可以参考

https://zhuanlan.zhihu.com/p/297736314

上面操作结束后运行脚本(点击全部运行)会发现有tqdm库报错问题,这个也好解决,点击左上角+代码的地方添加新的代码块,输入! pip install tqdm点击运行便可下载,

注意输入的!是英文状态的,下载完毕即可运行脚本,下面就耐心等待了,也用不了多久,大概到23%左右就得到p了。

2、在上述操作下得到p之后,下面就好解决了,利用c1 = p ^ m直接上代码

import gmpy2
from tqdm import *
from Crypto.Util.number import *

p = 11201139662236758800406931253538295757259990870588609533820056210585752522925662842097418194280333596411677923137891577493678147771013147838272857867768049
c1 = 11201139662236758800406931253538295757259990870588609533820056210585752522925690049252488581929717556881067021381940083808024384402885422258545946243513996
m = c1 ^ p
flag = long_to_bytes(m)
print(flag)
# LitCTF{oh!!!!coppersmith_is_fun}

 

posted @ 2023-05-16 12:21  Kicky_Mu  阅读(349)  评论(0编辑  收藏  举报