2021江西省赛线下赛

crypto1

题目:

from random import randint
from gmpy2 import *
from Crypto.Util.number import *
from flag import flag e = 65537 def getprime(bits):
while True:
n = 1
while n.bit_length() < bits:
n *= next_prime(randint(1, 1000))
if isPrime(n - 1):
return n - 1, next_prime(n - 1) m = bytes_to_long(flag) p, q = getprime(512)
n = p * q
print(n)
cipher = pow(m, e, n)
print(cipher) '''
1218619816262698783546648940878194669948979438203709672616480993515396961355395106056079918611561560475179643559119588585898564073516537184901016698826515936521556602092317546069579399703397931712467163230371193719052714305461017238967564606988838393544992753947092855374755747446894202750381311264877872839091
352354447911429303374519396490477565259821643971034839508568182565346164389287956989900378749729230944730331100775811131476843801977815021460665576439081472176097865974428184576142512412853496411268585776818066203487906030045789380455941042181582290374609632090947501064978978356385970005273609161215198427253
'''

思路:

  1. 直接yafu分解n
  2. 仔细看了看,好像可能是不是没有其它解法了?

crypto2

题目:

from Crypto.Util.number import *
from secret import flag, NBIT, MIDDLE
assert MIDDLE < 4096 def rsarsa(nbit):
while True:
p = getPrime(nbit)
middle = (2**nbit - 3) ^ p
q = middle + MIDDLE
if isPrime(q):
return p,q p,q = rsarsa(NBIT)
e = 0x10001
n = p * q
m = bytes_to_long(flag)
c = pow(m,e,n) print('n =', n)
print('c =', c) '''
n = 692224041388945379000542945310902880889100544298206558809223921382304144887565486168738878540375370962131523216110266003450063038852597901973959069961409252090233088923246072020448653242413438525803983280986587695098100053523677324314279892099704680639276122605007782194993832619487191722743054531524695485466578897531910673635843617334895918839728199336965513679879931120369894252383320216068550188557341291620047417322944706390751843111508918089789408109422357563835039746241760245490926252447703597477533668752930171198897054058982716965576506579176144003183647342789557878319494827627831312013617439863026665812607443
c = 307197727308287745314426467002903248074969761558679046606456172330293223597622415661766314599586983706525802752702590834171088229466177584813058269117390420554764305566689318459776899180134066369190626054796865325243251558047293127988662783785017198221284274732844911397443405439812227924713443788235973809737857889544240278704700770780579167766105940360383012181564955578959555701526997721449721679761556310570137638766549920135248234070586743609456381815893734230223940645912347773433002389063138902856398043379520285872239709077175291162768996775352120726794354655215827681853155145863834324898022202315574453344333550
'''

思路:

还是考虑直接分解n,可以尝试利用一元二次方程分解。原理如下:

因为\(x^2+bx+c=0\),所以如果找到一个\(b=a\sqrt{c}\),那么就有:

\[x^2+2\sqrt{c}\ x+c=0 \\
(x+\sqrt{c})^2=0
\]

这里有个非常相似的题:Crypto CTF 2019-roXen

其它部分这里就不再赘述,原文章写的很详尽,在这里只记录我在看的时候遇到的小小阻碍:

adlit函数实际上就是等式:\(p+adlit(p)=2^l-1\),其中\(l\)是p的二进制长度

这个推论的过程如下:

因为\(adlit(p)=(2^l-1)\oplus p\),而其中\(2^l-1\)是二进制下\(l-1\)位的数字。所以在两边同时加上p,有:

\[\begin{equation}
\begin{aligned}
p+adlit(p)&=((2^l-1)\oplus p)+p \\
p+adlit(p)&=\neg p+p
\end{aligned}
\end{equation}
\]

而\(\neg p+p\)的结果可以参考下面的程序:

p=eval(bin(2**12-1))
q=0b110101001011
k=p^q
print(bin(2**12-1))
print(len(bin(2**12-1)))
print(bin(q))
print(len(bin(q)))
print(bin(k))
print(len(bin(k)))
print(bin(q+k))
print(len(bin(q+k)))
>>>0b111111111111
>>>14
>>>0b1010110100
>>>12
>>>0b111111111111
>>>14

所以有\(\neg p+p=2^n-1\),其中\(n\)是p的位数加一(2的n次方有n+1位)

而在这个题中,adlit函数就是middle,功能是一样的(虽然我不理解为啥减三也可以……但是把上面那个代码改一改就会发现结果是一样的。)所以这样想的思路就明确了,有:

\[\begin{equation}
\begin{aligned}
p+middle&=2^{nbits}-3 \\
p+q&=2^{nbits}-3+MIDDLE
\end{aligned}
\end{equation}
\]

这里加上一个MIDDLE(\(MIDDLE<4096\))也可以在一定程度上可以抵消后面那个减三,从而可以把一个推测值直接设成\(2^{nbits}\),不过如果MIDDLE小于3,那么就可能会出现求不出来的情况~

而在这个题中我们无法完全肯定nbits的取值,所以在尽可能缩小取值之后可以进行爆破处理:

  1. 由于n的位数(二进制下)为2063,所以可以尝试将nbits设为1030或者1024等值
  2. 然后可以尝试寻找一个\(\sqrt{(p+q)^2-4p*q}\)可以完全开放的nbits和MIDDLE,从步骤1中设的值开始(或者也可以先做一个循环,找到满足\(4n-(2^{nbits}-3)<4096\)情况的nbits)
from gmpy2 import iroot,invert
from Crypto.Util.number import long_to_bytes
n=692224041388945379000542945310902880889100544298206558809223921382304144887565486168738878540375370962131523216110266003450063038852597901973959069961409252090233088923246072020448653242413438525803983280986587695098100053523677324314279892099704680639276122605007782194993832619487191722743054531524695485466578897531910673635843617334895918839728199336965513679879931120369894252383320216068550188557341291620047417322944706390751843111508918089789408109422357563835039746241760245490926252447703597477533668752930171198897054058982716965576506579176144003183647342789557878319494827627831312013617439863026665812607443
c=307197727308287745314426467002903248074969761558679046606456172330293223597622415661766314599586983706525802752702590834171088229466177584813058269117390420554764305566689318459776899180134066369190626054796865325243251558047293127988662783785017198221284274732844911397443405439812227924713443788235973809737857889544240278704700770780579167766105940360383012181564955578959555701526997721449721679761556310570137638766549920135248234070586743609456381815893734230223940645912347773433002389063138902856398043379520285872239709077175291162768996775352120726794354655215827681853155145863834324898022202315574453344333550
e = 0x10001
flag=True
nbits = 1033
while flag:
data1 = (1 << nbits) - 3
print(nbits)
for MIDDLE in range(1086,4096):
print(MIDDLE)
tmp = pow(data1 + MIDDLE,2) - 4*n
#if tmp < 0:
#continue
res,check=iroot(tmp,2)
if check:
p=(res+data1+MIDDLE)//2
q=-(res-data1-MIDDLE)//2
print(p)
print(q)
d=invert(e,(p-1)*(q-1))
print(long_to_bytes(pow(c,d,n)))
flag = False
break
nbits+=1

而且毕竟已经明确了这是一个类似一元二次方程的问题,也可以通过把p和q看做式子\((x-p)(x-q)=0\)的两个解,找到:

\[\triangle=\sqrt{b^2-4ac}
\]

可以开出平方的取值

n = 692224041388945379000542945310902880889100544298206558809223921382304144887565486168738878540375370962131523216110266003450063038852597901973959069961409252090233088923246072020448653242413438525803983280986587695098100053523677324314279892099704680639276122605007782194993832619487191722743054531524695485466578897531910673635843617334895918839728199336965513679879931120369894252383320216068550188557341291620047417322944706390751843111508918089789408109422357563835039746241760245490926252447703597477533668752930171198897054058982716965576506579176144003183647342789557878319494827627831312013617439863026665812607443
c = 307197727308287745314426467002903248074969761558679046606456172330293223597622415661766314599586983706525802752702590834171088229466177584813058269117390420554764305566689318459776899180134066369190626054796865325243251558047293127988662783785017198221284274732844911397443405439812227924713443788235973809737857889544240278704700770780579167766105940360383012181564955578959555701526997721449721679761556310570137638766549920135248234070586743609456381815893734230223940645912347773433002389063138902856398043379520285872239709077175291162768996775352120726794354655215827681853155145863834324898022202315574453344333550 from Crypto.Util.number import *
import gmpy2 def solve(a, b, c):
delta = b ** 2 - 4 * a * c
if delta < 0:
return None tmp, check = gmpy2.iroot(delta, 2)
if not check:
return None return ((-b + tmp) // (2 * a), (-b - tmp) // (2 * a),tmp,b) nbits = 1024
#这个只是一个大概的取值,毕竟这个nbits会在之后的循环中逐渐加一 flag=True while flag: data1 = (1 << nbits) for MIDDLE in range(4096):
res = solve(1, -(data1 + MIDDLE), n)
if res is not None:
p, q, r, b = res
e = 0x10001
d = inverse(e, (p - 1) * (q - 1))
print(long_to_bytes(pow(c, d, n)))
flag=False
break
nbits += 1

不过我也明确了一个问题:工具不是万能的,不能完全依赖工具(尤其是不是自己写的工具)

2021江西省赛线下赛赛后总结(Crypto)的更多相关文章

  1. CTF线下赛AWD套路小结

    近打了2场CTF线下赛,把AWD模式中的一些小套路做一些总结,本人web狗,二进制部分就不班门弄斧了. 一. AWD模式简介 AWD:Attack With Defence,比赛中每个队伍维护多台服务 ...

  2. CTF线下赛AWD模式下的生存技巧

    作者:Veneno@Nu1L 稿费:200RMB 投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿 原文:https://www.anquanke.com/post/id/8467 ...

  3. 虎符2021线下赛pwn writeup

    jdt 一个图书管理系统,但并不是常规的堆题.edit和show函数可以越界.edit函数和show函数相互配合泄露libc基地址,将main函数的返回地址覆盖成onegadgets拿shell. f ...

  4. 某团队线下赛AWD writeup&Beescms_V4.0代码审计

    还是跟上篇一样.拿别人比赛的来玩一下.  0x01 预留后门 连接方式: 0x02 后台登录口SQL注入 admin/login.php 在func.php当中找到定义的check_login函数 很 ...

  5. 某线下赛AWD

    拿别人比赛的来玩一下,或许这就是菜的力量吧. 0x01 任意文件读取: switch ($row['media_type']) { case 0: // 图片广告 ...... break; case ...

  6. ogeek线下赛web分析1-python-web

    1.python from flask import Flask, request, render_template,send_from_directory, make_response from A ...

  7. Redhat 线下赛 WEB WP

    赛制 给每个参赛队伍所有题目的gamebox,参赛队伍在开赛时就能获取到所有题目的源码,可以选择先防御后攻击或先攻击后防御,只要拿到gamebox上的flag,机器人就会自动帮你攻击场上所有未防御选手 ...

  8. 2017CUIT校赛-线上赛

    2017Pwnhub杯-CUIT校赛 这是CUIT第十三届校赛啦,也是我参加的第一次校赛. 在被虐到崩溃的过程中也学到了一些东西. 这次比赛是从5.27早上十点打到5.28晚上十点,共36小时,中间睡 ...

  9. 2019第十二届全国大学生信息安全实践创新赛线上赛Writeup

    本文章来自https://www.cnblogs.com/iAmSoScArEd/p/10780242.html  未经允许不得转载! 1.MISC-签到 下载附件后,看到readme.txt打开后提 ...

随机推荐

  1. Nginx入门--从核心配置与动静分离开始

    写在前面 优化我们项目,服务器部署,不仅仅可以是分布式,Nginx一样可以通过动静分离,负载均衡来减轻我们服务器的压力.Nginx的知识链,学习周期相对比较长,博主也是刚刚入门,这篇就先从实现基础的动 ...

  2. [学习笔记] Oracle运算符、连接符、结果去重、范围查询、模糊查询

    运算符 符号 解释 + 加法 - 减法 * 乘法 / 除法,结果是浮点数 = 等于 > 大于 < 小于 <>或者!= 不等于 >= 大于或者等于 <= 小于或者等于 ...

  3. ATA考试

    一.确定机房作为ATA考试机器的数量. (1)确定本次ATA考试本校每个机房上报了多少台机器. ATA考试机的使用总数量不包含ATA管理机器.在上报机房机器数量的时候,在      机房的总数量上减去 ...

  4. Ant 调用 Shell/CMD 命令

    Ant中调用Makefile,使用shell中的make命令 <?xml version="1.0" encoding="utf-8" ?> < ...

  5. Java复制文件用数据流方法,renameTO()方法是相当于剪切操作

    我想达到的效果是,一个文件复制到另一个地方,然后重命名 //判断是否存在 File file = new File("D:/tomcat9.0.12/apache-tomcat-9.0.12 ...

  6. Linux上天之路(二)之Linux安装

    1. vmware workstation使用 VMware是全球领先的虚拟化公司,为客户提供虚拟化解决方案,个人虚拟化产品workstation,可以让用户通过虚拟化的方式在一台物理电脑中安装多个操 ...

  7. antd的table组件设置Column的width列宽度不生效问题

    超长连续字段(长数字和长单词) 破坏表格布局的问题(即使你指定了列的宽度也会被挤开),之前组件内默认加过 word-break: break-word; 去纠正此类布局,又会引起其他的问题. 所以最好 ...

  8. [STM32F10x] 利用定时器测量频率

    硬件:STM32F103C8T6 平台:ARM-MDk V5.11 原理 利用STM32F10x的定时器的捕获(Capture)单元测量输入信号的频率. 基本原理是通过两次捕获达到的计数器的差值,来计 ...

  9. wordcount报错:org.apache.hadoop.mapreduce.lib.input.InvalidInputException: Input path does not exist:

    Exception in thread "main" org.apache.hadoop.mapreduce.lib.input.InvalidInputException: In ...

  10. Java 异步 I/O

    Java 中的异步 I/O 简称 AIO, A 即 Asynchronous.AIO 在 JDK1.7 时引入,基于操作系统提供的异步 I/O 通信模型,封装了一些进行异步 I/O 操作的 API. ...