MRCTF 2020 Crypto writeup_ctf vigen猫re-程序员宅基地

技术标签: python  CTF  密码学  

MRCTF 2020 Crypto writeup

古典密码知多少

一张图,标准银河字母+圣堂武士+猪圈变形,在网上找密码表对照解出 FGCPFLIRTUASYON ,栅栏栏数3,FLAGISCRYPTOFUN。

flag:MRCTF{CRYPTOFUN}

天干地支+甲子

网上找天干地支对应的数字表,都加上 60 转 ascii 得到 Goodjob。

flag:MRCTF{Goodjob}

keyboard

对照九键键盘,重复次数就是某个按键的第几个字母,mobilephone。

flag:MRCTF{mobilephone}

vigenere

复制到在线网站就可以解了….比如这个 ,解开看最后一行。

flag:mrctf{vigenere_crypto_crack_man}

babyRSA

这题利用 P_p 和 P_factor 计算出 _P ,用 Q_1 ,Q_2 ,sub_Q 计算出 _Q ,然后解 RSA 就可以了。

P_p 往前找 9 个素数,约隔 1500 出现一个素数,递减枚举即可得到 P[0] ,得到 P 列表,然后就是解一个多素因子 n 的 RSA ,得到 _P .

_Q 就更简单了…把出题人故意写的 sub_Q ** Q_2 % Q_1 改成 pow(sub_Q,Q_2,Q_1) 就可以了。快速幂取模算法当然远比计算出结果再取模快得多。

exp:

import sympy
import random
from gmpy2 import gcd, invert
from Crypto.Util.number import *
from z3 import *
base = 65537
Ciphertext =  1709187240516367141460862187749451047644094885791761673574674330840842792189795049968394122216854491757922647656430908587059997070488674220330847871811836724541907666983042376216411561826640060734307013458794925025684062804589439843027290282034999617915124231838524593607080377300985152179828199569474241678651559771763395596697140206072537688129790126472053987391538280007082203006348029125729650207661362371936196789562658458778312533505938858959644541233578654340925901963957980047639114170033936570060250438906130591377904182111622236567507022711176457301476543461600524993045300728432815672077399879668276471832
 
#计算_P
P_p =206027926847308612719677572554991143421
P_factor =213671742765908980787116579976289600595864704574134469173111790965233629909513884704158446946409910475727584342641848597858942209151114627306286393390259700239698869487469080881267182803062488043469138252786381822646126962323295676431679988602406971858136496624861228526070581338082202663895710929460596143281673761666804565161435963957655012011051936180536581488499059517946308650135300428672486819645279969693519039407892941672784362868653243632727928279698588177694171797254644864554162848696210763681197279758130811723700154618280764123396312330032986093579531909363210692564988076206283296967165522152288770019720928264542910922693728918198338839
t=0
while t<9:
      P_p-=2
      if isPrime(P_p):t+=1
#print(P_p)
#206027926847308612719677572554991142909
 
P = [0 for i in range(17)]
P[0] = 206027926847308612719677572554991142909
for i in range(1, 17):
      P[i] = sympy.nextprime(P[i-1])
phi_n=1
n=1
for i in range(17):
      phi_n *= P[i]-1
      n *= P[i]
p=pow(P_factor,invert(base,phi_n),n)
_P=sympy.nextprime(p)
 
#计算_Q
def gen_q():
      Q_1=103766439849465588084625049495793857634556517064563488433148224524638105971161051763127718438062862548184814747601299494052813662851459740127499557785398714481909461631996020048315790167967699932967974484481209879664173009585231469785141628982021847883945871201430155071257803163523612863113967495969578605521
      Q_2=151010734276916939790591461278981486442548035032350797306496105136358723586953123484087860176438629843688462671681777513652947555325607414858514566053513243083627810686084890261120641161987614435114887565491866120507844566210561620503961205851409386041194326728437073995372322433035153519757017396063066469743
      sub_Q=168992529793593315757895995101430241994953638330919314800130536809801824971112039572562389449584350643924391984800978193707795909956472992631004290479273525116959461856227262232600089176950810729475058260332177626961286009876630340945093629959302803189668904123890991069113826241497783666995751391361028949651
      Q = pow(sub_Q,Q_2,Q_1)
      return sympy.nextprime(Q)
_Q = gen_q()
 
#解RSA
_E = base
_M = pow(Ciphertext, invert(_E,(_P-1)*(_Q-1)), _P * _Q)
M=long_to_bytes(_M)
print(M)
flag:MRCTF{
    sti11_@_b@by_qu3st10n}

Easy_RSA

这题还是计算出 _P 和 _Q 解 RSA 的题。

  1. 先是利用 n 和 phi_n ,算出 p 和 q,n=p∗q ,phi_n=(p−1)∗(q−1)=p∗q−p−q−1 , 所以 p+q=n−phi_n−1 , 令 k=n−phi_n−1,把 p=k−q 带入到 n=p∗q 中就可以作为二次函数利用单调性二分法求解了,时间复杂度 O(logn) 相当快,脚本在这里。这样 _P 就有了。

  2. 另一个问题是用给出的 n 和 e*d 分解出 p 和 q , 这个算法可以直接用…
    在这里插入图片描述
    exp:

import base64
from random import randint
import sympy
from Crypto.Util.number import bytes_to_long, getPrime, getRandomNBitInteger,isPrime, long_to_bytes
from gmpy2 import gcd, invert

Ciphertext = 40855937355228438525361161524441274634175356845950884889338630813182607485910094677909779126550263304194796000904384775495000943424070396334435810126536165332565417336797036611773382728344687175253081047586602838685027428292621557914514629024324794275772522013126464926990620140406412999485728750385876868115091735425577555027394033416643032644774339644654011686716639760512353355719065795222201167219831780961308225780478482467294410828543488412258764446494815238766185728454416691898859462532083437213793104823759147317613637881419787581920745151430394526712790608442960106537539121880514269830696341737507717448946962021
_E = 65537
q = 118975085954858660642562584152139261422493348532593400307960127317249511761542030451912561362687361053191375307180413931721355251895350936376781657674896801388806379750757264377396608174235075021854614328009897408824235800167369204203680938298803752964983358298299699273425596382268869237139724754214443556383
p = 118153578345562250550767057731385782963063734586321112579869747650001448473633860305142281504862521928246520876300707405515141444727550839066835195905927281903880307860942630322499106164191736174201506457157272220802515607939618476716593888428832962374494147723577980992661629254713116923690067827155668889571
assert (p < q)
factor2 = 2021 * p + 2020 * q
_P = sympy.nextprime(factor2)

Q_n = 20714298338160449749545360743688018842877274054540852096459485283936802341271363766157976112525034004319938054034934880860956966585051684483662535780621673316774842614701726445870630109196016676725183412879870463432277629916669130494040403733295593655306104176367902352484367520262917943100467697540593925707162162616635533550262718808746254599456286578409187895171015796991910123804529825519519278388910483133813330902530160448972926096083990208243274548561238253002789474920730760001104048093295680593033327818821255300893423412192265814418546134015557579236219461780344469127987669565138930308525189944897421753947
Q_E_D = 100772079222298134586116156850742817855408127716962891929259868746672572602333918958075582671752493618259518286336122772703330183037221105058298653490794337885098499073583821832532798309513538383175233429533467348390389323225198805294950484802068148590902907221150968539067980432831310376368202773212266320112670699737501054831646286585142281419237572222713975646843555024731855688573834108711874406149540078253774349708158063055754932812675786123700768288048445326199880983717504538825498103789304873682191053050366806825802602658674268440844577955499368404019114913934477160428428662847012289516655310680119638600315228284298935201
f, s, tem = Q_E_D-1, 0, 1
while f % 2 == 0:
    f = f // 2
    s += 1
i, a, t = s, 2, f
b = pow(a, t, Q_n)
while b == 1:
    a = sympy.nextprime(a)
    b = pow(a, t, Q_n)

while i != 1:
    c = pow(b, 2, Q_n)
    if c != 1:
        b = c
        i -= 1
    else:
        break
if b == Q_n-1:
    a = sympy.nextprime(a)
    b = pow(a, t, Q_n)
    while b == 1:
        a = sympy.nextprime(a)
        b = pow(a, t, Q_n)

p = gcd(b-1, Q_n)
q = Q_n//p
factor2 = 2021 * p - 2020 * q
if factor2 < 0:
    factor2 = (-1) * factor2
_Q = sympy.nextprime(factor2)

_M = pow(Ciphertext, invert(_E, (_P-1)*(_Q-1)), _Q*_P)
m = long_to_bytes(_M)
print(m)

flag:MRCTF{Ju3t_@_31mp13_que3t10n}

real_random

感觉这题主要代码就是下面截取的部分,对 x 进行若干次 (b * x + c) % m 运算,最后会得到 gen_N(flag[t]) ,所以只要知道第几个 i 是满足random[t][i] = gen_N(flag[t]) 就可以了,尝试了几次发现得到的 i 是和 c 是无关的,当然也是和 gen_N(flag[t]) 无关。

x = ((gen_N(flag[t]) - c) * _b) % m
for i in range(2**d):
    x = (b * x + c) % m
for i in range(times):
    x = (b * x + c) % m
    random[t][i] = x

既然 i 的值仅与 p , q , d 等变量有关,那么就可以自定义一个数 K 来代替 flag[t] ,本地利用给出的 p , q , d 算出其他变量(p q 很容易用 M 枚举出来),一模一样的跑一遍和服务器上一样的程序,本地得到的 i 就一定是服务器上的 i ,send 上去就可以了。

得到的是 (flag * 16^2) + flag 的结果,对 16^2 取模就是 flag 。

exp:

from pwn import *
from Crypto.Util.number import*
from gmpy2 import*
import re
 
host, port = ('38.39.244.2', 28101)
r = remote(host, port)
 
null = r.recvline().decode()
null = r.recvline().decode()
 
def gen_N(flag):
    return (flag * 16**2) + flag
 
def reM(M):
    p = getPrime(6)
    q = getPrime(6)
    while (p-1)*(q-1) != M:
        p = getPrime(6)
        q = getPrime(6)
    m = p * q * 2 ** 5
    b = 4 * p * q + 1
    return (b, m)
 
def Slove(M, d):
    b, m = reM(M)
    c = getPrime(10)
    _b = invert(b, m)
    times = getPrime(19)
    x = ((gen_N(102) - c) * _b) % m
    for i in range(2**d):
        x = (b * x + c) % m
    for i in range(times):
        x = (b * x + c) % m
        if x == gen_N(102):
            return i
            break
 
ans = b''
while True:
    r. recvuntil('m:  ')
    M = r.recv(4).decode()
    r. recvuntil('d:  ')
    d = r.recv(2).decode()
    M = int(M)
    d = int(d)
    r. recvuntil('Now guess where the flag is ^_^ ')
    I = Slove(M, d)
    print('I=', str(I))
    r. send(str(I)+'\n')
    r. recvuntil('\n')
    k = int(r. recvline().strip(). decode())
    k %= 16**2
    ans += long_to_bytes(k)
    print(ans)

flag:MRCTF{It_13_n0t_r3@11y_r@nd0m}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41956187/article/details/105189556

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签